From 839bec824c902524003f0b52eb31226f5537ad7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Georges=20Dup=C3=A9ron?= <georges.duperon@gmail.com> Date: Tue, 11 Apr 2017 14:06:35 +0200 Subject: [PATCH] =?UTF-8?q?WIP=20on=20#62:=20Encoding=20of=20relations=20a?= =?UTF-8?q?s=20types=20(=E2=89=A1,=20=E2=88=88,=20=3D=20length,=20<=20leng?= =?UTF-8?q?th)=20=E2=80=94=20finished=20most=20of=20the=20type-level=20enc?= =?UTF-8?q?oding,=20fixed=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Graph-notes-copy2.vue | 8 +- info.rkt | 3 +- invariants-phantom.hl.rkt | 116 ++++++++++------- test/invariant-phantom/simple.rkt | 203 ++++++++++++++++++------------ 4 files changed, 194 insertions(+), 136 deletions(-) diff --git a/Graph-notes-copy2.vue b/Graph-notes-copy2.vue index a21ea07..2f91b26 100644 --- 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) 2017-03-23 --> +<!-- Tufts VUE 3.3.0 concept-map (Graph-notes-copy2.vue) 2017-04-11 --> <!-- 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 Mar 23 01:54:28 CET 2017 by georges on platform Linux 4.4.40 in JVM 1.8.0_122-04 --> +<!-- Do Not Remove: Saved date Tue Apr 11 14:04:44 CEST 2017 by georges on platform Linux 4.4.40 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="1490230468578" size="216025" + <resource referenceCreated="1491912284366" size="216026" spec="/home/georges/phc/racket-packages/phc-graph/Graph-notes-copy2.vue" type="1" xsi:type="URLResource"> <title>Graph-notes-copy2.vue</title> @@ -3914,7 +3914,7 @@ <URIString>http://vue.tufts.edu/rdf/resource/6dbf6b15c0a80026548592b8d2f3fee2</URIString> </layer> <userZoom>0.75</userZoom> - <userOrigin x="-1182.522" y="-189.81644"/> + <userOrigin x="-1182.522" y="-282.81644"/> <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 index 0d7b185..eb4e939 100644 --- a/info.rkt +++ b/info.rkt @@ -16,7 +16,8 @@ "remember" "extensible-parser-specifications" "subtemplate" - "stxparse-info")) + "stxparse-info" + "dotlambda")) (define build-deps '("scribble-lib" "racket-doc" "remember" diff --git a/invariants-phantom.hl.rkt b/invariants-phantom.hl.rkt index c89b684..43400a9 100644 --- a/invariants-phantom.hl.rkt +++ b/invariants-phantom.hl.rkt @@ -331,8 +331,10 @@ invariants, and therefore use a second nested function type to flip again the variance direction. We always include the @racket[Or] element in the union, to avoid ever having an empty union. +@chunk[<Or> + (struct Or ())] + @chunk[<grouping-invariants> - (struct Or ()) (define-type-expander (Invariants stx) (syntax-case stx () [(_ invᵢ …) @@ -405,25 +407,6 @@ making a union of all paths, without factoring out common parts. @chunk[<parse> (begin-for-syntax - (define-syntax-class dot-ish - #:literals (dot λdot) - (pattern ({~and d dot} e …) - #:with full - (add-between (syntax->list #'(e …)) - (datum->syntax #'d '|.| #'d #'d))) - (pattern ({~and d λdot} e …) - #:with full - (cons (datum->syntax #'d '|.| #'d #'d) - (add-between (syntax->list #'(e …)) - (datum->syntax #'d '|.| #'d #'d))))) - (define-syntax ~dot-ish - (pattern-expander - (λ (stx) - (syntax-case stx () - [(_ pat …) - #'(~and x:dot-ish - (~parse (pat …) #'x.full))])))) - (define (match-id rx id) (let ([m (regexp-match rx (identifier→string id))]) (and m (map (λ (%) (datum->syntax id (string->symbol %) id id)) @@ -445,25 +428,34 @@ making a union of all paths, without factoring out common parts. #:attributes (τ) (pattern {~rx-id #px"^:([^:]+)$" τ})) (define-syntax-class π-elements - #:datum-literals (|.|) + #:literals (#%dotted-id #%dot-separator) #:attributes ([f 1] [τ 1]) - (pattern (~dot-ish {~seq |.| :f+τ} …))) + (pattern (#%dotted-id {~seq #%dot-separator :f+τ} …))) + (define-syntax-class extract-star + #:literals (* #%dotted-id) + (pattern (#%dotted-id {~and st *} . rest) + #:with {extracted-star …} #'{st (#%dotted-id . rest)}) + (pattern other + #:with {extracted-star …} #'{other})) (define-syntax-class sub-elements - #:literals (*) #:datum-literals (|.|) + #:literals (* #%dot-separator) #:attributes ([f 2] [τ 2] [sub 1]) (pattern - ({~either :π-elements {~seq sub:sub-elements *}} …))))] + (:extract-star …) + #:with ({~either :π-elements {~seq sub:sub-elements *}} …) + #| |# #'(extracted-star … …))))] @chunk[<parse> - (define-type-expander (<~τ stx) - (syntax-case stx () + (define-type-expander <~τ + (syntax-parser [(_ τ) #'τ] [(_ f₀ . more) - #'(f₀ (<~τ . more))])) + #`(f₀ (<~τ . more))])) (begin-for-syntax (define-template-metafunction generate-sub-π (syntax-parser [(_ :sub-elements after) + #:with R (gensym 'R) (template (Rec R (U (<~τ (?? (∀ (more) (generate-sub-π sub more)) @@ -476,14 +468,22 @@ making a union of all paths, without factoring out common parts. after)))]))) (define-type-expander Π (syntax-parser - [(_ {~optional (~dot-ish fst-τ:just-τ {~seq |.| fst:f+τ} …)} + #:literals (#%dotted-id #%dot-separator) + [(_ {~optional (~or (#%dotted-id fst-τ:just-τ + {~seq #%dot-separator fst:f+τ} …) + (~and fst-τ:just-τ + {~parse (fst:f+τ …) #'()}) + {~datum :})} . :sub-elements) - (template (Rec R (U (Pairof Any R) - (List* (?? (?@ (Pairof AnyField fst-τ.τ) - (Pairof (?? 'fst.f AnyField) - (?? fst.τ AnyType)) - …)) - <π>))))]))] + #:with R (gensym 'R) + (template/top-loc + this-syntax + (Rec R (U (Pairof Any R) + (List* (?? (?@ (Pairof AnyField fst-τ.τ) + (Pairof (?? 'fst.f AnyField) + (?? fst.τ AnyType)) + …)) + <π>))))]))] @chunk[<π> (<~τ (?? (∀ (more) (generate-sub-π sub more)) @@ -494,18 +494,31 @@ making a union of all paths, without factoring out common parts. Null)] @chunk[<Invariant> + ;; TODO: /top-loc everywhere (define-type-expander Invariant (syntax-parser #:literals (≡ ≢ ∈ ∉ ∋ ∌) - ;; For ≡ and ≢, use (U l r) because they are symmetric - [(_ π₁ … ≡ π₂ …) #`(inv≡ (U (Π π₁ …) (Π π₂ …)))] - [(_ π₁ … ≢ π₂ …) #`(inv≢ (U (Π π₁ …) (Π π₂ …)))] + [(_ π₁ … ≡ π₂ …) #`(U (inv≡ (Pairof (Π π₁ …) (Π π₂ …))) + (inv≡ (Pairof (Π π₂ …) (Π π₁ …))))] + [(_ π₁ … ≢ π₂ …) #`(U (inv≢ (Pairof (Π π₁ …) (Π π₂ …))) + (inv≢ (Pairof (Π π₂ …) (Π π₁ …))))] [(_ π₁ … ∈ π₂ …) #`(inv∈ (Pairof (Π π₁ …) (Π π₂ …)))] [(_ π₁ … ∋ π₂ …) #`(inv∈ (Pairof (Π π₂ …) (Π π₁ …)))] [(_ π₁ … ∉ π₂ …) #`(inv≢ (Pairof (Π π₁ …) (Π π₂ … ?)))] [(_ π₁ … ∌ π₂ …) #`(inv≢ (Pairof (Π π₂ …) (Π π₁ … ?)))] ))] +@chunk[<Invariants> + (define-type-expander Invariants + (syntax-parser + [(_ inv …) + #`(→ (U Or (Invariant . inv) …) Void)]))] + +@chunk[<Any*> + (struct AnyField () #:transparent) + (struct AnyType () #:transparent) + (define-type ε (Π))] + @subsubsection{Comparison operator tokens} We define some tokens which will be used to identify the operator which @@ -551,9 +564,6 @@ relates two nodes in the graph. (struct ε () #:transparent) (struct (T) Target ([x : T]) #:transparent) (struct (T) NonTarget Target () #:transparent) - - (struct AnyField () #:transparent) - (struct AnyType () #:transparent) (define-type-expander Cycle (syntax-parser @@ -617,16 +627,23 @@ relates two nodes in the graph. @subsection{Putting it all together} -@chunk[<*> - (require (for-syntax racket/base +@CHUNK[<*> + (require (only-in typed/dotlambda #%dotted-id #%dot-separator) + "dot-lang.rkt" + (for-syntax racket/base racket/list phc-toolkit/untyped syntax/parse syntax/parse/experimental/template) (for-meta 2 racket/base) (for-meta 2 phc-toolkit/untyped/aliases) - (for-meta 3 racket/base) - "dot-lang.rkt") + (for-meta 3 racket/base)) + + (begin-for-syntax + (define-syntax-rule (quasisyntax e) + (quasisyntax/top-loc this-syntax e)) + (define-syntax-rule (template/top-loc loc e) + (quasisyntax/top-loc loc #,(template e)))) (provide ≡ ≢ ∈ ∉ ∋ ∌) @@ -637,8 +654,8 @@ relates two nodes in the graph. inv≡ inv≢ Or - Target - NonTarget + ;Target + ;NonTarget ε witness-value Π @@ -649,8 +666,11 @@ relates two nodes in the graph. <parse> <witness-value> - <grouping-invariants> - <cycles> + ;<grouping-invariants> + ;<cycles> + <Any*> <comparison-operators> <Invariant> + <Invariants> + <Or> <≡>] diff --git a/test/invariant-phantom/simple.rkt b/test/invariant-phantom/simple.rkt index d159073..e12133a 100644 --- a/test/invariant-phantom/simple.rkt +++ b/test/invariant-phantom/simple.rkt @@ -1,4 +1,5 @@ -#lang type-expander +#lang typed/dotlambda +(require type-expander) (require (lib "phc-graph/invariants-phantom.hl.rkt") "util.rkt" @@ -6,122 +7,161 @@ phc-toolkit) (check-same-type - (Π (λdot a aa) ((λdot b c))* (λdot d e)) + (Π .a.aa(.b.c)*.d.e) (Rec - R - (U (Pairof Any R) + R1 + (U (Pairof Any R1) (Pairof (Pairof 'a AnyType) (Pairof (Pairof 'aa AnyType) (Rec - R + R2 (U (Pairof (Pairof 'b AnyType) - (Pairof (Pairof 'c AnyType) R)) + (Pairof (Pairof 'c AnyType) R2)) (List (Pairof 'd AnyType) (Pairof 'e AnyType))))))))) -(struct a ()); the field. + +(struct a ()); the node. +(struct b ()); the node. + (check-same-type - (Π (dot :a aa) ((λdot b c))* (λdot d e)) + (Π :a.aa(.b.c)*.d.e) (Rec - R - (U (Pairof Any R) + R1 + (U (Pairof Any R1) (Pairof (Pairof AnyField a) (Pairof (Pairof 'aa AnyType) (Rec - R + R2 (U (List (Pairof 'd AnyType) (Pairof 'e AnyType)) - (Pairof (Pairof 'b AnyType) (Pairof (Pairof 'c AnyType) R))))))))) + (Pairof (Pairof 'b AnyType) (Pairof (Pairof 'c AnyType) R2))))))))) (check-same-type - (Π (dot :a) ((λdot b c))* (λdot d e)) + (Π :a(.b.c)*.d.e) (Rec - R - (U (Pairof Any R) + R1 + (U (Pairof Any R1) (Pairof (Pairof AnyField a) (Rec - R + R2 (U (List (Pairof 'd AnyType) (Pairof 'e AnyType)) - (Pairof (Pairof 'b AnyType) (Pairof (Pairof 'c AnyType) R)))))))) + (Pairof (Pairof 'b AnyType) (Pairof (Pairof 'c AnyType) R2)))))))) (check-same-type - (Π (dot :a) ((λdot b c) ((λdot w)) * (λdot x y))* (λdot d e)) + (Π :a(.b.c(.w)*.x.y)*.d.e) (Rec - R - (U (Pairof Any R) + R1 + (U (Pairof Any R1) (Pairof (Pairof AnyField a) - (U (List (Pairof 'd AnyType) (Pairof 'e AnyType)) - (Pairof - (Pairof 'b AnyType) + (Rec + R2 + (U (List (Pairof 'd AnyType) (Pairof 'e AnyType)) (Pairof - (Pairof 'c AnyType) - (Rec - R - (U (Pairof (Pairof 'w AnyType) R) - (Pairof - (Pairof 'x AnyType) - (Pairof (Pairof 'y AnyType) R))))))))))) + (Pairof 'b AnyType) + (Pairof + (Pairof 'c AnyType) + (Rec + R3 + (U (Pairof (Pairof 'w AnyType) R3) + (Pairof + (Pairof 'x AnyType) + (Pairof (Pairof 'y AnyType) R2)))))))))))) ;; TODO: test with deeper nesting of ()* (check-same-type - (Invariant (dot :a) ((λdot b c) ((λdot w)) * (λdot x y))* (λdot d e) - ≡ - (dot :a) ((λdot b c))* (λdot d e)) - (inv≡ - (U (Rec - R - (U (Pairof Any R) - (Pairof - (Pairof AnyField a) - (Rec - R - (U (List (Pairof 'd AnyType) (Pairof 'e AnyType)) - (Pairof (Pairof 'b AnyType) (Pairof (Pairof 'c AnyType) R))))))) - (Rec - R - (U (Pairof Any R) - (Pairof - (Pairof AnyField a) - (U (List (Pairof 'd AnyType) (Pairof 'e AnyType)) - (Pairof - (Pairof 'b AnyType) - (Pairof - (Pairof 'c AnyType) - (Rec - R - (U (Pairof (Pairof 'w AnyType) R) - (Pairof - (Pairof 'x AnyType) - (Pairof (Pairof 'y AnyType) R))))))))))))) + (Invariant :a(.b.c(.w)*.x.y)*.d.e ≡ :a(.b.c)*.d.e) + (U (inv≡ + (Pairof + (Rec + R1 + (U (Pairof Any R1) + (Pairof + (Pairof AnyField a) + (Rec + R2 + (U (List (Pairof 'd AnyType) (Pairof 'e AnyType)) + (Pairof + (Pairof 'b AnyType) + (Pairof (Pairof 'c AnyType) R2))))))) + (Rec + R1 + (U (Pairof Any R1) + (Pairof + (Pairof AnyField a) + (Rec + R2 + (U (List (Pairof 'd AnyType) (Pairof 'e AnyType)) + (Pairof + (Pairof 'b AnyType) + (Pairof + (Pairof 'c AnyType) + (Rec + R3 + (U (Pairof (Pairof 'w AnyType) R3) + (Pairof + (Pairof 'x AnyType) + (Pairof (Pairof 'y AnyType) R2))))))))))))) + (inv≡ + (Pairof + (Rec + R1 + (U (Pairof Any R1) + (Pairof + (Pairof AnyField a) + (Rec + R2 + (U (List (Pairof 'd AnyType) (Pairof 'e AnyType)) + (Pairof + (Pairof 'b AnyType) + (Pairof + (Pairof 'c AnyType) + (Rec + R3 + (U (Pairof (Pairof 'w AnyType) R3) + (Pairof + (Pairof 'x AnyType) + (Pairof (Pairof 'y AnyType) R2))))))))))) + (Rec + R1 + (U (Pairof Any R1) + (Pairof + (Pairof AnyField a) + (Rec + R2 + (U (List (Pairof 'd AnyType) (Pairof 'e AnyType)) + (Pairof + (Pairof 'b AnyType) + (Pairof (Pairof 'c AnyType) R2))))))))))) (check-same-type - (Invariant (dot :a) ((λdot b c) ((λdot w)) * (λdot x y))* (λdot d e) + (Invariant :a(.b.c(.w)*.x.y)*.d.e ∈ - (dot :a) ((λdot b c))* (λdot d e)) - (Invariant (dot :a) ((λdot b c))* (λdot d e) + :a(.b.c)*.d.e) + (Invariant :a(.b.c)*.d.e ∋ - (dot :a) ((λdot b c) ((λdot w)) * (λdot x y))* (λdot d e))) + :a(.b.c(.w)*.x.y)*.d.e)) +;;; + (check-ann witness-value (Invariants)) ;; No invariants -(check-ann witness-value (Invariants (≡x (_ a) (_ a b c)))) +(check-ann witness-value (Invariants (:a ≡ :a.b.c))) -(check-a-stronger-than-b (Invariants (≡x (_ a) (_ a b c))) +(check-a-stronger-than-b (Invariants (:a ≡ :a.b.c)) (Invariants)) - -(check-a-same-as-b (Invariants (≡x (_ a) (_ a b c))) - (Invariants (≡x (_ a b c) (_ a)))) - -(check-a-stronger-than-b (Invariants (≡x (_) (_ b c)) - (≡x (_) (_ b d))) - (Invariants (≡x (_) (_ b c)))) -(check-a-stronger-than-b (Invariants (≡x (_) (_ b d)) - (≡x (_) (_ b c))) - (Invariants (≡x (_) (_ b c)))) +(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 @@ -129,12 +169,9 @@ ;; 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 (≡x (_) - (_ b d ↙ a b (d)))) - (Invariants (≡x (_) - (_ b d a b d ↙ a b (d))))) +(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))) -(check-a-stronger-than-b (Invariants (≡x (_) - (_ a b c ↙ d (e)))) - (Invariants (≡x (_) - (_ a b c d e))))