Commit 801cea03 authored by Guillaume Sabbagh's avatar Guillaume Sabbagh
Browse files

Clusters fonctionnels

parent 79cc5242
from Morphisme import Morphisme
from CategorieCones import CategorieCones
from CategorieCocones import CategorieCocones
from config import *
import itertools
from collections import defaultdict
from copy import copy
if GRAPHVIZ_ENABLED:
from graphviz import Digraph
class BouquetAbstrait(Morphisme):
nb_viz = 0
def __init__(self,foncteur1, foncteur2, tiges, cat_cones1=None,cat_cones2=None,cat_cocones1=None,cat_cocones2=None):
self.foncteur1 = foncteur1
self.foncteur2 = foncteur2
self.tiges = list(tiges) #liste de morphismes de la catégorie cible des foncteurs
self.categorie = self.foncteur1.cat_cible
self.cat_cones1 = cat_cones1
self.cat_cones2 = cat_cones2
self.cat_cocones1 = cat_cocones1
self.cat_cocones2 = cat_cocones2
identite = False
if self.foncteur1 == self.foncteur2:
for tige in self.tiges:
if not tige.is_identite:
break
else:
for objet in self.foncteur1.app_objets.values():
if self.categorie.identites[objet] not in self.tiges:
break
else:
identite = True
Morphisme.__init__(self,self.foncteur1,self.foncteur2,str(self),identite)
def __eq__(self,other):
if issubclass(type(other),BouquetAbstrait):
if len([e for e in self.tiges if e not in other.tiges]) > 0:
return False
if len([e for e in other.tiges if e not in self.tiges]) > 0:
return False
return self.foncteur1 == other.foncteur1 and self.foncteur2 == other.foncteur2
return False
def __hash__(self):
return hash((tuple(self.tiges),self.foncteur1,self.foncteur2))
def __str__(self):
return '/'.join(map(str,self.tiges))
def __repr__(self):
return '('+str(self.foncteur1)+','+'/'.join(map(str,self.tiges))+','+str(self.foncteur2)+')'
def verifier_coherence(self):
raise NotImplementedError()
def transformer_graphviz(self, destination=None):
"""Permet de visualiser le bouquet avec graphviz
Composante rouge : diagramme 1
Composante verte : diagramme 2
Composante bleue : Cones
Composante bleue foncée : cocones
Composante orange: Bouquet"""
BouquetAbstrait.nb_viz += 1
if self.cat_cones1 == None:
self.cat_cones1 = CategorieCones(self.foncteur1)
if self.cat_cones2 == None:
self.cat_cones2 = CategorieCones(self.foncteur2)
if self.cat_cocones1 == None:
self.cat_cocones1 = CategorieCocones(self.foncteur1)
if self.cat_cocones2 == None:
self.cat_cocones2 = CategorieCocones(self.foncteur2)
image1 = self.foncteur1.categorie_image()
image2 = self.foncteur2.categorie_image()
if destination == None:
destination = "graphviz/bouquet"+str(BouquetAbstrait.nb_viz)
graph = Digraph('bouquet')
graph.attr(concentrate="true" if GRAPHVIZ_CONCENTRATE_GRAPHS else "false")
graph.attr(label="Bouquet entre "+str(self.foncteur1)+" et "+str(self.foncteur2))
for o in self.categorie.objets:
couleur = [0,0,0]
if o in image1.objets:
couleur[0] += 200
if o in image2.objets:
couleur[1] += 200
if o in [e.apex for e in self.cat_cones1.objets] or o in [e.apex for e in self.cat_cones2.objets]:
couleur[2] += 200
if o in [e.nadir for e in self.cat_cocones1.objets] or o in [e.nadir for e in self.cat_cocones2.objets]:
couleur[2] += 55
graph.node(str(o),color="#"+''.join(map(lambda x:(2-len(str(hex(x))[2:]))*"0"+str(hex(x))[2:],couleur)))#"grey60")
morphismes = self.categorie.morphismes+image1.morphismes+image2.morphismes+\
[e for cone in self.cat_cones1.objets for e in cone.jambes.values()]+\
[e for cone in self.cat_cones2.objets for e in cone.jambes.values()]+\
[e for cocone in self.cat_cocones1.objets for e in cocone.jambes.values()]+\
[e for cocone in self.cat_cocones2.objets for e in cocone.jambes.values()]+\
self.tiges
for morph in [morphismes[i] for i in range(len(morphismes)) if i==len(morphismes) or morphismes[i] not in morphismes[i+1:]]:
if not morph.is_identite or morph in [e for cone in self.cat_cones1.objets for e in cone.jambes.values()]+\
[e for cone in self.cat_cones2.objets for e in cone.jambes.values()]+\
[e for cocone in self.cat_cocones1.objets for e in cocone.jambes.values()]+\
[e for cocone in self.cat_cocones2.objets for e in cocone.jambes.values()]:
couleur = [0,0,0]
if morph in image1.morphismes:
couleur[0] += 200
if morph in image2.morphismes:
couleur[1] += 200
if morph in [e for cone in self.cat_cones1.objets for e in cone.jambes.values()]+\
[e for cone in self.cat_cones2.objets for e in cone.jambes.values()]:
couleur[2] += 200
if [e for cocone in self.cat_cocones1.objets for e in cocone.jambes.values()]+\
[e for cocone in self.cat_cocones2.objets for e in cocone.jambes.values()]:
couleur[2] += 55
if morph in self.tiges:
couleur = [255,110,0]
graph.edge(str(morph.source),str(morph.cible),label=str(morph.representant), color="#"+''.join(map(lambda x:(2-len(str(hex(x))[2:]))*"0"+str(hex(x))[2:],couleur)))
else:
graph.edge(str(morph.source),str(morph.cible),label=str(morph.representant), weight="1000", color="#"+''.join(map(lambda x:(2-len(str(hex(x))[2:]))*"0"+str(hex(x))[2:],couleur)))
graph.render(destination)
if CLEAN_GRAPHVIZ_MODEL:
import os
os.remove(destination)
class BouquetPerceptif(BouquetAbstrait):
"""Seules les contraintes sur les cônes sont prises en compte pour le bouquet perceptif"""
def __init__(self, foncteur1, foncteur2, tiges, cat_cones1=None,cat_cones2=None):
"""On peut fournir cat_cones1 et cat_cones2 pour économiser du temps de calcul."""
BouquetAbstrait.__init__(self,foncteur1, foncteur2, tiges, cat_cones1,cat_cones2)
if TOUJOURS_VERIFIER_COHERENCE:
BouquetPerceptif.verifier_coherence(self)
def verifier_coherence(self):
if self.foncteur1.cat_cible != self.foncteur2.cat_cible:
raise Exception("Incoherence Bouquet : les deux foncteurs n'ont pas la meme image.")
impl1, impl2 = [self.foncteur1.categorie_image(),self.foncteur2.categorie_image()]
for tige in self.tiges:
if tige.source not in impl1.objets:
raise Exception("Incoherence Bouquet : la tige "+str(tige)+" ne prend pas sa source dans l'image de F1")
if tige.cible not in impl2.objets:
raise Exception("Incoherence Bouquet : la tige "+str(tige)+" ne prend pas sa cible dans l'image de F2")
if self.cat_cones1 == None:
self.cat_cones1 = CategorieCones(self.foncteur1)
if self.cat_cones2 == None:
self.cat_cones2 = CategorieCones(self.foncteur2)
for cone1 in self.cat_cones1.objets:
list_qB = []
for A,pA in cone1.jambes.items():
for g in self.tiges:
if g.source == pA.cible:
list_qB += [self.categorie.Composee(pA,g)]
image_existe = False
for cone2 in self.cat_cones2.objets:
for j in cone2.jambes.values():
if j not in list_qB:
break
else:
image_existe = True
break
if not image_existe:
raise Exception("Incoherence Bouquet : le cone "+str(cone1)+" n'a pas d'image par le bouquet")
class BouquetActif(BouquetAbstrait):
"""Seules les contraintes sur les cocônes sont prises en compte pour le bouquet actif"""
def __init__(self, foncteur1, foncteur2, tiges,cat_cocones1=None,cat_cocones2=None):
"""On peut fournir cat_cocones1 et cat_cocones2 pour économiser du temps de calcul."""
BouquetAbstrait.__init__(self,foncteur1, foncteur2, tiges,None,None,cat_cocones1,cat_cocones2)
if TOUJOURS_VERIFIER_COHERENCE:
BouquetActif.verifier_coherence(self)
def verifier_coherence(self):
if self.foncteur1.cat_cible != self.foncteur2.cat_cible:
raise Exception("Incoherence Bouquet : les deux foncteurs n'ont pas la meme image.")
impl1, impl2 = [self.foncteur1.categorie_image(),self.foncteur2.categorie_image()]
for tige in self.tiges:
if tige.source not in impl1.objets:
raise Exception("Incoherence Bouquet : la tige "+str(tige)+" ne prend pas sa source dans l'image de F1")
if tige.cible not in impl2.objets:
raise Exception("Incoherence Bouquet : la tige "+str(tige)+" ne prend pas sa cible dans l'image de F2")
if self.cat_cocones1 == None:
self.cat_cocones1 = CategorieCocones(self.foncteur1)
if self.cat_cocones2 == None:
self.cat_cocones2 = CategorieCocones(self.foncteur2)
for cocone2 in self.cat_cocones2.objets:
list_pA = []
for B,qB in cocone2.jambes.items():
for g in self.tiges:
if g.cible == qB.source:
list_pA += [self.categorie.Composee(g,qB)]
image_existe = False
for cocone1 in self.cat_cocones1.objets:
for j in cocone1.jambes.values():
if j not in list_pA:
break
else:
image_existe = True
break
if not image_existe:
raise Exception("Incoherence Bouquet : le cocone "+str(cocone2)+" compose avec le bouquet n'a pas d'image")
class Bouquet(BouquetPerceptif,BouquetActif):
"""Un bouquet est à la fois perceptif et actif."""
def __init__(self, foncteur1, foncteur2, tiges, cat_cones1=None,cat_cones2=None,cat_cocones1=None,cat_cocones2=None):
"""On peut fournir cat_cones1, cat_cones2, cat_cocones1 et cat_cocones2 pour économiser du temps de calcul."""
BouquetPerceptif.__init__(self,foncteur1,foncteur2,tiges,cat_cones1,cat_cones2)
BouquetActif.__init__(self,foncteur1,foncteur2,tiges,cat_cocones1,cat_cocones2)
BouquetAbstrait.__init__(self,foncteur1,foncteur2,tiges,cat_cones1,cat_cones2,cat_cocones1,cat_cocones2)
class BouquetsPerceptifs:
def __init__(self, foncteur1, foncteur2, cat_cones1=None, cat_cones2=None):
"""On peut spécifier les catégories de cônes pour économiser du temps de calcul"""
self.foncteur1 = foncteur1
self.foncteur2 = foncteur2
if self.foncteur1.cat_cible != self.foncteur2.cat_cible:
raise Exception("Incoherence BouquetsPerceptifs : les deux foncteurs n'ont pas la meme image.")
self.cat_cones1 = CategorieCones(foncteur1) if cat_cones1 == None else cat_cones1
self.cat_cones2 = CategorieCones(foncteur2) if cat_cones2 == None else cat_cones2
self.categorie = self.foncteur1.cible
self.bouquets_perceptifs = []
# on énumère toutes les flèches de D1 à D2
objets_comma_category = {(i,j):self.categorie.enumerer_composees(self.foncteur1(i),self.foncteur2(j))\
for i in self.foncteur1.source.objets for j in self.foncteur2.source.objets}
fleches = [e for liste in objets_comma_category.values() for e in liste]
# on énumère toutes les interactions de D1 à D2
for nb_fleches in range(1,len(fleches)+1):
for interaction in itertools.combinations(fleches,nb_fleches):
ajouter_bouquet = True
for cone in self.cat_cones1.objets:
fleches_generees = set()
for jambe in cone.jambes.values():
for fleche in interaction:
if fleche.source == jambe.cible:
fleches_generees |= {self.categorie.Composee(jambe,fleche)}
cone_a_l_arrivee = False
for cone2 in self.cat_cones2.objets:
if fleches_generees == set(cone2.jambes.values()):
cone_a_l_arrivee = True
break
if not cone_a_l_arrivee:
ajouter_bouquet = False
break
if ajouter_bouquet:
self.bouquets_perceptifs += [BouquetPerceptif(self.foncteur1,self.foncteur2,interaction,cat_cones1,cat_cones2)]
def __getitem__(self,key):
return self.bouquets_perceptifs[key]
def __iter__(self):
for bouquet in self.bouquets_perceptifs:
yield bouquet
def transformer_graphviz(self):
for bouquet in self.bouquets_perceptifs:
bouquet.transformer_graphviz()
class BouquetsActifs:
def __init__(self, foncteur1, foncteur2, cat_cocones1=None, cat_cocones2=None):
"""On peut spécifier les catégories de cocônes pour économiser du temps de calcul"""
self.foncteur1 = foncteur1
self.foncteur2 = foncteur2
if self.foncteur1.cat_cible != self.foncteur2.cat_cible:
raise Exception("Incoherence BouquetsActifs : les deux foncteurs n'ont pas la meme image.")
self.cat_cocones1 = CategorieCocones(foncteur1) if cat_cocones1 == None else cat_cocones1
self.cat_cocones2 = CategorieCocones(foncteur2) if cat_cocones2 == None else cat_cocones2
self.categorie = self.foncteur1.cible
self.bouquets_actifs = []
# on énumère toutes les flèches de D1 à D2
objets_comma_category = {(i,j):self.categorie.enumerer_composees(self.foncteur1(i),self.foncteur2(j))\
for i in self.foncteur1.source.objets for j in self.foncteur2.source.objets}
fleches = [e for liste in objets_comma_category.values() for e in liste]
# on énumère toutes les interactions de D1 à D2
for nb_fleches in range(1,len(fleches)+1):
for interaction in itertools.combinations(fleches,nb_fleches):
ajouter_bouquet = True
for cocone in self.cat_cocones2.objets:
fleches_generees = set()
for jambe in cocone.jambes.values():
for fleche in interaction:
if fleche.cible == jambe.source:
fleches_generees |= {self.categorie.Composee(fleche,jambe)}
cocone_au_depart = False
for cocone1 in self.cat_cocones1.objets:
if fleches_generees == set(cocone1.jambes.values()):
cocone_au_depart = True
break
if not cocone_au_depart:
ajouter_bouquet = False
break
if ajouter_bouquet:
self.bouquets_actifs += [BouquetActif(self.foncteur1,self.foncteur2,interaction,cat_cocones1,cat_cocones2)]
def transformer_graphviz(self):
for bouquet in self.bouquets_actifs:
bouquet.transformer_graphviz()
def __getitem__(self,key):
return self.bouquets_actifs[key]
def __iter__(self):
for bouquet in self.bouquets_actifs:
yield bouquet
class Bouquets:
def __init__(self, foncteur1, foncteur2, cat_cones1=None, cat_cones2=None, cat_cocones1=None, cat_cocones2=None):
"""On peut spécifier les catégories de cônes et cocônes pour économiser du temps de calcul"""
self.foncteur1 = foncteur1
self.foncteur2 = foncteur2
self.cat_cones1 = cat_cones1
self.cat_cones2 = cat_cones2
self.cat_cocones1 = cat_cocones1
self.cat_cocones2 = cat_cocones2
self.bouquets_perceptifs = BouquetsPerceptifs(foncteur1,foncteur2,cat_cones1,cat_cones2)
print("fin création bouquets perceptifs")
self.bouquets_actifs = BouquetsActifs(foncteur1,foncteur2,cat_cocones1,cat_cocones2)
print("fin création bouquets actifs")
self.bouquets = [Bouquet(foncteur1,foncteur2,b.tiges,cat_cones1,cat_cones2,cat_cocones1,cat_cocones2)\
for b in self.bouquets_perceptifs.bouquets_perceptifs if b in self.bouquets_actifs.bouquets_actifs]
def transformer_graphviz(self):
for bouquet in self.bouquets:
bouquet.transformer_graphviz()
def __getitem__(self,key):
return self.bouquets[key]
def __iter__(self):
for bouquet in self.bouquets:
yield bouquet
class CompositionBouquets(BouquetAbstrait):
"""Appeler le constructeur de Composition n'instancie pas forcément une nouvelle composition.
Comparer les composée avec les opérateurs == et !=
/!\ si une identité incohérente est placée dans une composition valide, elle sera simplement omise /!\
"""
def __new__(cls,*bouquets):
if len(bouquets) == 0:
raise Exception("Composition de 0 bouquets")
backup = bouquets
bouquets = [m for m in bouquets if not m.is_identite] #on supprime les identités
if len(bouquets) == 0:
for i in range(1,len(backup)):
if backup[i-1] != backup[i]:
raise Exception("Composition d'identites differentes"+str(backup))
return backup[0]
elif len(bouquets) == 1:
return bouquets[0]
else:
for i in range(1,len(bouquets)):
if bouquets[i-1].cible != bouquets[i].source:
raise Exception("Composition de bouquets impossible : "+bouquets.__repr__())
tiges = bouquets[0].tiges
for i in range(1,len(bouquets)):
nouvelles_tiges = []
for t1 in tiges:
for t2 in bouquets[i].tiges:
if t1.cible == t2.source:
nouvelles_tiges += [bouquets[i].categorie.Composee(t1,t2)]
tiges = copy(nouvelles_tiges)
instance = BouquetAbstrait(bouquets[0].source,bouquets[-1].cible,tiges,bouquets[0].cat_cones1,bouquets[-1].cat_cones2,bouquets[0].cat_cocones1,bouquets[-1].cat_cocones2)
return instance
def main():
# import random
# random.seed(156)
# import CategorieAleatoire
# cat1 = CategorieAleatoire.CategorieAleaPreOrdreAcyclique(10,0.5)
# from Morphisme import Morphisme
# nouveau = Morphisme(4,7,'m')
# cat1.ajouter_morphisme(nouveau)
# cat1.transformer_graphviz()
# import Diagramme
# diag1 = Diagramme.DiagrammeAlea(cat1,1)
# diag1.transformer_graphviz()
# for i in range(100):
# random.random()
# diag2 = Diagramme.DiagrammeAlea(cat1,1)
# diag2.transformer_graphviz()
# import CategorieCones, CategorieCocones
# cat_cones1 = CategorieCones.CategorieCones(diag1)
# cat_cones1.transformer_graphviz(destination="graphviz/cat_cones1")
# cat_cones2 = CategorieCones.CategorieCones(diag2)
# cat_cones2.transformer_graphviz(destination="graphviz/cat_cones2")
# cat_cocones1 = CategorieCocones.CategorieCocones(diag1)
# cat_cocones1.transformer_graphviz(destination="graphviz/cat_cocones1")
# cat_cocones2 = CategorieCocones.CategorieCocones(diag2)
# cat_cocones2.transformer_graphviz(destination="graphviz/cat_cocones2")
# bouquets = Bouquets(diag1,diag2)
# bouquets.transformer_graphviz()
from Categorie import Categorie
from Morphisme import Morphisme
from Foncteur import Foncteur
cat = Categorie()
cat.ajouter_objets("ABCDO")
f,g,h,i,j,k,l,m = [Morphisme('O','A','f'),Morphisme('O','B','g'),Morphisme('A','B','h'),Morphisme('O','C','i'),Morphisme('O','D','j'),Morphisme('C','D','k'),Morphisme('B','C','l'),Morphisme('A','D','m')]
cat.ajouter_morphismes([f,g,h,i,j,k,l,m])
from CategoriePreordre import CategoriePreordre
cat2 = CategoriePreordre(cat)
n,o = [Morphisme('O','A','n'),Morphisme('O','B','o')]
cat2.ajouter_morphismes([n,o])
cat2.transformer_graphviz()
cat_fleche = Categorie()
cat_fleche.ajouter_objets("AB")
a = Morphisme('A','B','a')
cat_fleche.ajouter_morphismes([a])
fonct1 = Foncteur(cat_fleche,cat2,{'A':'A','B':'B'},{a:h})
fonct2 = Foncteur(cat_fleche,cat2,{'A':'C','B':'D'},{a:k})
bouquets = BouquetsPerceptifs(fonct1,fonct1)
bouquets.transformer_graphviz()
for b in bouquets.bouquets_perceptifs:
print(b)
print(b.is_identite)
bouquets2 = BouquetsPerceptifs(fonct1,fonct2)
bouquets2.transformer_graphviz()
bouquet3 = CompositionBouquets(bouquets.bouquets_perceptifs[0],bouquets2.bouquets_perceptifs[0])
bouquet3.transformer_graphviz()
if __name__ == '__main__':
main()
\ No newline at end of file
......@@ -97,7 +97,10 @@ class Categorie:
## On vérifie que les identités sont neutres
for morphisme in self(self.objets,self.objets):
if not (morphisme@self.identite(morphisme.source) == self.identite(morphisme.cible)@morphisme == morphisme):
raise Exception("Incoherence Categorie : le morphisme "+str(morphisme)+" est modifie par une identite.")
raise Exception("Incoherence Categorie : le morphisme "+str(morphisme)+" est modifie par une identite.\n"\
+repr(morphisme)+" o "+repr(self.identite(morphisme.source))+" = "+repr(morphisme@self.identite(morphisme.source))+"\n"\
+repr(self.identite(morphisme.cible))+" o "+repr(morphisme)+" = "+repr(self.identite(morphisme.cible)@morphisme)+"\n"+\
repr(morphisme))
## On vérifie l'associativité
for m1,m2,m3 in itertools.product(sorted(self(self.objets,self.objets)),repeat=3):
......
from Categorie import Categorie
import Cluster
from Cluster import ClusterActif,CompositionClustersActifs
from Diagramme import Triangle,DiagrammeIdentite, DiagrammeObjets
import itertools
from Morphisme import Composition,Morphisme
from config import TOUJOURS_VERIFIER_COHERENCE
class CategorieClustersAbstraite(Categorie):
"""Catégorie dont les objets sont des diagrammes Di d'intérêt d'une catégorie C.
Les flèches entre les diagrammes sont des clusters."""
def __init__(self,categorie,representant="Categorie de clusters"):
Categorie.__init__(self,representant)
self.categorie_initiale = categorie
# on ajoute tous les diagrammes constants
self.diagrammes_constants = dict() #{obj:Δ(obj)}
self.cat_cones_cocones = {} #{diagramme:{"cat_cones":CategorieCones,"cat_cocones":CategorieCocones}}
for obj in categorie.objets:
print(obj)
diag_constant = DiagrammeObjets(categorie,[obj])
diag_constant.representant = "C("+str(obj)+")"
self.diagrammes_constants[obj] = diag_constant
self.ajouter_diagramme_interet(diag_constant)
if TOUJOURS_VERIFIER_COHERENCE:
self.verifier_coherence2()
def verifier_coherence2(self):
for A,B,C in itertools.product(self.objets,repeat=3):
for morph1 in self.fleches_elem(A,B,inclure_id=False):
for morph2 in self.fleches_elem(B,C,inclure_id=False):
if Composition(morph1,morph2) not in self.Composee.loi_de_composition:
raise Exception("Incohérence CategorieClustersAbstraite : les morphismes "+str(morph1)+" et "+str(morph2)+" n'ont pas de composée dans la loi de composition")
def ajouter_diagramme_interet(self,diagramme):
if diagramme.cat_cible != self.categorie_initiale:
raise Exception("Incohérence CategorieClustersAbstraite : tentative d'ajout d'un diagramme d'interet qui n'a pas pour cible la meme categorie initiale que les autres diagrammes."+str(diagramme))
self.ajouter_objet(diagramme)
for obj in self.objets:
cluster = self.chercher_clusters(obj,diagramme)
self.ajouter_morphismes(cluster)
if obj != diagramme: #on a déjà fait les flèches de diag vers diag
cluster = self.chercher_clusters(diagramme,obj)
self.ajouter_morphismes(cluster)
for A,B,C in itertools.product(self.objets,repeat=3):
for morph1 in self.fleches_elem(A,B,False):
for morph2 in self.fleches_elem(B,C,False):
composee = self.composer_clusters(morph1,morph2)
for fleche in self.morphismes:
if fleche == composee:
composee = fleche
break
else:
raise Exception("Composition des clusters n'est pas un cluster "+str(morph1)+" "+str(morph2)+" "+str(composee)+"\n"+str(self.morphismes))
diagramme = Triangle(self,[A,B,C],[morph1,morph2,composee])
diagramme.faire_commuter()
def chercher_clusters(self,source,cible):
raise NotImplementedError("Les classes filles doivent implementer la méthode chercher_clusters")
def composer_clusters(self,cluster1,cluster2):
raise NotImplementedError("Les classes filles doivent implementer la méthode composer_clusters")
class CategorieClustersActifs(CategorieClustersAbstraite):
"""Catégorie fleurie où les morphismes sont des bouquets actifs"""
def __init__(self,categorie,representant="Categorie de clusters actifs"):
CategorieClustersAbstraite.__init__(self,categorie,representant)
def chercher_clusters(self,source,cible):
result = ClusterActif(source,cible)
return [result] if result != None else []
def composer_clusters(self,cluster1,cluster2):
result = CompositionClustersActifs(cluster1,cluster2)
return result
def main():
import CategorieAleatoire
import random
import Diagramme
random.seed(196587456841456485485485648564856456565656564516412)
youpi = False
while not youpi:
cat = CategorieAleatoire.CategorieAleaPreOrdre(nb_objets = 5)
diag1 = Diagramme.DiagrammeAlea(cat)
diag2 = Diagramme.DiagrammeAlea(cat)
diag1.transformer_graphviz()
diag2.transformer_graphviz()
# cat_f = CategorieClustersActifs(cat)
# cat_f.transformer_graphviz(complet=True)
# cat_f.ajouter_diagramme_interet(diag1)
# cat_f.transformer_graphviz()
# cat_f.ajouter_diagramme_interet(diag2)
# cat_f.transformer_graphviz()
youpi = False
a = ClusterActif(diag1,diag2)
if a == None:
youpi = True
b = ClusterActif(diag2,diag1)
if b == None:
youpi = True
fonct = diag1.est_homologue_a(diag2)
if fonct == None or len(fonct.cat_source.objets) == 0:
youpi=False
cat.transformer_graphviz(afficher_identites=True)
fonct.transformer_graphviz()
print(a,b,fonct)
b.transformer_graphviz()
# cat = Categorie("3")
# cat.ajouter_objets("ABabC")
# F,G,f,g = [Morphisme('A','C','F'),Morphisme('B','C','G'),Morphisme('a','C','f'),Morphisme('b','C','g')]
# cat.ajouter_morphismes([F,G,f,g])
# diag1 = Diagramme.DiagrammeObjets(cat,"Aa")
# diag2 = Diagramme.DiagrammeObjets(cat,"Bb")
# diag1.transformer_graphviz()
# diag2.transformer_graphviz()
# cat_clusters = CategorieClustersActifs(cat)