Commit 5730dc0e authored by Guillaume Sabbagh's avatar Guillaume Sabbagh
Browse files

fonction est prohomologue a fonctionnelle mais a une complexité en O(n!)

parent 55201fab
......@@ -8,6 +8,8 @@ from config import *
if GRAPHVIZ_ENABLED:
from graphviz import Digraph
import random
import itertools
from collections import defaultdict
class Diagramme(Foncteur.Foncteur):
"""categorie_indexante est shallow copiée,
......@@ -76,23 +78,69 @@ class Diagramme(Foncteur.Foncteur):
import FoncteurOubli
assert(self.categorie_indexee == other.categorie_indexee)
cat_cones1 = self.champ_perceptif()
apex1 = set([e.apex for e in cat_cones1.objets])
cat_cones1.transformer_graphviz(complet=False)
cat_cones2 = other.champ_perceptif()
apex2 = set([e.apex for e in cat_cones2.objets])
if apex1 != apex2:
cat_cones2.transformer_graphviz(complet=False)
apices = set([e.apex for e in cat_cones1.objets])
apices2 = set([e.apex for e in cat_cones2.objets])
if apices != apices2:
return None
if len(cat_cones1.morphismes) != len(cat_cones2.morphismes) or len(cat_cones1.objets) != len(cat_cones2.objets):
return None
oubli1 = FoncteurOubli.FoncteurOubli(cat_cones1)
oubli2 = FoncteurOubli.FoncteurOubli(cat_cones2)
app_obj = {}
app_morph = {}
for objet in apex1:
antecedants = [e for e in cat_cones1.objets if e.apex == objet]
images = [e for e in cat_cones2.objets if e.apex == objet]
# si on note C1_o les cônes d'apex o de D1 et C2_o les cônes d'apex o de D2
# on cherche toutes les applications (C1_o1 ~> C2_o1) x (C1_o2 ~> C2_o2) x ... x (C1_oN ~> C2_oN)
applications_cones = []
for apex in apices:
antecedants = [e for e in cat_cones1.objets if e.apex == apex]
images = [e for e in cat_cones2.objets if e.apex == apex]
if len(antecedants) != len(images):
return None
#on sépare les cônes en fonction de leurs degrés
classes_degre_cone_ante = defaultdict(list)
for ante in antecedants:
classes_degre_cone_ante[(len(cat_cones1.morph_sortants[ante]),len(cat_cones1.morph_entrants[ante]))] += [ante]
classes_degre_cone_im = defaultdict(list)
for im in images:
classes_degre_cone_im[(len(cat_cones2.morph_sortants[im]),len(cat_cones2.morph_entrants[im]))] += [im]
applications_intra_classe = []
for degre in classes_degre_cone_ante:
if len(classes_degre_cone_ante[degre]) != len(classes_degre_cone_im[degre]):
return None
images_internes_possibles = itertools.permutations(classes_degre_cone_im[degre])
applications_intra_classe += [list(map(lambda x:dict(zip(classes_degre_cone_ante[degre],x)),images_internes_possibles))]
applications_cones += [[{cle:val for app in app_intra for cle,val in app.items()} for app_intra in itertools.product(*applications_intra_classe)]]
for application_cones in itertools.product(*applications_cones):
application_cones = {cle:val for app in application_cones for cle,val in app.items()}
applications_fleches = []
for source,cible in itertools.product(cat_cones1.objets,repeat=2):
antecedants = cat_cones1.fleches_elem(source,cible,False)
images = cat_cones2.fleches_elem(application_cones[source],application_cones[cible],False)
if len(antecedants) != len(images):
break
if len(antecedants) > 0:
images_possibles = itertools.permutations(images)
applications_fleches += [list(map(lambda x:dict(zip(antecedants,x)),images_possibles))]
else:
# ici on a toujours pu trouver au moins un isomorphisme entre les flèches elem
for application_fleches in itertools.product(*applications_fleches):
application_fleches = {cle:val for app in application_fleches for cle,val in app.items()}
try:
foncteur = Foncteur.Foncteur(cat_cones1,cat_cones2,application_cones,application_fleches)
foncteur.verifier_coherence()
# on va vérifier la coherence de l'isomorphisme
for obj in cat_cones1.objets:
if oubli1(obj) != oubli2(foncteur(obj)):
raise Exception("L'isomorphisme ne commute pas avec les foncteurs d'oubli pour l'objet "+str(obj))
for morph in cat_cones1.morphismes:
if oubli1(morph) != oubli2(foncteur(morph)):
raise Exception("L'isomorphisme ne commute pas avec les foncteurs d'oubli pour le morphisme "+str(morph.pretty_print()))
return foncteur
except Exception as e:
print("Warning : foncteur incoherent cree, on passe au suivant, "+str(e))
def transformer_graphviz(self, destination=None):
......@@ -121,6 +169,15 @@ class Diagramme(Foncteur.Foncteur):
import os
os.remove(destination)
class DiagrammeObjets(Diagramme):
"""Permet de selectionner des objets sans selectionner de flèches"""
def __init__(self, categorie_indexee, objets_a_selectionner):
""" objets_a_selectionner est une listes d'objets à selectionner dans la catégorie."""
cat = Categorie.Categorie("Objets")
cat.ajouter_objets(range(len(objets_a_selectionner)))
Diagramme.__init__(self,cat,categorie_indexee,{i:objets_a_selectionner[i] for i in range(len(objets_a_selectionner))},dict())
class Parallele(Diagramme):
_cat = Categorie.Categorie("Parallele")
_cat.ajouter_objets([1,2])
......@@ -240,11 +297,34 @@ def main():
# new_c = triangle.implementation()
# new_c.transformer_graphviz()
from CategorieAleatoire import CategorieAleaPreOrdreAcyclique
c = CategorieAleaPreOrdreAcyclique()
c.transformer_graphviz(complet = False)
d = DiagrammeAlea(c,retirer_objets_isoles=False)
d.transformer_graphviz()
c = Categorie.Categorie()
c.ajouter_objets("ABCDEFG")
m1,m2,m3,m4,m5,m6,m7,m8,a = [Morphisme('A','B','1'),Morphisme('A','B','2'),Morphisme('B','C','3'),Morphisme('A','C','4'),Morphisme('C','D','5'),Morphisme('C','E','6'),Morphisme('C','F','7'),Morphisme('C','G','8'),Morphisme('A','A','a')]
c.ajouter_morphismes([m1,m3,m4,m5,m6,m7,m8])
diag = DiagrammeIdentite(c)
diag.faire_commuter()
d1 = DiagrammeObjets(c,'DE')
d1.transformer_graphviz()
d2 = DiagrammeObjets(c,'FG')
d2.transformer_graphviz()
isomorphisme = d1.est_prohomologue_a(d2)
isomorphisme.transformer_graphviz()
# c.ajouter_morphismes([m2])
# d1.transformer_graphviz()
# d2.transformer_graphviz()
# isomorphisme = d1.est_prohomologue_a(d2)
# isomorphisme.transformer_graphviz()
c.ajouter_morphismes([a])
diag = Triangle(c,"AAA",[a,a,a])
diag.faire_commuter()
d1.transformer_graphviz()
d2.transformer_graphviz()
isomorphisme = d1.est_prohomologue_a(d2)
isomorphisme.transformer_graphviz()
if __name__ == '__main__':
......
......@@ -3,6 +3,10 @@ import Diagramme
import CategorieCones,CategorieCocones
import Bouquet
import random
import itertools
random.seed(156451564156748745)
......
......@@ -3,4 +3,11 @@
- tester catégorie cones avec un diagramme où la catégorie indexante n'a pas de flèches (on est censé avoir toutes les permutations de jambes)
- L200-205 Catégorie -> investiguer à quoi ça sert ?
- Problème dans catégorie aléatoire : un morphisme peut avoir deux inverses (voir s'il y a pas d'autres problèmes du genre)
- Corriger catégorie aléatoire isomophisme : il faut faire commuter les composantes isomorphes
\ No newline at end of file
- Corriger catégorie aléatoire isomophisme : il faut faire commuter les composantes isomorphes
- Retirer image objets de Parallele
(1) Un diagramme constant vers un objet A (et son identité) a toujours une limite et une colimite, qui coïncident avec A (et son identité comme unique jambe du co/cône). Son champ d'action (resp. de perception) coïncide avec le champ d'action (resp. de perception) de l'objet A et admet un objet initial (resp. final). Deux objets A et B qui ont des champs d'action isomorphes au-dessus de la catégorie C sont isomorphes (idem pour les champs de perception). Le principe de multiplicité ne concerne pas les diagrammes constants.
(2) Un diagramme vers A-->B (et les identités) a toujours une limite (A, Id_A, A-->B) et une colimite (B, A-->B, Id_B) qui ne coïncident donc pas. Champ d'action seul ne caractérise pas le diagramme (idem pour champ de perception), mais les deux ensemble si (à vérifier).
(3) Pour les diagrammes plus généraux, on ne peut rien dire, et le principe de multiplicité peut se déployer...
\ No newline at end of file
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