Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Guillaume Sabbagh
Modification de categories
Commits
13fdff59
Commit
13fdff59
authored
Apr 26, 2021
by
Guillaume Sabbagh
Browse files
Tests
parent
5730dc0e
Changes
8
Hide whitespace changes
Inline
Side-by-side
Bouquet.py
View file @
13fdff59
...
...
@@ -209,11 +209,7 @@ class BouquetsPerceptifs:
applications_cones
=
[]
for
apex
in
apices
:
domaine
=
[
e
for
e
in
self
.
cat_cones1
.
objets
if
e
.
apex
==
apex
]
for
c
in
domaine
:
c
.
transformer_graphviz
()
codomaine
=
[
e
for
e
in
self
.
cat_cones2
.
objets
if
e
.
apex
==
apex
]
for
c
in
codomaine
:
c
.
transformer_graphviz
()
images
=
itertools
.
product
(
codomaine
,
repeat
=
len
(
domaine
))
applications
=
[
dict
(
zip
(
domaine
,
image
))
for
image
in
images
]
applications_cones
+=
[
applications
]
...
...
@@ -270,11 +266,7 @@ class BouquetsActifs:
applications_cocones
=
[]
for
nadir
in
nadirs
:
domaine
=
[
e
for
e
in
self
.
cat_cocones2
.
objets
if
e
.
nadir
==
nadir
]
for
c
in
domaine
:
c
.
transformer_graphviz
()
codomaine
=
[
e
for
e
in
self
.
cat_cocones1
.
objets
if
e
.
nadir
==
nadir
]
for
c
in
codomaine
:
c
.
transformer_graphviz
()
images
=
itertools
.
product
(
codomaine
,
repeat
=
len
(
domaine
))
applications
=
[
dict
(
zip
(
domaine
,
image
))
for
image
in
images
]
applications_cocones
+=
[
applications
]
...
...
CategorieCocones.py
View file @
13fdff59
...
...
@@ -9,7 +9,7 @@ from config import *
class
CategorieCocones
(
Categorie
):
def
__init__
(
self
,
foncteur
,
image_op
=
None
):
def
__init__
(
self
,
foncteur
):
Categorie
.
__init__
(
self
,
"Categorie de cocones de "
+
str
(
foncteur
))
self
.
foncteur
=
foncteur
cocones
=
[
e
for
nadir
in
foncteur
.
cat_cible
.
objets
for
e
in
foncteur
.
enumerer_cocones
(
nadir
)]
...
...
@@ -32,10 +32,12 @@ class CategorieCocones(Categorie):
ancien_nouveau
=
defaultdict
(
list
)
for
cle
,
valeur
in
nouveau_ancien
.
items
():
ancien_nouveau
[
valeur
]
+=
[
cle
]
# Si le cycle est une identite il faut le faire commuter dès le début
for
cycle_nouveau
in
nouveau_ancien
:
if
nouveau_ancien
[
cycle_nouveau
].
is_identite
:
t
=
Triangle
(
self
,[
cocone
]
*
3
,[
cycle_nouveau
,
self
.
identites
[
cocone
],
self
.
identites
[
cocone
]])
t
.
faire_commuter
()
# Pour les autres cycles on fait commuter que la frontière de l'arbre de composition
cycles
=
sorted
(
self
.
foncteur
.
cat_cible
.
enumerer_cycles
(
cocone
.
nadir
),
key
=
len
)
for
debut_antecedant_ancien
,
fin_antecedant_ancien
in
product
(
cycles
,
cycles
+
[
self
.
foncteur
.
cat_cible
.
identites
[
cocone
.
nadir
]]):
# pour chaque simplification des cycles originels, on fait la même pour les nouveaux cycles
...
...
@@ -128,7 +130,7 @@ class CategorieCocones(Categorie):
noeud_courant
=
graphe
[
noeud_courant
][
0
]
while
type
(
noeud_courant
)
==
tuple
:
noeud_courant
=
noeud_courant
[
0
]
noeud_initial
=
noeud_courant
noeud_initial
=
noeud_courant
#on est arrivé au bout du chemin
for
cocone
in
self
.
objets
:
fleches
=
self
.
enumerer_composees
(
noeud_initial
,
cocone
)
...
...
Cone.py
View file @
13fdff59
...
...
@@ -17,6 +17,9 @@ class Cone():
def
__str__
(
self
):
return
str
(
self
.
apex
)
+
','
+
'/'
.
join
(
map
(
lambda
x
:
str
(
x
.
representant
),
self
.
jambes
.
values
()))
def
__repr__
(
self
):
return
str
(
self
)
+
","
+
super
().
__repr__
().
split
(
'object at '
)[
-
1
].
split
(
'>'
)[
0
]
def
__eq__
(
self
,
other
):
if
issubclass
(
type
(
other
),
Cone
):
...
...
Diagramme.py
View file @
13fdff59
...
...
@@ -71,7 +71,7 @@ class Diagramme(Foncteur.Foncteur):
def
champ_actif
(
self
):
import
CategorieCocones
return
CategorieCocones
.
CategorieCocones
(
self
)
def
est_prohomologue_a
(
self
,
other
):
"""Renvoie un foncteur isomorphisme entre les champs perceptifs des deux diagrammes s'il existe (les diagrammes sont prohomologues)
None sinon"""
...
...
@@ -112,7 +112,10 @@ class Diagramme(Foncteur.Foncteur):
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
))]
# print(list(map(list,applications_intra_classe)))
applications_cones
+=
[[{
cle
:
val
for
app
in
app_intra
for
cle
,
val
in
app
.
items
()}
for
app_intra
in
itertools
.
product
(
*
applications_intra_classe
)]]
# print(applications_cones)
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
=
[]
...
...
@@ -141,6 +144,76 @@ class Diagramme(Foncteur.Foncteur):
return
foncteur
except
Exception
as
e
:
print
(
"Warning : foncteur incoherent cree, on passe au suivant, "
+
str
(
e
))
def
est_homologue_a
(
self
,
other
):
"""Renvoie un foncteur isomorphisme entre les champs perceptifs des deux diagrammes s'il existe (les diagrammes sont prohomologues)
None sinon"""
import
FoncteurOubli
assert
(
self
.
categorie_indexee
==
other
.
categorie_indexee
)
cat_cocones1
=
self
.
champ_actif
()
cat_cocones1
.
transformer_graphviz
(
complet
=
False
)
cat_cocones2
=
other
.
champ_actif
()
cat_cocones2
.
transformer_graphviz
(
complet
=
False
)
nadirs
=
set
([
e
.
nadir
for
e
in
cat_cocones1
.
objets
])
nadirs2
=
set
([
e
.
nadir
for
e
in
cat_cocones2
.
objets
])
if
nadirs
!=
nadirs2
:
return
None
if
len
(
cat_cocones1
.
morphismes
)
!=
len
(
cat_cocones2
.
morphismes
)
or
len
(
cat_cocones1
.
objets
)
!=
len
(
cat_cocones2
.
objets
):
return
None
oubli1
=
FoncteurOubli
.
FoncteurOubli
(
cat_cocones1
)
oubli2
=
FoncteurOubli
.
FoncteurOubli
(
cat_cocones2
)
# si on note C1_o les cônes de nadir o de D1 et C2_o les cônes de nadir 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
nadir
in
nadirs
:
antecedants
=
[
e
for
e
in
cat_cocones1
.
objets
if
e
.
nadir
==
nadir
]
images
=
[
e
for
e
in
cat_cocones2
.
objets
if
e
.
nadir
==
nadir
]
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_cocones1
.
morph_sortants
[
ante
]),
len
(
cat_cocones1
.
morph_entrants
[
ante
]))]
+=
[
ante
]
classes_degre_cone_im
=
defaultdict
(
list
)
for
im
in
images
:
classes_degre_cone_im
[(
len
(
cat_cocones2
.
morph_sortants
[
im
]),
len
(
cat_cocones2
.
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_cocones1
.
objets
,
repeat
=
2
):
antecedants
=
cat_cocones1
.
fleches_elem
(
source
,
cible
,
False
)
images
=
cat_cocones2
.
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_cocones1
,
cat_cocones2
,
application_cones
,
application_fleches
)
foncteur
.
verifier_coherence
()
# on va vérifier la coherence de l'isomorphisme
for
obj
in
cat_cocones1
.
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_cocones1
.
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
):
...
...
@@ -170,13 +243,25 @@ class Diagramme(Foncteur.Foncteur):
os
.
remove
(
destination
)
class
DiagrammeObjets
(
Diagramme
):
"""Permet de selectionner des objets sans selectionner de flèche
s
"""
"""Permet de selectionner des objets sans selectionner de flèche"""
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
Fleche
(
Diagramme
):
"""Permet de selectionner deux objets réliés par une flèche"""
_cat
=
Categorie
.
Categorie
(
"1 Flèche"
)
_cat
.
ajouter_objets
([
1
,
2
])
_f
=
Morphisme
(
1
,
2
,
'f'
)
_cat
.
ajouter_morphisme
(
_f
)
def
__init__
(
self
,
categorie_indexee
,
fleche_a_selectionner
):
""" objets_a_selectionner est une listes d'objets à selectionner dans la catégorie."""
Diagramme
.
__init__
(
self
,
Fleche
.
_cat
,
categorie_indexee
,{
1
:
fleche_a_selectionner
.
source
,
2
:
fleche_a_selectionner
.
cible
},{
Fleche
.
_f
:
fleche_a_selectionner
})
class
Parallele
(
Diagramme
):
_cat
=
Categorie
.
Categorie
(
"Parallele"
)
...
...
@@ -311,11 +396,11 @@ def main():
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
([
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
])
...
...
FoncteurOubli.py
View file @
13fdff59
...
...
@@ -8,11 +8,13 @@ class FoncteurOubli(Foncteur):
"""categorie : catégorie de cônes ou de cocônes"""
if
issubclass
(
type
(
categorie
),
CategorieCones
):
app_morph
=
categorie
.
app_morph_fleche_cone
app_obj
=
{
cone
:
cone
.
apex
for
cone
in
categorie
.
objets
}
elif
issubclass
(
type
(
categorie
),
CategorieCocones
):
app_morph
=
categorie
.
app_morph_fleche_cocone
app_obj
=
{
cone
:
cone
.
nadir
for
cone
in
categorie
.
objets
}
else
:
raise
Exception
(
"Foncteur d'oubli sur une categorie qui n'est pas une categorie de cones ou de cocones"
)
Foncteur
.
__init__
(
self
,
categorie
,
categorie
.
foncteur
.
cat_cible
,
{
cone
:
cone
.
apex
for
cone
in
categorie
.
objets
}
,
Foncteur
.
__init__
(
self
,
categorie
,
categorie
.
foncteur
.
cat_cible
,
app_obj
,
app_morph
,
representant
=
"Foncteur d'oubli de "
+
categorie
.
nom
,
is_identite
=
False
)
...
...
Morphisme.py
View file @
13fdff59
...
...
@@ -28,6 +28,9 @@ class Morphisme:
def
pretty_print
(
self
):
return
str
(
self
.
representant
)
+
' : '
+
str
(
self
.
source
)
+
" -> "
+
str
(
self
.
cible
)
def
__repr__
(
self
):
return
pretty_print
(
self
)
+
","
+
super
().
__repr__
().
split
(
'object at '
)[
-
1
].
split
(
'>'
)[
0
]
def
__len__
(
self
):
return
len
(
self
.
composee
)
...
...
Tests.py
View file @
13fdff59
...
...
@@ -4,27 +4,60 @@ import CategorieCones,CategorieCocones
import
Bouquet
import
random
import
itertools
from
Morphisme
import
Morphisme
random
.
seed
(
156
451564156748745
)
#
random.seed(156
17156
)
cat
=
CategorieAleatoire
.
CategorieAleaIsomorph
()
cat
.
transformer_graphviz
(
complet
=
False
)
cat
.
transformer_graphviz
(
complet
=
True
)
#
cat = CategorieAleatoire.CategorieAleaIsomorph(
10,16
)
#
cat.transformer_graphviz(complet=False)
#
cat.transformer_graphviz(complet=True)
diag
=
Diagramme
.
DiagrammeAlea
(
cat
,
1
)
diag
.
transformer_graphviz
()
#
diag
1
= Diagramme.DiagrammeAlea(cat,1)
#
diag
1
.transformer_graphviz()
cat_cones
=
CategorieCones
.
CategorieCones
(
diag
)
cat_cones
.
transformer_graphviz
(
complet
=
False
)
#
cat_cones = CategorieCones.CategorieCones(diag
1
)
#
cat_cones.transformer_graphviz(complet=False)
for
lim
in
cat_cones
.
limites
():
lim
.
transformer_graphviz
()
#
for lim in cat_cones.limites():
#
lim.transformer_graphviz()
cat_cocones
=
CategorieCocones
.
CategorieCocones
(
diag
)
cat_cocones
.
transformer_graphviz
(
complet
=
False
)
#
cat_cocones = CategorieCocones.CategorieCocones(diag
1
)
#
cat_cocones.transformer_graphviz(complet=False)
for
lim
in
cat_cocones
.
colimites
():
lim
.
transformer_graphviz
()
\ No newline at end of file
# for lim in cat_cocones.colimites():
# lim.transformer_graphviz()
# diag2 = Diagramme.DiagrammeAlea(cat,1)
# diag2.transformer_graphviz()
# f = diag2.est_prohomologue_a(diag1)
# if f != None:
# f.transformer_graphviz()
# b = Bouquet.Bouquets(diag1,diag2)
# b.transformer_graphviz()
# b = Bouquet.Bouquets(diag2,diag1)
# b.transformer_graphviz()
cat
=
Categorie
.
Categorie
()
cat
.
ajouter_objets
(
"AB"
)
f
,
g
=
[
Morphisme
(
'A'
,
'B'
,
'f'
),
Morphisme
(
'A'
,
'B'
,
'g'
)]
cat
.
ajouter_morphismes
([
f
,
g
])
cat
.
transformer_graphviz
()
diag1
=
Diagramme
.
Fleche
(
cat
,
f
)
diag1
.
champ_perceptif
().
transformer_graphviz
()
diag2
=
Diagramme
.
Fleche
(
cat
,
g
)
diag2
.
champ_perceptif
().
transformer_graphviz
()
f
=
diag1
.
est_prohomologue_a
(
diag2
)
if
f
!=
None
:
f
.
transformer_graphviz
()
f
=
diag1
.
est_homologue_a
(
diag2
)
if
f
!=
None
:
f
.
transformer_graphviz
()
\ No newline at end of file
todo.txt
View file @
13fdff59
- Ajouter morphisme -> renvoyer la liste des cycles créés ?
- Mettre en cache les composées enumérées dans catégorie
- 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
- Retirer image objets de Parallele
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment