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

Catégorie quotient est fausse, il faut définir la catégorie sur tous les...

Catégorie quotient est fausse, il faut définir la catégorie sur tous les morphismes, pas seulement les morphismes élémentaires, voir si on peut pas faire une classe plus jolie.
parent adab0db9
......@@ -5,6 +5,15 @@ class CategorieAcyclique(CategorieQuotient):
"""Catégorie quotientée par la relation d'équivalence sur les objets suivante :
x ~ y ssi il existe f: x -> y et il existe g: y -> x."""
def __init__(self,categorie_a_quotienter:Categorie, nom:str = None):
if nom == None:
nom = "Catégorie acyclique engendrée par "+str(categorie_a_quotienter)
obj_vers_classe = dict()
CategorieQuotient.__init__(self,categorie_a_quotienter,nom)
def rel_equiv_morph(self, morph1:Morphisme, morph2:Morphisme) -> bool:
if morph1 == morph2:
return True
......@@ -21,6 +30,7 @@ class CategorieAcyclique(CategorieQuotient):
def test_CategorieAcyclique():
from CategorieAleatoire import GrapheCompositionAleatoire
import random
random.seed(1233)
for i in range(5):
c = GrapheCompositionAleatoire()
......
from Categorie import Categorie
from Foncteur import Foncteur
from CategorieQuotient import CategorieQuotient
from Morphisme import Morphisme
from typing import *
class MorphismePreordre(Morphisme):
"""MorphismePreordre peut être abrégé en MPO.
Un morphisme préordre est un morphisme au sein d'une catégorie préordre,
c'est-à-dire qu'entre deux objets il y a au plus un morphisme.
Deux morphismes préordre sont égaux ssi ils ont la même source et la même cible."""
def __init__(self, source:Any, cible:Any, nom:str = None):
Morphisme.__init__(self,source,cible,nom,source==cible)
def __eq__(self, other:'MorphismePreordre') -> bool:
return type(self) == type(other) and self.source == other.source and self.cible == other.cible
def __hash__(self) -> int:
return hash((self.source,self.cible))
def __matmul__(self, other:'MorphismePreordre') -> 'MorphismePreordre':
return MorphismePreordre(other.source,self.cible,str(self)+'o'+str(other))
MPO = MorphismePreordre
class CategoriePreordre(Categorie):
"""CategoriePreordre peut être abrégé en CatFine.
Classe abstraite qui définit ce qu'est une catégorie préordre.
Les classes filles doivent implémenter la méthode existe_morphisme(self,source:Any,cible:Any) -> Union(Morphisme,None) qui détermine
entièrement les flèches de la catégorie.
class CategoriePreordre(CategorieQuotient):
"""CategoriePreordre est aussi appelée CatFine.
Une catégorie préordre C est une catégorie telle qu'il n'y a pas plus de deux flèches entre deux objets de C."""
_id = 0
def __init__(self, objets:set = set(), nom:Union[str,None] = None):
CategoriePreordre._id += 1
self._id = CategoriePreordre._id
if nom == None:
nom = "Catégorie préordre "+str(self._id)
self.nom = nom
Categorie.__init__(self, objets, nom)
def identite(self, objet:Any) -> MorphismePreordre:
return MorphismePreordre(objet,objet)
def __call__(self, sources:set, cibles:set) -> Generator[MorphismePreordre,None,None]:
for source in sources:
for cible in cibles:
if self.existe_morphisme(source,cible) != None:
yield MorphismePreordre(source,cible)
def __getitem__(self, couple_sources_cibles:tuple) -> Generator[MorphismePreordre,None,None]:
sources,cibles = couple_sources_cibles
for source in sources:
for cible in cibles:
if self.existe_morphisme_elementaire(source,cible) != None:
yield MorphismePreordre(source,cible)
def rel_equiv_morph(self, morph1:Morphisme, morph2:Morphisme) -> bool:
return morph1.source == morph2.source and morph1.cible == morph2.cible
CatFine = CategoriePreordre
class CategoriePreordreEngendree(CategoriePreordre):
"""La catégorie préordre engendrée par une catégorie C est une sous-catégorie maximale C' de C
telle qu'il n'y a pas plus de deux flèches entre deux objets de C'.
L'attribut `foncteur_engendre` est le foncteur de la catégorie initiale vers la catégorie préordre engendrée."""
def __init__(self, categorie:Categorie, nom:str = None):
self._categorie_initiale = categorie
CategoriePreordre.__init__(self,categorie.objets, "Catégorie préordre engendrée par "+str(categorie) if nom == None else nom)
def existe_morphisme(self, source:Any, cible:Any) -> Union[Morphisme,None]:
return self._categorie_initiale.existe_morphisme(source,cible)
def existe_morphisme_elementaire(self, source:Any, cible:Any) -> Union[Morphisme,None]:
return self._categorie_initiale.existe_morphisme_elementaire(source,cible)
@property
def foncteur_engendre(self):
c_i = self._categorie_initiale
return Foncteur(c_i,self,{o:o for o in self.objets},{m:next(self({m.source},{m.cible})) for m in c_i[c_i.objets,c_i.objets]})
def test_CategoriePreordreEngendree():
def test_CategoriePreordre():
from GrapheDeComposition import GC,MGC
gc = GC()
......@@ -89,10 +22,22 @@ def test_CategoriePreordreEngendree():
gc.transformer_graphviz()
c_po = CategoriePreordreEngendree(gc)
c_po = CategoriePreordre(gc)
c_po.transformer_graphviz()
c_po.foncteur_engendre.transformer_graphviz()
c_po.fonct_surjection.transformer_graphviz()
from CategorieAleatoire import GrapheCompositionAleatoire
import random
random.seed(1233)
for i in range(5):
c = GrapheCompositionAleatoire()
c.transformer_graphviz()
c_a = CategoriePreordre(c)
c_a.transformer_graphviz()
c_a.fonct_surjection.transformer_graphviz()
if __name__ == '__main__':
test_CategoriePreordreEngendree()
\ No newline at end of file
test_CategoriePreordre()
\ No newline at end of file
......@@ -22,8 +22,7 @@ class MorphismeQuotient(Morphisme):
self._classe_morphismes = frozenset(morphismes)
def __eq__(self, other:'MorphismeQuotient') -> bool:
return issubclass(type(other),MorphismeQuotient) and (len(self._classe_morphismes-other._classe_morphismes) == 0 or
len(other._classe_morphismes-self._classe_morphismes) == 0)
return issubclass(type(other),MorphismeQuotient) and self._classe_morphismes == other._classe_morphismes
def __hash__(self) -> int:
return hash((self.source,self.cible))
......@@ -46,7 +45,7 @@ class CategorieQuotient(CategorieLibre):
(les identités équivalentes définissent la relation d'équivalence sur les objets).
Cette classe donne accès en lecture au foncteur de surjection canonique : fonct_surjection.
Cette classe donne accès en lecture à la catégorie à quotienter : cat_a_quotienter.
Pour voir un exemple, voir `CategorieAcyclique`."""
Pour voir un exemple, voir `CategoriePreordre` et `CategorieAcyclique`."""
def __init__(self,categorie_a_quotienter:Categorie, nom:str = None):
c = categorie_a_quotienter
......@@ -66,7 +65,7 @@ class CategorieQuotient(CategorieLibre):
obj_vers_classe[obj] = len(set(obj_vers_classe.values()))+1
classe_vers_obj[obj_vers_classe[obj]] = {obj}
obj_vers_classe = {o:ObjetQuotient(classe_vers_obj[obj_vers_classe[o]]) for o in c.objets}
for morph in c[c.objets,c.objets]:
for morph in c(c.objets,c.objets):
for cle in morph_vers_classe:
if self.rel_equiv_morph(morph,cle):
morph_vers_classe[morph] = morph_vers_classe[cle]
......@@ -77,9 +76,8 @@ class CategorieQuotient(CategorieLibre):
classe_vers_morph[morph_vers_classe[morph]] = {morph}
classe_vers_morph_quotient = {classe:MorphismeQuotient(obj_vers_classe[list(classe_vers_morph[classe])[0].source],\
obj_vers_classe[list(classe_vers_morph[classe])[0].cible],classe_vers_morph[classe]) for classe in classe_vers_morph}
morph_vers_classe = {m:classe_vers_morph_quotient[morph_vers_classe[m]] for m in c[c.objets,c.objets]}
morph_vers_classe = {m:classe_vers_morph_quotient[morph_vers_classe[m]] for m in c(c.objets,c.objets)}
CategorieLibre.__init__(self,set(obj_vers_classe.values()),nom if nom != None else "Catégorie quotient de "+str(categorie_a_quotienter))
backup = config.TOUJOURS_VERIFIER_COHERENCE
config.TOUJOURS_VERIFIER_COHERENCE = False
self._fonct_surjection = Foncteur(c,self,obj_vers_classe,morph_vers_classe)
......@@ -126,7 +124,7 @@ class CategorieQuotient(CategorieLibre):
return self.fonct_surjection(self.cat_a_quotienter.identite(next(iter(objet))))
def rel_equiv_morph(self, morph1:Morphisme, morph2:Morphisme) -> bool:
'''Cette méthode doit être une relation d'équivalence sur les flèches élémentaires de la catégorie à quotienter.'''
'''Cette méthode doit être une relation d'équivalence sur toute les flèches de la catégorie à quotienter.'''
raise NotImplementedError("Les classes filles doivent implementer cette methode afin de definir la relation d'equivalence par laquelle quotienter.")
......
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 = 1
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_COMPOSEE = 0
DEBUG_LOI_DE_COMPOSITION = False
GRAPHVIZ_ENABLED = True # booléen qui indique s'il faut charger la bibliothèque graphviz
GRAPHVIZ_CONCENTRATE_GRAPHS = False
......
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