CommaCategorie.py 9.98 KB
Newer Older
1
2
from Morphisme import Morphisme
from Categorie import Categorie
3
4
5
from Foncteur import Foncteur
from Diagramme import DiagrammeIdentite, DiagrammeObjets
from config import *
6

Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
7
class ObjetCommaCategorie(Morphisme):
8
9
10
    """Soit C une catégorie, T et S deux foncteurs de E dans C et D dans C.
       Un objet de la comma-categorie (T|S) est un triplet (e,f,d) où e est un objet de E, f une flèche de T(e) vers S(d) et d un objet de D. 
       (cf. Mac Lane "Categories for the working mathematician" P.45)
11
       On a changé l'ordre par rapport au texte de MacLane qui considérait plutôt les triplets (e,d,f)
12
13
14
15
16
17
       
       Objet : <e,f,d>
       
         e        d
       D1|        |D2
         V    f   V
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
18
19
       D1(e) --> D2(d)

Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
20
       On peut aussi voir ObjetCommaCategorie comme un morphisme, on peut alors composer deux objets de comma-catégorie <e1,f1,d1> et <e2,f2,d2> si d1=e2,
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
21
22
23
24
25
26
       on a alors  <e2,f2,d2>o<e1,f1,d1> = <e1,f2of1,d2>
       
         e1       d1=e2        d2 
        D1|         |D2        |D3    
          V   f1    V    f2    V   
       D1(e1) --> D2(d1) --> D3(d2)
27
    """
28
    def __init__(self, e:any, f:any, d:any):
29
30
31
        self.__e = e #attribut read-only
        self.__f = f #attribut read-only
        self.__d = d #attribut read-only
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
32
33
34
35
        Morphisme.__init__(self,self.e,self.d,'('+str(self.e)+','+str(self.f)+','+str(self.d)+')',self.f.is_identite and self.e == self.d)
    
    @property
    def e(self):
36
        return self.__e
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
37
38
    @property
    def f(self):
39
        return self.__f
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
40
41
    @property
    def d(self):
42
        return self.__d
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
43
44
    
    
45
46
47
48
49
50
51
    def __eq__(self,other:'ObjetCommaCategorie') -> bool:
        if not issubclass(type(other),ObjetCommaCategorie):
            raise TypeError("Tentative de comparaison avec un objet de type inconnu "+str(other))
        return self.e == other.e and self.f == other.f and self.d == other.d
        
    def __hash__(self) -> int:
        return hash((self.e,self.f,self.d))
52
        
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
53
    def __matmul__(self, other:'ObjetCommaCategorie') -> 'ObjetCommaCategorie':
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
54
        if self.e != other.d:
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
55
56
57
            raise Exception("Tentative de composer deux ObjetCommaCategorie pas composables : "+str(self)+" o "+str(other))
        return ObjetCommaCategorie(other.e, self.f@other.f, self.d)
        
58
59
60
61
62
63
64
65
66
67
68
69
70
class FlecheCommaCategorie(Morphisme):
    """Soit C une catégorie, T et S deux foncteurs de E dans C et D dans C.
       Une flèche de la comma-categorie (T|S) entre deux objets (e,f,d) et (e',f',d') est un couple (k,h)
       où k est une flèche de E(e,e') et h est une flèche de D(d,d') tel que la carré
        T(e) -T(k)-> T(e')
         |             |
         f             f'
         |             |
         v             v
        S(d) -S(h)-> S(d')
        commute.
       (cf. Mac Lane "Categories for the working mathematician" P.45)
    """
71
    def __init__(self, source:any, cible:any, k:Morphisme, h:Morphisme):
72
73
        self.__k = k #attribut read-only
        self.__h = h #attribut read-only
74
        Morphisme.__init__(self,source,cible,'('+str(self.k)+','+str(self.h)+')',source == cible and k.is_identite and h.is_identite)
75
76
77
78
79
80
81
82
        
    @property
    def k(self):
        return self.__k
    @property
    def h(self):
        return self.__h 
        
83
84
    def verifier_coherence(self, T:Foncteur, S:Foncteur):
        if T.cible != S.cible:
85
            raise Exception("Incoherence FlecheCommaCategorie : T et S de cibles differentes : "+str(T)+" != "+str(S))
86
87
        categorie = T.cible
        if self.cible.f@T(self.k) != S(self.h)@self.source.f:
88
89
            raise Exception("Incoherence FlecheCommaCategorie : le carre ne commute pas, "+str(self.cible.f)+" o "+str(T(self.k))+" != "+str(S(self.h))+" o "+str(self.source.f))
            
90
91
    def __matmul__(self,other:'FlecheCommaCategorie') -> 'FlecheCommaCategorie':
        return FlecheCommaCategorie(other.source,self.cible,self.k@other.k,self.h@other.h)
92
93
94
95
96
97
98
        
    def __eq__(self,other:'FlecheCommaCategorie') -> bool:
        return self.k == other.k and self.h == other.h
        
    def __hash__(self) -> int:
        return hash((self.k,self.h))
        
99
100
101
102
103
104
105
106
    
class CommaCategorie(Categorie):
    """
    Soit C une catégorie, T et S deux foncteurs de E dans C et D dans C.
    Cette catégorie est (T|S).
    Voir Mac Lane "Categories for the working mathematician" P.45
    """
    
107
    def __init__(self, T:Foncteur, S:Foncteur, nom:str = None):
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
108
        Categorie.__init__(self,set(),"Comma-catégorie ("+str(T)+'|'+str(S)+')' if nom == None else nom)
109
110
111
        if T.cible != S.cible:
            raise Exception("Incoherence CommaCategorie : T et S de cibles differentes : "+str(T)+" vs "+str(S))
        self.__C = T.cible
112
113
        self._T = T
        self._S = S
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
114
        self |= {ObjetCommaCategorie(e,f,d) for e in T.source.objets for d in S.source.objets for f in self.__C({T(e)},{S(d)})} # on ajoute tous les objets
115
116
117
118
119
120
121
    
    def __eq__(self, other:'CommaCategorie') -> bool:
        return self._T == other._T and self._S == other._S

    def __hash__(self) -> int:
        return hash((self._T,self._S))
    
122
123
    def identite(self, objet:ObjetCommaCategorie) -> FlecheCommaCategorie:
        '''L'identité pour un objet (e,f,d) est la paire d'identité de T(e) et S(d).'''
124
        return FlecheCommaCategorie(objet,objet,self.__C.identite(self._T(objet.e)),self.__C.identite(self._S(objet.d)))
125
        
126
    def __call__(self, sources:set, cibles:set) -> set:
127
        result = set()
128
129
        for a in sources:
            for b in cibles:
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
130
131
                for k in self._T.source({a.e},{b.e}):
                    for h in self._S.source({a.d},{b.d}):
132
                        if b.f@self._T(k) == self._S(h)@a.f:
133
134
135
136
137
138
139
140
141
142
143
144
145
                            result |= {FlecheCommaCategorie(a,b,k,h)}
        return result
        
class CategorieFleches(CommaCategorie):
    """Catégorie des flèches d'une catégorie C.
    (cf. https://en.wikipedia.org/wiki/Comma_category#Arrow_category)
    """
    def __init__(self, C:Categorie, nom:str = None):
        CommaCategorie.__init__(self,DiagrammeIdentite(C),DiagrammeIdentite(C),"Categorie des flèches de "+str(C) if nom == None else nom)

class CategorieSous(CommaCategorie):
    """CategorieSous peut aussi être appelée CosliceCategorie.
       Soit C une catégorie, et b un objet de C.
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
146
       CategorieSous est la catégorie en-dessous de b (b|C)
147
148
149
150
151
152
153
154
155
       (cf. Mac Lane "Categories for the working mathematician" P.45)
       On construit la catégorie sous b en créant la comma-catégorie (1_b|Id(C)) c'est-à-dire
       la comma-catégorie du diagramme qui associe à un objet unique b avec le diagramme identité de C.
    """
    def __init__(self, C:Categorie, objet:any, nom:str = None):
        CommaCategorie.__init__(self,DiagrammeObjets(C,{objet}),DiagrammeIdentite(C),str(C)+" sous "+str(objet) if nom == None else nom)

CosliceCategorie = CategorieSous

156
157
158
159
160
161
class CategorieFSous(CommaCategorie):
    """Soit C une catégorie, b un objet de C et F un foncteur de I vers C
       CategorieFSous est la catégorie F-en-dessous de b (b|F)
       (cf. Mac Lane "Categories for the working mathematician" P.45)
       On construit la catégorie sous b en créant la comma-catégorie (1_b|F) c'est-à-dire
       la comma-catégorie du diagramme qui associe à un objet unique b avec le foncteur F.
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
162
163
       
       Les objets de cette comma-catégorie sont de la forme <0,f,d>.
164
165
    """
    def __init__(self, F:Foncteur, objet:any, nom:str = None):
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
166
        CommaCategorie.__init__(self,DiagrammeObjets(F.cible,{objet}),F,str(F)+" sous "+str(objet) if nom == None else nom)
167
168
169

CosliceCategorie = CategorieSous

170
171
172
class CategorieSur(CommaCategorie):
    """CategorieSur peut aussi être appelée SliceCategorie.
       Soit C une catégorie, et b un objet de C.
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
173
       CategorieSur est la catégorie au-dessus de b (C|b)
174
175
176
177
178
179
180
181
182
       (cf. Mac Lane "Categories for the working mathematician" P.45)
       On construit la catégorie sur b en créant la comma-catégorie (Id(C)|1_b) c'est-à-dire
       la comma-catégorie du diagramme identité de C avec le diagramme qui associe à un objet unique b .
    """
    def __init__(self, C:Categorie, objet:any, nom:str = None):
        CommaCategorie.__init__(self,DiagrammeIdentite(C),DiagrammeObjets(C,{objet}),str(C)+" sur "+str(objet) if nom == None else nom)

SliceCategorie = CategorieSur

183
184
185
186
187
188
class CategorieFSur(CommaCategorie):
    """Soit C une catégorie, b un objet de C et F un foncteur de I vers C.
       CategorieFSur est la catégorie F-au-dessus de b (F|b)
       (cf. Mac Lane "Categories for the working mathematician" P.45)
       On construit la catégorie sur b en créant la comma-catégorie (F|1_b) c'est-à-dire
       la comma-catégorie de F avec le diagramme qui associe à un objet unique b .
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
189
       Les objets de cette comma-catégorie sont de la forme <e,f,0>.
190
    """
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
191
    def __init__(self, F:Foncteur, objet:any, nom:str = None):
Guillaume Sabbagh's avatar
Guillaume Sabbagh committed
192
        CommaCategorie.__init__(self,F,DiagrammeObjets(F.cible,{objet}),str(F)+" sur "+str(objet) if nom == None else nom)
193
194


195
196
197
198
199
   
def test_CategorieFleches():
    from GrapheDeComposition import GC,MGC
    
    cat = GC('C')
200
    cat |= {'A','B','C'}
201
    morphismes = [MGC('A','B','f'),MGC('B','C','g')]
202
    cat |= morphismes
203
204
205
206
    cat.transformer_graphviz()
    
    cat_fleches = CategorieFleches(cat)
    cat_fleches.transformer_graphviz()
207
    
208
209
210
211
def test_CategorieSous():
    from GrapheDeComposition import GC,MGC
    
    cat = GC('C')
212
    cat |= {'A','B','C','D','E'}
213
    morphismes = [MGC('A','B','f'),MGC('B','C','g'),MGC('C','D','h'),MGC('E','C','i'),MGC('E','A','j')]
214
    cat |= morphismes
215
216
217
218
219
220
221
222
223
224
    cat.transformer_graphviz()
    
    cat_sous = CategorieSous(cat,'B')
    cat_sous.transformer_graphviz()
    
    
def test_CategorieSur():
    from GrapheDeComposition import GC,MGC
    
    cat = GC('C')
225
    cat |= {'A','B','C','D','E'}
226
    morphismes = [MGC('A','B','f'),MGC('B','C','g'),MGC('C','D','h'),MGC('E','C','i'),MGC('E','A','j')]
227
    cat |= morphismes
228
229
230
231
232
233
234
235
236
237
238
    cat.transformer_graphviz()
    
    cat_sur = CategorieSur(cat,'B')
    cat_sur.transformer_graphviz()  


    
if __name__ == '__main__':
    test_CategorieFleches()
    test_CategorieSous()
    test_CategorieSur()