Commit 6f200014 authored by Guillaume Sabbagh's avatar Guillaume Sabbagh
Browse files

Catégorie prohomologue finie

parent 687e20a9
...@@ -16,8 +16,8 @@ class CatFinies(Categorie): ...@@ -16,8 +16,8 @@ class CatFinies(Categorie):
for app_obj in ens_objets({a.objets},{b.objets}): for app_obj in ens_objets({a.objets},{b.objets}):
app_fleche_foncteur = dict() # à chaque couple d'objets on associe un ensemble d'applications app_fleche_foncteur = dict() # à chaque couple d'objets on associe un ensemble d'applications
for c,d in itertools.product(a.objets, repeat=2): for c,d in itertools.product(a.objets, repeat=2):
ens_fleches = EnsFinis({frozenset(a(c,d)),frozenset(b(app_obj(c),app_obj(d)))}) ens_fleches = EnsFinis({frozenset(a({c},{d})),frozenset(b({app_obj(c)},{app_obj(d)}))})
app_fleches_c_vers_d = ens_fleches({frozenset(a(c,d))},{frozenset(b(app_obj(c),app_obj(d)))}) app_fleches_c_vers_d = ens_fleches({frozenset(a({c},{d}))},{frozenset(b({app_obj(c)},{app_obj(d)}))})
app_fleche_foncteur[(c,d)] = app_fleches_c_vers_d app_fleche_foncteur[(c,d)] = app_fleches_c_vers_d
if len(app_fleches_c_vers_d) == 0: if len(app_fleches_c_vers_d) == 0:
break break
...@@ -28,7 +28,7 @@ class CatFinies(Categorie): ...@@ -28,7 +28,7 @@ class CatFinies(Categorie):
for app in applications_fleches: for app in applications_fleches:
app_fleches.update(app.as_dict()) app_fleches.update(app.as_dict())
for f in a(abs(a),abs(a)): for f in a(abs(a),abs(a)):
for g in a({f},abs(a)): for g in a(abs(a),{f.source}):
if app_fleches[f@g] != app_fleches[f]@app_fleches[g]: if app_fleches[f@g] != app_fleches[f]@app_fleches[g]:
break break
else: else:
......
...@@ -30,13 +30,13 @@ class Categorie: ...@@ -30,13 +30,13 @@ class Categorie:
- visualiser son graphe sous-jacent avec la méthode transformer_graphviz - visualiser son graphe sous-jacent avec la méthode transformer_graphviz
- exporter sa loi de composition en csv avec loi_de_composition_to_csv - exporter sa loi de composition en csv avec loi_de_composition_to_csv
""" """
__id = 0 _id = 0
nb_viz = 0 # nombre de graphes graphviz générés nb_viz = 0 # nombre de graphes graphviz générés
def __init__(self, objets:set = set(), nom:str = None): def __init__(self, objets:set = set(), nom:str = None):
Categorie.__id += 1 Categorie._id += 1
self.__id = Categorie.__id self._id = Categorie._id
self.nom = "Categorie "+str(self.__id) if nom == None else nom self.nom = "Categorie "+str(self._id) if nom == None else nom
self.objets = frozenset() self.objets = frozenset()
self |= objets self |= objets
......
from Categorie import Categorie
from Foncteur import Foncteur
from CatFinies import CatFinies
from EnsFinis import EnsFinis,Application
from ChampPerceptif import ChampPerceptif
from collections import defaultdict
import itertools
class FoncteurOubli(Foncteur):
"""Foncteur d'oubli du champ perceptif.
Associe à chaque cône sont apex et à chaque flèche entre cône la flèche d'où elle vient."""
def __init__(self, champ_perceptif:ChampPerceptif):
univers = champ_perceptif.foncteur_diagonal.source
Foncteur.__init__(self, champ_perceptif, univers, {obj:obj.e for obj in abs(champ_perceptif)},
{f:f.k for f in champ_perceptif(abs(champ_perceptif),abs(champ_perceptif))})
class CategorieProhomologue(CatFinies):
"""Catégorie dont les objets sont des champs perceptifs et les morphismes sont des foncteurs qui commutent avec le foncteur d'oubli."""
def verifier_coherence(self):
CatFinies.verifier_coherence(self)
for f in self(abs(self),abs(self)):
fonct_oubli_source = FoncteurOubli(f.source)
fonct_oubli_cible = FoncteurOubli(f.cible)
if fonct_oubli_source != fonct_oubli_cible@f:
raise Exception("Incoherence CategorieProhomologue : "+str(f)+" ne commute pas avec les foncteurs d'oublis")
def identite(self, objet:ChampPerceptif) -> Foncteur:
return Foncteur(objet,objet,{o:o for o in abs(objet)},{f:f for f in objet(abs(objet),abs(objet))})
def __call__(self, sources:set, cibles:set) -> set:
result = set()
for source in sources:
for cible in cibles:
dict_apex_cone_source = defaultdict(frozenset)
for obj in abs(source):
dict_apex_cone_source[obj.e] |= {obj}
dict_apex_cone_cible = defaultdict(frozenset)
for obj in abs(cible):
dict_apex_cone_cible[obj.e] |= {obj}
if set(dict_apex_cone_source.keys()) != set(dict_apex_cone_cible.keys()):
continue
applications_objets = set() # applications entre cônes de même apex
ens_objets = EnsFinis()
for apex in dict_apex_cone_source:
ens_objets |= {dict_apex_cone_source[apex]}
ens_objets |= {dict_apex_cone_cible[apex]}
applications_objets |= {ens_objets({dict_apex_cone_source[apex]},{dict_apex_cone_cible[apex]})}
for application_objet in itertools.product(*applications_objets):
app_obj = dict([x for app in application_objet for x in app.as_dict().items()])
app_fleche_foncteur = dict() # à chaque couple d'objets on associe un ensemble d'applications
for c,d in itertools.product(source.objets, repeat=2):
ens_fleches = EnsFinis({frozenset(source({c},{d})),frozenset(cible({app_obj[c]},{app_obj[d]}))})
app_fleches_c_vers_d = ens_fleches({frozenset(source({c},{d}))},{frozenset(cible({app_obj[c]},{app_obj[d]}))})
app_fleche_foncteur[(c,d)] = app_fleches_c_vers_d
if len(app_fleches_c_vers_d) == 0:
break
if len(app_fleche_foncteur[(c,d)]) == 0: #la dernière recherche d'applications à échouée, on passe à l'application objet suivante
continue
for applications_fleches in itertools.product(*app_fleche_foncteur.values()):
app_fleches = dict()
for app in applications_fleches:
app_fleches.update(app.as_dict())
for f in source(abs(source),abs(source)):
for g in source(abs(source),{f.source}):
if app_fleches[f@g] != app_fleches[f]@app_fleches[g]:
break
else:
continue
break
else:
result |= {Foncteur(source,cible,app_obj,app_fleches)}
return result
def test_FoncteurOubli():
from GrapheDeComposition import GC,MGC
from Diagramme import Triangle,DiagrammeIdentite
gc = GC()
gc |= set("ABCDEF")
f,g,h,i,j,k,l = [MGC('A','B','f'),MGC('B','C','g'),MGC('D','E','h'),MGC('E','F','i'),MGC('A','D','j'),MGC('B','E','k'),MGC('C','F','l')]
gc |= {f,g,h,i,j,k,l}
# diag_identite = DiagrammeIdentite(gc)
# diag_identite.faire_commuter()
d1 = Triangle(gc,"DEF",[h,i,i@h])
c_p = ChampPerceptif(d1)
foncteur_oubli = FoncteurOubli(c_p)
foncteur_oubli.transformer_graphviz()
def test_CategorieProhomologue():
from GrapheDeComposition import GC,MGC
from Diagramme import Fleche,DiagrammeIdentite
gc = GC()
gc |= set("ABCDEFGH")
f,g,h,i,j,k,l,m,n = [MGC('A','B','f'),MGC('B','C','g'),MGC('D','E','h'),MGC('E','F','i'),MGC('A','D','j'),MGC('B','E','k'),MGC('C','F','l'),MGC('F','G','m'),MGC('F','H','n')]
gc |= {f,g,h,i,j,k,l,m,n}
diag_identite = DiagrammeIdentite(gc)
diag_identite.faire_commuter()
d1 = Fleche(gc,m)
c_p1 = ChampPerceptif(d1)
d2 = Fleche(gc,n)
c_p2 = ChampPerceptif(d2)
cph = CategorieProhomologue({c_p1,c_p2})
cph.transformer_graphviz()
f,g = cph.isomorphismes(c_p1,c_p2).pop()
f.transformer_graphviz()
g.transformer_graphviz()
if __name__ == '__main__':
test_FoncteurOubli()
test_CategorieProhomologue()
\ No newline at end of file
from Categorie import Categorie
from CommaCategorie import CommaCategorie, CategorieSur from CommaCategorie import CommaCategorie, CategorieSur
from TransformationNaturelle import CatTransfoNat,TransfoNat from TransformationNaturelle import CatTransfoNat,TransfoNat
from Foncteur import Foncteur from Foncteur import Foncteur
...@@ -25,7 +26,7 @@ class ChampPerceptif(CommaCategorie): ...@@ -25,7 +26,7 @@ class ChampPerceptif(CommaCategorie):
self.foncteur_vers_D = DiagrammeObjets(self.categorie_diagrammes,{diagramme}) self.foncteur_vers_D = DiagrammeObjets(self.categorie_diagrammes,{diagramme})
CommaCategorie.__init__(self,self.foncteur_diagonal,self.foncteur_vers_D, "Champ perceptif de "+str(diagramme) if nom == None else nom) CommaCategorie.__init__(self,self.foncteur_diagonal,self.foncteur_vers_D, "Champ perceptif de "+str(diagramme)+" ("+str(Categorie._id)+")" if nom == None else nom)
def cones(self,apices:set) -> set: def cones(self,apices:set) -> set:
"""`apices` est un ensemble d'objets de Q """`apices` est un ensemble d'objets de Q
......
...@@ -111,6 +111,7 @@ class ClusterActif(ProtoClusterActif): ...@@ -111,6 +111,7 @@ class ClusterActif(ProtoClusterActif):
return self.__categorie_proto_cluster return self.__categorie_proto_cluster
def verifier_coherence(self): def verifier_coherence(self):
ProtoClusterActif.verifier_coherence(self)
proto_clusters = self.__get_categorie_proto_cluster()({self.source},{self.cible}) proto_clusters = self.__get_categorie_proto_cluster()({self.source},{self.cible})
for proto_cluster in proto_clusters: for proto_cluster in proto_clusters:
if proto_cluster > self: if proto_cluster > self:
...@@ -230,7 +231,7 @@ class CategorieClusters(CategorieInteractions): ...@@ -230,7 +231,7 @@ class CategorieClusters(CategorieInteractions):
def main(): def test_CategorieClusters():
from GrapheDeComposition import GC,MGC from GrapheDeComposition import GC,MGC
from Diagramme import DiagrammeObjets,Fleche from Diagramme import DiagrammeObjets,Fleche
...@@ -270,4 +271,4 @@ def main(): ...@@ -270,4 +271,4 @@ def main():
cluster.transformer_graphviz(afficher_identites=True) cluster.transformer_graphviz(afficher_identites=True)
if __name__ == '__main__': if __name__ == '__main__':
main() test_CategorieClusters()
\ No newline at end of file \ No newline at end of file
...@@ -26,20 +26,20 @@ class ObjetCommaCategorie(Morphisme): ...@@ -26,20 +26,20 @@ class ObjetCommaCategorie(Morphisme):
D1(e1) --> D2(d1) --> D3(d2) D1(e1) --> D2(d1) --> D3(d2)
""" """
def __init__(self, e:any, f:any, d:any): def __init__(self, e:any, f:any, d:any):
self._e = e #attribut read-only self.__e = e #attribut read-only
self._f = f #attribut read-only self.__f = f #attribut read-only
self._d = d #attribut read-only self.__d = d #attribut read-only
Morphisme.__init__(self,self.e,self.d,'('+str(self.e)+','+str(self.f)+','+str(self.d)+')',self.f.is_identite and self.e == self.d) Morphisme.__init__(self,self.e,self.d,'('+str(self.e)+','+str(self.f)+','+str(self.d)+')',self.f.is_identite and self.e == self.d)
@property @property
def e(self): def e(self):
return self._e return self.__e
@property @property
def f(self): def f(self):
return self._f return self.__f
@property @property
def d(self): def d(self):
return self._d return self.__d
def __eq__(self,other:'ObjetCommaCategorie') -> bool: def __eq__(self,other:'ObjetCommaCategorie') -> bool:
...@@ -69,10 +69,17 @@ class FlecheCommaCategorie(Morphisme): ...@@ -69,10 +69,17 @@ class FlecheCommaCategorie(Morphisme):
(cf. Mac Lane "Categories for the working mathematician" P.45) (cf. Mac Lane "Categories for the working mathematician" P.45)
""" """
def __init__(self, source:any, cible:any, k:Morphisme, h:Morphisme): def __init__(self, source:any, cible:any, k:Morphisme, h:Morphisme):
self.k = k self.__k = k #attribut read-only
self.h = h self.__h = h #attribut read-only
Morphisme.__init__(self,source,cible,'('+str(self.k)+','+str(self.h)+')',source == cible and k.is_identite and h.is_identite) Morphisme.__init__(self,source,cible,'('+str(self.k)+','+str(self.h)+')',source == cible and k.is_identite and h.is_identite)
@property
def k(self):
return self.__k
@property
def h(self):
return self.__h
def verifier_coherence(self, T:Foncteur, S:Foncteur): def verifier_coherence(self, T:Foncteur, S:Foncteur):
if T.cible != S.cible: if T.cible != S.cible:
raise Exception("Incoherence FlecheCommaCategorie : T et S de cibles differentes : "+str(T)+" != "+str(S)) raise Exception("Incoherence FlecheCommaCategorie : T et S de cibles differentes : "+str(T)+" != "+str(S))
......
...@@ -52,7 +52,7 @@ class Application(Morphisme): ...@@ -52,7 +52,7 @@ class Application(Morphisme):
graph = Digraph('application') graph = Digraph('application')
graph.attr(concentrate="true" if GRAPHVIZ_CONCENTRATE_GRAPHS else "false") graph.attr(concentrate="true" if GRAPHVIZ_CONCENTRATE_GRAPHS else "false")
graph.attr(label="Application "+self.representant) graph.attr(label="Application "+self.nom)
with graph.subgraph(name='cluster_0') as cluster: with graph.subgraph(name='cluster_0') as cluster:
cluster.attr(label=str(self.source)) cluster.attr(label=str(self.source))
for o in self.source: for o in self.source:
...@@ -75,7 +75,7 @@ class CategorieEnsemblesFinis(Categorie): ...@@ -75,7 +75,7 @@ class CategorieEnsemblesFinis(Categorie):
"""CategorieEnsFinis peut être abrégé en EnsFinis """CategorieEnsFinis peut être abrégé en EnsFinis
Catégorie des ensembles finis, cette catégorie est infinie, on ajoute uniquement les ensembles dont on a besoin.""" Catégorie des ensembles finis, cette catégorie est infinie, on ajoute uniquement les ensembles dont on a besoin."""
def __init__(self, objets:set = None, nom:str = "Catégorie d'ensembles finis"): def __init__(self, objets:set = set(), nom:str = "Catégorie d'ensembles finis"):
Categorie.__init__(self,objets,nom) Categorie.__init__(self,objets,nom)
def identite(self, ensemble:frozenset()) -> Application: def identite(self, ensemble:frozenset()) -> Application:
......
...@@ -108,7 +108,7 @@ class Foncteur(Morphisme): ...@@ -108,7 +108,7 @@ class Foncteur(Morphisme):
graph = Digraph('foncteur') graph = Digraph('foncteur')
graph.attr(concentrate="true" if GRAPHVIZ_CONCENTRATE_GRAPHS else "false") graph.attr(concentrate="true" if GRAPHVIZ_CONCENTRATE_GRAPHS else "false")
graph.attr(label="Foncteur "+self.representant) graph.attr(label="Foncteur "+self.nom)
with graph.subgraph(name='cluster_0') as cluster: with graph.subgraph(name='cluster_0') as cluster:
cluster.attr(label=self.source.nom) cluster.attr(label=self.source.nom)
nodes = [] nodes = []
...@@ -117,7 +117,7 @@ class Foncteur(Morphisme): ...@@ -117,7 +117,7 @@ class Foncteur(Morphisme):
for morph in self.source(self.source.objets,self.source.objets): for morph in self.source(self.source.objets,self.source.objets):
if not morph.is_identite or afficher_identites: if not morph.is_identite or afficher_identites:
couleur = 'black' if len(morph) == 1 else 'grey70' couleur = 'black' if not issubclass(type(morph),MGC) or len(morph) == 1 else 'grey70'
cluster.node(str(morph)+suffixe1_morph,style="invis",shape="point") cluster.node(str(morph)+suffixe1_morph,style="invis",shape="point")
graph.edge(str(morph.source)+suffixe1_objet,str(morph)+suffixe1_morph,color=couleur,label=str(morph)+suffixe1_morph,headclip="False",arrowhead="none") graph.edge(str(morph.source)+suffixe1_objet,str(morph)+suffixe1_morph,color=couleur,label=str(morph)+suffixe1_morph,headclip="False",arrowhead="none")
graph.edge(str(morph)+suffixe1_morph,str(morph.cible)+suffixe1_objet,color=couleur,tailclip="false") graph.edge(str(morph)+suffixe1_morph,str(morph.cible)+suffixe1_objet,color=couleur,tailclip="false")
......
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