Commit 13fdff59 authored by Guillaume Sabbagh's avatar Guillaume Sabbagh
Browse files

Tests

parent 5730dc0e
......@@ -209,11 +209,7 @@ class BouquetsPerceptifs:
applications_cones = []
for apex in apices:
domaine = [e for e in self.cat_cones1.objets if e.apex == apex]
for c in domaine:
c.transformer_graphviz()
codomaine = [e for e in self.cat_cones2.objets if e.apex == apex]
for c in codomaine:
c.transformer_graphviz()
images = itertools.product(codomaine,repeat=len(domaine))
applications = [dict(zip(domaine,image)) for image in images]
applications_cones += [applications]
......@@ -270,11 +266,7 @@ class BouquetsActifs:
applications_cocones = []
for nadir in nadirs:
domaine = [e for e in self.cat_cocones2.objets if e.nadir == nadir]
for c in domaine:
c.transformer_graphviz()
codomaine = [e for e in self.cat_cocones1.objets if e.nadir == nadir]
for c in codomaine:
c.transformer_graphviz()
images = itertools.product(codomaine,repeat=len(domaine))
applications = [dict(zip(domaine,image)) for image in images]
applications_cocones += [applications]
......
......@@ -9,7 +9,7 @@ from config import *
class CategorieCocones(Categorie):
def __init__(self, foncteur, image_op=None):
def __init__(self, foncteur):
Categorie.__init__(self,"Categorie de cocones de "+str(foncteur))
self.foncteur = foncteur
cocones = [e for nadir in foncteur.cat_cible.objets for e in foncteur.enumerer_cocones(nadir)]
......@@ -32,10 +32,12 @@ class CategorieCocones(Categorie):
ancien_nouveau = defaultdict(list)
for cle,valeur in nouveau_ancien.items():
ancien_nouveau[valeur] += [cle]
# Si le cycle est une identite il faut le faire commuter dès le début
for cycle_nouveau in nouveau_ancien:
if nouveau_ancien[cycle_nouveau].is_identite:
t = Triangle(self,[cocone]*3,[cycle_nouveau,self.identites[cocone],self.identites[cocone]])
t.faire_commuter()
# Pour les autres cycles on fait commuter que la frontière de l'arbre de composition
cycles = sorted(self.foncteur.cat_cible.enumerer_cycles(cocone.nadir),key=len)
for debut_antecedant_ancien,fin_antecedant_ancien in product(cycles, cycles+[self.foncteur.cat_cible.identites[cocone.nadir]]):
# pour chaque simplification des cycles originels, on fait la même pour les nouveaux cycles
......@@ -128,7 +130,7 @@ class CategorieCocones(Categorie):
noeud_courant = graphe[noeud_courant][0]
while type(noeud_courant) == tuple:
noeud_courant = noeud_courant[0]
noeud_initial = noeud_courant
noeud_initial = noeud_courant
#on est arrivé au bout du chemin
for cocone in self.objets:
fleches = self.enumerer_composees(noeud_initial,cocone)
......
......@@ -17,6 +17,9 @@ class Cone():
def __str__(self):
return str(self.apex)+','+'/'.join(map(lambda x:str(x.representant),self.jambes.values()))
def __repr__(self):
return str(self)+","+super().__repr__().split('object at ')[-1].split('>')[0]
def __eq__(self, other):
if issubclass(type(other),Cone):
......
......@@ -71,7 +71,7 @@ class Diagramme(Foncteur.Foncteur):
def champ_actif(self):
import CategorieCocones
return CategorieCocones.CategorieCocones(self)
def est_prohomologue_a(self,other):
"""Renvoie un foncteur isomorphisme entre les champs perceptifs des deux diagrammes s'il existe (les diagrammes sont prohomologues)
None sinon"""
......@@ -112,7 +112,10 @@ class Diagramme(Foncteur.Foncteur):
return None
images_internes_possibles = itertools.permutations(classes_degre_cone_im[degre])
applications_intra_classe += [list(map(lambda x:dict(zip(classes_degre_cone_ante[degre],x)),images_internes_possibles))]
# print(list(map(list,applications_intra_classe)))
applications_cones += [[{cle:val for app in app_intra for cle,val in app.items()} for app_intra in itertools.product(*applications_intra_classe)]]
# print(applications_cones)
for application_cones in itertools.product(*applications_cones):
application_cones = {cle:val for app in application_cones for cle,val in app.items()}
applications_fleches = []
......@@ -141,6 +144,76 @@ class Diagramme(Foncteur.Foncteur):
return foncteur
except Exception as e:
print("Warning : foncteur incoherent cree, on passe au suivant, "+str(e))
def est_homologue_a(self,other):
"""Renvoie un foncteur isomorphisme entre les champs perceptifs des deux diagrammes s'il existe (les diagrammes sont prohomologues)
None sinon"""
import FoncteurOubli
assert(self.categorie_indexee == other.categorie_indexee)
cat_cocones1 = self.champ_actif()
cat_cocones1.transformer_graphviz(complet=False)
cat_cocones2 = other.champ_actif()
cat_cocones2.transformer_graphviz(complet=False)
nadirs = set([e.nadir for e in cat_cocones1.objets])
nadirs2 = set([e.nadir for e in cat_cocones2.objets])
if nadirs != nadirs2:
return None
if len(cat_cocones1.morphismes) != len(cat_cocones2.morphismes) or len(cat_cocones1.objets) != len(cat_cocones2.objets):
return None
oubli1 = FoncteurOubli.FoncteurOubli(cat_cocones1)
oubli2 = FoncteurOubli.FoncteurOubli(cat_cocones2)
# si on note C1_o les cônes de nadir o de D1 et C2_o les cônes de nadir o de D2
# on cherche toutes les applications (C1_o1 ~> C2_o1) x (C1_o2 ~> C2_o2) x ... x (C1_oN ~> C2_oN)
applications_cones = []
for nadir in nadirs:
antecedants = [e for e in cat_cocones1.objets if e.nadir == nadir]
images = [e for e in cat_cocones2.objets if e.nadir == nadir]
if len(antecedants) != len(images):
return None
#on sépare les cônes en fonction de leurs degrés
classes_degre_cone_ante = defaultdict(list)
for ante in antecedants:
classes_degre_cone_ante[(len(cat_cocones1.morph_sortants[ante]),len(cat_cocones1.morph_entrants[ante]))] += [ante]
classes_degre_cone_im = defaultdict(list)
for im in images:
classes_degre_cone_im[(len(cat_cocones2.morph_sortants[im]),len(cat_cocones2.morph_entrants[im]))] += [im]
applications_intra_classe = []
for degre in classes_degre_cone_ante:
if len(classes_degre_cone_ante[degre]) != len(classes_degre_cone_im[degre]):
return None
images_internes_possibles = itertools.permutations(classes_degre_cone_im[degre])
applications_intra_classe += [list(map(lambda x:dict(zip(classes_degre_cone_ante[degre],x)),images_internes_possibles))]
applications_cones += [[{cle:val for app in app_intra for cle,val in app.items()} for app_intra in itertools.product(*applications_intra_classe)]]
for application_cones in itertools.product(*applications_cones):
application_cones = {cle:val for app in application_cones for cle,val in app.items()}
applications_fleches = []
for source,cible in itertools.product(cat_cocones1.objets,repeat=2):
antecedants = cat_cocones1.fleches_elem(source,cible,False)
images = cat_cocones2.fleches_elem(application_cones[source],application_cones[cible],False)
if len(antecedants) != len(images):
break
if len(antecedants) > 0:
images_possibles = itertools.permutations(images)
applications_fleches += [list(map(lambda x:dict(zip(antecedants,x)),images_possibles))]
else:
# ici on a toujours pu trouver au moins un isomorphisme entre les flèches elem
for application_fleches in itertools.product(*applications_fleches):
application_fleches = {cle:val for app in application_fleches for cle,val in app.items()}
try:
foncteur = Foncteur.Foncteur(cat_cocones1,cat_cocones2,application_cones,application_fleches)
foncteur.verifier_coherence()
# on va vérifier la coherence de l'isomorphisme
for obj in cat_cocones1.objets:
if oubli1(obj) != oubli2(foncteur(obj)):
raise Exception("L'isomorphisme ne commute pas avec les foncteurs d'oubli pour l'objet "+str(obj))
for morph in cat_cocones1.morphismes:
if oubli1(morph) != oubli2(foncteur(morph)):
raise Exception("L'isomorphisme ne commute pas avec les foncteurs d'oubli pour le morphisme "+str(morph.pretty_print()))
return foncteur
except Exception as e:
print("Warning : foncteur incoherent cree, on passe au suivant, "+str(e))
def transformer_graphviz(self, destination=None):
......@@ -170,13 +243,25 @@ class Diagramme(Foncteur.Foncteur):
os.remove(destination)
class DiagrammeObjets(Diagramme):
"""Permet de selectionner des objets sans selectionner de flèches"""
"""Permet de selectionner des objets sans selectionner de flèche"""
def __init__(self, categorie_indexee, objets_a_selectionner):
""" objets_a_selectionner est une listes d'objets à selectionner dans la catégorie."""
cat = Categorie.Categorie("Objets")
cat.ajouter_objets(range(len(objets_a_selectionner)))
Diagramme.__init__(self,cat,categorie_indexee,{i:objets_a_selectionner[i] for i in range(len(objets_a_selectionner))},dict())
class Fleche(Diagramme):
"""Permet de selectionner deux objets réliés par une flèche"""
_cat = Categorie.Categorie("1 Flèche")
_cat.ajouter_objets([1,2])
_f = Morphisme(1,2,'f')
_cat.ajouter_morphisme(_f)
def __init__(self, categorie_indexee, fleche_a_selectionner):
""" objets_a_selectionner est une listes d'objets à selectionner dans la catégorie."""
Diagramme.__init__(self,Fleche._cat,categorie_indexee,{1:fleche_a_selectionner.source,2:fleche_a_selectionner.cible},{Fleche._f:fleche_a_selectionner})
class Parallele(Diagramme):
_cat = Categorie.Categorie("Parallele")
......@@ -311,11 +396,11 @@ def main():
isomorphisme = d1.est_prohomologue_a(d2)
isomorphisme.transformer_graphviz()
# c.ajouter_morphismes([m2])
# d1.transformer_graphviz()
# d2.transformer_graphviz()
# isomorphisme = d1.est_prohomologue_a(d2)
# isomorphisme.transformer_graphviz()
c.ajouter_morphismes([m2])
d1.transformer_graphviz()
d2.transformer_graphviz()
isomorphisme = d1.est_prohomologue_a(d2)
isomorphisme.transformer_graphviz()
c.ajouter_morphismes([a])
diag = Triangle(c,"AAA",[a,a,a])
......
......@@ -8,11 +8,13 @@ class FoncteurOubli(Foncteur):
"""categorie : catégorie de cônes ou de cocônes"""
if issubclass(type(categorie),CategorieCones):
app_morph = categorie.app_morph_fleche_cone
app_obj = {cone:cone.apex for cone in categorie.objets}
elif issubclass(type(categorie),CategorieCocones):
app_morph = categorie.app_morph_fleche_cocone
app_obj = {cone:cone.nadir for cone in categorie.objets}
else:
raise Exception("Foncteur d'oubli sur une categorie qui n'est pas une categorie de cones ou de cocones")
Foncteur.__init__(self, categorie, categorie.foncteur.cat_cible, {cone:cone.apex for cone in categorie.objets},
Foncteur.__init__(self, categorie, categorie.foncteur.cat_cible, app_obj,
app_morph, representant = "Foncteur d'oubli de "+categorie.nom, is_identite = False)
......
......@@ -28,6 +28,9 @@ class Morphisme:
def pretty_print(self):
return str(self.representant)+' : '+str(self.source)+" -> "+str(self.cible)
def __repr__(self):
return pretty_print(self)+","+super().__repr__().split('object at ')[-1].split('>')[0]
def __len__(self):
return len(self.composee)
......
......@@ -4,27 +4,60 @@ import CategorieCones,CategorieCocones
import Bouquet
import random
import itertools
from Morphisme import Morphisme
random.seed(156451564156748745)
# random.seed(15617156)
cat = CategorieAleatoire.CategorieAleaIsomorph()
cat.transformer_graphviz(complet=False)
cat.transformer_graphviz(complet=True)
# cat = CategorieAleatoire.CategorieAleaIsomorph(10,16)
# cat.transformer_graphviz(complet=False)
# cat.transformer_graphviz(complet=True)
diag = Diagramme.DiagrammeAlea(cat,1)
diag.transformer_graphviz()
# diag1 = Diagramme.DiagrammeAlea(cat,1)
# diag1.transformer_graphviz()
cat_cones = CategorieCones.CategorieCones(diag)
cat_cones.transformer_graphviz(complet=False)
# cat_cones = CategorieCones.CategorieCones(diag1)
# cat_cones.transformer_graphviz(complet=False)
for lim in cat_cones.limites():
lim.transformer_graphviz()
# for lim in cat_cones.limites():
# lim.transformer_graphviz()
cat_cocones = CategorieCocones.CategorieCocones(diag)
cat_cocones.transformer_graphviz(complet=False)
# cat_cocones = CategorieCocones.CategorieCocones(diag1)
# cat_cocones.transformer_graphviz(complet=False)
for lim in cat_cocones.colimites():
lim.transformer_graphviz()
\ No newline at end of file
# for lim in cat_cocones.colimites():
# lim.transformer_graphviz()
# diag2 = Diagramme.DiagrammeAlea(cat,1)
# diag2.transformer_graphviz()
# f = diag2.est_prohomologue_a(diag1)
# if f != None:
# f.transformer_graphviz()
# b = Bouquet.Bouquets(diag1,diag2)
# b.transformer_graphviz()
# b = Bouquet.Bouquets(diag2,diag1)
# b.transformer_graphviz()
cat = Categorie.Categorie()
cat.ajouter_objets("AB")
f,g = [Morphisme('A','B','f'),Morphisme('A','B','g')]
cat.ajouter_morphismes([f,g])
cat.transformer_graphviz()
diag1 = Diagramme.Fleche(cat,f)
diag1.champ_perceptif().transformer_graphviz()
diag2 = Diagramme.Fleche(cat,g)
diag2.champ_perceptif().transformer_graphviz()
f = diag1.est_prohomologue_a(diag2)
if f != None:
f.transformer_graphviz()
f = diag1.est_homologue_a(diag2)
if f != None:
f.transformer_graphviz()
\ No newline at end of file
- Ajouter morphisme -> renvoyer la liste des cycles créés ?
- Mettre en cache les composées enumérées dans catégorie
- tester catégorie cones avec un diagramme où la catégorie indexante n'a pas de flèches (on est censé avoir toutes les permutations de jambes)
- L200-205 Catégorie -> investiguer à quoi ça sert ?
- Problème dans catégorie aléatoire : un morphisme peut avoir deux inverses (voir s'il y a pas d'autres problèmes du genre)
- Corriger catégorie aléatoire isomophisme : il faut faire commuter les composantes isomorphes
- Retirer image objets de Parallele
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment