Commit 9501ead0 authored by Guillaume Sabbagh's avatar Guillaume Sabbagh
Browse files

Catégorie sous et catégorie sur, afin de créer des clusters

parent 4b74e9d1
......@@ -62,7 +62,7 @@ class BouquetAbstrait(Morphisme):
Composante bleue : Cones
Composante bleue foncée : cocones
Composante orange: Bouquet"""
Bouquet.nb_viz += 1
BouquetAbstrait.nb_viz += 1
if self.cat_cones1 == None:
self.cat_cones1 = CategorieCones(self.foncteur1)
if self.cat_cones2 == None:
......@@ -74,7 +74,7 @@ class BouquetAbstrait(Morphisme):
image1 = self.foncteur1.categorie_image()
image2 = self.foncteur2.categorie_image()
if destination == None:
destination = "graphviz/bouquet"+str(Bouquet.nb_viz)
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))
......
from Categorie import Categorie
import itertools
from Morphisme import Morphisme
from copy import copy
class CategorieSous(Categorie):
"""Soit C une catégorie, et a un objet de C.
CategorieSous n'est pas la catégorie T-en-dessous de a (
(cf. Mac Lane "Categories for the working mathematician" P.46)
C'est plutôt la sous-catégorie C' de C telle que pour tout objet b de la catégorie C' il existe une flèche de a à b"""
def __new__(cls,categorie,objet):
if objet not in categorie.objets:
raise Exception("Incohérence CategorieSous : objet "+str(objet)+" pas dans la categorie.")
result = copy(categorie)
for obj in categorie.objets:
if len(categorie.enumerer_composees_sans_cycle(objet,obj)) == 0:
result.supprimer_objet(obj)
return result
def main():
import CategorieAleatoire
import random
random.seed(14896488564964)
cat = CategorieAleatoire.CategorieAleaIsomorph()
cat.transformer_graphviz()
obj = random.choice(cat.objets)
print(obj)
cat2 = CategorieSous(cat,obj)
cat2.transformer_graphviz()
obj = random.choice(cat.objets)
print(obj)
cat2 = CategorieSous(cat,obj)
cat2.transformer_graphviz()
if __name__ == '__main__':
main()
\ No newline at end of file
from categorie.Categorie import Categorie
from Categorie import Categorie
import itertools
from Morphisme import Morphisme
from Foncteur import Composition
class ObjetCatSur():
def __init__(self, f, e):
self.f = f
self.e = e
def __str__(self):
return "("+str(self.f)+","+str(self.e)+")"
from copy import copy
class CategorieSur(Categorie):
"""Soit T:E->C un foncteur, et a un objet de C.
CategorieSur est la catégorie T-au-dessus de a (
(cf. Mac Lane "Categories for the working mathematician" P.46)"""
"""Soit C une catégorie, et a un objet de C.
CategorieSur n'est pas la catégorie T-au-dessus de a (
(cf. Mac Lane "Categories for the working mathematician" P.46)
C'est plutôt la sous-catégorie C' de C telle que pour tout objet b de la catégorie C' il existe une flèche de b à a"""
def __init__(self, T, a):
"""Soit T:E->C un foncteur, et a un objet de C.
CategorieSur est la catégorie T-au-dessus de a (
(cf. Mac Lane "Categories for the working mathematician" P.46)"""
Categorie.__init__(self, "Categorie "+str(T)+"-en-dessous de "+str(a))
E = T.cat_source
C = T.cat_cible
implementation = T.cat_image()
for e in E.objets:
c = S(e)
for f in C.enumerer_composees(c,a):
self.ajouter_objet(ObjetCatSur(f, e))
for obj1, obj2 in itertools.combinations(self.objets,2):
for h in [elem for elem in E.morph_sortants[obj1.e] if elem.cible == obj2.e]:
if obj1.f == self.Composee(T(h),obj2.f):
self.ajouter_morphisme(Morphisme(obj1,obj2,T(h).representant))
fpr diag in C.diagrammes:
nouveau_diag = Composition(diag,S)
nouveau_diag.
def __new__(cls,categorie,objet):
if objet not in categorie.objets:
raise Exception("Incohérence CategorieSur : objet "+str(objet)+" pas dans la categorie.")
result = copy(categorie)
for obj in categorie.objets:
if len(categorie.enumerer_composees_sans_cycle(obj, objet)) == 0:
result.supprimer_objet(obj)
return result
def main():
import CategorieAleatoire
import random
random.seed(14896488564964)
cat = CategorieAleatoire.CategorieAleaIsomorph()
cat.transformer_graphviz()
obj = random.choice(cat.objets)
print(obj)
cat2 = CategorieSur(cat,obj)
cat2.transformer_graphviz()
obj = random.choice(cat.objets)
print(obj)
cat2 = CategorieSur(cat,obj)
cat2.transformer_graphviz()
if __name__ == '__main__':
main()
\ No newline at end of file
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 ClusterAbstrait(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.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:
if not composante.is_identite:
break
else:
for objet in self.foncteur1.app_objets.values():
if self.categorie.identites[objet] not in self.composantes:
break
else:
identite = True
Morphisme.__init__(self,self.foncteur1,self.foncteur2,str(self),identite)
def __eq__(self,other):
if issubclass(type(other),ClusterAbstrait):
if len([e for e in self.composantes if e not in other.composantes]) > 0:
return False
if len([e for e in other.composantes if e not in self.composantes]) > 0:
return False
return self.foncteur1 == other.foncteur1 and self.foncteur2 == other.foncteur2
return False
def __hash__(self):
return hash((tuple(self.composantes),self.foncteur1,self.foncteur2))
def __str__(self):
return '('+str(self.foncteur1)+','+'/'.join(map(str,self.composantes))+','+str(self.foncteur2)+')'
def __repr__(self):
return str(self)
def verifier_coherence(self):
raise NotImplementedError()
def transformer_graphviz(self, destination=None):
"""Permet de visualiser le cluster avec graphviz
Composante rouge : diagramme 1
Composante verte : diagramme 2
Composante bleue: cluster"""
ClusterAbstrait.nb_viz += 1
image1 = self.foncteur1.categorie_image()
image2 = self.foncteur2.categorie_image()
if destination == None:
destination = "graphviz/cluster"+str(ClusterAbstrait.nb_viz)
graph = Digraph('cluster')
graph.attr(concentrate="true" if GRAPHVIZ_CONCENTRATE_GRAPHS else "false")
graph.attr(label="Cluster 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] += 255
if o in image2.objets:
couleur[1] += 255
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+self.composantes
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:
couleur = [0,0,0]
if morph in image1.morphismes:
couleur[0] += 255
if morph in image2.morphismes:
couleur[1] += 255
if morph in self.composantes:
couleur = [0,0,255]
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 ClusterActif(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)
if TOUJOURS_VERIFIER_COHERENCE:
ClusterActif.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.")
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")
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)
# 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 self.composantes:
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")
\ 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