diff --git a/Graph-notes-copy2.vue b/Graph-notes-copy2.vue index e863db8..b7341f9 100644 --- a/Graph-notes-copy2.vue +++ b/Graph-notes-copy2.vue @@ -1,14 +1,14 @@ - + - + - Graph-notes-copy2.vue @@ -1046,8 +1046,8 @@ + created="1479312437302" x="-526.0517" y="273.2496" width="162.0" + height="107.0" strokeWidth="1.0" autoSized="true" xsi:type="node"> #F2AE45 #000000 #000000 @@ -1083,6 +1083,16 @@ http://vue.tufts.edu/rdf/resource/6e13f9e943a6be970d2ffe25a12d6061 + + #F2AE45 + #776D6D + #000000 + SansSerif-plain-12 + http://vue.tufts.edu/rdf/resource/518eb6ce534430712734d86a5ed52578 + + 216 269 - #000000 #404040 SansSerif-plain-11 http://vue.tufts.edu/rdf/resource/6e18c7e043a6be970d2ffe25213bebda - - + + 269 215 @@ -1614,16 +1624,16 @@ 278 264 - #000000 #404040 SansSerif-plain-11 http://vue.tufts.edu/rdf/resource/6e1c69c643a6be970d2ffe2578e91de4 - - + + 280 215 @@ -2015,10 +2025,9 @@ 335 + width="726.0" height="202.25" strokeWidth="1.0" autoSized="true" xsi:type="node"> #F2AE45 #776D6D #000000 @@ -2130,15 +2139,15 @@ - #404040 #404040 SansSerif-plain-11 http://vue.tufts.edu/rdf/resource/6ec139aac0a80026616d92397220832f - - + + 293 342 @@ -3704,7 +3713,7 @@ http://vue.tufts.edu/rdf/resource/6dbf6b15c0a80026548592b8d2f3fee2 1.0 - + #FFFFFF + (define-type At-Least-InvB+InvD + (Rec R₁ (U (Pairof Any R₁) + (Pairof 'InvB (Rec R₂ (U (Pairof Any R₂) + (Pairof 'InvD (Listof Any))))))))] -@; Subtyping: when C1 ⇒ C2, -@; make the marker for C1 a subtype of the marker for C2 +@chunk[ + (ann '(InvA InvB InvC InvD InvE) At-Least-InvB+InvD) + (ann '(InvB InvD) At-Least-InvB+InvD) + (code:comment "Rejected, because it lacks 'InvD") + (code:comment "(ann '(InvB InvC InvE) At-Least-InvB+InvD)") + (code:comment "The elements must be in the right order,") + (code:comment "this would be rejected by the typechecker:") + (code:comment "(ann '(InvD InvB) At-Least-InvB+InvD)")] + +Another solution is to group the witnesses in an untagged union with +@racket[U], and place it in a contravariant position: + +@chunk[ + (define-type At-Least-InvB+InvD + (→ (U 'InvB 'InvD) Void))] + +This solution also has the advantage that the size of the run-time witness is +constant, and does not depend on the number of checked contracts (unlike the +representation using a list). In practice the function should never be called. +It can however simply be implemented in a way which pleases the type checked +as a function accepting anything and returning void. + +In addition to testifying that a graph node was checked against multiple, +separate contracts, there might be some contracts which check stronger +properties than others. A way to encode this relationship in the type system +is to have subtyping relationships between the contract witnesses, so that +@; TODO: get rid of the mathit +@${\mathit{P}₁(x) ⇒ \mathit{P}₂(x) ⇒ \mathit{Inv}₁ @texsubtype \mathit{Inv}₂}: + +@chunk[ + (struct InvWeak ()) + (struct InvStrong InvWeak ())] + +If the witnesses must appear in a contravariant position (when using +@racket[U] to group them), the relationship must be reversed: + +@chunk[ + (struct InvStrongContra ()) + (struct InvWeakContra InvStrongContra ())] + +Alternatively, it is possible to use a second contravariant position to +reverse the subtyping relationship again: + +@chunk[ + (struct InvWeak ()) + (struct InvStrong InvWeak ()) + + (define InvWeakContra (→ InvWeak Void)) + (define InvStrongContra (→ InvStrong Void))] + +Finally, we note that the invariants should always be represented using a +particular struct type, instead of using a symbol, so that name clashes are +not a problem. + +@section{Types for some graph contracts} + +@chunk[ + (≡ [a : Nd] (get a f1 f2)) + (∈ [a : Nd] (get a f1 f2)) + (∉ [a : Nd] (get a f1 f2)) + (∉ [a : Nd] (get a (* f1 f2 f3 f4) (* f5 f6)))] @chunk[<*> (void)] \ No newline at end of file diff --git a/notations.rkt b/notations.rkt new file mode 100644 index 0000000..e82ddf5 --- /dev/null +++ b/notations.rkt @@ -0,0 +1,7 @@ +#lang racket + +(require scribble/base) + +(provide texsubtype) + +(define texsubtype "<:") \ No newline at end of file diff --git a/test/test-flexible-with.rkt b/test/test-flexible-with.rkt index 9b428e6..c4ab572 100644 --- a/test/test-flexible-with.rkt +++ b/test/test-flexible-with.rkt @@ -22,15 +22,13 @@ [struct struct-field …] …)))])) (gs bt-fields - 257 + 16 (a b c) [sab a b] [sbc b c] [sabc a b c]) -;(define-type btac (bt-fields a c)) - -#| +(define-type btac (bt-fields a c)) (check-equal?: (~> (ann (with-c (sab→tree 1 2) 'nine) @@ -78,5 +76,4 @@ (call-with-values #λ(tree→sbc (without-a (with-c (sab→tree 1 2) 3))) list) - '(2 3)) -|# \ No newline at end of file + '(2 3)) \ No newline at end of file diff --git a/times.rkt b/times.rkt.txt similarity index 100% rename from times.rkt rename to times.rkt.txt