www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit e951c7b26f0e1ef3f523d47f4ca39cb46ca0050c
parent 48bc1ed2f926c45f01eb781c97e4fd94682908cd
Author: Georges Dupéron <georges.duperon@gmail.com>
Date:   Sun,  1 Jan 2017 21:03:03 +0100

Started writing on phantom types as witnesses for invariants

Diffstat:
MGraph-notes-copy2.vue | 51++++++++++++++++++++++++++++++---------------------
Minfo.rkt | 3++-
Minvariants-phantom.hl.rkt | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Anotations.rkt | 8++++++++
Mtest/test-flexible-with.rkt | 11++++-------
Rtimes.rkt -> times.rkt.txt | 0
6 files changed, 129 insertions(+), 41 deletions(-)

diff --git a/Graph-notes-copy2.vue b/Graph-notes-copy2.vue @@ -1,14 +1,14 @@ -<!-- Tufts VUE 3.3.0 concept-map (Graph-notes-copy2.vue) 2016-12-29 --> +<!-- Tufts VUE 3.3.0 concept-map (Graph-notes-copy2.vue) 2016-12-30 --> <!-- Tufts VUE: http://vue.tufts.edu/ --> <!-- Do Not Remove: VUE mapping @version(1.1) jar:file:/nix/store/z92y35qgs6g3cvvh0i4f14mg5n47zvvi-vue-3.3.0/share/vue/vue.jar!/tufts/vue/resources/lw_mapping_1_1.xml --> -<!-- Do Not Remove: Saved date Thu Dec 29 22:27:01 CET 2016 by georges on platform Linux 4.4.38 in JVM 1.8.0_122-04 --> +<!-- Do Not Remove: Saved date Fri Dec 30 22:07:05 CET 2016 by georges on platform Linux 4.4.38 in JVM 1.8.0_122-04 --> <!-- Do Not Remove: Saving version @(#)VUE: built October 8 2015 at 1724 by tomadm on Linux 2.6.32-504.23.4.el6.x86_64 i386 JVM 1.7.0_21-b11(bits=32) --> <?xml version="1.0" encoding="US-ASCII"?> <LW-MAP xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="none" ID="0" label="Graph-notes-copy2.vue" created="1479309847604" x="0.0" y="0.0" width="1.4E-45" height="1.4E-45" strokeWidth="0.0" autoSized="false"> - <resource referenceCreated="1483046821901" size="202869" + <resource referenceCreated="1483132025205" size="204773" spec="/home/georges/phc/racket-packages/phc-graph/Graph-notes-copy2.vue" type="1" xsi:type="URLResource"> <title>Graph-notes-copy2.vue</title> @@ -1046,8 +1046,8 @@ <shape arcwidth="20.0" archeight="20.0" xsi:type="roundRect"/> </child> <child ID="215" label="Structural invariant" layerID="1" - created="1479312437302" x="-526.0517" y="296.2496" width="162.0" - height="86.75" strokeWidth="1.0" autoSized="true" xsi:type="node"> + created="1479312437302" x="-526.0517" y="273.2496" width="162.0" + height="107.0" strokeWidth="1.0" autoSized="true" xsi:type="node"> <fillColor>#F2AE45</fillColor> <strokeColor>#000000</strokeColor> <textColor>#000000</textColor> @@ -1083,6 +1083,16 @@ <URIString>http://vue.tufts.edu/rdf/resource/6e13f9e943a6be970d2ffe25a12d6061</URIString> <shape arcwidth="20.0" archeight="20.0" xsi:type="roundRect"/> </child> + <child ID="537" label="a.c = count(a.b)" created="1483131981450" + x="34.0" y="83.75" width="118.0" height="23.0" + strokeWidth="1.0" autoSized="true" xsi:type="node"> + <fillColor>#F2AE45</fillColor> + <strokeColor>#776D6D</strokeColor> + <textColor>#000000</textColor> + <font>SansSerif-plain-12</font> + <URIString>http://vue.tufts.edu/rdf/resource/518eb6ce534430712734d86a5ed52578</URIString> + <shape arcwidth="20.0" archeight="20.0" xsi:type="roundRect"/> + </child> <shape arcwidth="20.0" archeight="20.0" xsi:type="roundRect"/> </child> <child ID="216" label="Fill in auto fields" layerID="1" @@ -1516,16 +1526,16 @@ <ID1 xsi:type="node">216</ID1> <ID2 xsi:type="node">269</ID2> </child> - <child ID="273" layerID="1" created="1479315784203" x="-550.9628" - y="268.6448" width="41.538574" height="28.104797" + <child ID="273" layerID="1" created="1479315784203" x="-547.75836" + y="268.64478" width="22.596802" height="13.172211" strokeWidth="1.0" autoSized="false" controlCount="0" arrowState="2" xsi:type="link"> <strokeColor>#000000</strokeColor> <textColor>#404040</textColor> <font>SansSerif-plain-11</font> <URIString>http://vue.tufts.edu/rdf/resource/6e18c7e043a6be970d2ffe25213bebda</URIString> - <point1 x="-550.4628" y="269.1448"/> - <point2 x="-509.92426" y="296.2496"/> + <point1 x="-547.25836" y="269.1448"/> + <point2 x="-525.66156" y="281.31702"/> <ID1 xsi:type="node">269</ID1> <ID2 xsi:type="node">215</ID2> </child> @@ -1614,16 +1624,16 @@ <ID1 xsi:type="node">278</ID1> <ID2 xsi:type="node">264</ID2> </child> - <child ID="286" layerID="1" created="1479316060242" x="-444.86713" - y="59.84375" width="4.7231445" height="236.90625" + <child ID="286" layerID="1" created="1479316060242" x="-444.6682" + y="59.84375" width="4.5158997" height="213.90625" strokeWidth="1.0" autoSized="false" controlCount="0" arrowState="2" xsi:type="link"> <strokeColor>#000000</strokeColor> <textColor>#404040</textColor> <font>SansSerif-plain-11</font> <URIString>http://vue.tufts.edu/rdf/resource/6e1c69c643a6be970d2ffe2578e91de4</URIString> - <point1 x="-440.64398" y="60.34375"/> - <point2 x="-444.36713" y="296.25"/> + <point1 x="-440.65234" y="60.34375"/> + <point2 x="-444.16824" y="273.25"/> <ID1 xsi:type="node">280</ID1> <ID2 xsi:type="node">215</ID2> </child> @@ -2015,10 +2025,9 @@ <ID2 xsi:type="node">335</ID2> </child> <child ID="342" - label="Define a wrapper, which may alter the input and input types, and the output and output types" + label="Define a wrapper, which may alter the input value and input types, and the output value and output types" layerID="1" created="1479326681064" x="347.9707" y="1262.2448" - width="683.25" height="202.25" strokeWidth="1.0" - autoSized="true" xsi:type="node"> + width="726.0" height="202.25" strokeWidth="1.0" autoSized="true" xsi:type="node"> <fillColor>#F2AE45</fillColor> <strokeColor>#776D6D</strokeColor> <textColor>#000000</textColor> @@ -2130,15 +2139,15 @@ </child> <shape arcwidth="20.0" archeight="20.0" xsi:type="roundRect"/> </child> - <child ID="345" layerID="1" created="1479326900002" x="219.06221" - y="1077.2448" width="304.619" height="185.5" strokeWidth="1.0" + <child ID="345" layerID="1" created="1479326900002" x="219.88948" + y="1077.2448" width="317.8918" height="185.5" strokeWidth="1.0" autoSized="false" controlCount="0" arrowState="2" xsi:type="link"> <strokeColor>#404040</strokeColor> <textColor>#404040</textColor> <font>SansSerif-plain-11</font> <URIString>http://vue.tufts.edu/rdf/resource/6ec139aac0a80026616d92397220832f</URIString> - <point1 x="219.56223" y="1077.7448"/> - <point2 x="523.1812" y="1262.2448"/> + <point1 x="220.3895" y="1077.7448"/> + <point2 x="537.2813" y="1262.2448"/> <ID1 xsi:type="node">293</ID1> <ID2 xsi:type="node">342</ID2> </child> @@ -3704,7 +3713,7 @@ <URIString>http://vue.tufts.edu/rdf/resource/6dbf6b15c0a80026548592b8d2f3fee2</URIString> </layer> <userZoom>1.0</userZoom> - <userOrigin x="-1573.3625" y="-374.75525"/> + <userOrigin x="-1829.3625" y="-403.75525"/> <presentationBackground>#FFFFFF</presentationBackground> <PathwayList currentPathway="0" revealerIndex="-1"> <pathway ID="0" label="Chemin sans nom" created="1479309847603" diff --git a/info.rkt b/info.rkt @@ -11,7 +11,8 @@ "srfi-lite-lib" "delay-pure" "backport-template-pr1514" - "typed-map")) + "typed-map" + "scribble-lib")) (define build-deps '("scribble-lib" "racket-doc" "remember" diff --git a/invariants-phantom.hl.rkt b/invariants-phantom.hl.rkt @@ -1,15 +1,19 @@ #lang aful/unhygienic hyper-literate type-expander/lang -@title[#;#:style #;(with-html5 manual-doc-style) - #:tag "invariants-phantom" - #:tag-prefix "phc-graph/invariants-phantom"]{Tracking checked contracts +@require[scribble-math + scribble-enhanced/doc + "notations.rkt"] + +@title[#:style (with-html5 manual-doc-style) + #:tag "inv-phantom" + #:tag-prefix "phc-graph/inv-phantom"]{Tracking checked contracts via phantom types} @(chunks-toc-prefix '("(lib phc-graph/scribblings/phc-graph-implementation.scrbl)" - "phc-graph/invariants-phantom")) + "phc-graph/inv-phantom")) -@section{Overview} +@section{Introduction} The cautious compiler writer will no doubt want to check that the graph used to represent the program verifies some structural properties. For example, the @@ -18,6 +22,8 @@ property is that the @racket[in-method] field of an instruction points back to the method containing it. We will use this second property as a running example in this section. +@section{Implementation overview} + It is possible to express with Typed/Racket that a @racket[Method] should contain a list of @racket[Instruction]s, and that @racket[Instruction]s should point to a @racket[Method]@note{We are not concerned here about the ability to @@ -86,13 +92,80 @@ to wrap it in a struct type which is only accessible by the graph library: (code:comment "provide only the type, not the constructor or accessor") (provide Flag-Wrapper)] -@; size → use a dummy function which errors when called -@; (accepts an opaque token to prevent calling) - -@; Subtyping: multiple contracts with case→ - -@; Subtyping: when C1 ⇒ C2, -@; make the marker for C1 a subtype of the marker for C2 +We would like to be able to indicate that a graph node has validated several +invariants. For that, we need a way to represent the type of a "set" of +invariant witnesses. We also want some subtyping relationship between the +sets: a set @${s₁} with more invariant witnesses should be a subtype of a +subset @${s₂ ⊆ s₁}. We can order the invariant witnesses and use @racket[Rec] +to build the type of a list of invariant witnesses, where some may be missing: + +@chunk[<invariant-set-as-List+Rec> + (define-type At-Least-InvB+InvD + (Rec R₁ (U (Pairof Any R₁) + (Pairof 'InvB (Rec R₂ (U (Pairof Any R₂) + (Pairof 'InvD (Listof Any))))))))] + +@chunk[<invariant-set-as-List+Rec-use> + (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[<invariant-set-as-contravariant-U> + (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[<invariant-contract-subtyping> + (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[<invariant-contract-subtyping> + (struct InvStrongContra ()) + (struct InvWeakContra InvStrongContra ())] + +Alternatively, it is possible to use a second contravariant position to +reverse the subtyping relationship again: + +@chunk[<invariant-contract-subtyping> + (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[<structural> + (≡ [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 @@ -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 @@ -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