Commit 878547e7 authored by Guillaume Sabbagh's avatar Guillaume Sabbagh
Browse files

Clusters Actifs fonctionnels

parent 8bf8a687
......@@ -232,7 +232,7 @@ class BouquetsPerceptifs:
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(objets_comma_category)+1):
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:
......@@ -281,7 +281,7 @@ class BouquetsActifs:
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(objets_comma_category)+1):
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:
......
......@@ -66,18 +66,24 @@ class CategorieFleurieAbstraite(Categorie):
raise NotImplementedError("Les classes filles doivent implementer la méthode chercher_bouquets")
class CategorieFleurie(CategorieFleurieAbstraite):
"""Catégorie fleurie où les morphismes sont des bouquets"""
"""Catégorie fleurie où les morphismes sont des bouquets"""
def chercher_bouquets(self,source,cible):
return Bouquets(source,cible,self.cat_cones_cocones[source]["cat_cones"],self.cat_cones_cocones[cible]["cat_cones"],
self.cat_cones_cocones[source]["cat_cocones"], self.cat_cones_cocones[cible]["cat_cocones"])
class CategorieFleuriePerceptive(CategorieFleurieAbstraite):
"""Catégorie fleurie où les morphismes sont des bouquets perceptifs"""
def __init__(self,categorie,representant="Categorie fleurie perceptive"):
CategorieFleurieAbstraite.__init__(self,categorie,representant)
def chercher_bouquets(self,source,cible):
return BouquetsPerceptifs(source,cible,self.cat_cones_cocones[source]["cat_cones"],self.cat_cones_cocones[cible]["cat_cones"])
class CategorieFleurieActive(CategorieFleurieAbstraite):
"""Catégorie fleurie où les morphismes sont des bouquets actifs"""
def __init__(self,categorie,representant="Categorie fleurie active"):
CategorieFleurieAbstraite.__init__(self,categorie,representant)
def chercher_bouquets(self,source,cible):
return BouquetsPerceptifs(source,cible,self.cat_cones_cocones[source]["cat_cocones"],self.cat_cones_cocones[cible]["cat_cocones"])
......
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
......@@ -14,15 +11,11 @@ from CategorieComposantesConnexes import CategorieComposantesConnexes
class ClusterAbstrait(Morphisme):
nb_viz = 0
def __init__(self,foncteur1, foncteur2, tiges, cat_cones1=None,cat_cones2=None,cat_cocones1=None,cat_cocones2=None):
def __init__(self,foncteur1, foncteur2, tiges):
self.foncteur1 = foncteur1
self.foncteur2 = foncteur2
self.composantes = 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 composante in self.composantes:
......@@ -45,6 +38,20 @@ class ClusterAbstrait(Morphisme):
return self.foncteur1 == other.foncteur1 and self.foncteur2 == other.foncteur2
return False
def __le__(self,other):
if issubclass(type(other),ClusterAbstrait):
if len([e for e in self.composantes if e not in other.composantes]) > 0:
return False
return True
raise Exception("On essaie de comparer un Cluster avec un "+type(other))
def __ge__(self,other):
if issubclass(type(other),ClusterAbstrait):
if len([e for e in other.composantes if e not in self.composantes]) > 0:
return False
return True
raise Exception("On essaie de comparer un Cluster avec un "+type(other))
def __hash__(self):
return hash((tuple(self.composantes),self.foncteur1,self.foncteur2))
......@@ -99,28 +106,23 @@ class ClusterAbstrait(Morphisme):
os.remove(destination)
class ClusterActif(ClusterAbstrait):
class ProtoClusterActif(ClusterAbstrait):
"""Seules les contraintes sur les cocônes sont prises en compte pour le cluster actif"""
def __init__(self, foncteur1, foncteur2, composantes, cat_cocones1=None,cat_cocones2=None):
"""On peut fournir cat_cocones1 et cat_cocones2 pour économiser du temps de calcul."""
ClusterAbstrait.__init__(self,foncteur1, foncteur2, composantes,None,None,cat_cocones1,cat_cocones2)
def __init__(self, foncteur1, foncteur2, composantes):
ClusterAbstrait.__init__(self,foncteur1, foncteur2, composantes)
if TOUJOURS_VERIFIER_COHERENCE:
ClusterActif.verifier_coherence(self)
ProtoClusterActif.verifier_coherence(self)
def verifier_coherence(self):
if self.foncteur1.cat_cible != self.foncteur2.cat_cible:
raise Exception("Incoherence ClusterActif : les deux foncteurs n'ont pas la meme image.")
raise Exception("Incoherence ProtoClusterActif : les deux foncteurs n'ont pas la meme image.")
impl1, impl2 = [self.foncteur1.categorie_image(),self.foncteur2.categorie_image()]
for composante in self.composantes:
if composante.source not in impl1.objets:
raise Exception("Incoherence Cluster : la composante "+str(composante)+" ne prend pas sa source dans l'image de F1")
raise Exception("Incoherence ProtoClusterActif : la composante "+str(composante)+" ne prend pas sa source dans l'image de F1")
if composante.cible not in impl2.objets:
raise Exception("Incoherence Cluster : la composante "+str(composante)+" 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)
raise Exception("Incoherence ProtoClusterActif : la composante "+str(composante)+" ne prend pas sa cible dans l'image de F2")
# contrainte 1) au moins une flèche part de chacun des objets de D1
for d in self.foncteur1.cat_source.objets:
......@@ -128,7 +130,7 @@ class ClusterActif(ClusterAbstrait):
if composante.source == self.foncteur1(d):
break
else:
raise Exception("Incoherence Cluster : l'objet "+str(self.foncteur1(d))+" de D1 n'a pas de d'image par le cluster")
raise Exception("Incoherence ProtoClusterActif : l'objet "+str(self.foncteur1(d))+" de D1 n'a pas de d'image par le cluster")
# contrainte 2) les composantes qui sortent d'un objet d de D1 mènent à des objets e de D2 reliés par un zig zag dans la catégorie sous d
for d in self.foncteur1.cat_source.objets:
......@@ -141,5 +143,155 @@ class ClusterActif(ClusterAbstrait):
# on vérifie que tous les E(e) sont isomorphes dans la catégorie des composantes connexes de la catégorie sous D(d)
for e in E_e[1:]:
if cat_cc.existe_composee(E_e[0],e) == None:
raise Exception("Toutes les ")
\ No newline at end of file
raise Exception("Incoherence ProtoClusterActif : l'objet "+str(E_e[0])+" n'est pas dans la même composante connexe que "+str(e))
# contrainte 3) eog = g'
for composante in self.composantes:
for e in self.foncteur2.cat_source.objets:
if self.foncteur2(e) == composante.cible:
for eps in self.foncteur2.cat_source.morph_sortants[e]:
composee = self.categorie.Composee(composante,self.foncteur2(eps))
if composee not in self.composantes:
raise Exception("Incoherence ProtoClusterActif : la composee de la composante "+str(composante)+" avec la fleche "+str(self.foncteur2(eps))+" de D2 n'est pas dans le cluster")
# contrainte 4) god = g'
for composante in self.composantes:
for d in self.foncteur1.cat_source.objets:
if self.foncteur1(d) == composante.source:
for delta in self.foncteur1.cat_source.morph_entrants[d]:
composee = self.categorie.Composee(self.foncteur1(delta),composante)
if composee not in self.composantes:
raise Exception("Incoherence ProtoClusterActif : la composee de la fleche "+str(self.foncteur1(delta))+" de D1 avec la composante "+str(composante)+" n'est pas dans le cluster")
class ProtoClustersActifs:
def __init__(self, foncteur1, foncteur2):
self.foncteur1 = foncteur1
self.foncteur2 = foncteur2
if self.foncteur1.cat_cible != self.foncteur2.cat_cible:
raise Exception("Incoherence ClustersActifs : les deux foncteurs n'ont pas la meme image.")
self.categorie = self.foncteur1.cat_cible
self.clusters_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_cluster = True
# contrainte 1) au moins une flèche part de chacun des objets de D1
for d in self.foncteur1.cat_source.objets:
for composante in interaction:
if composante.source == self.foncteur1(d):
break
else:
ajouter_cluster = False #raise Exception("Incoherence ProtoClusterActif : l'objet "+str(self.foncteur1(d))+" de D1 n'a pas de d'image par le cluster")
if not ajouter_cluster:
continue
# contrainte 2) les composantes qui sortent d'un objet d de D1 mènent à des objets e de D2 reliés par un zig zag dans la catégorie sous d
for d in self.foncteur1.cat_source.objets:
E_e = [] #les images des composantes
for composante in interaction:
if composante.source == self.foncteur1(d):
E_e += [composante.cible]
cat_sous = CategorieSous(self.categorie, d)
cat_cc = CategorieComposantesConnexes(cat_sous)
# on vérifie que tous les E(e) sont isomorphes dans la catégorie des composantes connexes de la catégorie sous D(d)
for e in E_e[1:]:
if cat_cc.existe_composee(E_e[0],e) == None:
ajouter_cluster = False #raise Exception("Incoherence ProtoClusterActif : l'objet "+str(E_e[0])+" n'est pas dans la même composante connexe que "+str(e))
break
else:
continue
break
if not ajouter_cluster:
continue
# contrainte 3) eog = g'
for composante in interaction:
for e in self.foncteur2.cat_source.objets:
if self.foncteur2(e) == composante.cible:
for eps in self.foncteur2.cat_source.morph_sortants[e]:
composee = self.categorie.Composee(composante,self.foncteur2(eps))
if composee not in interaction:
ajouter_cluster = False #raise Exception("Incoherence ProtoClusterActif : la composee de la composante "+str(composante)+" avec la fleche "+str(self.foncteur2(eps))+" de D2 n'est pas dans le cluster")
break
else:
continue
break
else:
continue
break
if not ajouter_cluster:
continue
# contrainte 4) god = g'
for composante in interaction:
for d in self.foncteur1.cat_source.objets:
if self.foncteur1(d) == composante.source:
for delta in self.foncteur1.cat_source.morph_entrants[d]:
composee = self.categorie.Composee(self.foncteur1(delta),composante)
if composee not in interaction:
ajouter_cluster = False #raise Exception("Incoherence ProtoClusterActif : la composee de la fleche "+str(self.foncteur1(delta))+" de D1 avec la composante "+str(composante)+" n'est pas dans le cluster")
break
else:
continue
break
else:
continue
break
if not ajouter_cluster:
continue
self.clusters_actifs += [ProtoClusterActif(self.foncteur1,self.foncteur2,interaction)]
def transformer_graphviz(self):
for cluster in self.clusters_actifs:
cluster.transformer_graphviz()
def __getitem__(self,key):
return self.clusters_actifs[key]
def __iter__(self):
for cluster in self.clusters_actifs:
yield cluster
class ClusterActif(ProtoClusterActif):
def __new__(cls,foncteur1,foncteur2):
proto_clusters = ProtoClustersActifs(foncteur1,foncteur2)
cluster_maxi = None
for cluster in proto_clusters:
if cluster_maxi == None or cluster >= cluster_maxi:
cluster_maxi = cluster
return copy(cluster_maxi)
def main():
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})
fonct1.transformer_graphviz()
fonct2.transformer_graphviz()
cluster = ClusterActif(fonct1,fonct2)
cluster.transformer_graphviz()
if __name__ == '__main__':
main()
\ No newline at end of file
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