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
9501ead0
Commit
9501ead0
authored
May 11, 2021
by
Guillaume Sabbagh
Browse files
Catégorie sous et catégorie sur, afin de créer des clusters
parent
4b74e9d1
Changes
4
Hide whitespace changes
Inline
Side-by-side
Bouquet.py
View file @
9501ead0
...
...
@@ -62,7 +62,7 @@ class BouquetAbstrait(Morphisme):
Composante bleue : Cones
Composante bleue foncée : cocones
Composante orange: Bouquet"""
Bouquet
.
nb_viz
+=
1
Bouquet
Abstrait
.
nb_viz
+=
1
if
self
.
cat_cones1
==
None
:
self
.
cat_cones1
=
CategorieCones
(
self
.
foncteur1
)
if
self
.
cat_cones2
==
None
:
...
...
@@ -74,7 +74,7 @@ class BouquetAbstrait(Morphisme):
image1
=
self
.
foncteur1
.
categorie_image
()
image2
=
self
.
foncteur2
.
categorie_image
()
if
destination
==
None
:
destination
=
"graphviz/bouquet"
+
str
(
Bouquet
.
nb_viz
)
destination
=
"graphviz/bouquet"
+
str
(
Bouquet
Abstrait
.
nb_viz
)
graph
=
Digraph
(
'bouquet'
)
graph
.
attr
(
concentrate
=
"true"
if
GRAPHVIZ_CONCENTRATE_GRAPHS
else
"false"
)
graph
.
attr
(
label
=
"Bouquet entre "
+
str
(
self
.
foncteur1
)
+
" et "
+
str
(
self
.
foncteur2
))
...
...
CategorieSous.py
0 → 100644
View file @
9501ead0
from
Categorie
import
Categorie
import
itertools
from
Morphisme
import
Morphisme
from
copy
import
copy
class
CategorieSous
(
Categorie
):
"""Soit C une catégorie, et a un objet de C.
CategorieSous n'est pas la catégorie T-en-dessous de a (
(cf. Mac Lane "Categories for the working mathematician" P.46)
C'est plutôt la sous-catégorie C' de C telle que pour tout objet b de la catégorie C' il existe une flèche de a à b"""
def
__new__
(
cls
,
categorie
,
objet
):
if
objet
not
in
categorie
.
objets
:
raise
Exception
(
"Incohérence CategorieSous : objet "
+
str
(
objet
)
+
" pas dans la categorie."
)
result
=
copy
(
categorie
)
for
obj
in
categorie
.
objets
:
if
len
(
categorie
.
enumerer_composees_sans_cycle
(
objet
,
obj
))
==
0
:
result
.
supprimer_objet
(
obj
)
return
result
def
main
():
import
CategorieAleatoire
import
random
random
.
seed
(
14896488564964
)
cat
=
CategorieAleatoire
.
CategorieAleaIsomorph
()
cat
.
transformer_graphviz
()
obj
=
random
.
choice
(
cat
.
objets
)
print
(
obj
)
cat2
=
CategorieSous
(
cat
,
obj
)
cat2
.
transformer_graphviz
()
obj
=
random
.
choice
(
cat
.
objets
)
print
(
obj
)
cat2
=
CategorieSous
(
cat
,
obj
)
cat2
.
transformer_graphviz
()
if
__name__
==
'__main__'
:
main
()
\ No newline at end of file
CategorieSur.py
View file @
9501ead0
from
categorie.
Categorie
import
Categorie
from
Categorie
import
Categorie
import
itertools
from
Morphisme
import
Morphisme
from
Foncteur
import
Composition
class
ObjetCatSur
():
def
__init__
(
self
,
f
,
e
):
self
.
f
=
f
self
.
e
=
e
def
__str__
(
self
):
return
"("
+
str
(
self
.
f
)
+
","
+
str
(
self
.
e
)
+
")"
from
copy
import
copy
class
CategorieSur
(
Categorie
):
"""Soit T:E->C un foncteur, et a un objet de C.
CategorieSur est la catégorie T-au-dessus de a (
(cf. Mac Lane "Categories for the working mathematician" P.46)"""
"""Soit C une catégorie, et a un objet de C.
CategorieSur n'est pas la catégorie T-au-dessus de a (
(cf. Mac Lane "Categories for the working mathematician" P.46)
C'est plutôt la sous-catégorie C' de C telle que pour tout objet b de la catégorie C' il existe une flèche de b à a"""
def
__init__
(
self
,
T
,
a
):
"""Soit T:E->C un foncteur, et a un objet de C.
CategorieSur est la catégorie T-au-dessus de a (
(cf. Mac Lane "Categories for the working mathematician" P.46)"""
Categorie
.
__init__
(
self
,
"Categorie "
+
str
(
T
)
+
"-en-dessous de "
+
str
(
a
))
E
=
T
.
cat_source
C
=
T
.
cat_cible
implementation
=
T
.
cat_image
()
for
e
in
E
.
objets
:
c
=
S
(
e
)
for
f
in
C
.
enumerer_composees
(
c
,
a
):
self
.
ajouter_objet
(
ObjetCatSur
(
f
,
e
))
for
obj1
,
obj2
in
itertools
.
combinations
(
self
.
objets
,
2
):
for
h
in
[
elem
for
elem
in
E
.
morph_sortants
[
obj1
.
e
]
if
elem
.
cible
==
obj2
.
e
]:
if
obj1
.
f
==
self
.
Composee
(
T
(
h
),
obj2
.
f
):
self
.
ajouter_morphisme
(
Morphisme
(
obj1
,
obj2
,
T
(
h
).
representant
))
fpr
diag
in
C
.
diagrammes
:
nouveau_diag
=
Composition
(
diag
,
S
)
nouveau_diag
.
def
__new__
(
cls
,
categorie
,
objet
):
if
objet
not
in
categorie
.
objets
:
raise
Exception
(
"Incohérence CategorieSur : objet "
+
str
(
objet
)
+
" pas dans la categorie."
)
result
=
copy
(
categorie
)
for
obj
in
categorie
.
objets
:
if
len
(
categorie
.
enumerer_composees_sans_cycle
(
obj
,
objet
))
==
0
:
result
.
supprimer_objet
(
obj
)
return
result
def
main
():
import
CategorieAleatoire
import
random
random
.
seed
(
14896488564964
)
cat
=
CategorieAleatoire
.
CategorieAleaIsomorph
()
cat
.
transformer_graphviz
()
obj
=
random
.
choice
(
cat
.
objets
)
print
(
obj
)
cat2
=
CategorieSur
(
cat
,
obj
)
cat2
.
transformer_graphviz
()
obj
=
random
.
choice
(
cat
.
objets
)
print
(
obj
)
cat2
=
CategorieSur
(
cat
,
obj
)
cat2
.
transformer_graphviz
()
if
__name__
==
'__main__'
:
main
()
\ No newline at end of file
Cluster.py
0 → 100644
View file @
9501ead0
from
Morphisme
import
Morphisme
from
CategorieCones
import
CategorieCones
from
CategorieCocones
import
CategorieCocones
from
config
import
*
import
itertools
from
collections
import
defaultdict
from
copy
import
copy
if
GRAPHVIZ_ENABLED
:
from
graphviz
import
Digraph
class
ClusterAbstrait
(
Morphisme
):
nb_viz
=
0
def
__init__
(
self
,
foncteur1
,
foncteur2
,
tiges
,
cat_cones1
=
None
,
cat_cones2
=
None
,
cat_cocones1
=
None
,
cat_cocones2
=
None
):
self
.
foncteur1
=
foncteur1
self
.
foncteur2
=
foncteur2
self
.
composantes
=
list
(
tiges
)
#liste de morphismes de la catégorie cible des foncteurs
self
.
categorie
=
self
.
foncteur1
.
cat_cible
self
.
cat_cones1
=
cat_cones1
self
.
cat_cones2
=
cat_cones2
self
.
cat_cocones1
=
cat_cocones1
self
.
cat_cocones2
=
cat_cocones2
identite
=
False
if
self
.
foncteur1
==
self
.
foncteur2
:
for
composante
in
self
.
composantes
:
if
not
composante
.
is_identite
:
break
else
:
for
objet
in
self
.
foncteur1
.
app_objets
.
values
():
if
self
.
categorie
.
identites
[
objet
]
not
in
self
.
composantes
:
break
else
:
identite
=
True
Morphisme
.
__init__
(
self
,
self
.
foncteur1
,
self
.
foncteur2
,
str
(
self
),
identite
)
def
__eq__
(
self
,
other
):
if
issubclass
(
type
(
other
),
ClusterAbstrait
):
if
len
([
e
for
e
in
self
.
composantes
if
e
not
in
other
.
composantes
])
>
0
:
return
False
if
len
([
e
for
e
in
other
.
composantes
if
e
not
in
self
.
composantes
])
>
0
:
return
False
return
self
.
foncteur1
==
other
.
foncteur1
and
self
.
foncteur2
==
other
.
foncteur2
return
False
def
__hash__
(
self
):
return
hash
((
tuple
(
self
.
composantes
),
self
.
foncteur1
,
self
.
foncteur2
))
def
__str__
(
self
):
return
'('
+
str
(
self
.
foncteur1
)
+
','
+
'/'
.
join
(
map
(
str
,
self
.
composantes
))
+
','
+
str
(
self
.
foncteur2
)
+
')'
def
__repr__
(
self
):
return
str
(
self
)
def
verifier_coherence
(
self
):
raise
NotImplementedError
()
def
transformer_graphviz
(
self
,
destination
=
None
):
"""Permet de visualiser le cluster avec graphviz
Composante rouge : diagramme 1
Composante verte : diagramme 2
Composante bleue: cluster"""
ClusterAbstrait
.
nb_viz
+=
1
image1
=
self
.
foncteur1
.
categorie_image
()
image2
=
self
.
foncteur2
.
categorie_image
()
if
destination
==
None
:
destination
=
"graphviz/cluster"
+
str
(
ClusterAbstrait
.
nb_viz
)
graph
=
Digraph
(
'cluster'
)
graph
.
attr
(
concentrate
=
"true"
if
GRAPHVIZ_CONCENTRATE_GRAPHS
else
"false"
)
graph
.
attr
(
label
=
"Cluster entre "
+
str
(
self
.
foncteur1
)
+
" et "
+
str
(
self
.
foncteur2
))
for
o
in
self
.
categorie
.
objets
:
couleur
=
[
0
,
0
,
0
]
if
o
in
image1
.
objets
:
couleur
[
0
]
+=
255
if
o
in
image2
.
objets
:
couleur
[
1
]
+=
255
graph
.
node
(
str
(
o
),
color
=
"#"
+
''
.
join
(
map
(
lambda
x
:(
2
-
len
(
str
(
hex
(
x
))[
2
:]))
*
"0"
+
str
(
hex
(
x
))[
2
:],
couleur
)))
#"grey60")
morphismes
=
self
.
categorie
.
morphismes
+
image1
.
morphismes
+
image2
.
morphismes
+
self
.
composantes
for
morph
in
[
morphismes
[
i
]
for
i
in
range
(
len
(
morphismes
))
if
i
==
len
(
morphismes
)
or
morphismes
[
i
]
not
in
morphismes
[
i
+
1
:]]:
if
not
morph
.
is_identite
:
couleur
=
[
0
,
0
,
0
]
if
morph
in
image1
.
morphismes
:
couleur
[
0
]
+=
255
if
morph
in
image2
.
morphismes
:
couleur
[
1
]
+=
255
if
morph
in
self
.
composantes
:
couleur
=
[
0
,
0
,
255
]
graph
.
edge
(
str
(
morph
.
source
),
str
(
morph
.
cible
),
label
=
str
(
morph
.
representant
),
color
=
"#"
+
''
.
join
(
map
(
lambda
x
:(
2
-
len
(
str
(
hex
(
x
))[
2
:]))
*
"0"
+
str
(
hex
(
x
))[
2
:],
couleur
)))
else
:
graph
.
edge
(
str
(
morph
.
source
),
str
(
morph
.
cible
),
label
=
str
(
morph
.
representant
),
weight
=
"1000"
,
color
=
"#"
+
''
.
join
(
map
(
lambda
x
:(
2
-
len
(
str
(
hex
(
x
))[
2
:]))
*
"0"
+
str
(
hex
(
x
))[
2
:],
couleur
)))
graph
.
render
(
destination
)
if
CLEAN_GRAPHVIZ_MODEL
:
import
os
os
.
remove
(
destination
)
class
ClusterActif
(
ClusterAbstrait
):
"""Seules les contraintes sur les cocônes sont prises en compte pour le cluster actif"""
def
__init__
(
self
,
foncteur1
,
foncteur2
,
composantes
,
cat_cocones1
=
None
,
cat_cocones2
=
None
):
"""On peut fournir cat_cocones1 et cat_cocones2 pour économiser du temps de calcul."""
ClusterAbstrait
.
__init__
(
self
,
foncteur1
,
foncteur2
,
composantes
,
None
,
None
,
cat_cocones1
,
cat_cocones2
)
if
TOUJOURS_VERIFIER_COHERENCE
:
ClusterActif
.
verifier_coherence
(
self
)
def
verifier_coherence
(
self
):
if
self
.
foncteur1
.
cat_cible
!=
self
.
foncteur2
.
cat_cible
:
raise
Exception
(
"Incoherence ClusterActif : les deux foncteurs n'ont pas la meme image."
)
impl1
,
impl2
=
[
self
.
foncteur1
.
categorie_image
(),
self
.
foncteur2
.
categorie_image
()]
for
composante
in
self
.
composantes
:
if
composante
.
source
not
in
impl1
.
objets
:
raise
Exception
(
"Incoherence Cluster : la composante "
+
str
(
composante
)
+
" ne prend pas sa source dans l'image de F1"
)
if
composante
.
cible
not
in
impl2
.
objets
:
raise
Exception
(
"Incoherence Cluster : la composante "
+
str
(
composante
)
+
" ne prend pas sa cible dans l'image de F2"
)
if
self
.
cat_cocones1
==
None
:
self
.
cat_cocones1
=
CategorieCocones
(
self
.
foncteur1
)
if
self
.
cat_cocones2
==
None
:
self
.
cat_cocones2
=
CategorieCocones
(
self
.
foncteur2
)
# contrainte 1) au moins une flèche part de chacun des objets de D1
for
d
in
self
.
foncteur1
.
cat_source
.
objets
:
for
composante
in
self
.
composantes
:
if
composante
.
source
==
self
.
foncteur1
(
d
):
break
else
:
raise
Exception
(
"Incoherence Cluster : l'objet "
+
str
(
self
.
foncteur1
(
d
))
+
" de D1 n'a pas de d'image par le cluster"
)
\ No newline at end of file
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