diff --git a/Graph-notes-copy2.vue b/Graph-notes-copy2.vue index 340d24d..a21ea07 100644 --- a/Graph-notes-copy2.vue +++ b/Graph-notes-copy2.vue @@ -1,14 +1,14 @@ - + - + - Graph-notes-copy2.vue @@ -3913,8 +3913,8 @@ y="0.0" width="1.4E-45" height="1.4E-45" strokeWidth="0.0" autoSized="false"> http://vue.tufts.edu/rdf/resource/6dbf6b15c0a80026548592b8d2f3fee2 - 1.0 - + 0.75 + #FFFFFF list v))))))) diff --git a/invariants-phantom.hl.rkt b/invariants-phantom.hl.rkt index 49199f6..200335d 100644 --- a/invariants-phantom.hl.rkt +++ b/invariants-phantom.hl.rkt @@ -15,12 +15,12 @@ @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 -compiled language might not allow cycles between types. Another desirable -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. +The cautious compiler writer will no doubt want to check that the Abstract +Syntax Tree or Graph used to represent the program verifies some structural +properties. For example, the compiled language might not allow cycles between +types. Another desirable property is that the @racket[in-method] field of the +node representing 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 : subtyping, variance and phantom types} @@ -341,6 +341,12 @@ having an empty union. @subsection{Structural (in)equality and (non-)membership invariants} +@subsubsection{Invariants and their relationships} + +@itemlist[ + @item{Paths, } + ] + @subsubsection{Comparison operator tokens} We define some tokens which will be used to identify the operator which @@ -377,17 +383,20 @@ relates two nodes in the graph. (define-type-expander Cycle (syntax-parser [(_ field:id … {~literal ↙} loop1:id … (target:id) loop2:id …) - #'(List* (NonTarget ε) - (NonTarget 'field) … - (Rec R (List* (NonTarget 'loop1) … ;(NonTarget 'loop1) … - (Target 'target) ;(NonTarget 'target) - (NonTarget 'loop2) … ;(NonTarget 'loop2) … - R)))] + #'(→ (List* (NonTarget ε) + (NonTarget 'field) … + (Rec R (List* (NonTarget 'loop1) … ;(NonTarget 'loop1) … + (Target 'target) ;(NonTarget 'target) + (U (List* (NonTarget 'loop2) … ;(NonTarget 'loop2) … + R) + Null)))) Void)] [(_ field … target) - ;; TODO: something special at the end? - #'(List (NonTarget ε) (NonTarget 'field) … (Target 'target))] + #'(→ (List (NonTarget ε) + (NonTarget 'field) + … + (Target 'target)) Void)] [(_) - #'(List (Target ε))]))] + #'(→ (List (Target ε)) Void)]))] @;{@[ @@ -431,57 +440,23 @@ Two sorts of paths inside (in)equality constraints: @subsection{Putting it all together} -@chunk[ - (define-syntax (check-a-stronger-than-b stx) - (syntax-case stx () - [(_ stronger weaker) - (syntax/top-loc stx - (begin (check-ann (ann witness-value stronger) - weaker) - (check-not-tc - (ann (ann witness-value weaker) stronger))))])) - - (define-syntax (check-a-same-as-b stx) - (syntax-case stx () - [(_ a b) - (syntax/top-loc stx - (begin - (check-ann (ann witness-value a) b) - (check-ann (ann witness-value b) a)))]))] - @chunk[<*> (require (for-syntax phc-toolkit/untyped syntax/parse)) - (provide Invariants ≡) - + ;; For testing: + (provide Invariants + ≡ + inv≡ + inv≢ + Or + Target + NonTarget + ε + witness-value) + - <≡> - - (module+ test - (require phc-toolkit) - - - (ann witness-value (Invariants)) ;; No invariants - (ann witness-value (Invariants (≡ (_ a) (_ a b c)))) - - (check-a-stronger-than-b (Invariants (≡ (_ a) (_ a b c))) - (Invariants)) - - (check-a-same-as-b (Invariants (≡ (_ a) (_ a b c))) - (Invariants (≡ (_ a b c) (_ a)))) - - (check-a-stronger-than-b (Invariants (≡ (_) (_ b c)) - (≡ (_) (_ b d))) - (Invariants (≡ (_) (_ b c)))) - (check-a-stronger-than-b (Invariants (≡ (_) (_ b d)) - (≡ (_) (_ b c))) - (Invariants (≡ (_) (_ b c)))) - - (check-a-stronger-than-b (Invariants (≡ (_) - (_ b d a b d ↙ a b (d)))) - (Invariants (≡ (_) - (_ b d ↙ a b (d))))))] + <≡>] diff --git a/test/invariant-phantom/simple.rkt b/test/invariant-phantom/simple.rkt new file mode 100644 index 0000000..f92a491 --- /dev/null +++ b/test/invariant-phantom/simple.rkt @@ -0,0 +1,37 @@ +#lang type-expander + +(require (lib "phc-graph/invariants-phantom.hl.rkt") + "util.rkt" + phc-toolkit) + +(check-ann witness-value (Invariants)) ;; No invariants +(check-ann witness-value (Invariants (≡ (_ a) (_ a b c)))) + +(check-a-stronger-than-b (Invariants (≡ (_ a) (_ a b c))) + (Invariants)) + +(check-a-same-as-b (Invariants (≡ (_ a) (_ a b c))) + (Invariants (≡ (_ a b c) (_ a)))) + +(check-a-stronger-than-b (Invariants (≡ (_) (_ b c)) + (≡ (_) (_ b d))) + (Invariants (≡ (_) (_ b c)))) +(check-a-stronger-than-b (Invariants (≡ (_) (_ b d)) + (≡ (_) (_ b c))) + (Invariants (≡ (_) (_ b c)))) + +;; ∀ .b.d(.a.b.>d)* of length ≥ 5 +;; is stronger than +;; ∀ .b.d(.a.b.>d)* of length ≥ 8 +;; as the elements of the latter are included in the former, but +;; the first element (length = 5) is missing in the latter, so the +;; former constrains more paths. +(check-a-stronger-than-b (Invariants (≡ (_) + (_ b d ↙ a b (d)))) + (Invariants (≡ (_) + (_ b d a b d ↙ a b (d))))) + +(check-a-stronger-than-b (Invariants (≡ (_) + (_ a b c ↙ d (e)))) + (Invariants (≡ (_) + (_ a b c d e)))) \ No newline at end of file diff --git a/test/invariant-phantom/util.rkt b/test/invariant-phantom/util.rkt new file mode 100644 index 0000000..9f82749 --- /dev/null +++ b/test/invariant-phantom/util.rkt @@ -0,0 +1,25 @@ +#lang type-expander + +(provide check-a-same-as-b + check-a-stronger-than-b) + +(require phc-toolkit + (lib "phc-graph/invariants-phantom.hl.rkt") + (for-syntax phc-toolkit/untyped)) + +(define-syntax (check-a-stronger-than-b stx) + (syntax-case stx () + [(_ stronger weaker) + (syntax/top-loc stx + (begin (check-ann (ann witness-value stronger) + weaker) + (check-not-tc + (ann (ann witness-value weaker) stronger))))])) + +(define-syntax (check-a-same-as-b stx) + (syntax-case stx () + [(_ a b) + (syntax/top-loc stx + (begin + (check-ann (ann witness-value a) b) + (check-ann (ann witness-value b) a)))])) \ No newline at end of file