OLD | NEW |
---|---|
1 \subsection*{Field lookup} | |
2 | |
3 \infrule{(C : \dclass{\TApp{C}{T_0,\ldots,T_n}}{\TApp{C'}{\upsilon_0, \ldots, \u psilon_k}}{\many{\mathit{ce}}}) \in \Phi \\ | |
4 \fieldDecl{x}{\tau} \in \many{\mathit{ce}} | |
5 } | |
6 {\fieldLookup{\Phi}{\TApp{C}{\tau_0, \ldots, \tau_n}}{x}{\subst{\tau_0, \ldots, \tau_n}{T_0, \ldots, T_n}{\tau}} | |
7 } | |
8 | |
9 \infrule{(C : \dclass{\TApp{C}{T_0,\ldots,T_n}}{\TApp{C'}{\upsilon_0, \ldots, \u psilon_k}}{\many{\mathit{ce}}}) \in \Phi \quad x \notin \many{\mathit{ce}} \\ | |
10 \fieldLookup{\Phi}{\TApp{C'}{\upsilon_0, \ldots, \upsilon_k}}{x}{\tau} | |
11 } | |
12 {\fieldLookup{\Phi}{\TApp{C}{\tau_0, \ldots, \tau_n}}{x}{\subst{\tau_0, \ldots, \tau_n}{T_0, \ldots, T_n}{\tau}} | |
13 } | |
14 | |
15 | |
16 \subsection*{Method lookup} | |
17 | |
18 \infrule{(C : \dclass{\TApp{C}{T_0,\ldots,T_n}}{\TApp{C'}{\upsilon_0, \ldots, \u psilon_k}}{\many{\mathit{ce}}}) \in \Phi \\ | |
19 \methodDecl{m}{\tau}{\sigma} \in \many{\mathit{ce}} | |
20 } | |
21 {\methodLookup{\Phi} | |
22 {\TApp{C}{\tau_0, \ldots, \tau_n}}{m} | |
23 {\subst{\tau_0, \ldots, \tau_n}{T_0, \ldots, T_n}{\tau}} | |
24 {\subst{\tau_0, \ldots, \tau_n}{T_0, \ldots, T_n}{\sigma}} | |
25 } | |
26 | |
27 \infrule{(C : \dclass{\TApp{C}{T_0,\ldots,T_n}}{\TApp{C'}{\upsilon_0, \ldots, \u psilon_k}}{\many{\mathit{ce}}}) \in \Phi \quad m \notin \many{\mathit{ce}} \\ | |
28 \methodLookup{\Phi}{\TApp{C'}{\upsilon_0, \ldots, \upsilon_k}}{m}{\tau} {\sigma} | |
29 } | |
30 {\methodLookup{\Phi}{\TApp{C}{\tau_0, \ldots, \tau_n}}{m} | |
31 {\subst{\tau_0, \ldots, \tau_n}{T_0, \ldots, T_n}{\tau}} | |
32 {\subst{\tau_0, \ldots, \tau_n}{T_0, \ldots, T_n}{\sigma}} | |
33 } | |
34 | |
35 \subsection*{Method and field absence} | |
36 | |
37 \infrule{(C : \dclass{\TApp{C}{T_0,\ldots,T_n}}{\TApp{C'}{\upsilon_0, \ldots, \u psilon_k}}{\many{\mathit{ce}}}) \in \Phi \quad x \notin \many{\mathit{ce}} \\ | |
38 \fieldAbsent{\Phi}{\TApp{C'}{\upsilon_0, \ldots, \upsilon_k}}{x} | |
39 } | |
40 {\fieldAbsent{\Phi}{\TApp{C}{\tau_0, \ldots, \tau_n}}{x} | |
41 } | |
42 | |
43 \infrule{(C : \dclass{\TApp{C}{T_0,\ldots,T_n}}{\TApp{C'}{\upsilon_0, \ldots, \u psilon_k}}{\many{\mathit{ce}}}) \in \Phi \quad m \notin \many{\mathit{ce}} \\ | |
44 \methodAbsent{\Phi}{\TApp{C'}{\upsilon_0, \ldots, \upsilon_k}}{m}{\tau} {\sigma} | |
45 } | |
46 {\methodAbsent{\Phi}{\TApp{C}{\tau_0, \ldots, \tau_n}}{m} | |
47 } | |
48 | |
49 \iftrans{ | |
50 | |
51 \subsection*{Type translation} | |
52 | |
53 To translate covariant generics, we essentially want to treat all contravariant | |
54 occurrences of type variables as $\Dynamic$. The type translation | |
55 $\down{\tau}$ implements this. It is defined in terms of the dual operator | |
56 $\up{\tau}$ which translates positive occurences of type variables as $\Dynamic$ . | |
57 | |
58 \begin{eqnarray*} | |
59 \down{T} & = & T \\ | |
60 \down{\Arrow[k]{\tau_0, \ldots, \tau_n}{\tau_r}} & = & | |
61 \Arrow[k]{\up{\tau_0}, \ldots, \up{\tau_n}}{\down{\tau_r}} \\ | |
62 \down{\TApp{C}{\tau_0, \ldots, \tau_n}} & = & \TApp{C}{\down{\tau_0}, \ldots, \down{\tau_n}} \\ | |
63 \down{\tau} & = & \tau\ \mbox{if $\tau$ is base type.} | |
vsm
2015/07/28 15:44:32
What is a "base type" in this case?
Also, if I ha
Leaf
2015/07/28 20:34:29
Anything which is not one of the previous three ca
| |
64 \end{eqnarray*} | |
65 | |
66 \begin{eqnarray*} | |
67 \up{T} & = & \Dynamic \\ | |
68 \up{\Arrow[k]{\tau_0, \ldots, \tau_n}{\tau_r}} & = & | |
69 \Arrow[k]{\down{\tau_0}, \ldots, \down{\tau_n}}{\up{\tau_r}} \\ | |
70 \up{\TApp{C}{\tau_0, \ldots, \tau_n}} & = & \TApp{C}{\up{\tau_0}, \ldots, \up{ \tau_n}} \\ | |
71 \up{\tau} & = & \tau\ \mbox{if $\tau$ is base type.} | |
72 \end{eqnarray*} | |
73 | |
74 | |
75 } | |
1 \subsection*{Expression typing: $\yieldsOk{\Phi, \Delta, \Gamma}{e}{\opt{\tau}}{ e'}{\tau'}$} | 76 \subsection*{Expression typing: $\yieldsOk{\Phi, \Delta, \Gamma}{e}{\opt{\tau}}{ e'}{\tau'}$} |
2 \hrulefill\\ | 77 \hrulefill\\ |
3 | 78 |
4 | 79 |
5 \sstext{ Expression typing is a relation between typing contexts, a term ($e$), | 80 \sstext{ Expression typing is a relation between typing contexts, a term ($e$), |
6 an optional type ($\opt{\tau}$), and a type ($\tau'$). The general idea is | 81 an optional type ($\opt{\tau}$), and a type ($\tau'$). The general idea is |
7 that we are typechecking a term ($e$) and want to know if it is well-typed. | 82 that we are typechecking a term ($e$) and want to know if it is well-typed. |
8 The term appears in a context, which may (or may not) impose a type constraint | 83 The term appears in a context, which may (or may not) impose a type constraint |
9 on the term. For example, in $\dvar{x:\tau}{e}$, $e$ appears in a context | 84 on the term. For example, in $\dvar{x:\tau}{e}$, $e$ appears in a context |
10 which requires it to be a subtype of $\tau$, or to be coercable to $\tau$. | 85 which requires it to be a subtype of $\tau$, or to be coercable to $\tau$. |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
81 declared types. | 156 declared types. |
82 }{ | 157 }{ |
83 | 158 |
84 A fully annotated function elaborates to a function with an elaborated body. | 159 A fully annotated function elaborates to a function with an elaborated body. |
85 The rest of the function elaboration rules fill in the reified type using | 160 The rest of the function elaboration rules fill in the reified type using |
86 contextual information if present and applicable, or $\Dynamic$ otherwise. | 161 contextual information if present and applicable, or $\Dynamic$ otherwise. |
87 | 162 |
88 } | 163 } |
89 | 164 |
90 \infrule{\Gamma' = \extends{\Gamma}{\many{x}}{\many{\tau}} \quad\quad | 165 \infrule{\Gamma' = \extends{\Gamma}{\many{x}}{\many{\tau}} \quad\quad |
91 \yieldsOk{\Phi, \Delta, \Gamma'}{e}{\sigma}{e'}{\sigma'} | 166 \stmtOk{\Phi, \Delta, \Gamma'}{s}{\sigma}{s'}{\Gamma'} |
92 } | 167 } |
93 {\yieldsOk{\Phi, \Delta, \Gamma} | 168 {\yieldsOk{\Phi, \Delta, \Gamma} |
94 {\elambda{\many{x:\tau}}{\sigma}{e}} | 169 {\elambda{\many{x:\tau}}{\sigma}{s}} |
95 {\_} | 170 {\_} |
96 {\elambda{\many{x:\tau}}{\sigma}{e'}} | 171 {\elambda{\many{x:\tau}}{\sigma}{s'}} |
97 {\Arrow[-]{\many{\tau}}{\sigma}} | 172 {\Arrow[-]{\many{\tau}}{\sigma}} |
98 } | 173 } |
99 | 174 |
100 \sstext{A function with a missing argument type is well-typed if it is well-type d with | 175 \sstext{A function with a missing argument type is well-typed if it is well-type d with |
101 the argument type replaced with $\Dynamic$.} | 176 the argument type replaced with $\Dynamic$.} |
102 {} | 177 {} |
103 | 178 |
104 \infrule{\yieldsOk{\Phi, \Delta, \Gamma} | 179 \infrule{\yieldsOk{\Phi, \Delta, \Gamma} |
105 {\elambda{x_0:\opt{\tau_0}, \ldots, x_i:\Dynamic, \ldots, x_n: \opt{\tau_n}}{\opt{\sigma}}{e}} | 180 {\elambda{x_0:\opt{\tau_0}, \ldots, x_i:\Dynamic, \ldots, x_n: \opt{\tau_n}}{\opt{\sigma}}{s}} |
106 {\opt{\tau}} | 181 {\opt{\tau}} |
107 {e_f} | 182 {e_f} |
108 {\tau_f} | 183 {\tau_f} |
109 } | 184 } |
110 {\yieldsOk{\Phi, \Delta, \Gamma} | 185 {\yieldsOk{\Phi, \Delta, \Gamma} |
111 {\elambda{x_0:\opt{\tau_0}, \ldots, x_i:\_, \ldots, x_n:\opt{\ tau_n}}{\opt{\sigma}}{e}} | 186 {\elambda{x_0:\opt{\tau_0}, \ldots, x_i:\_, \ldots, x_n:\opt{\ tau_n}}{\opt{\sigma}}{s}} |
112 {\opt{\tau}} | 187 {\opt{\tau}} |
113 {e_f} | 188 {e_f} |
114 {\tau_f} | 189 {\tau_f} |
115 } | 190 } |
116 | 191 |
117 \sstext{A function with a missing argument type is well-typed if it is well-type d with | 192 \sstext{A function with a missing argument type is well-typed if it is well-type d with |
118 the argument type replaced with the corresponding argument type from the context | 193 the argument type replaced with the corresponding argument type from the context |
119 type. Note that this rule overlaps with the previous: the formal presentation | 194 type. Note that this rule overlaps with the previous: the formal presentation |
120 leaves this as a non-deterministic choice.}{} | 195 leaves this as a non-deterministic choice.}{} |
121 | 196 |
122 \infrule{\tau_c = \Arrow[k]{\upsilon_0, \ldots, \upsilon_n}{\upsilon_r} \\ | 197 \infrule{\tau_c = \Arrow[k]{\upsilon_0, \ldots, \upsilon_n}{\upsilon_r} \\ |
123 \yieldsOk{\Phi, \Delta, \Gamma} | 198 \yieldsOk{\Phi, \Delta, \Gamma} |
124 {\elambda{x_0:\opt{\tau_0}, \ldots, x_i:\upsilon_i, \ldots, x_ n:\opt{\tau_n}}{\opt{\sigma}}{e}} | 199 {\elambda{x_0:\opt{\tau_0}, \ldots, x_i:\upsilon_i, \ldots, x_ n:\opt{\tau_n}}{\opt{\sigma}}{s}} |
125 {\tau_c} | 200 {\tau_c} |
126 {e_f} | 201 {e_f} |
127 {\tau_f} | 202 {\tau_f} |
128 } | 203 } |
129 {\yieldsOk{\Phi, \Delta, \Gamma} | 204 {\yieldsOk{\Phi, \Delta, \Gamma} |
130 {\elambda{x_0:\opt{\tau_0}, \ldots, x_i:\_, \ldots, x_n:\opt{\ tau_n}}{\opt{\sigma}}{e}} | 205 {\elambda{x_0:\opt{\tau_0}, \ldots, x_i:\_, \ldots, x_n:\opt{\ tau_n}}{\opt{\sigma}}{s}} |
131 {\tau_c} | 206 {\tau_c} |
132 {e_f} | 207 {e_f} |
133 {\tau_f} | 208 {\tau_f} |
134 } | 209 } |
135 | 210 |
136 \sstext{A function with a missing return type is well-typed if it is well-typed with | 211 \sstext{A function with a missing return type is well-typed if it is well-typed with |
137 the return type replaced with $\Dynamic$.}{} | 212 the return type replaced with $\Dynamic$.}{} |
138 | 213 |
139 \infrule{\yieldsOk{\Phi, \Delta, \Gamma} | 214 \infrule{\yieldsOk{\Phi, \Delta, \Gamma} |
140 {\elambda{\many{x:\opt{\tau}}}{\Dynamic}{e}} | 215 {\elambda{\many{x:\opt{\tau}}}{\Dynamic}{s}} |
141 {\opt{\tau_c}} | 216 {\opt{\tau_c}} |
142 {e_f} | 217 {e_f} |
143 {\tau_f} | 218 {\tau_f} |
144 } | 219 } |
145 {\yieldsOk{\Phi, \Delta, \Gamma} | 220 {\yieldsOk{\Phi, \Delta, \Gamma} |
146 {\elambda{\many{x:\opt{\tau}}}{\_}{e}} | 221 {\elambda{\many{x:\opt{\tau}}}{\_}{s}} |
147 {\opt{\tau_c}} | 222 {\opt{\tau_c}} |
148 {e_f} | 223 {e_f} |
149 {\tau_f} | 224 {\tau_f} |
150 } | 225 } |
151 | 226 |
152 \sstext{A function with a missing return type is well-typed if it is well-typed with | 227 \sstext{A function with a missing return type is well-typed if it is well-typed with |
153 the return type replaced with the corresponding return type from the context | 228 the return type replaced with the corresponding return type from the context |
154 type. Note that this rule overlaps with the previous: the formal presentation | 229 type. Note that this rule overlaps with the previous: the formal presentation |
155 leaves this as a non-deterministic choice. }{} | 230 leaves this as a non-deterministic choice. }{} |
156 | 231 |
157 \infrule{\tau_c = \Arrow[k]{\upsilon_0, \ldots, \upsilon_n}{\upsilon_r} \\ | 232 \infrule{\tau_c = \Arrow[k]{\upsilon_0, \ldots, \upsilon_n}{\upsilon_r} \\ |
158 \yieldsOk{\Phi, \Delta, \Gamma} | 233 \yieldsOk{\Phi, \Delta, \Gamma} |
159 {\elambda{\many{x:\opt{\tau}}}{\upsilon_r}{e}} | 234 {\elambda{\many{x:\opt{\tau}}}{\upsilon_r}{s}} |
160 {\tau_c} | 235 {\tau_c} |
161 {e_f} | 236 {e_f} |
162 {\tau_f} | 237 {\tau_f} |
163 } | 238 } |
164 {\yieldsOk{\Phi, \Delta, \Gamma} | 239 {\yieldsOk{\Phi, \Delta, \Gamma} |
165 {\elambda{\many{x:\opt{\tau}}}{\_}{e}} | 240 {\elambda{\many{x:\opt{\tau}}}{\_}{s}} |
166 {\tau_c} | 241 {\tau_c} |
167 {e_f} | 242 {e_f} |
168 {\tau_f} | 243 {\tau_f} |
169 } | 244 } |
170 | 245 |
171 | 246 |
172 \sstext{Instance creation creates an instance of the appropriate type.}{} | 247 \sstext{Instance creation creates an instance of the appropriate type.}{} |
173 | 248 |
174 % FIXME(leafp): inference | 249 % FIXME(leafp): inference |
175 % FIXME(leafp): deal with bounds | 250 % FIXME(leafp): deal with bounds |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
248 {e_a'} | 323 {e_a'} |
249 {\tau_a'} \quad \mbox{for}\ e_a \in \many{e_a} | 324 {\tau_a'} \quad \mbox{for}\ e_a \in \many{e_a} |
250 } | 325 } |
251 {\yieldsOk{\Phi, \Delta, \Gamma} | 326 {\yieldsOk{\Phi, \Delta, \Gamma} |
252 {\ecall{e}{\many{e_a}}} | 327 {\ecall{e}{\many{e_a}}} |
253 {\_} | 328 {\_} |
254 {\edcall{e'}{\many{e_a'}}} | 329 {\edcall{e'}{\many{e_a'}}} |
255 {\Dynamic} | 330 {\Dynamic} |
256 } | 331 } |
257 | 332 |
333 \iftrans{ | |
258 \sstext{A dynamic call expression is well-typed so long as the applicand and the | 334 \sstext{A dynamic call expression is well-typed so long as the applicand and the |
259 arguments are well-typed at any type.}{} | 335 arguments are well-typed at any type.}{} |
260 | 336 |
261 \infrule{\yieldsOk{\Phi, \Delta, \Gamma} | 337 \infrule{\yieldsOk{\Phi, \Delta, \Gamma} |
262 {e} | 338 {e} |
263 {\Dynamic} | 339 {\Dynamic} |
264 {e'} | 340 {e'} |
265 {\tau} \\ | 341 {\tau} \\ |
266 \yieldsOk{\Phi, \Delta, \Gamma} | 342 \yieldsOk{\Phi, \Delta, \Gamma} |
267 {e_a} | 343 {e_a} |
268 {\_} | 344 {\_} |
269 {e_a'} | 345 {e_a'} |
270 {\tau_a} \quad \mbox{for}\ e_a \in \many{e_a} | 346 {\tau_a} \quad \mbox{for}\ e_a \in \many{e_a} |
271 } | 347 } |
272 {\yieldsOk{\Phi, \Delta, \Gamma} | 348 {\yieldsOk{\Phi, \Delta, \Gamma} |
273 {\edcall{e}{\many{e_a}}} | 349 {\edcall{e}{\many{e_a}}} |
274 {\_} | 350 {\_} |
275 {\edcall{e'}{\many{e_a'}}} | 351 {\edcall{e'}{\many{e_a'}}} |
276 {\Dynamic} | 352 {\Dynamic} |
277 } | 353 } |
278 | 354 |
355 } | |
356 | |
279 \sstext{A method load is well-typed if the term is well-typed, and the method na me is | 357 \sstext{A method load is well-typed if the term is well-typed, and the method na me is |
280 present in the type of the term.}{} | 358 present in the type of the term.}{} |
281 | 359 |
282 \infrule{\yieldsOk{\Phi, \Delta, \Gamma} | 360 \infrule{\yieldsOk{\Phi, \Delta, \Gamma} |
283 {e} | 361 {e} |
284 {\_} | 362 {\_} |
285 {e'} | 363 {e'} |
286 {\sigma} \quad\quad | 364 {\sigma} \quad\quad |
287 \methodLookup{\Phi}{\sigma}{m}{\tau} | 365 \methodLookup{\Phi}{\sigma}{m}{\sigma}{\tau} |
288 } | 366 } |
289 {\yieldsOk{\Phi, \Delta, \Gamma} | 367 {\yieldsOk{\Phi, \Delta, \Gamma} |
290 {\eload{e}{m}} | 368 {\eload{e}{m}} |
291 {\_} | 369 {\_} |
292 {\eload{e'}{m}} | 370 {\eload{e'}{m}} |
293 {\tau} | 371 {\tau} |
294 } | 372 } |
295 | 373 |
296 \sstext{A method load from a term of type $\Dynamic$ is well-typed if the term i s | 374 \sstext{A method load from a term of type $\Dynamic$ is well-typed if the term i s |
297 well-typed.} | 375 well-typed.} |
(...skipping 10 matching lines...) Expand all Loading... | |
308 {e'} | 386 {e'} |
309 {\tau} | 387 {\tau} |
310 } | 388 } |
311 {\yieldsOk{\Phi, \Delta, \Gamma} | 389 {\yieldsOk{\Phi, \Delta, \Gamma} |
312 {\eload{e}{m}} | 390 {\eload{e}{m}} |
313 {\_} | 391 {\_} |
314 {\edload{e'}{m}} | 392 {\edload{e'}{m}} |
315 {\Dynamic} | 393 {\Dynamic} |
316 } | 394 } |
317 | 395 |
396 \iftrans{ | |
318 \sstext{A dynamic method load is well typed so long as the term is well-typed.}{ } | 397 \sstext{A dynamic method load is well typed so long as the term is well-typed.}{ } |
319 | 398 |
320 \infrule{\yieldsOk{\Phi, \Delta, \Gamma} | 399 \infrule{\yieldsOk{\Phi, \Delta, \Gamma} |
321 {e} | 400 {e} |
322 {\Dynamic} | 401 {\Dynamic} |
323 {e'} | 402 {e'} |
324 {\tau} | 403 {\tau} |
325 } | 404 } |
326 {\yieldsOk{\Phi, \Delta, \Gamma} | 405 {\yieldsOk{\Phi, \Delta, \Gamma} |
327 {\edload{e}{m}} | 406 {\edload{e}{m}} |
328 {\_} | 407 {\_} |
329 {\edload{e'}{m}} | 408 {\edload{e'}{m}} |
330 {\Dynamic} | 409 {\Dynamic} |
331 } | 410 } |
332 | 411 |
412 } | |
413 | |
333 \sstext{A field load from $\ethis$ is well-typed if the field name is present in the | 414 \sstext{A field load from $\ethis$ is well-typed if the field name is present in the |
334 type of $\ethis$.}{} | 415 type of $\ethis$.}{} |
335 | 416 |
336 \infrule{\Gamma = \Gamma_\tau & \fieldLookup{\Phi}{\tau}{x}{\sigma} | 417 \infrule{\Gamma = \Gamma_\tau & \fieldLookup{\Phi}{\tau}{x}{\sigma} |
337 } | 418 } |
338 {\yieldsOk{\Phi, \Delta, \Gamma} | 419 {\yieldsOk{\Phi, \Delta, \Gamma} |
339 {\eload{\ethis}{x}} | 420 {\eload{\ethis}{x}} |
340 {\_} | 421 {\_} |
341 {\eload{\ethis}{x}} | 422 {\eload{\ethis}{x}} |
342 {\sigma} | 423 {\sigma} |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
389 {\ethrow} | 470 {\ethrow} |
390 {\_} | 471 {\_} |
391 {\ethrow} | 472 {\ethrow} |
392 {\sigma} | 473 {\sigma} |
393 } | 474 } |
394 | 475 |
395 \sstext{A cast expression is well-typed so long as the term being cast is well-t yped. | 476 \sstext{A cast expression is well-typed so long as the term being cast is well-t yped. |
396 The synthesized type is the cast-to type. We require that the cast-to type be a | 477 The synthesized type is the cast-to type. We require that the cast-to type be a |
397 ground type.}{} | 478 ground type.}{} |
398 | 479 |
399 \comment{TODO(leafp): specify ground types} | |
vsm
2015/07/28 15:44:32
Did you add a definition of ground type? I don't
Leaf
2015/07/28 20:34:29
Done.
| |
400 | |
401 \infrule{\yieldsOk{\Phi, \Delta, \Gamma}{e}{\_}{e'}{\sigma} \quad\quad \mbox{$\t au$ is ground} | 480 \infrule{\yieldsOk{\Phi, \Delta, \Gamma}{e}{\_}{e'}{\sigma} \quad\quad \mbox{$\t au$ is ground} |
402 } | 481 } |
403 {\yieldsOk{\Phi, \Delta, \Gamma} | 482 {\yieldsOk{\Phi, \Delta, \Gamma} |
404 {\eas{e}{\tau}} | 483 {\eas{e}{\tau}} |
405 {\_} | 484 {\_} |
406 {\eas{e'}{\tau}} | 485 {\eas{e'}{\tau}} |
407 {\tau} | 486 {\tau} |
408 } | 487 } |
409 | 488 |
410 \sstext{An instance check expression is well-typed if the term being checked is | 489 \sstext{An instance check expression is well-typed if the term being checked is |
411 well-typed. We require that the cast to-type be a ground type.}{} | 490 well-typed. We require that the cast to-type be a ground type.}{} |
412 | 491 |
413 \infrule{\yieldsOk{\Phi, \Delta, \Gamma}{e}{\_}{e'}{\sigma} \quad\quad \mbox{$\t au$ is ground} | 492 \infrule{\yieldsOk{\Phi, \Delta, \Gamma}{e}{\_}{e'}{\sigma} \quad\quad \mbox{$\t au$ is ground} |
414 } | 493 } |
415 {\yieldsOk{\Phi, \Delta, \Gamma} | 494 {\yieldsOk{\Phi, \Delta, \Gamma} |
416 {\eis{e}{\tau}} | 495 {\eis{e}{\tau}} |
417 {\_} | 496 {\_} |
418 {\eis{e'}{\tau}} | 497 {\eis{e'}{\tau}} |
419 {\Bool} | 498 {\Bool} |
420 } | 499 } |
421 | 500 |
501 \iftrans{ | |
502 | |
422 \sstext{A check expression is well-typed so long as the term being checked is | 503 \sstext{A check expression is well-typed so long as the term being checked is |
423 well-typed. The synthesized type is the target type of the check.}{} | 504 well-typed. The synthesized type is the target type of the check.}{} |
424 | 505 |
425 | 506 |
426 \infrule{\yieldsOk{\Phi, \Delta, \Gamma}{e}{\_}{e'}{\sigma} | 507 \infrule{\yieldsOk{\Phi, \Delta, \Gamma}{e}{\_}{e'}{\sigma} |
427 } | 508 } |
428 {\yieldsOk{\Phi, \Delta, \Gamma} | 509 {\yieldsOk{\Phi, \Delta, \Gamma} |
429 {\echeck{e}{\tau}} | 510 {\echeck{e}{\tau}} |
430 {\_} | 511 {\_} |
431 {\echeck{e'}{\tau}} | 512 {\echeck{e'}{\tau}} |
432 {\tau} | 513 {\tau} |
433 } | 514 } |
434 | 515 |
516 } | |
517 | |
435 \subsection*{Declaration typing: $\declOk[d]{\Phi, \Delta, \Gamma}{\mathit{vd}}{ \mathit{vd'}}{\Gamma'}$} | 518 \subsection*{Declaration typing: $\declOk[d]{\Phi, \Delta, \Gamma}{\mathit{vd}}{ \mathit{vd'}}{\Gamma'}$} |
436 \hrulefill\\ | 519 \hrulefill\\ |
437 | 520 |
438 \sstext{ | 521 \sstext{ |
439 Variable declaration typing checks the well-formedness of the components, and | 522 Variable declaration typing checks the well-formedness of the components, and |
440 produces an output context $\Gamma'$ which contains the binding introduced by | 523 produces an output context $\Gamma'$ which contains the binding introduced by |
441 the declaration. | 524 the declaration. |
442 | 525 |
443 A simple variable declaration with a declared type is well-typed if the | 526 A simple variable declaration with a declared type is well-typed if the |
444 initializer for the declaration is well-typed at the declared type. The output | 527 initializer for the declaration is well-typed at the declared type. The output |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
547 \sstext{A sequence statement is well-typed if the first component is well-typed, and the | 630 \sstext{A sequence statement is well-typed if the first component is well-typed, and the |
548 second component is well-typed with the output context of the first component as | 631 second component is well-typed with the output context of the first component as |
549 its input context. The final output context is the output context of the second | 632 its input context. The final output context is the output context of the second |
550 component.}{} | 633 component.}{} |
551 | 634 |
552 \infrule{\stmtOk{\Phi, \Delta, \Gamma}{s_1}{\tau_r}{s_1'}{\Gamma'} \quad\quad | 635 \infrule{\stmtOk{\Phi, \Delta, \Gamma}{s_1}{\tau_r}{s_1'}{\Gamma'} \quad\quad |
553 \stmtOk{\Phi, \Delta, \Gamma'}{s_2}{\tau_r}{s_2'}{\Gamma''} | 636 \stmtOk{\Phi, \Delta, \Gamma'}{s_2}{\tau_r}{s_2'}{\Gamma''} |
554 } | 637 } |
555 {\stmtOk{\Phi, \Delta, \Gamma}{s_1;s_2}{\tau_r}{s_1';s_2'}{\Gamma''} | 638 {\stmtOk{\Phi, \Delta, \Gamma}{s_1;s_2}{\tau_r}{s_1';s_2'}{\Gamma''} |
556 } | 639 } |
640 | |
641 \subsection*{Class member typing: $\declOk[ce]{\Phi, \Delta, \Gamma}{\mathit{vd } : \mathit{ce}}{\mathit{vd}'}{\Gamma'}$} | |
642 \hrulefill\\ | |
643 | |
644 \sstext{ | |
645 | |
646 A class member is well-typed with a given signature ($\mathit{ce}$) taken from | |
647 the class hierarchy if the signature type matches the type on the definition, | |
648 and if the definition is well-typed. | |
649 | |
650 } | |
651 { | |
652 | |
653 Elaborating class members is done with respect to a signature. The field | |
654 translation simply translates the field as a variable declaration. | |
655 | |
656 } | |
657 | |
658 | |
659 \infrule{ | |
660 \declOk[d]{\Phi, \Delta, \Gamma} | |
661 {\dvar{x:\opt{\tau}}{e}} | |
662 {\mathit{vd'}} | |
663 {\Gamma'} | |
664 } | |
665 { | |
666 \declOk[ce]{\Phi, \Delta, \Gamma} | |
667 {\dvar{x:\opt{\tau}}{e} : \fieldDecl{x}{\opt{\tau}}} | |
668 {\mathit{vd'}} | |
669 {\Gamma'} | |
670 } | |
671 | |
672 | |
673 \iftrans{ | |
674 | |
675 Translating methods requires introducing guard expressions. The signature | |
676 provides an internal and an external type for the method. The external type is | |
677 the original declared type of the method, and is the signature which the method | |
678 presents to external clients. Because we implement covariant generics, clients | |
679 may see an instantiation of this signature which will allow them to violate the | |
680 contract expected by the implementation. To handle this, we rewrite the method | |
681 to match an internal signature which is in fact covariant in the type | |
vsm
2015/07/28 15:44:32
"covariant" -> "soundly covariant"? I was a littl
Leaf
2015/07/28 20:34:29
Rephrased and clarified.
| |
682 parameters. This property is enforced in the override checking relation: from | |
683 the perspective of this relation, there is simply another internal type which | |
684 defines how to wrap the method with guards. | |
685 | |
686 The translation insists that the internal and external types be function types | |
687 of the appropriate arity, and that the external type is equal to the type of the | |
688 declaration. The declaration is translated using the underlying function | |
689 definition translation, but is then wrapped with guards to enforce the type | |
690 contract, producing a valid function of the internal (covariant) type. The | |
691 original body of the function is wrapped in a lambda function, which is applied | |
692 using a dynamic call which checks that the arguments (which may have negative | |
693 occurrences of type variables which are treated as $\Dynamic$ in the internal | |
694 type) are appropriate for the actual body. The original function returns a type | |
695 $\tau_r$ which may be a super-type of the internal type (since negative | |
696 occurrences of type variables must be treated as dynamic), and so we insert a | |
697 check expression to guard against runtime type mismatches here. | |
698 | |
699 This is a very simplistic translation for now. We could choose, in the case | |
700 that the body returns a lambda, to push the checking down into the lambda | |
701 (essentially wrapping it in place). | |
702 | |
703 } | |
704 | |
705 \infrule{ \mathit{vd} = \dfun{\tau_r}{f}{x_0:\tau_0, \ldots, x_n:\tau_n}{s} \\ | |
706 \sigma_e = \Arrow[+]{\tau_0, \ldots, \tau_n}{\tau_r} | |
707 \iftrans{\quad\quad | |
708 \sigma_i = \Arrow{\upsilon_0, \ldots, \upsilon_n}{\upsilon_r} | |
709 } \\ | |
710 \declOk[d]{\Phi, \Delta, \Gamma} | |
711 {\mathit{vd}} | |
712 {\dfun{\tau_r}{f}{x_0:\tau_0, \ldots, x_n:\tau_n}{s'}} | |
713 {\Gamma'} | |
714 \iftrans{\\ | |
715 e_g = \elambda{x_0:\tau_0, \ldots, x_n:\tau_n}{\tau_r}{s'}\\ | |
716 s_g = \sreturn{(\echeck{\edcall{e_g}{x_0 , \ldots, x_n}}{\upsil on_r})} \\ | |
717 \mathit{vd}_g = \dfun{\upsilon_r}{f}{x_0:\upsilon_0, \ldots, x_ n:\upsilon_n}{s_g} | |
718 } | |
719 } | |
720 { | |
721 \declOk[ce]{\Phi, \Delta, \Gamma} | |
722 {\mathit{vd} : \methodDecl{f}{\sigma_i}{\sigma_e}} | |
723 {\mathit{vd}_g} | |
724 {\Gamma'} | |
725 } | |
726 | |
727 \subsection*{Class declaration typing: $\declOk[c]{\Phi, \Gamma}{\mathit{cd}}{\ mathit{cd'}}{\Gamma'}$} | |
728 \hrulefill\\ | |
729 | |
730 \sstext{ | |
731 | |
732 A class declaration is well-typed with a given signature ($\Sig$) taken from the | |
733 class hierarchy if the signature matches the definition, and if each member of | |
734 the class is well-typed with the corresponding signature from the class | |
735 signature. The members are checked with the generic type parameters bound in | |
736 the type context, and with the type of the current class set as the type of | |
737 $\ethis$ on the term context $\Gamma$. | |
738 | |
739 } | |
740 { | |
741 | |
742 Elaboration of a class requires that the class hierarchy $\Phi$ have a matching | |
743 signature for the class declaration. Each class member in the class is | |
744 elaborated using the corresponding class element from the signature. | |
745 | |
746 } | |
747 | |
748 | |
749 \infrule{\mathit{cd} = \dclass{\TApp{C}{\many{T}}}{\TApp{G}{\many{\tau}}}{\mathi t{vd}_0, \ldots, \mathit{vd}_n} \\ | |
750 (C : \dclass{\TApp{C}{\many{T}}}{\TApp{G}{\many{\tau}}}{\mathit{ce}_0, \ldots, \many{ce}_n}) \in \Phi \\ | |
751 \Delta = \many{T} \quad \Gamma_c = \Gamma_{\TApp{C}{\many{T}}} \\ | |
752 \declOk[ce]{\Phi, \Delta, \Gamma_c}{\mathit{vd}_i : \mathit{ce}_i}{\mat hit{vd}'_i}{\Gamma'} \quad\quad | |
753 \mbox{for}\ i \in 0, \ldots, n | |
754 \iftrans{\\ | |
755 \mathit{cd'} = \dclass{\TApp{C}{\many{T}}}{\TApp{G}{\many{\tau}}}{\many {\mathit{vd'}}} | |
756 } | |
757 } | |
758 {\declOk[c]{\Phi, \Gamma} | |
759 {\mathit{cd}} | |
760 {\mathit{cd'}}{\Gamma'} | |
761 } | |
762 | |
763 \subsection*{Override checking:\\ \quad\quad$\overrideOk{\Phi} | |
764 {\TApp{C}{T_0, \ldots, T_n}} | |
765 {\TApp{G}{\tau_0, \ldots, \tau_k}} | |
766 {\mathit{ce}}$} | |
767 \hrulefill\\ | |
768 | |
769 \sstext{ | |
770 | |
771 The override checking relation is the primary relation that checks the | |
772 consistency of the class hierarchy. We assume a non-cyclic class hierarchy as a | |
773 syntactic pre-condition. The override check relation checks that in a class | |
774 declaration $\TApp{C}{T_0, \ldots, T_n}$ which extends $\TApp{G}{\tau_0, \ldots, | |
775 \tau_k}$, the definition of an element with signature $\mathit{ce}$ is valid. | |
776 | |
777 }{ | |
778 | |
779 Override checking remains largely the same, with the exception of additional | |
780 consistency constraints on the internal signatures for methods. | |
781 | |
782 } | |
783 | |
784 \sstext{ | |
785 | |
786 A field with the type elided is a valid override if the same field with type | |
787 $\Dynamic$ is valid. | |
788 | |
789 }{ | |
790 | |
791 } | |
792 | |
793 \infrule{ | |
794 \overrideOk{\Phi} | |
795 {\TApp{C}{T_0, \ldots, T_n}} | |
796 {\TApp{G}{\tau_0, \ldots, \tau_k}} | |
797 {\fieldDecl{x}{\Dynamic}} | |
798 | |
799 } | |
800 { | |
801 \overrideOk{\Phi} | |
802 {\TApp{C}{T_0, \ldots, T_n}} | |
803 {\TApp{G}{\tau_0, \ldots, \tau_k}} | |
804 {\fieldDecl{x}{\_}} | |
805 } | |
806 | |
807 \sstext{ | |
808 | |
809 A field with a type $\tau$ is a valid override if it appears in the super type | |
810 with the same type. | |
811 | |
812 }{ | |
813 | |
814 } | |
815 | |
816 \infrule{\fieldLookup{\Phi}{\TApp{G}{\tau_0, \ldots, \tau_k}}{x}{\tau} | |
817 } | |
818 { | |
819 \overrideOk{\Phi} | |
820 {\TApp{C}{T_0, \ldots, T_n}} | |
821 {\TApp{G}{\tau_0, \ldots, \tau_k}} | |
822 {\fieldDecl{x}{\tau}} | |
823 } | |
824 | |
825 \sstext{ | |
826 | |
827 A field with a type $\tau$ is a valid override if it does not appear in the supe r type. | |
828 | |
829 }{ | |
830 | |
831 } | |
832 | |
833 \infrule{\fieldAbsent{\Phi}{\TApp{G}{\tau_0, \ldots, \tau_k}}{x} | |
834 } | |
835 { | |
836 \overrideOk{\Phi} | |
837 {\TApp{C}{T_0, \ldots, T_n}} | |
838 {\TApp{G}{\tau_0, \ldots, \tau_k}} | |
839 {\fieldDecl{x}{\tau}} | |
840 } | |
841 | |
842 \sstext{ | |
843 | |
844 A method with a type $\sigma$ is a valid override if it does not appear in the s uper type. | |
845 | |
846 }{ | |
847 | |
848 For a non-override method, we require that the internal type $\tau$ be a subtype | |
849 of $\down{\sigma}$ where $\sigma$ is the declared type. Essentially, this | |
850 enforces the property that the initial declaration of a method in the hierarchy | |
851 has a covariant internal type. | |
852 | |
853 } | |
854 | |
855 \infrule{ | |
856 \iftrans{ | |
857 \Delta = T_0, \ldots, T_n \quad\quad | |
858 \subtypeOf{\Phi, \Delta}{\tau}{\down{\sigma}}\ \\ | |
859 } | |
860 \methodAbsent{\Phi}{\TApp{G}{\tau_0, \ldots, \tau_k}}{f} | |
861 } | |
862 { | |
863 \overrideOk{\Phi} | |
864 {\TApp{C}{T_0, \ldots, T_n}} | |
865 {\TApp{G}{\tau_0, \ldots, \tau_k}} | |
866 {\methodDecl{f}{\tau}{\sigma}} | |
867 } | |
868 | |
869 \sstext{ | |
870 | |
871 A method with a type $\sigma$ is a valid override if it appears in the super | |
872 type, and $\sigma$ is a subtype of the type of the method in the super class. | |
873 | |
874 }{ | |
875 | |
876 For a method override, we reqire two coherence conditions. As before, we | |
vsm
2015/07/28 15:44:32
reqire -> require
Leaf
2015/07/28 20:34:29
Done.
| |
877 require that the internal type $\tau$ be a subtype of the $\down{\sigma}$ where | |
878 $\sigma$ is the external type. Moreover, we also insist that the external type | |
879 $\sigma$ be a subtype of the external type of the method in the superclass, and | |
vsm
2015/07/28 15:44:32
I thought that external types would not soundly su
Leaf
2015/07/28 20:34:29
In the presence of variant type parameters, you ca
| |
880 that the internal type $\tau$ be a subtype of the internal type in the | |
881 superclass. Note that it this last consistency property that ensures that | |
882 covariant generics are ``poisonous'' in the sense that non-generic subclasses of | |
883 generic classes must still have additional checks. For example, a superclass | |
884 with a method of external type $\sigma_s = \Arrow{T}{T}$ will have internal type | |
885 $\tau_s = \Arrow{\Dynamic}{T}$. A subclass of an instantiation of this class | |
886 with $\Num$ can validly override this method with one of external type $\sigma = | |
887 \Arrow{\Num}{\Num}$. This is unsound in general since the argument occurrence | |
888 of $T$ in $\sigma_s$ is contra-variant. However, the additional consistency | |
889 requirement is that the internal type of the subclass method must be a subtype | |
890 of $\subst{\Num}{T}{\tau_s} = \Arrow{\Dynamic}{\Num}$. This enforces the | |
891 property that the overriden method must expect to be used at type | |
vsm
2015/07/28 15:44:32
overriden -> overridden
Leaf
2015/07/28 20:34:29
Done.
| |
892 $\Arrow{\Dynamic}{\Num}$, and hence must check its arguments (and potentially | |
893 its return value as well in the higher-order case). This checking code is | |
894 inserted during the elaboration of class members above. | |
895 | |
896 } | |
897 | |
898 \infrule{ | |
899 \iftrans{ | |
900 \Delta = T_0, \ldots, T_n \quad\quad | |
901 \subtypeOf{\Phi, \Delta}{\tau}{\down{\sigma}}\ \\ | |
902 } | |
903 \methodLookup{\Phi}{\TApp{G}{\tau_0, \ldots, \tau_k}}{f}{\tau_s}{\sigma_s} \\ | |
904 \iftrans{ | |
905 \subtypeOf{\Phi, \Delta}{\tau}{\tau_s}\quad\quad | |
906 } | |
907 \subtypeOf{\Phi, \Delta}{\sigma}{\sigma_s} | |
908 } | |
909 { | |
910 \overrideOk{\Phi} | |
911 {\TApp{C}{T_0, \ldots, T_n}} | |
912 {\TApp{G}{\tau_0, \ldots, \tau_k}} | |
913 {\methodDecl{f}{\tau}{\sigma}} | |
914 } | |
915 | |
916 \subsection*{Toplevel declaration typing: $\declOk[t]{\Phi, \Gamma}{\mathit{td} }{\mathit{td'}}{\Gamma'}$} | |
917 \hrulefill\\ | |
918 | |
919 \sstext{ | |
920 | |
921 Top level variable declarations are well-typed if they are well-typed according | |
922 to their respective specific typing relations. | |
923 | |
924 }{ | |
925 | |
926 Top level declaration elaboration falls through to the underlying variable and | |
927 class declaration code. | |
928 | |
929 } | |
930 | |
931 \infrule | |
932 {\declOk[d]{\Phi, \epsilon, \Gamma}{\mathit{vd}}{\mathit{vd'}}{\Gamma'} | |
933 | |
934 } | |
935 {\declOk[t]{\Phi, \Gamma}{\mathit{vd}}{\mathit{vd'}}{\Gamma'} | |
936 } | |
937 | |
938 \infrule | |
939 {\declOk[c]{\Phi, \Gamma}{\mathit{cd}}{\mathit{cd'}}{\Gamma'} | |
940 | |
941 } | |
942 {\declOk[t]{\Phi, \Gamma}{\mathit{cd}}{\mathit{cd'}}{\Gamma'} | |
943 } | |
944 | |
945 | |
946 \subsection*{Well-formed class signature: $\ok{\Phi}{\Sig}$} | |
947 \hrulefill\\ | |
948 | |
949 \sstext{ | |
950 | |
951 The well-formed class signature relation checks whether a class signature is | |
952 well-formed with respect to a given class hierarchy $\Phi$. | |
953 | |
954 }{ | |
955 | |
956 } | |
957 | |
958 \sstext{ | |
959 | |
960 The $\Object$ signature is always well-formed. | |
961 | |
962 }{ | |
963 | |
964 } | |
965 | |
966 \axiom{\ok{\Phi}{\Object} | |
967 } | |
968 | |
969 \sstext{ | |
970 | |
971 A signature for a class $C$ is well-formed if its super-class signature is | |
972 well-formed, and if every element in its signature is a valid override of the | |
973 super-class. | |
974 | |
975 }{ | |
976 | |
977 } | |
978 | |
979 \infrule{\Sig = \dclass{\TApp{C}{\many{T}}} | |
980 {\TApp{G}{\tau_0, \ldots, \tau_k}} | |
981 {\mathit{ce}_0, \ldots, \mathit{ce}_n} \\ | |
982 (G : \Sig') \in \Phi \quad\quad \ok{\Phi}{\Sig'} \\ | |
983 \overrideOk{\Phi}{\TApp{C}{\many{T}}}{\TApp{G}{\tau_0, \ldots, \tau_k}}{ \mathit{ce}_i} | |
984 \quad\quad | |
985 \mbox{for}\ \mathit{ce}_i \in \mathit{ce}_0, \ldots, \mathit{ce}_n | |
986 } | |
987 {\ok{\Phi}{\Sig} | |
988 } | |
989 | |
990 \subsection*{Well-formed class hierarchy: $\ok{}{\Phi}$} | |
991 \hrulefill\\ | |
992 | |
993 \sstext{ | |
994 | |
995 A class hierarchy is well-formed if all of the signatures in it are well-formed | |
996 with respect to it. | |
997 | |
998 }{ | |
999 | |
1000 } | |
1001 | |
1002 \infrule{\ok{\Phi}{\Sig}\ \mbox{for}\, \Sig\, \in \Phi | |
1003 } | |
1004 {\ok{}{\Phi} | |
1005 } | |
1006 | |
1007 \subsection*{Program typing: $\programOk{\Phi}{P}{P'}$} | |
1008 \hrulefill\\ | |
1009 | |
1010 %%Definitions: | |
1011 %% | |
1012 %% \begin{eqnarray*} | |
1013 %% \sigof{\mathit{vd}} & = & | |
1014 %% \begin{cases} | |
1015 %% \fieldDecl{x}{\tau} & \mbox{if}\ \mathit{vd} = \dvar{x:\tau}{e}\\ | |
1016 %% \fieldDecl{x}{\Dynamic} & \mbox{if}\ \mathit{vd} = \dvar{x:\_}{e}\\ | |
1017 %% \methodDecl{f}{\tau_f}{\Arrow[+]{\many{\tau}}{\sigma}} & \mbox{if}\ \math it{vd} = \dfun{\sigma}{f}{\many{x:\tau}}{s} | |
1018 %% \end{cases}\\ | |
1019 %% \sigof{\mathit{cd}} & = & C\, : \, \dclass{\TApp{C}{\many{T}}} | |
1020 %% {\TApp{G}{\tau_0, \ldots, \tau_k}} | |
1021 %% {\mathit{ce}_0, \ldots, \mathit{ce}_ n} \\ | |
1022 %% \mbox{where} && | |
1023 %% \mathit{cd} = \dclass{\TApp{C}{\many{T}}} | |
1024 %% {\TApp{G}{\tau_0, \ldots, \tau_k}} | |
1025 %% {\mathit{vd}_0, \ldots, \mathit{vd}_n} \\ | |
1026 %% \mbox{and} && | |
1027 %% \mathit{ce}_i = \sigof{vd_i} \quad \mbox{for}\ i \in 0, \ldots, n | |
1028 %%\end{eqnarray*} | |
1029 | |
1030 \sstext{ | |
1031 | |
1032 Program well-formedness is defined with respect to a class hierarchy $\Phi$. It | |
1033 is not specified how $\Phi$ is produced, but the well-formedness constraints in | |
1034 the various judgments should constrain it appropriately. A program is | |
1035 well-formed if each of the top level declarations in the program is well-formed | |
1036 in a context in which all of the previous variable declarations have been | |
1037 checked and inserted in the context, and if the body of the program is | |
1038 well-formed in the final context. We allow classes to refer to each other in | |
1039 any order, since $\Phi$ is pre-specified, but do not model out of order | |
1040 definitions of top level variables and functions. We assume as a syntactic | |
1041 property that the class hierarchy $\Phi$ is acyclic. | |
1042 | |
1043 }{ | |
1044 | |
1045 } | |
1046 | |
1047 \infrule{ \Gamma_0 = \epsilon \quad\quad | |
1048 \declOk[t]{\Phi, \Gamma_i}{\mathit{td}_i}{\mathit{td}'_i}{\Gamma_{i+1 }} \quad | |
1049 \mbox{for}\ i \in 0,\ldots,n\\ | |
1050 \stmtOk{\Phi, \epsilon, \Gamma_{n+1}}{s}{\tau}{s'}{\Gamma_{n+1}'} | |
1051 } | |
1052 { \programOk{\Phi}{\program{\mathit{td}_0, \ldots, \mathit{td}_n}{s}} | |
1053 {\program{\mathit{td}'_0, \ldots, \mathit{td}'_n}{s'}} | |
1054 } | |
OLD | NEW |