Can now translate case to match

This commit is contained in:
William J. Bowman 2015-02-04 18:47:25 -05:00
parent be2fd4a6af
commit 999800d6f1
2 changed files with 64 additions and 27 deletions

71
oll.rkt
View File

@ -152,6 +152,16 @@
;; Generate Coq from Cur: ;; Generate Coq from Cur:
(begin-for-syntax (begin-for-syntax
(define coq-defns (make-parameter ""))
(define (coq-lift-top-level str)
(coq-defns (format "~a~a~n" (coq-defns) str)))
;; TODO: OOps, type-infer doesn't return a cur term but a redex syntax bla
(define (constructor-args syn)
(syntax-parse (type-infer/syn syn)
#:datum-literals (Π :)
[(Π (x:id : t) body)
(cons #'x (constructor-args #'body))]
[_ null]))
(define (output-coq syn) (define (output-coq syn)
(syntax-parse (cur-expand syn) (syntax-parse (cur-expand syn)
;; TODO: Need to add these to a literal set and export it ;; TODO: Need to add these to a literal set and export it
@ -164,20 +174,33 @@
(format "(forall ~a : ~a, ~a)" (syntax-e #'x) (output-coq #'t) (format "(forall ~a : ~a, ~a)" (syntax-e #'x) (output-coq #'t)
(output-coq #'body))] (output-coq #'body))]
[(data ~! n:id (~datum :) t (x*:id (~datum :) t*) ...) [(data ~! n:id (~datum :) t (x*:id (~datum :) t*) ...)
(format "Inductive ~a : ~a :=~n~a." (begin
(coq-lift-top-level
(format "Inductive ~a : ~a :=~a."
(syntax-e #'n) (syntax-e #'n)
(output-coq #'t) (output-coq #'t)
(string-trim
(for/fold ([strs ""]) (for/fold ([strs ""])
([clause (syntax->list #'((x* : t*) ...))]) ([clause (syntax->list #'((x* : t*) ...))])
(syntax-parse clause (syntax-parse clause
[(x (~datum :) t) [(x (~datum :) t)
(format "~a~a : ~a~n| " strs (syntax-e #'x) (format "~a~n| ~a : ~a" strs (syntax-e #'x)
(output-coq #'t))])) (output-coq #'t))]))))
#px"\\s\\| $" "")]
#:left? #f))] [(case e (ec eb) ...)
;; TODO: Add "case". Will be slightly tricky since the syntax is (format "(match ~a with~n~aend)"
;; quite different from Coq. (output-coq #'e)
(for/fold ([strs ""])
([con (syntax->list #'(ec ...))]
[body (syntax->list #'(eb ...))])
(let* ([ids (generate-temporaries (constructor-args con))]
[names (map (compose ~a syntax->datum) ids)])
(format "~a| (~a) => ~a~n" strs
(for/fold ([str (output-coq con)])
([n names])
(format "~a ~a" str n))
(for/fold ([body (output-coq body)])
([n names])
(format "(~a ~a)" body n))))))]
[(real-app e1 e2) [(real-app e1 e2)
(format "(~a ~a)" (output-coq #'e1) (output-coq #'e2))] (format "(~a ~a)" (output-coq #'e1) (output-coq #'e2))]
[e:id (format "~a" (syntax->datum #'e))]))) [e:id (format "~a" (syntax->datum #'e))])))
@ -186,29 +209,41 @@
(syntax-parse syn (syntax-parse syn
[(_ (~optional (~seq #:file file)) body:expr) [(_ (~optional (~seq #:file file)) body:expr)
(parameterize ([current-output-port (if (attribute file) (parameterize ([current-output-port (if (attribute file)
(syntax->datum #'file) (open-output-file (syntax->datum #'file)
(current-output-port))]) #:exists 'replace)
(displayln (output-coq #'body)) (current-output-port))]
#'Type)])) [coq-defns ""])
(define body
(let ([body (output-coq #'body)])
(if (equal? body "")
""
(format "Eval compute in ~a." body))))
(displayln (format "~a~a" (coq-defns) body))
#'(begin))]))
(module+ test (module+ test
(require "stdlib/sugar.rkt") (require "stdlib/sugar.rkt")
(begin-for-syntax (begin-for-syntax
(require rackunit) (require rackunit)
(check-equal? (check-equal?
(format "Inductive nat : Type :=~nz : nat.") (parameterize ([coq-defns ""]) (output-coq #'(data nat : Type (z : nat))) (coq-defns))
(output-coq #'(data nat : Type (z : nat)))) (format "Inductive nat : Type :=~n| z : nat.~n"))
(check-regexp-match (check-regexp-match
"(forall .+ : Type, Type)" "(forall .+ : Type, Type)"
(output-coq #'(-> Type Type))) (output-coq #'(-> Type Type)))
;; TODO: Not sure why these tests are failing. (let ([t (parameterize ([coq-defns ""])
(let ([t (output-coq #'(define-relation (meow gamma term type) (output-coq #'(define-relation (meow gamma term type)
[(g : gamma) (e : term) (t : type) [(g : gamma) (e : term) (t : type)
--------------- T-Bla --------------- T-Bla
(meow g e t)]))]) (meow g e t)]))
(coq-defns))])
(check-regexp-match (check-regexp-match
"Inductive meow : \\(forall temp. : gamma, \\(forall temp. : term, \\(forall temp. : type, Type\\)\\)\\) :=" "Inductive meow : \\(forall temp. : gamma, \\(forall temp. : term, \\(forall temp. : type, Type\\)\\)\\) :="
(first (string-split t "\n"))) (first (string-split t "\n")))
(check-regexp-match (check-regexp-match
"\\| T-Bla : \\(forall g : gamma, \\(forall e : term, \\(forall t : type, \\(\\(\\(meow g\\) e\\) t\\)\\)\\)\\)\\." "\\| T-Bla : \\(forall g : gamma, \\(forall e : term, \\(forall t : type, \\(\\(\\(meow g\\) e\\) t\\)\\)\\)\\)\\."
(second (string-split t "\n")))))) (second (string-split t "\n"))))
(let ([t (output-coq #'(case z (z z) (s (lambda (n : nat) (s n)))))])
(check-regexp-match
"\\(match z with\n\\| \\(z\\) => z\n\\| \\(s .+\\) => \\(\\(fun n : nat => \\(s n\\)\\) .+\\)\nend\\)"
t))))

View File

@ -792,9 +792,11 @@
;; Reflection tools ;; Reflection tools
;; TODO: OOps, type-infer doesn't return a cur term but a redex term
;; wrapped in syntax bla. This is bad.
(define (type-infer/syn syn) (define (type-infer/syn syn)
(let ([t (type-infer/term (cur->datum syn))]) (let ([t (type-infer/term (cur->datum syn))])
(and t (denote syn t)))) (and t (datum->syntax syn t))))
(define (type-check/syn? syn type) (define (type-check/syn? syn type)
(let ([t (type-infer/term (cur->datum syn))]) (let ([t (type-infer/term (cur->datum syn))])