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

Correction CategorieOrdreTotal

parent 8cf4145d
......@@ -23,6 +23,27 @@ class CategorieAcyclique(CategorieQuotient):
else:
for m in categorie_a_quotienter({obj1},{obj1}):
self.identifier_morphismes(m,categorie_a_quotienter.identite(obj1))
def tri_topologique(self) -> list:
"""Renvoie une liste d'objets de la catégorie dans l'ordre topologique.
Si a vient avant b dans la liste alors il n'existe aucune flèche de b vers a.
La construction suit le principe suivant : on prend tous les objets sans pères, on les ajoute au tri,
puis on les retire et on recommence jusqu'à ce qu'il n'y ait plus d'objets à trier.
"""
objets_a_trier = self.objets
tri = []
while len(objets_a_trier) > 0:
nouveaux_objets_tries = set()
for obj in objets_a_trier:
# on cherche à savoir si obj a un père dans la liste des objets à trier
# si c'est le cas, il n'y a aucune flèche dans self(objets_a_trier-{obj},{obj})
if next(self(objets_a_trier-{obj},{obj}),None) == None:
tri += [obj]
nouveaux_objets_tries |= {obj}
objets_a_trier -= nouveaux_objets_tries
return tri
CatAcyclique = CategorieAcyclique
CatOrdre = CatAcyclique
......@@ -33,7 +54,7 @@ def test_CategorieAcyclique():
random.seed(1)
for i in range(1):
c = GrapheCompositionAleatoire()
c = GrapheCompositionAleatoire(20,150)
c.transformer_graphviz()
c_a = CategorieAcyclique(c)
......@@ -41,6 +62,7 @@ def test_CategorieAcyclique():
c_a.fonct_surjection.transformer_graphviz()
for obj in c_a.objets:
c_a.sous_cat_equiv(obj).transformer_graphviz()
print(c_a.tri_topologique())
if __name__ == '__main__':
test_CategorieAcyclique()
\ No newline at end of file
......@@ -4,75 +4,30 @@ from CategorieQuotient import CategorieQuotient
import copy
import itertools
from typing import *
class CategorieQuasiOrdreTotal(CategorieQuotient):
"""`CategorieQuasiOrdreTotal` peut être abrégé en `CatQuasiOrdreTotal`
Catégorie qui correspond à une quasi-relation d'ordre totale : catégorie acyclique telle que tous les éléments sont comparables (toutes les flèches sont composables).
/!\ il peut cependant y avoir plusieurs flèches entre deux objets contrairement à `CategorieOrdreTotal`/!\
Catégorie quotientée par la relation d'équivalence sur les objets suivante :
Les objets sans père sont équivalents.
Les enfants de ces objets sont équivalents (les enfants de A sont des objets B tel qu'il existe une flèche de A vers B mais il n'existe aucune flèche d'un C vers B tel qu'il existe une flèche de A vers C).
Les enfants des enfants de ces objets sont équivalents.
etc.
"""
def __init__(self,categorie_a_quotienter:CatOrdre, nom:str = None):
if nom == None:
nom = "Catégorie quasi-ordre total engendrée par "+str(categorie_a_quotienter)
CategorieQuotient.__init__(self,categorie_a_quotienter,nom)
cat = categorie_a_quotienter # on a besoin que d'une flèche entre deux objets
noeuds_courants = {obj for obj in cat.objets if all(map(lambda x:x.is_identite,cat[cat.objets,{obj}]))} # les objets sans père n'ont que l'identité comme flèche entrante
self.identifier_ensemble_morphismes(set(map(lambda x:cat.identite(x),noeuds_courants))) # on identifie les identités des objets de départ
while len(noeuds_courants) > 0:
fleches_descendantes = {f for f in cat(noeuds_courants,cat.objets) if not f.is_identite}
print(fleches_descendantes)
fils_associes = set(map(lambda x:x.cible,fleches_descendantes))
vrais_fils = copy.copy(fils_associes)
for fils in fils_associes:
vrais_fils -= {f.cible for f in cat({fils},cat.objets) if not f.is_identite}
fleches_courantes = set(cat(noeuds_courants,vrais_fils))
self.identifier_ensemble_morphismes(set(map(lambda x:cat.identite(x.cible),fleches_courantes))) # on identifie les identités des cibles des flèches courantes
self.identifier_ensemble_morphismes(fleches_courantes) # on identifie les identités des cibles des flèches courantes
noeuds_courants = vrais_fils
CatQuasiOrdreTotal = CategorieQuasiOrdreTotal
def test_CatQuasiOrdreTotal():
from CategorieAleatoire import GrapheCompositionAleatoire
import random
random.seed(3)
for i in range(10):
c = GrapheCompositionAleatoire()
c.transformer_graphviz()
c_o = CatOrdre(c)
c_o.transformer_graphviz()
c_ot = CatQuasiOrdreTotal(c_o)
c_ot.transformer_graphviz()
from typing import *
class CategorieOrdreTotal(CategorieQuotient):
"""`CategorieOrdreTotal` peut être abrégé en `CatOrdreTotal`
Catégorie qui correspond à une quasi-relation d'ordre totale : catégorie acyclique telle que tous les éléments sont comparables (toutes les flèches sont composables).
/!\ il peut cependant y avoir plusieurs flèches entre deux objets contrairement à `CategorieOrdreTotal`/!\
Catégorie quotientée par la relation d'équivalence sur les objets suivante :
Les objets sans père sont équivalents.
Les enfants de ces objets sont équivalents (les enfants de A sont des objets B tel qu'il existe une flèche de A vers B mais il n'existe aucune flèche d'un C vers B tel qu'il existe une flèche de A vers C).
Les enfants des enfants de ces objets sont équivalents.
etc.
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).
On fait un tri topologique. En suivant le tri, les objets sont équivalents tant qu'il n'y a aucune flèche intraclasse.
"""
def __init__(self,categorie_a_quotienter:CatQuasiOrdreTotal, nom:str = None):
def __init__(self,categorie_a_quotienter:CatOrdre, nom:str = None):
if nom == None:
nom = "Catégorie ordre total engendrée par "+str(categorie_a_quotienter)
CategorieQuotient.__init__(self,categorie_a_quotienter,nom)
# simples contraintes de catégorie fine
for obj1, obj2 in itertools.product(categorie_a_quotienter.objets,repeat=2):
self.identifier_ensemble_morphismes(set(categorie_a_quotienter({obj1},{obj2})))
tri = categorie_a_quotienter.tri_topologique()
classe_equiv_en_cours = set()
for obj in tri:
if next(categorie_a_quotienter(classe_equiv_en_cours,{obj}),None) == None:
classe_equiv_en_cours |= {obj}
else:
self.identifier_ensemble_morphismes(set(map(lambda x:categorie_a_quotienter.identite(x),classe_equiv_en_cours)))
classe_equiv_en_cours = {obj}
self.identifier_ensemble_morphismes(set(map(lambda x:categorie_a_quotienter.identite(x),classe_equiv_en_cours)))
for classe1,classe2 in itertools.product(self.objets,repeat=2):
self.identifier_ensemble_morphismes(set(categorie_a_quotienter(classe1,classe2)))
CatOrdreTotal = CategorieOrdreTotal
......@@ -83,11 +38,10 @@ def test_CatOrdreTotal():
random.seed(3)
for i in range(10):
c = GrapheCompositionAleatoire()
c.transformer_graphviz()
c_o = CatOrdre(c)
c_qot = CategorieQuasiOrdreTotal(c_o)
c_ot = CatOrdreTotal(c_qot)
c_ot = CatOrdreTotal(c_o)
c_ot.transformer_graphviz()
if __name__ == '__main__':
test_CatQuasiOrdreTotal()
test_CatOrdreTotal()
\ No newline at end of file
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