Commit cb1e5c12 authored by Guillaume Sabbagh's avatar Guillaume Sabbagh
Browse files

avancement sur l'algo de modification

parent 6123ac46
...@@ -2,8 +2,8 @@ from CommaCategorie import CommaCategorie, ObjetCommaCategorie ...@@ -2,8 +2,8 @@ from CommaCategorie import CommaCategorie, ObjetCommaCategorie
from TransformationNaturelle import CatTransfoNat,TransfoNat from TransformationNaturelle import CatTransfoNat,TransfoNat
from Foncteur import Foncteur from Foncteur import Foncteur
from Diagramme import DiagrammeConstant,DiagrammeObjets from Diagramme import DiagrammeConstant,DiagrammeObjets
from typing import *
from Cluster import ClusterActif,ProtoClusterActif from Cluster import ClusterActif,ProtoClusterActif
from typing import *
class Cocone(TransfoNat): class Cocone(TransfoNat):
"""Un cocône sur D de nadir N est une transformation naturelle de D vers le foncteur constant Δ_N.""" """Un cocône sur D de nadir N est une transformation naturelle de D vers le foncteur constant Δ_N."""
......
from Categorie import Categorie
from CommaCategorie import CommaCategorie, ObjetCommaCategorie from CommaCategorie import CommaCategorie, ObjetCommaCategorie
from TransformationNaturelle import CatTransfoNat,TransfoNat from TransformationNaturelle import CatTransfoNat,TransfoNat
from Foncteur import Foncteur from Foncteur import Foncteur
from Diagramme import DiagrammeConstant,DiagrammeObjets from Diagramme import DiagrammeConstant,DiagrammeObjets
# from Cluster import ClusterActif,ProtoClusterActif
from typing import *
class Cone(TransfoNat): class Cone(TransfoNat):
"""Un cône sur D d'apex A est une transformation naturelle du foncteur constant Δ_A vers D.""" """Un cône sur D d'apex A est une transformation naturelle du foncteur constant Δ_A vers D."""
...@@ -36,7 +37,7 @@ class ChampPerceptif(CommaCategorie): ...@@ -36,7 +37,7 @@ class ChampPerceptif(CommaCategorie):
self.foncteur_diagonal = Foncteur(Q,self.categorie_diagrammes,{o:DiagrammeConstant(P,Q,o) for o in Q.objets}, self.foncteur_diagonal = Foncteur(Q,self.categorie_diagrammes,{o:DiagrammeConstant(P,Q,o) for o in Q.objets},
{f: TransfoNat(DiagrammeConstant(P,Q,f.source),DiagrammeConstant(P,Q,f.cible),{p:f for p in P.objets}) for f in Q(abs(Q),abs(Q))}) {f: TransfoNat(DiagrammeConstant(P,Q,f.source),DiagrammeConstant(P,Q,f.cible),{p:f for p in P.objets}) for f in Q(abs(Q),abs(Q))})
## on associe à chaque objet son diagramme constant bite et à chaque flèche F:a->b la transformation naturelle qui va de Δa à Δb ## on associe à chaque objet son diagramme constant et à chaque flèche F:a->b la transformation naturelle qui va de Δa à Δb
self.foncteur_vers_D = DiagrammeObjets(self.categorie_diagrammes,{diagramme}) self.foncteur_vers_D = DiagrammeObjets(self.categorie_diagrammes,{diagramme})
......
...@@ -130,7 +130,6 @@ class CommaCategorie(CategorieLibre): ...@@ -130,7 +130,6 @@ class CommaCategorie(CategorieLibre):
'''L'identité pour un objet (e,f,d) est la paire d'identité de T(e) et S(d).''' '''L'identité pour un objet (e,f,d) est la paire d'identité de T(e) et S(d).'''
return FlecheCommaCategorie(objet,objet,self._T.source.identite(objet.e),self._S.source.identite(objet.d)) return FlecheCommaCategorie(objet,objet,self._T.source.identite(objet.e),self._S.source.identite(objet.d))
@mise_en_cache_getitem
def __getitem__(self, couple_sources_cibles:tuple) -> Generator[FlecheCommaCategorie, None, None]: def __getitem__(self, couple_sources_cibles:tuple) -> Generator[FlecheCommaCategorie, None, None]:
sources,cibles = couple_sources_cibles sources,cibles = couple_sources_cibles
for obj_comma_source in sources: for obj_comma_source in sources:
...@@ -140,7 +139,6 @@ class CommaCategorie(CategorieLibre): ...@@ -140,7 +139,6 @@ class CommaCategorie(CategorieLibre):
if obj_comma_cible.f@self._T(k) == self._S(h)@obj_comma_source.f: if obj_comma_cible.f@self._T(k) == self._S(h)@obj_comma_source.f:
yield FlecheCommaCategorie(obj_comma_source,obj_comma_cible,k,h) yield FlecheCommaCategorie(obj_comma_source,obj_comma_cible,k,h)
@mise_en_cache_call
def __call__(self, sources:set, cibles:set) -> Generator[FlecheCommaCategorie, None, None]: def __call__(self, sources:set, cibles:set) -> Generator[FlecheCommaCategorie, None, None]:
for obj_comma_source in sources: for obj_comma_source in sources:
for obj_comma_cible in cibles: for obj_comma_cible in cibles:
......
from Categorie import Categorie from Categorie import Categorie
from Foncteur import Foncteur
from Morphisme import Morphisme from Morphisme import Morphisme
from GrapheDeComposition import GC,MGC from GrapheDeComposition import GC,MGC
from Diagramme import Diagramme, DiagrammeIdentite from Diagramme import Diagramme, DiagrammeIdentite, Fleche
from ChampActif import ChampActif from ChampActif import ChampActif,Cocone
from copy import copy from copy import copy
from TransformationNaturelle import TransfoNat
from typing import * from typing import *
cat = GC(set("ABC")) cat = GC(set("ABC"))
f,g = [MGC('A','B','f'),MGC('A','C','g')] f,g = [MGC('A','B','f'),MGC('A','C','g')]
cat |= {f,g} cat |= {f,g}
# diag = DiagrammeIdentite(cat) /!\ marche pas si les flèches ajoutées ajoute de nouveaux cocônes.
# c_a = ChampActif(diag) Faire une boucle while. /!\
# diag.transformer_graphviz()
# c_a.transformer_graphviz()
# cat2 = copy(cat) def modification(gc: GC, option_ajout:Tuple[Sequence[Any],Sequence[Morphisme]] = (set(),set()), option_elimination:Sequence[Diagramme] = set(), option_complex_agissante:Sequence[Diagramme] = set()) -> Tuple[GC,Foncteur]:
# cat2 |= {'L'}
# h,i,j = [MGC('A','L','h'),MGC('B','L','i'),MGC('C','L','j')]
# cat2 |= {h,i,j}
# diag2 = Diagramme(cat,cat2,{'A':'A','B':'B','C':'C'},{f:f,g:g})
# MGC.identifier_morphismes(i@f,h)
# MGC.identifier_morphismes(j@g,h)
# diag2.transformer_graphviz()
# c_a2 = ChampActif(diag2)
# c_a2.transformer_graphviz()
def modification(gc: GC, option_ajout:Tuple[Sequence[Any],Sequence[Morphisme]], option_elimination:Sequence[Diagramme], option_complex_agissante:Sequence[Diagramme]) -> GC:
nouveau_gc = copy(gc) nouveau_gc = copy(gc)
fonct = Foncteur(gc,nouveau_gc,{o:o for o in gc.objets},{m:m for m in gc[gc.objets,gc.objets]})
nouveaux_obj, nouvelles_fleches = option_ajout nouveaux_obj, nouvelles_fleches = option_ajout
nouveau_gc |= set(nouveaux_obj) nouveau_gc |= set(nouveaux_obj)
nouveau_gc |= set(nouvelles_fleches) nouveau_gc |= set(nouvelles_fleches)
nouveau_gc -= set(option_elimination) nouveau_gc -= set(option_elimination)
for for diag in option_complex_agissante:
c_a = ChampActif(fonct@diag)
c_a.transformer_graphviz()
colimites = c_a.objets_colimites()
if len(colimites) == 0:
# S'il n'y avait pas de colimite, on la créé
nouvel_objet = str(diag)
while nouvel_objet in nouveau_gc.objets:
nouvel_objet += "'"
nouveau_gc |= {nouvel_objet}
dico_index_jambe = dict() # {i:jambe}
for i in diag.source.objets:
jambe = MGC(diag(i),nouvel_objet)
dico_index_jambe[i] = jambe
nouveau_gc |= {jambe}
for fleche_i in diag.source[diag.source.objets, diag.source.objets]:
if dico_index_jambe[fleche_i.source] != dico_index_jambe[fleche_i.cible]@diag(fleche_i):
MGC.identifier_morphismes(dico_index_jambe[fleche_i.cible]@diag(fleche_i),dico_index_jambe[fleche_i.source])
#ajouter les flèches vers les autres cocônes
for cocone in c_a.objets:
cocone = Cocone(cocone)
nouvelle_fleche = MGC(nouvel_objet,cocone.nadir)
for fleche_i in diag.source[diag.source.objets, diag.source.objets]:
if dico_index_jambe[fleche_i.source] != cocone(fleche_i.cible)@diag(fleche_i):
MGC.identifier_morphismes(cocone(fleche_i.cible)@diag(fleche_i),dico_index_jambe[fleche_i.source])
return nouveau_gc return nouveau_gc,fonct
cat.transformer_graphviz() cat.transformer_graphviz()
cat2 = modification(cat,({'S','T'},{MGC('S','T','h')}),{'C'},{}) h = MGC('S','T','h')
diag = DiagrammeIdentite(cat)
cat2,fonct = modification(cat,({'S','T'},{h}),{},{diag})
cat2.transformer_graphviz() cat2.transformer_graphviz()
fonct.transformer_graphviz()
diag = fonct@diag
diag.transformer_graphviz()
ChampActif(diag).transformer_graphviz()
for cocone in ChampActif(diag).objets:
Cocone(cocone).transformer_graphviz()
\ No newline at end of file
...@@ -73,7 +73,8 @@ class Application(Morphisme): ...@@ -73,7 +73,8 @@ class Application(Morphisme):
if CLEAN_GRAPHVIZ_MODEL: if CLEAN_GRAPHVIZ_MODEL:
import os import os
os.remove(destination) os.remove(destination)
class CategorieEnsemblesFinis(Categorie): 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.
...@@ -194,9 +195,9 @@ class CategorieBijections(EnsFinis): ...@@ -194,9 +195,9 @@ class CategorieBijections(EnsFinis):
yield Bijection(source,cible,{source_liste[j]:rotation[j] for j in range(len(source_liste))}) yield Bijection(source,cible,{source_liste[j]:rotation[j] for j in range(len(source_liste))})
def test_EnsFinis(): def test_EnsFinis():
cat = EnsFinis(set(map(frozenset,[{},{1,2},{3,4,5},{6,7,8,9,10}]))) cat = EnsFinis(set(map(frozenset,[{},{1,2},{3,4,5}])))
cat.transformer_graphviz(limite_fleches=243,complet=False)
cat.transformer_graphviz(limite_fleches=243,complet=False) cat.transformer_graphviz(limite_fleches=243,complet=False)
cat.transformer_graphviz(limite_fleches=243,complet=True)
# for source,cible in itertools.product(cat.objets,repeat=2): # for source,cible in itertools.product(cat.objets,repeat=2):
# print(source,cible) # print(source,cible)
# print(len(list(cat({source},{cible})))) # print(len(list(cat({source},{cible}))))
...@@ -222,6 +223,6 @@ def test_CategorieBijections(): ...@@ -222,6 +223,6 @@ def test_CategorieBijections():
cat.transformer_graphviz(limite_fleches=27) cat.transformer_graphviz(limite_fleches=27)
if __name__ == '__main__': if __name__ == '__main__':
# test_EnsFinis() test_EnsFinis()
test_EnsParties() # test_EnsParties()
# test_CategorieBijections() # test_CategorieBijections()
\ No newline at end of file
...@@ -3,11 +3,11 @@ from enum import Enum, unique ...@@ -3,11 +3,11 @@ from enum import Enum, unique
from ModelCallable import ModelCallable from ModelCallable import ModelCallable
from GrapheDeComposition import GrapheDeComposition, GC, \ # from GrapheDeComposition import GrapheDeComposition, GC, \
MorphismeGrapheDeComposition, MGC # MorphismeGrapheDeComposition, MGC
from Categorie import Categorie # from Categorie import Categorie
from Interaction import Interaction # from Interaction import Interaction
from ChampPerceptif import ChampPerceptif # from ChampPerceptif import ChampPerceptif
@unique @unique
class ModelObjects(Enum): class ModelObjects(Enum):
......
...@@ -17,7 +17,8 @@ class MorphismeGrapheDeComposition(Morphisme): ...@@ -17,7 +17,8 @@ class MorphismeGrapheDeComposition(Morphisme):
#{tuple de morphismes : tuple de morphismes} #{tuple de morphismes : tuple de morphismes}
def identifier_morphismes(morph1:'MorphismeGrapheDeComposition',morph2:'MorphismeGrapheDeComposition'): def identifier_morphismes(morph1:'MorphismeGrapheDeComposition',morph2:'MorphismeGrapheDeComposition'):
"""Identifie le `morph1` au `morph2`. """Identifie le `morph1` au `morph2` /!\ dans cet ordre (c-a-d morph1 devient morph2) /!\.
`morph1` ne doit pas être élémentaire.
Cette fonction statique modifie la loi de composition de la classe `MorphismeGrapheDeComposition`. Cette fonction statique modifie la loi de composition de la classe `MorphismeGrapheDeComposition`.
Les morphismes seront identifiés indépendamment des catégories auxquelles ils appartiennent.""" Les morphismes seront identifiés indépendamment des catégories auxquelles ils appartiennent."""
MorphismeGrapheDeComposition.loi_de_composition[morph1.__chemin] = morph2.__chemin MorphismeGrapheDeComposition.loi_de_composition[morph1.__chemin] = morph2.__chemin
......
...@@ -38,7 +38,8 @@ class TransformationNaturelle(Interaction): ...@@ -38,7 +38,8 @@ class TransformationNaturelle(Interaction):
self.verifier_coherence() self.verifier_coherence()
def __call__(self, obj:Any) -> Morphisme: def __call__(self, obj:Any) -> Morphisme:
"""Renvoie l'image d'un objet de C.""" """Renvoie l'image d'un objet de C.
L'image d'un objet i de C est une composante qui fait la "translation" du premier objet indexé par i vers le second objet indexé par i."""
if obj not in self.__C.objets: if obj not in self.__C.objets:
raise Exception("L'objet "+str(obj)+" n'appartient pas à la categorie C = "+str(self.__C)) raise Exception("L'objet "+str(obj)+" n'appartient pas à la categorie C = "+str(self.__C))
return self._composantes[obj] return self._composantes[obj]
...@@ -69,9 +70,9 @@ class TransformationNaturelle(Interaction): ...@@ -69,9 +70,9 @@ class TransformationNaturelle(Interaction):
for f in self.__C({source},{cible}): for f in self.__C({source},{cible}):
c1,c2 = [f.source,f.cible] c1,c2 = [f.source,f.cible]
if self.__G(f)@self(c1) != self(c2)@self.__F(f): if self.__G(f)@self(c1) != self(c2)@self.__F(f):
raise Exception("Incoherence TransformationNaturelle : la commutativité des diagrammes est pas respectee"+\ raise Exception("Incoherence TransformationNaturelle : la commutativité des diagrammes est pas respectee\n"+\
"Sf = "+str(self.__F(f))+"\ntC' = "+str(self(c2))+"\ntC = "+str(self(c1))+"\nTf = "+str(self.__G(f))+\ "Sf = "+str(self.__F(f))+"\ntC' = "+str(self(c2))+"\ntC = "+str(self(c1))+"\nTf = "+str(self.__G(f))+\
"tC' o Sf != Tf o tC : "+str(self(c2)@self.__F(f)) + " != "+str(self.__G(f)@self(c1))) "\ntC' o Sf != Tf o tC : "+str(self(c2)@self.__F(f)) + " != "+str(self.__G(f)@self(c1)))
TransfoNat = TransformationNaturelle TransfoNat = TransformationNaturelle
...@@ -114,7 +115,6 @@ class CategorieTransformationsNaturelles(Categorie): ...@@ -114,7 +115,6 @@ class CategorieTransformationsNaturelles(Categorie):
def identite(self, diag:Diagramme) -> TransfoNat: def identite(self, diag:Diagramme) -> TransfoNat:
return TransfoNat(diag,diag,{o:diag.cible.identite(diag(o)) for o in diag.source.objets}) return TransfoNat(diag,diag,{o:diag.cible.identite(diag(o)) for o in diag.source.objets})
@mise_en_cache_call
def __call__(self, sources:set, cibles:set) -> Generator[TransfoNat,None,None]: def __call__(self, sources:set, cibles:set) -> Generator[TransfoNat,None,None]:
if len(sources) > 0: if len(sources) > 0:
J = list(sources)[0].source J = list(sources)[0].source
......
TOUJOURS_VERIFIER_COHERENCE = 0 # booléen qui indique si on doit toujours vérifier la cohérence des structures qu'on construit TOUJOURS_VERIFIER_COHERENCE = 1 # booléen qui indique si on doit toujours vérifier la cohérence des structures qu'on construit
TOUJOURS_VERIFIER_COHERENCE_COMPOSEE = 0 TOUJOURS_VERIFIER_COHERENCE_COMPOSEE = 1
DEBUG_LOI_DE_COMPOSITION = False DEBUG_LOI_DE_COMPOSITION = False
DEBUG_MONOIDE_ALEATOIRE = True DEBUG_MONOIDE_ALEATOIRE = True
GRAPHVIZ_ENABLED = True # booléen qui indique s'il faut charger la bibliothèque graphviz GRAPHVIZ_ENABLED = True # booléen qui indique s'il faut charger la bibliothèque graphviz
......
Markdown is supported
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