Commit 00024ea9 authored by Guillaume Sabbagh's avatar Guillaume Sabbagh
Browse files

sous_cat_equiv pour les morphismes_quotients

parent ec854a45
......@@ -374,10 +374,7 @@ class SousCategorie(Categorie):
for morph in self._cat_origin(sources,cibles):
if morph in self._morph or morph.is_identite:
yield morph
def __getitem__(self, couple_sources_cibles:tuple) -> Generator[Morphisme,None,None]:
for morph in self(*couple_sources_cibles):
yield morph
def test_SousCategorie():
from GrapheDeComposition import GC,MGC
......@@ -428,7 +425,7 @@ def test_CategorieDiscrete():
if __name__ == '__main__':
test_Categorie()
test_CategorieDiscrete()
test_SousCategoriePleine()
# test_Categorie()
# test_CategorieDiscrete()
# test_SousCategoriePleine()
test_SousCategorie()
\ No newline at end of file
......@@ -414,54 +414,20 @@ def test_FoncteurAleatoireCatOrdreTotal():
f.transformer_graphviz()
f.as_diagram().transformer_graphviz()
class FoncteurAleatoireCatFineAcycliqueConnexe(Foncteur):
"""Foncteur aléatoire entre deux catégories fines acycliques et connexes."""
def __init__(self, categorie_indexante:Categorie, categorie_cible:Categorie, nom:Union[str,None] = None):
'''Les deux catégories doivent être fines, acycliques et connexes.'''
#todo : vérifier ques les catégories sont fines, acycliques et connexes
class FoncteurAleatoireCatOrdreConnexe(Foncteur):
"""Foncteur aléatoire entre deux catégories ordre et connexes."""
def __init__(self, categorie_indexante:CatOrdre, categorie_cible:CatOrdre, nom:Union[str,None] = None):
'''Les deux catégories doivent être des catégories connexes.'''
assert(len(CatCC(categorie_indexante).objets) == 1) # on vérifie qu'il n'y a qu'une seule composante connexe
assert(len(CatCC(categorie_cible).objets) == 1) # on vérifie qu'il n'y a qu'une seule composante connexe
cat1,cat2 = categorie_indexante,categorie_cible
app_obj, app_morph = dict(),dict()
morph = None
for f in cat1[cat1.objets,cat1.objets]:
if not f.is_identite:
morph = f
break
if morph == None:
#il n'y a qu'une identité dans cat1 (il ne peut pas y en avoir plusieurs puisqu'on est dans une composante connexe)
app_obj[list(cat1.objets)[0]] = random.choice(list(cat2.objets))
else:
# on doit mapper le morphisme morph
fleches_deja_map = {morph}
app_morph[morph] = random.choice(list(cat2(cat2.objets,cat2.objets)))
app_obj[morph.source] = app_morph[morph].source
app_obj[morph.cible] = app_morph[morph].cible
print(morph,app_morph[morph])
continuer = True
while continuer:
continuer = False
for fleche_deja_map in fleches_deja_map:
for fleche_a_map in cat1[{fleche_deja_map.cible},cat1.objets]:
if fleche_a_map not in fleches_deja_map and not fleche_a_map.is_identite:
image = random.choice(list(cat2({app_obj[fleche_deja_map.cible]},cat2.objets)))
print(fleche_a_map,image)
fleche_deja_map |= {fleche_a_map}
app_morph[fleche_a_map] = image
app_obj[fleche_a_map.cible] = image.cible
continuer = True
for fleche_a_map in cat1[cat1.objets,{fleche_deja_map.source}]:
if fleche_a_map not in fleches_deja_map and not fleche_a_map.is_identite:
image = random.choice(list(cat2(cat2.objets,{app_obj[fleche_deja_map.source]})))
print(fleche_a_map,image)
fleche_deja_map |= {fleche_a_map}
app_morph[fleche_a_map] = image
app_obj[fleche_a_map.source] = image.source
continuer = True
Foncteur.__init__(self,cat1,cat2,app_obj,app_morph)
def test_FoncteurAleatoireCatFineAcycliqueConnexe():
def test_FoncteurAleatoireCatOrdreConnexe():
import random
random.seed(4)
......@@ -475,7 +441,7 @@ def test_FoncteurAleatoireCatFineAcycliqueConnexe():
c1_.transformer_graphviz()
c2_.transformer_graphviz()
f = FoncteurAleatoireCatFineAcycliqueConnexe(c1_,c2_)
f = FoncteurAleatoireCatOrdreConnexe(c1_,c2_)
f.transformer_graphviz()
f.as_diagram().transformer_graphviz()
......
......@@ -32,6 +32,9 @@ def test_CategorieOrdre():
for obj in c_a.objets:
c_a.sous_cat_equiv(obj).transformer_graphviz()
print(c_a.tri_topologique())
for morph in c_a(c_a.objets,c_a.objets):
morph.sous_cat_equiv().transformer_graphviz()
if __name__ == '__main__':
test_CategorieOrdre()
\ No newline at end of file
......@@ -9,6 +9,7 @@ from typing import *
class CategorieOrdreTotal(CatOrdre):
"""`CategorieOrdreTotal` peut être abrégé en `CatOrdreTotal`
Catégorie qui correspond à une relation d'ordre totale : catégorie acyclique telle que tous les éléments sont comparables (toutes les flèches sont composables).
De plus, au sein d'un objet classe d'équivalence, il n'y a aucune flèche d'un objet vers un autre.
On fait un tri topologique. En suivant le tri, les objets sont équivalents tant qu'il n'y a aucune flèche intraclasse.
"""
......
from Categorie import Categorie, unique_generator, SousCategoriePleine
from Categorie import Categorie, unique_generator, SousCategoriePleine, SousCategorie
from CategorieLibre import CategorieLibre
from Foncteur import Foncteur
from Morphisme import Morphisme
......@@ -52,6 +52,11 @@ class MorphismeQuotient(Morphisme):
print("Warning : lors du calcul de la composition "+str(self)+" o "+str(other)+", aucun morphisme composable")
return MorphismeQuotient(other.source,self.cible,set(),self)
def sous_cat_equiv(self) -> SousCategorie:
"""Renvoie la sous-catégorie qui est envoyée sur le morphisme par le foncteur de surjection.
Pour la même fonction mais qui renvoie la sous-catégorie qui est envoyée sur un objet, voir `CategorieQuotient.sous_cat_equiv`"""
return SousCategorie(self._cat_quotient_associee.cat_a_quotienter,self.source|self.cible,self._classe_morphismes)
class CategorieQuotient(CategorieLibre):
"""
Définit ce qu'est une catégorie quotient. Cette classe est lourde et ne passe pas à l'échelle sur de grosses catégories.
......@@ -161,7 +166,8 @@ class CategorieQuotient(CategorieLibre):
return self._morph_vers_classe[self.cat_a_quotienter.identite(next(iter(objet)))]
def sous_cat_equiv(self, objet:ObjetQuotient) -> SousCategoriePleine:
'''Renvoie la sous-catégorie qui est envoyée sur un objet par le foncteur de surjection.'''
"""Renvoie la sous-catégorie qui est envoyée sur un objet par le foncteur de surjection.
Pour la même fonction mais qui renvoie la sous-catégorie qui est envoyée sur un morphisme, voir `MorphismeQuotient.sous_cat_equiv`"""
return SousCategoriePleine(self.cat_a_quotienter,{obj for obj in self.cat_a_quotienter.objets if self._obj_vers_classe[obj] == objet})
......
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