ChampActif.py 5.17 KB
Newer Older
1
from CommaCategorie import CommaCategorie, ObjetCommaCategorie
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
2
3
4
from TransformationNaturelle import CatTransfoNat,TransfoNat
from Foncteur import Foncteur
from Diagramme import DiagrammeConstant,DiagrammeObjets
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
5
from Cluster import ClusterActif,ProtoClusterActif
6
from typing import *
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
7

8
9
10
11
12
13
14
15
16
17
18
19
20
class Cocone(TransfoNat):
    """Un cocône sur D de nadir N est une transformation naturelle de D vers le foncteur constant Δ_N."""
    def __init__(self, objet_champ_actif:ObjetCommaCategorie):
        self.__nadir = objet_champ_actif.d # attribut read-only
        f = objet_champ_actif.f
        TransfoNat.__init__(self,f.source,f.cible,f._composantes,f.nom)
    
    @property
    def nadir(self):
        return self.__nadir
        
    def as_ObjetCommaCategorie(self) -> ObjetCommaCategorie:
        return ObjetCommaCategorie(0,self,self.nadir)
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
21
22
23
        
    def as_Cluster(self) -> ClusterActif:
        return ClusterActif(ProtoClusterActif(self.source,self.cible,self._composantes,"Cluster issu du cocône "+str(self)))
24

Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class ChampActif(CommaCategorie):
    """Le champ actif d'un diagramme(ou foncteur) D:P->Q est défini comme étant la comma-catégorie (D|Δ)
    (cf. https://en.wikipedia.org/wiki/Cone_(category_theory)#Equivalent_formulations)
    Un objet (Id,C,A) du champ actif nous donne un cocône C de nadir A sur le diagramme D.
    Δ:Q -> (P->Q) est un foncteur dans une catégorie infinie, on ne s'intéresse qu'aux diagrammes constants Δq : P->Q, _|->q,_|->1q avec q \in Q
    et au diagramme D.
    En ne s'intéressant qu'à ces diagrammes, on obtient quand même tous les cocônes sur D.
    """
    
    def __init__(self, diagramme:Foncteur, nom:str = None):
        P = diagramme.source
        Q = diagramme.cible
        self.categorie_diagrammes = CatTransfoNat({DiagrammeConstant(P,Q,o) for o in Q.objets},
        "Categorie de diagrammes du champ actif de "+str(diagramme))
        self.categorie_diagrammes |= {diagramme}
        
        self.foncteur_diagonal = Foncteur(Q,self.categorie_diagrammes,{o:DiagrammeConstant(P,Q,o) for o in Q.objets},
        {f: TransfoNat(DiagrammeConstant(P,Q,f.source),DiagrammeConstant(P,Q,f.cible),{p:f for p in P.objets}) for f in Q(abs(Q),abs(Q))})
        ## on associe à chaque objet son diagramme constant et à chaque flèche F:a->b la transformation naturelle qui va de Δa à Δb
        
        self.foncteur_vers_D = DiagrammeObjets(self.categorie_diagrammes,{diagramme})
        
        CommaCategorie.__init__(self,self.foncteur_vers_D,self.foncteur_diagonal, "Champ actif de "+str(diagramme) if nom == None else nom)
        
49
    def objets_cocones(self,nadirs:set) -> set:
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
50
51
        """`nadirs` est un ensemble d'objets de Q
        Cette fonction renvoie l'ensemble tous les cocônes de nadir un objets d'`nadirs`.
52
53
54
        Un cocône est une transformation naturelle de D vers le diagramme constant sur le nadir.
        Cette fonction renvoie les objets de la comma-catégorie qui contiennent ces cocônes."""
        return {obj for obj in self.objets for nadir in nadirs if obj.d == nadir}
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
55
    
56
    def objets_colimites(self) -> set:
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
57
        """Renvoie un ensemble de cocônes colimites.
58
59
        Les cocônes colimites sont des objets initiaux dans le champ actif.
        Cette fonction renvoie les objets de la comma-catégorie qui contiennent ces cocônes."""
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
60
61
62
63
64
65
        if len(self.objets) == 0:
            return set()
        cocones = list(self.objets)
        cocone_courant = cocones[0]
        cocones_visites = {cocone_courant}
        cocones_restants = self.objets-cocones_visites
66
67
68
69
70
        fleche_accessible = next(self[cocones_restants,{cocone_courant}],None)
        if fleche_accessible == None:
            fleche_accessible = next(self(cocones_restants,{cocone_courant}),None)
        while fleche_accessible != None:            
            cocone_courant = fleche_accessible.source
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
71
72
            cocones_visites |= {cocone_courant}
            cocones_restants = self.objets-cocones_visites
73
74
75
            fleche_accessible = next(self[cocones_restants,{cocone_courant}],None)
            if fleche_accessible == None:
                fleche_accessible = next(self(cocones_restants,{cocone_courant}),None)
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
76
        # ici cocone_courant est un objet initial de la catégorie
77
        return {cocone for cocone in self.objets if self.existe_isomorphisme(cocone_courant,cocone) != None}
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
78
79
80
81
82
83
84
85
86
87
88
89
90
        
def test_ChampActif():
    from GrapheDeComposition import GC,MGC
    from Diagramme import Triangle,DiagrammeIdentite
    
    gc = GC()
    gc |= set("ABCDEF")
    f,g,h,i,j,k,l = [MGC('A','B','f'),MGC('B','C','g'),MGC('D','E','h'),MGC('E','F','i'),MGC('A','D','j'),MGC('B','E','k'),MGC('C','F','l')]
    gc |= {f,g,h,i,j,k,l}
    
    diag_identite = DiagrammeIdentite(gc)
    diag_identite.faire_commuter()
    
91
    d1 = Triangle(gc,"ABC",[f,g,g@f])
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
92
93
    
    c_p = ChampActif(d1)
94
95
    for cocone in c_p.objets_cocones(gc.objets):
        Cocone(cocone).transformer_graphviz()
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
96
97
    c_p.transformer_graphviz()
    
98
    colimites = list(c_p.objets_colimites())
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
99
100
    for i in range(len(colimites)):   
        print("colimite")
101
        Cocone(colimites[i]).nom = "Colimite "+str(i)
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
102
        print(str(colimites))
103
        Cocone(colimites[i]).transformer_graphviz()
104
 
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
105
106
if __name__ == '__main__':
    test_ChampActif()