Compare commits

..

10 Commits

Author SHA1 Message Date
William J. Bowman
3af3d8dbe9
Small syntax fixes 2016-01-19 11:20:19 -05:00
William J. Bowman
22404dfe98
Fixed up inferrence rules 2016-01-19 11:12:04 -05:00
William J. Bowman
0e46da74ab
[Broken] rewriting the rest of olly
Rewriting the rest of olly, including the latex and coq generators, and
the define-relation form.
Unfortunately, managed to break parsing somehow.
2016-01-19 11:12:03 -05:00
William J. Bowman
d613b53700
Renamed "nested-expression" syntax to match docs 2016-01-19 11:12:03 -05:00
William J. Bowman
c7aefdb032
Removed Var "abstractions"
Olly uses De Bruijn, but was attempting to use abstractions to allow
changing that. Unfortunately, these were not really abstractions. So
they're now gone.
2016-01-19 11:12:03 -05:00
William J. Bowman
fd52c764da
Fixed bug in define-relation
Previously, define-relation would not accept declarations with types
that did not match syntax-class id
2016-01-19 11:12:02 -05:00
William J. Bowman
fb39a88eac
Converted stlc example to use List for environment 2016-01-19 11:12:02 -05:00
William J. Bowman
9fb4c55799
Fixed binding in olly 2016-01-19 11:12:02 -05:00
William J. Bowman
f0dce3bf92
Fixed syntax-class of non-terminal definitions
Previously, syntax class would accept definitions for which I could not
generate inductive constructors. Changed the syntax class to rule these out.
2016-01-19 11:12:01 -05:00
William J. Bowman
345c12f040
Rewrote define-language
Working on #9 and fixing issues in Olly
2016-01-19 11:12:01 -05:00
31 changed files with 604 additions and 650 deletions

View File

@ -45,10 +45,6 @@ Try it out: open up DrRacket and put the following in the definition area:
(if true (if true
false false
true) true)
(: + (-> Nat Nat Nat))
(define + plus)
(+ z (s z))
``` ```
Try entering the following in the interaction area: Try entering the following in the interaction area:
@ -56,23 +52,6 @@ Try entering the following in the interaction area:
(sub1 (s (s z))) (sub1 (s (s z)))
``` ```
Don't like parenthesis? Use Cur with sweet-expressions:
```racket
#lang sweet-exp cur
require
cur/stdlib/sugar
cur/stdlib/bool
cur/stdlib/nat
if true
false
true
define + plus
{z + s(z)}
```
See the docs: `raco docs cur`. See the docs: `raco docs cur`.
Going further Going further

View File

@ -17,7 +17,7 @@ Edwin C. Brady.
@(define curnel-eval (curnel-sandbox "(require cur/stdlib/nat cur/stdlib/bool cur/stdlib/prop)")) @(define curnel-eval (curnel-sandbox "(require cur/stdlib/nat cur/stdlib/bool cur/stdlib/prop)"))
@defform*[((Type n) @defform*[((Type n)
Type)]{ Type)]{
Define the universe of types at level @racket[n], where @racket[n] is any natural number. Define the universe of types at level @racket[n], where @racket[n] is any natural number.
@racket[Type] is a synonym for @racket[(Type 0)]. Cur is impredicative @racket[Type] is a synonym for @racket[(Type 0)]. Cur is impredicative
in @racket[(Type 0)], although this is likely to change to a more in @racket[(Type 0)], although this is likely to change to a more
@ -33,44 +33,43 @@ restricted impredicative universe.
Type] Type]
} }
@defform[(λ (id : type-expr) body-expr)]{ @defform*[((lambda (id : type-expr) body-expr)
Produces a single-arity procedure, binding the identifier @racket[id] of type (λ (id : type-expr) body-expr))]{
@racket[type-expr] in @racket[body-expr] and in the type of @racket[body-expr]. Produces a single arity procedure, binding the identifier @racket[id] of type @racket[type-expr] in @racket[body-expr] and in the type of
Both @racket[type-expr] and @racket[body-expr] can contain non-curnel forms, @racket[body-expr].
such as macros. Both @racket[type-expr] and @racket[body-expr] can contain non-curnel forms, such as macros.
Currently, Cur will return the underlying representation of a procedure when a Currently, Cur will return the underlying representation of a procedure when a @racket[lambda] is
@racket[λ] is evaluated at the top-level. evaluated at the top-level. Do not rely on this representation.
Do not rely on this representation.
@examples[#:eval curnel-eval @examples[#:eval curnel-eval
(λ (x : Type) x)] (lambda (x : Type) x)]
@examples[#:eval curnel-eval @examples[#:eval curnel-eval
(λ (x : Type) (λ (y : x) y))] (λ (x : Type) (lambda (y : x) y))]
@defform[(#%app procedure argument)]{ @defform[(#%app procedure argument)]{
Applies the single-arity @racket[procedure] to @racket[argument]. Applies the single arity @racket[procedure] to @racket[argument].
} }
@examples[#:eval curnel-eval @examples[#:eval curnel-eval
((λ (x : (Type 1)) x) Type)] ((lambda (x : (Type 1)) x) Type)]
@examples[#:eval curnel-eval @examples[#:eval curnel-eval
(#%app (λ (x : (Type 1)) x) Type)] (#%app (lambda (x : (Type 1)) x) Type)]
} }
@defform[(Π (id : type-expr) body-expr)]{ @defform*[((forall (id : type-expr) body-expr)
Produces a dependent function type, binding the identifier @racket[id] of type (∀ (id : type-expr) body-expr))]{
@racket[type-expr] in @racket[body-expr]. Produces a dependent function type, binding the identifier @racket[id] of type @racket[type-expr] in @racket[body-expr].
@examples[#:eval curnel-eval @examples[#:eval curnel-eval
(Π (x : Type) Type)] (forall (x : Type) Type)]
@examples[#:eval curnel-eval @examples[#:eval curnel-eval
(λ (x : (Π (x : (Type 1)) Type)) (lambda (x : (forall (x : (Type 1)) Type))
(x Type))] (x Type))]
} }
@ -84,35 +83,32 @@ For instance, Cur does not currently perform strict positivity checking.
(data Bool : Type (data Bool : Type
(true : Bool) (true : Bool)
(false : Bool)) (false : Bool))
((λ (x : Bool) x) true) ((lambda (x : Bool) x) true)
(data False : Type) (data False : Type)
(data And : (Π (A : Type) (Π (B : Type) Type)) (data And : (forall (A : Type) (forall (B : Type) Type))
(conj : (Π (A : Type) (Π (B : Type) (Π (a : A) (Π (b : B) ((And A) B))))))) (conj : (forall (A : Type) (forall (B : Type) (forall (a : A) (forall (b : B) ((And A) B)))))))
((((conj Bool) Bool) true) false)] ((((conj Bool) Bool) true) false)]
} }
@defform[(elim inductive-type motive (index ...) (method ...) disc)]{ @defform[(elim type motive-universe)]{
Fold over the term @racket[disc] of the inductively defined type @racket[inductive-type]. Returns the inductive eliminator for @racket[type] where the @racket[motive-universe] is the universe
The @racket[motive] is a function that expects the indices of the inductive of the motive.
type and a term of the inductive type and produces the type that this The eliminator expects the next argument to be the motive, the next @racket[N] arguments to be the methods for
fold returns. each of the @racket[N] constructors of the inductive type @racket[type], the next @racket[P] arguments
The type of @racket[disc] is @racket[(inductive-type index ...)]. to be the parameters @racket[p_0 ... p_P] of the inductive @racket[type], and the final argument to be the term to
@racket[elim] takes one method for each constructor of @racket[inductive-type]. eliminate of type @racket[(type p_0 ... p_P)].
Each @racket[method] expects the arguments for its corresponding constructor,
and the inductive hypotheses generated by recursively eliminating all recursive
arguments of the constructor.
The following example runs @racket[(sub1 (s z))]. The following example runs @racket[(sub1 (s z))].
@examples[#:eval curnel-eval @examples[#:eval curnel-eval
(data Nat : Type (data Nat : Type
(z : Nat) (z : Nat)
(s : (Π (n : Nat) Nat))) (s : (forall (n : Nat) Nat)))
(elim Nat (λ (x : Nat) Nat) (((((elim Nat Type)
() (lambda (x : Nat) Nat))
(z z)
(λ (n : Nat) (λ (IH : Nat) n))) (lambda (n : Nat) (lambda (IH : Nat) n)))
(s z))] (s z))]
} }
@defform[(define id expr)]{ @defform[(define id expr)]{
@ -121,13 +117,11 @@ Binds @racket[id] to the result of @racket[expr].
@examples[#:eval curnel-eval @examples[#:eval curnel-eval
(data Nat : Type (data Nat : Type
(z : Nat) (z : Nat)
(s : (Π (n : Nat) Nat))) (s : (forall (n : Nat) Nat)))
(define sub1 (λ (n : Nat) (define sub1 (lambda (n : Nat)
(elim Nat (λ (x : Nat) Nat) (((((elim Nat Type) (lambda (x : Nat) Nat))
() z)
(z (lambda (n : Nat) (lambda (IH : Nat) n))) n)))
(λ (n : Nat) (λ (IH : Nat) n)))
n)))
(sub1 (s (s z))) (sub1 (s (s z)))
(sub1 (s z)) (sub1 (s z))
(sub1 z)] (sub1 z)]

View File

@ -25,61 +25,61 @@ phase 1 in Cur.}
@examples[ @examples[
(eval:alts (define-syntax-rule (computed-type _) Type) (void)) (eval:alts (define-syntax-rule (computed-type _) Type) (void))
(eval:alts (cur-expand #'(λ (x : (computed-type bla)) x)) (eval:alts (cur-expand #'(lambda (x : (computed-type bla)) x))
(eval:result @racket[#'(λ (x : Type) x)] "" "")) (eval:result @racket[#'(lambda (x : Type) x)] "" ""))
] ]
} }
@defproc[(cur-type-infer [syn syntax?]) @defproc[(type-infer/syn [syn syntax?])
(or/c syntax? #f)]{ (or/c syntax? #f)]{
Returns the type of the Cur term @racket[syn], or @racket[#f] if no type could be inferred. Returns the type of the Cur term @racket[syn], or @racket[#f] if no type could be inferred.
@examples[ @examples[
(eval:alts (cur-type-infer #'(λ (x : Type) x)) (eval:alts (type-infer/syn #'(lambda (x : Type) x))
(eval:result @racket[#'(Π (x : (Type 0)) (Type 0))] "" "")) (eval:result @racket[#'(forall (x : (Type 0)) (Type 0))] "" ""))
(eval:alts (cur-type-infer #'Type) (eval:alts (type-infer/syn #'Type)
(eval:result @racket[#'(Type 1)] "" "")) (eval:result @racket[#'(Type 1)] "" ""))
] ]
} }
@defproc[(cur-type-check? [syn syntax?]) @defproc[(type-check/syn? [syn syntax?])
boolean?]{ boolean?]{
Returns @racket[#t] if the Cur term @racket[syn] is well-typed, or @racket[#f] otherwise. Returns @racket[#t] if the Cur term @racket[syn] is well-typed, or @racket[#f] otherwise.
@examples[ @examples[
(eval:alts (cur-type-check? #'(λ (x : Type) x)) (eval:alts (type-check/syn? #'(lambda (x : Type) x))
(eval:result @racket[#t] "" "")) (eval:result @racket[#t] "" ""))
(eval:alts (cur-type-check? #'Type) (eval:alts (type-check/syn? #'Type)
(eval:result @racket[#t] "" "")) (eval:result @racket[#t] "" ""))
(eval:alts (cur-type-check? #'x) (eval:alts (type-check/syn? #'x)
(eval:result @racket[#f] "" "")) (eval:result @racket[#f] "" ""))
] ]
} }
@defproc[(cur-normalize [syn syntax?]) @defproc[(normalize/syn [syn syntax?])
syntax?]{ syntax?]{
Runs the Cur term @racket[syn] to a value. Runs the Cur term @racket[syn] to a value.
@examples[ @examples[
(eval:alts (cur-normalize #'((λ (x : Type) x) Bool)) (eval:alts (normalize/syn #'((lambda (x : Type) x) Bool))
(eval:result @racket[#'Bool] "" "")) (eval:result @racket[#'Bool] "" ""))
(eval:alts (cur-normalize #'(sub1 (s (s z)))) (eval:alts (normalize/syn #'(sub1 (s (s z))))
(eval:result @racket[#'(s z)] "" "")) (eval:result @racket[#'(s z)] "" ""))
] ]
} }
@defproc[(cur-step [syn syntax?]) @defproc[(step/syn [syn syntax?])
syntax?]{ syntax?]{
Runs the Cur term @racket[syn] for one step. Runs the Cur term @racket[syn] for one step.
@examples[ @examples[
(eval:alts (cur-step #'((λ (x : Type) x) Bool)) (eval:alts (step/syn #'((lambda (x : Type) x) Bool))
(eval:result @racket[#'Bool] "" "")) (eval:result @racket[#'Bool] "" ""))
(eval:alts (cur-step #'(sub1 (s (s z)))) (eval:alts (step/syn #'(sub1 (s (s z))))
(eval:result @racket[#'(elim Nat (λ (x2 : Nat) Nat) (eval:result @racket[#'(((((elim Nat (Type 0))
() (lambda (x2 : Nat) Nat)) z)
(z (λ (x2 : Nat) (λ (ih-n2 : Nat) x2))) (lambda (x2 : Nat) (lambda (ih-n2 : Nat) x2)))
(s (s z)))] "" "")) (s (s z)))] "" ""))
] ]
} }
@ -90,11 +90,11 @@ equal modulo α and β-equivalence.
@examples[ @examples[
(eval:alts (cur-equal? #'(λ (a : Type) a) #'(λ (b : Type) b)) (eval:alts (cur-equal? #'(lambda (a : Type) a) #'(lambda (b : Type) b))
(eval:result @racket[#t] "" "")) (eval:result @racket[#t] "" ""))
(eval:alts (cur-equal? #'((λ (a : Type) a) Bool) #'Bool) (eval:alts (cur-equal? #'((lambda (a : Type) a) Bool) #'Bool)
(eval:result @racket[#t] "" "")) (eval:result @racket[#t] "" ""))
(eval:alts (cur-equal? #'(λ (a : Type) (sub1 (s z))) #'(λ (a : Type) z)) (eval:alts (cur-equal? #'(lambda (a : Type) (sub1 (s z))) #'(lambda (a : Type) z))
(eval:result @racket[#f] "" "")) (eval:result @racket[#f] "" ""))
] ]
} }
@ -106,7 +106,7 @@ Converts @racket[s] to a datum representation of the @tech{curnel form}, after e
@examples[ @examples[
(eval:alts (cur->datum #'(λ (a : Type) a)) (eval:alts (cur-?datum #'(lambda (a : Type) a))
(eval:result @racket['(λ (a : (Unv 0) a))] "" "")) (eval:result @racket['(λ (a : (Unv 0) a))] "" ""))
] ]
} }

View File

@ -7,10 +7,10 @@ Cur has a small standard library, primary for demonstration purposes.
@local-table-of-contents[] @local-table-of-contents[]
@include-section{stdlib/tactics.scrbl}
@include-section{stdlib/sugar.scrbl} @include-section{stdlib/sugar.scrbl}
@include-section{stdlib/bool.scrbl} @include-section{stdlib/bool.scrbl}
@include-section{stdlib/nat.scrbl} @include-section{stdlib/nat.scrbl}
@include-section{stdlib/maybe.scrbl} @include-section{stdlib/maybe.scrbl}
@include-section{stdlib/list.scrbl} @include-section{stdlib/list.scrbl}
@include-section{stdlib/typeclass.scrbl} @include-section{stdlib/typeclass.scrbl}
@include-section{stdlib/tactics.scrbl}

View File

@ -22,7 +22,7 @@ A syntactic form that expands to the inductive eliminator for @racket[Bool]. Thi
@examples[#:eval curnel-eval @examples[#:eval curnel-eval
(if true false true) (if true false true)
(elim Bool (λ (x : Bool) Bool) () (false true) true)] (elim Bool Type (λ (x : Bool) Bool) false true true)]
} }
@defproc[(not [x Bool]) @defproc[(not [x Bool])

View File

@ -21,15 +21,12 @@ This library defines various syntactic extensions making Cur easier to write tha
@defform*[((-> decl decl ... type) @defform*[((-> decl decl ... type)
(→ decl decl ... type) (→ decl decl ... type)
(forall decl decl ... type) (forall decl decl ... type)
(∀ decl decl ... type) (∀ decl decl ... type))
(Π decl decl ... type)
(Pi decl decl ... type))
#:grammar #:grammar
[(decl [(decl
type type
(code:line (identifier : type)))]]{ (code:line (identifier : type)))]]{
A multi-artiy function type that supports dependent and non-dependent type declarations and automatic currying. A multi-artiy function type that supports dependent and non-dependent type declarations and automatic currying.
We provide lots of names for this form, because there are lots of synonyms in the literature.
@examples[#:eval curnel-eval @examples[#:eval curnel-eval
(data And : (-> Type Type Type) (data And : (-> Type Type Type)
@ -62,24 +59,21 @@ Defines multi-arity procedure application via automatic currying.
(conj Bool Bool true false)] (conj Bool Bool true false)]
} }
@defform[(: name type)]{
Declare that the @emph{function} which will be defined as @racket[name] has type @racket[type].
Must precede the definition of @racket[name].
@racket[type] must expand to a function type of the form @racket[(Π (x : t1) t2)]
When used, this form allows omitting the annotations on arguments in the definition @racket[name]
}
@defform*[((define name body) @defform*[((define name body)
(define (name x ...) body) (define (name (x : t) ...) body))]{
(define (name (x : t) ...) body))]{
Like the @racket[define] provided by @racketmodname[cur], but supports Like the @racket[define] provided by @racketmodname[cur], but supports
defining curried functions via @racket[lambda]. defining curried functions via @racket[lambda].
The second form, @racket[(define (name x ...) body)], can only be used when }
a @racket[(: name type)] form appears earlier in the module.
@defform[(elim type motive-result-type e ...)]{
Like the @racket[elim] provided by @racketmodname[cur], but supports
automatically curries the remaining arguments @racket[e ...].
@examples[#:eval curnel-eval @examples[#:eval curnel-eval
(: id (forall (A : Type) (a : A) A)) (elim Bool Type (lambda (x : Bool) Bool)
(define (id A a) a)] false
true
true)]
} }
@defform*[((define-type name type) @defform*[((define-type name type)
@ -172,7 +166,7 @@ Check that expression @racket[e] has type @racket[type], causing a type-error if
} }
@defform[(run syn)]{ @defform[(run syn)]{
Like @racket[cur-normalize], but is a syntactic form to be used in surface syntax. Like @racket[normalize/syn], but is a syntactic form to be used in surface syntax.
Allows a Cur term to be written by computing part of the term from Allows a Cur term to be written by computing part of the term from
another Cur term. another Cur term.
@ -182,7 +176,7 @@ another Cur term.
} }
@defform[(step syn)]{ @defform[(step syn)]{
Like @racket[run], but uses @racket[cur-step] to evaluate only one step and prints intermediate Like @racket[run], but uses @racket[step/syn] to evaluate only one step and prints intermediate
results before returning the result of evaluation. results before returning the result of evaluation.
@examples[#:eval curnel-eval @examples[#:eval curnel-eval

View File

@ -1,6 +1,6 @@
#lang info #lang info
(define collection 'multi) (define collection 'multi)
(define deps '("base" "racket-doc")) (define deps '("base" "racket-doc"))
(define build-deps '("scribble-lib" ("cur-lib" #:version "0.4") "sandbox-lib")) (define build-deps '("scribble-lib" ("cur-lib" #:version "0.2") "sandbox-lib"))
(define pkg-desc "Documentation for \"cur\".") (define pkg-desc "Documentation for \"cur\".")
(define pkg-authors '(wilbowma)) (define pkg-authors '(wilbowma))

View File

@ -26,11 +26,11 @@
(define-language ttL (define-language ttL
(i j k ::= natural) (i j k ::= natural)
(U ::= (Unv i)) (U ::= (Unv i))
(D x c ::= variable-not-otherwise-mentioned) (t e ::= U (λ (x : t) e) x (Π (x : t) t) (e e) (elim D U))
;; Δ (signature). (inductive-name : type ((constructor : type) ...))
;; NB: Δ is a map from a name x to a pair of it's type and a map of constructor names to their types
(Δ ::= (Δ (D : t ((c : t) ...)))) (Δ ::= (Δ (D : t ((c : t) ...))))
(t e ::= U (λ (x : t) e) x (Π (x : t) t) (e e) (D x c ::= variable-not-otherwise-mentioned)
;; (elim inductive-type motive (indices ...) (methods ...) discriminant)
(elim D e (e ...) (e ...) e))
#:binding-forms #:binding-forms
(λ (x : t) e #:refers-to x) (λ (x : t) e #:refers-to x)
(Π (x : t_0) t_1 #:refers-to x)) (Π (x : t_0) t_1 #:refers-to x))
@ -44,8 +44,6 @@
;;; ------------------------------------------------------------------------ ;;; ------------------------------------------------------------------------
;;; Universe typing ;;; Universe typing
;; Universe types
;; aka Axioms A of a PTS
(define-judgment-form ttL (define-judgment-form ttL
#:mode (unv-type I O) #:mode (unv-type I O)
#:contract (unv-type U U) #:contract (unv-type U U)
@ -55,7 +53,6 @@
(unv-type (Unv i_0) (Unv i_1))]) (unv-type (Unv i_0) (Unv i_1))])
;; Universe predicativity rules. Impredicative in (Unv 0) ;; Universe predicativity rules. Impredicative in (Unv 0)
;; aka Rules R of a PTS
(define-judgment-form ttL (define-judgment-form ttL
#:mode (unv-pred I I O) #:mode (unv-pred I I O)
#:contract (unv-pred U U U) #:contract (unv-pred U U U)
@ -108,6 +105,27 @@
[(Δ-union Δ_2 (Δ_1 (x : t any))) [(Δ-union Δ_2 (Δ_1 (x : t any)))
((Δ-union Δ_2 Δ_1) (x : t any))]) ((Δ-union Δ_2 Δ_1) (x : t any))])
;; Returns the inductively defined type that x constructs
;; NB: Depends on clause order
(define-metafunction ttL
Δ-key-by-constructor : Δ x -> x or #f
[(Δ-key-by-constructor (Δ (x : t ((x_0 : t_0) ... (x_c : t_c) (x_1 : t_1) ...))) x_c)
x]
[(Δ-key-by-constructor (Δ (x_1 : t_1 any)) x)
(Δ-key-by-constructor Δ x)]
[(Δ-key-by-constructor Δ x)
#f])
;; Returns the constructor map for the inductively defined type x_D in the signature Δ
(define-metafunction ttL
Δ-ref-constructor-map : Δ x -> ((x : t) ...) or #f
;; NB: Depends on clause order
[(Δ-ref-constructor-map x_D) #f]
[(Δ-ref-constructor-map (Δ (x_D : t_D any)) x_D)
any]
[(Δ-ref-constructor-map (Δ (x_1 : t_1 any)) x_D)
(Δ-ref-constructor-map Δ x_D)])
;; TODO: Should not use Δ-ref-type ;; TODO: Should not use Δ-ref-type
(define-metafunction ttL (define-metafunction ttL
Δ-ref-constructor-type : Δ x x -> t Δ-ref-constructor-type : Δ x x -> t
@ -127,6 +145,14 @@
;; TODO: Mix of pure Redex/escaping to Racket sometimes is getting confusing. ;; TODO: Mix of pure Redex/escaping to Racket sometimes is getting confusing.
;; TODO: Justify, or stop. ;; TODO: Justify, or stop.
;; Return the number of constructors that D has
(define-metafunction ttL
Δ-constructor-count : Δ D -> natural or #f
[(Δ-constructor-count Δ D)
,(length (term (x ...)))
(where (x ...) (Δ-ref-constructors Δ D))]
[(Δ-constructor-count Δ D) #f])
;; NB: Depends on clause order ;; NB: Depends on clause order
(define-metafunction ttL (define-metafunction ttL
sequence-index-of : any (any ...) -> natural sequence-index-of : any (any ...) -> natural
@ -163,31 +189,47 @@
;; TODO: Test ;; TODO: Test
#| TODO: #| TODO:
| This essentially eta-expands t at the type-level. Why is this necessary? Shouldn't it be true | This essentially eta-expands t at the type-level. Why is this necessary? Shouldn't it be true
| that (convert t (Ξ-apply Ξ t))? | that (equivalent t (Ξ-apply Ξ t))?
| Maybe not. t is a lambda whose type is convert to (Ξ-apply Ξ t)? Yes. | Maybe not. t is a lambda whose type is equivalent to (Ξ-apply Ξ t)? Yes.
|# |#
(define-metafunction tt-ctxtL (define-metafunction tt-ctxtL
Ξ-apply : Ξ t -> t Ξ-apply : Ξ t -> t
[(Ξ-apply hole t) t] [(Ξ-apply hole t) t]
[(Ξ-apply (Π (x : t) Ξ) t_0) (Ξ-apply Ξ (t_0 x))]) [(Ξ-apply (Π (x : t) Ξ) t_0) (Ξ-apply Ξ (t_0 x))])
;; Compose multiple telescopes into a single telescope:
(define-metafunction tt-ctxtL
Ξ-compose : Ξ Ξ ... -> Ξ
[(Ξ-compose Ξ) Ξ]
[(Ξ-compose Ξ_0 Ξ_1 Ξ_rest ...)
(Ξ-compose (in-hole Ξ_0 Ξ_1) Ξ_rest ...)])
;; Compute the number of arguments in a Ξ ;; Compute the number of arguments in a Ξ
(define-metafunction tt-ctxtL (define-metafunction tt-ctxtL
Ξ-length : Ξ -> natural Ξ-length : Ξ -> natural
[(Ξ-length hole) 0] [(Ξ-length hole) 0]
[(Ξ-length (Π (x : t) Ξ)) ,(add1 (term (Ξ-length Ξ)))]) [(Ξ-length (Π (x : t) Ξ)) ,(add1 (term (Ξ-length Ξ)))])
;; Compute the number of applications in a Θ
(define-metafunction tt-ctxtL
Θ-length : Θ -> natural
[(Θ-length hole) 0]
[(Θ-length (Θ e)) ,(add1 (term (Θ-length Θ)))])
;; Convert an apply context to a sequence of terms
(define-metafunction tt-ctxtL
Θ->list : Θ -> (e ...)
[(Θ->list hole) ()]
[(Θ->list (Θ e))
(e_r ... e)
(where (e_r ...) (Θ->list Θ))])
(define-metafunction tt-ctxtL (define-metafunction tt-ctxtL
list->Θ : (e ...) -> Θ list->Θ : (e ...) -> Θ
[(list->Θ ()) hole] [(list->Θ ()) hole]
[(list->Θ (e e_r ...)) [(list->Θ (e e_r ...))
(in-hole (list->Θ (e_r ...)) (hole e))]) (in-hole (list->Θ (e_r ...)) (hole e))])
(define-metafunction tt-ctxtL
apply : e e ... -> e
[(apply e_f e ...)
(in-hole (list->Θ (e ...)) e_f)])
;; Reference an expression in Θ by index; index 0 corresponds to the the expression applied to a hole. ;; Reference an expression in Θ by index; index 0 corresponds to the the expression applied to a hole.
(define-metafunction tt-ctxtL (define-metafunction tt-ctxtL
Θ-ref : Θ natural -> e or #f Θ-ref : Θ natural -> e or #f
@ -209,6 +251,15 @@
[(Δ-ref-parameter-Ξ Δ x) [(Δ-ref-parameter-Ξ Δ x)
#f]) #f])
;; Return the number of parameters of D
(define-metafunction tt-ctxtL
Δ-parameter-count : Δ D -> natural or #f
[(Δ-parameter-count Δ D)
(Ξ-length Ξ)
(where Ξ (Δ-ref-parameter-Ξ Δ D))]
[(Δ-parameter-count Δ D)
#f])
;; Returns the telescope of the arguments for the constructor x_ci of the inductively defined type x_D ;; Returns the telescope of the arguments for the constructor x_ci of the inductively defined type x_D
(define-metafunction tt-ctxtL (define-metafunction tt-ctxtL
Δ-constructor-telescope : Δ x x -> Ξ Δ-constructor-telescope : Δ x x -> Ξ
@ -226,6 +277,21 @@
(where (in-hole Ξ (in-hole Θ x_D)) (where (in-hole Ξ (in-hole Θ x_D))
(Δ-ref-constructor-type Δ x_D x_ci))]) (Δ-ref-constructor-type Δ x_D x_ci))])
;; Inner loop for Δ-constructor-noninductive-telescope
(define-metafunction tt-ctxtL
noninductive-loop : x Φ -> Φ
[(noninductive-loop x_D hole) hole]
[(noninductive-loop x_D (Π (x : (in-hole Φ (in-hole Θ x_D))) Φ_1))
(noninductive-loop x_D Φ_1)]
[(noninductive-loop x_D (Π (x : t) Φ_1))
(Π (x : t) (noninductive-loop x_D Φ_1))])
;; Returns the noninductive arguments to the constructor x_ci of the inductively defined type x_D
(define-metafunction tt-ctxtL
Δ-constructor-noninductive-telescope : Δ x x -> Ξ
[(Δ-constructor-noninductive-telescope Δ x_D x_ci)
(noninductive-loop x_D (Δ-constructor-telescope Δ x_D x_ci))])
;; Inner loop for Δ-constructor-inductive-telescope ;; Inner loop for Δ-constructor-inductive-telescope
;; NB: Depends on clause order ;; NB: Depends on clause order
(define-metafunction tt-ctxtL (define-metafunction tt-ctxtL
@ -254,6 +320,36 @@
(hypotheses-loop x_D t_P Φ_1)) (hypotheses-loop x_D t_P Φ_1))
(where x_h ,(variable-not-in (term (x_D t_P any_0)) 'x-ih))]) (where x_h ,(variable-not-in (term (x_D t_P any_0)) 'x-ih))])
;; Returns the inductive hypotheses required for the elimination method of constructor x_ci for
;; inductive type x_D, when eliminating with motive t_P.
(define-metafunction tt-ctxtL
Δ-constructor-inductive-hypotheses : Δ x x t -> Ξ
[(Δ-constructor-inductive-hypotheses Δ x_D x_ci t_P)
(hypotheses-loop x_D t_P (Δ-constructor-inductive-telescope Δ x_D x_ci))])
(define-metafunction tt-ctxtL
Δ-constructor-method-telescope : Δ x x t -> Ξ
[(Δ-constructor-method-telescope Δ x_D x_ci t_P)
(Π (x_mi : (in-hole Ξ_a (in-hole Ξ_h ((in-hole Θ_p t_P) (Ξ-apply Ξ_a x_ci)))))
hole)
(where Θ_p (Δ-constructor-parameters Δ x_D x_ci))
(where Ξ_a (Δ-constructor-telescope Δ x_D x_ci))
(where Ξ_h (Δ-constructor-inductive-hypotheses Δ x_D x_ci t_P))
(where x_mi ,(variable-not-in (term (t_P Δ)) 'x-mi))])
;; fold Ξ-compose over map Δ-constructor-method-telescope over the list of constructors
(define-metafunction tt-ctxtL
method-loop : Δ x t (x ...) -> Ξ
[(method-loop Δ x_D t_P ()) hole]
[(method-loop Δ x_D t_P (x_0 x_rest ...))
(Ξ-compose (Δ-constructor-method-telescope Δ x_D x_0 t_P) (method-loop Δ x_D t_P (x_rest ...)))])
;; Returns the telescope of all methods required to eliminate the type x_D with motive t_P
(define-metafunction tt-ctxtL
Δ-methods-telescope : Δ x t -> Ξ
[(Δ-methods-telescope Δ x_D t_P)
(method-loop Δ x_D t_P (Δ-ref-constructors Δ x_D))])
;; Computes the type of the eliminator for the inductively defined type x_D with a motive whose result ;; Computes the type of the eliminator for the inductively defined type x_D with a motive whose result
;; is in universe U. ;; is in universe U.
;; ;;
@ -269,40 +365,29 @@
;; Ξ_P*D is the telescope of the parameters of x_D and ;; Ξ_P*D is the telescope of the parameters of x_D and
;; the witness of type x_D (applied to the parameters) ;; the witness of type x_D (applied to the parameters)
;; Ξ_m is the telescope of the methods for x_D ;; Ξ_m is the telescope of the methods for x_D
;; Returns the inductive hypotheses required for the elimination method of constructor c_i for
;; inductive type D, when eliminating with motive t_P.
(define-metafunction tt-ctxtL (define-metafunction tt-ctxtL
Δ-constructor-inductive-hypotheses : Δ D c t -> Ξ Δ-elim-type : Δ x U -> t
[(Δ-constructor-inductive-hypotheses Δ D c_i t_P) [(Δ-elim-type Δ x_D U)
(hypotheses-loop D t_P (Δ-constructor-inductive-telescope Δ D c_i))]) (Π (x_P : (in-hole Ξ_P*D U))
;; The methods Ξ_m for each constructor of type x_D
;; Returns the type of the method corresponding to c_i (in-hole Ξ_m
(define-metafunction tt-ctxtL ;; And finally, the parameters and discriminant
Δ-constructor-method-type : Δ D c t -> t (in-hole Ξ_P*D
[(Δ-constructor-method-type Δ D c_i t_P) ;; The result is (P a ... (x_D a ...)), i.e., the motive
(in-hole Ξ_a (in-hole Ξ_h ((in-hole Θ_p t_P) (Ξ-apply Ξ_a c_i)))) ;; applied to the paramters and discriminant
(where Θ_p (Δ-constructor-parameters Δ D c_i)) (Ξ-apply Ξ_P*D x_P))))
(where Ξ_a (Δ-constructor-telescope Δ D c_i)) ;; Get the parameters of x_D
(where Ξ_h (Δ-constructor-inductive-hypotheses Δ D c_i t_P))]) (where Ξ (Δ-ref-parameter-Ξ Δ x_D))
(define-metafunction tt-ctxtL
Δ-method-types : Δ D e -> (t ...)
[(Δ-method-types Δ D e)
,(map (lambda (c) (term (Δ-constructor-method-type Δ D ,c e))) (term (c ...)))
(where (c ...) (Δ-ref-constructors Δ D))])
(define-metafunction tt-ctxtL
Δ-motive-type : Δ D U -> t
[(Δ-motive-type Δ D U)
(in-hole Ξ_P*D U)
(where Ξ (Δ-ref-parameter-Ξ Δ D))
;; A fresh name to bind the discriminant ;; A fresh name to bind the discriminant
(where x ,(variable-not-in (term (Δ D Ξ)) 'x-D)) (where x ,(variable-not-in (term (Δ Γ x_D Ξ)) 'x-D))
;; The telescope (∀ a -> ... -> (D a ...) hole), i.e., ;; The telescope (∀ a -> ... -> (D a ...) hole), i.e.,
;; of the indices and the inductive type applied to the ;; of the parameters and the inductive type applied to the
;; indices ;; parameters
(where Ξ_P*D (in-hole Ξ (Π (x : (Ξ-apply Ξ D)) hole)))]) (where Ξ_P*D (in-hole Ξ (Π (x : (Ξ-apply Ξ x_D)) hole)))
;; A fresh name for the motive
(where x_P ,(variable-not-in (term (Δ Γ x_D Ξ Ξ_P*D x)) 'x-P))
;; The types of the methods for this inductive.
(where Ξ_m (Δ-methods-telescope Δ x_D x_P))])
;;; ------------------------------------------------------------------------ ;;; ------------------------------------------------------------------------
;;; Dynamic semantics ;;; Dynamic semantics
@ -310,21 +395,16 @@
;;; inductively defined type x with a motive whose result is in universe U ;;; inductively defined type x with a motive whose result is in universe U
(define-extended-language tt-redL tt-ctxtL (define-extended-language tt-redL tt-ctxtL
(v ::= x U (Π (x : t) t) (λ (x : t) t) (in-hole Θv c)) ;; NB: (in-hole Θv (elim x U)) is only a value when it's a partially applied elim. However,
(Θv ::= hole (Θv v)) ;; determining whether or not it is partially applied cannot be done with the grammar alone.
(C-elim ::= (elim D t_P (e_i ...) (e_m ...) hole)) (v ::= x U (Π (x : t) t) (λ (x : t) t) (elim x U) (in-hole Θv x) (in-hole Θv (elim x U)))
;; call-by-value (Θv ::= hole (Θv v))
(E ::= hole (E e) (v E) ;; call-by-value, plus reduce under Π (helps with typing checking)
(elim D e (e ...) (v ... E e ...) e) (E ::= hole (E e) (v E) (Π (x : v) E) (Π (x : E) e)))
(elim D e (e ...) (v ...) E)
;; reduce under Π (helps with typing checking)
;; TODO: Should be done in conversion judgment
(Π (x : v) E) (Π (x : E) e)))
(define Θv? (redex-match? tt-redL Θv)) (define Θv? (redex-match? tt-redL Θv))
(define E? (redex-match? tt-redL E)) (define E? (redex-match? tt-redL E))
(define v? (redex-match? tt-redL v)) (define v? (redex-match? tt-redL v))
#| #|
| The elim form must appear applied like so: | The elim form must appear applied like so:
| (elim D U v_P m_0 ... m_i m_j ... m_n p ... (c_i a ...)) | (elim D U v_P m_0 ... m_i m_j ... m_n p ... (c_i a ...))
@ -340,6 +420,75 @@
| |
| Using contexts, this appears as (in-hole Θ ((elim D U) v_P)) | Using contexts, this appears as (in-hole Θ ((elim D U) v_P))
|# |#
;;; NB: Next 3 meta-function Assume of Θ n constructors, j parameters, n+j+1-th element is discriminant
;; Given the apply context Θ in which an elimination of D with motive
;; v of type U appears, extract the parameters p ... from Θ.
(define-metafunction tt-redL
elim-parameters : Δ D Θ -> Θ
[(elim-parameters Δ D Θ)
;; Drop the methods, take the parameters
(list->Θ
,(take
(drop (term (Θ->list Θ)) (term (Δ-constructor-count Δ D)))
(term (Δ-parameter-count Δ D))))])
;; Given the apply context Θ in which an elimination of D with motive
;; v of type U appears, extract the methods m_0 ... m_n from Θ.
(define-metafunction tt-redL
elim-methods : Δ D Θ -> Θ
[(elim-methods Δ D Θ)
;; Take the methods, one for each constructor
(list->Θ
,(take
(term (Θ->list Θ))
(term (Δ-constructor-count Δ D))))])
;; Given the apply context Θ in which an elimination of D with motive
;; v of type U appears, extract the discriminant (c_i a ...) from Θ.
(define-metafunction tt-redL
elim-discriminant : Δ D Θ -> e
[(elim-discriminant Δ D Θ)
;; Drop the methods, the parameters, and take the last element
,(car
(drop
(drop (term (Θ->list Θ)) (term (Δ-constructor-count Δ D)))
(term (Δ-parameter-count Δ D))))])
;; Check that Θ is valid and ready to be evaluated as the arguments to an elim.
;; has length m = n + j + 1 and D has n constructors and j parameters,
;; and the 1 represents the discriminant.
;; discharges assumption for previous 3 meta-functions
(define-metafunction tt-redL
Θ-valid : Δ D Θ -> #t or #f
[(Θ-valid Δ D Θ)
#t
(where natural_m (Θ-length Θ))
(where natural_n (Δ-constructor-count Δ D))
(where natural_j (Δ-parameter-count Δ D))
(side-condition (= (+ (term natural_n) (term natural_j) 1) (term natural_m)))
;; As Cur allows reducing (through reflection) open terms,
;; check that the discriminant is a canonical form so that
;; reduction can proceed; otherwise not valid.
(where (in-hole Θ_i c_i) (elim-discriminant Δ D Θ))
(where D (Δ-key-by-constructor Δ c_i))]
[(Θ-valid Δ D Θ) #f])
(module+ test
(require rackunit)
(check-equal?
(term (Θ-length (((hole (s zero)) (λ (x : nat) (λ (ih-x : nat) (s (s x))))) zero)))
3)
(check-true
(term
(Θ-valid
(( (nat : (Unv 0) ((zero : nat) (s : (Π (x : nat) nat))))) (bool : (Unv 0) ((true : bool) (false : bool))))
nat
(((hole (s zero)) (λ (x : nat) (λ (ih-x : nat) (s (s x))))) zero)))))
(define-metafunction tt-ctxtL (define-metafunction tt-ctxtL
is-inductive-argument : Δ D t -> #t or #f is-inductive-argument : Δ D t -> #t or #f
;; Think this only works in call-by-value. A better solution would ;; Think this only works in call-by-value. A better solution would
@ -353,34 +502,39 @@
;; x_ci for x_D, for each inductively smaller term t_i of type (in-hole Θ_p x_D) inside Θ_i, ;; x_ci for x_D, for each inductively smaller term t_i of type (in-hole Θ_p x_D) inside Θ_i,
;; generate: (elim x_D U t_P Θ_m ... Θ_p ... t_i) ;; generate: (elim x_D U t_P Θ_m ... Θ_p ... t_i)
;; TODO TTEESSSSSTTTTTTTT ;; TODO TTEESSSSSTTTTTTTT
(define-metafunction tt-redL (define-metafunction tt-ctxtL
Δ-inductive-elim : Δ D C-elim Θ -> Θ Δ-inductive-elim : Δ x U t Θ Θ Θ -> Θ
;; NB: If metafunction fails, recursive ;; NB: If metafunction fails, recursive
;; NB: elimination will be wrong. This will introduced extremely sublte bugs, ;; NB: elimination will be wrong. This will introduced extremely sublte bugs,
;; NB: inconsistency, failure of type safety, and other bad things. ;; NB: inconsistency, failure of type safety, and other bad things.
;; NB: It should be tested and audited thoroughly ;; NB: It should be tested and audited thoroughly
[(Δ-inductive-elim any ... hole) [(Δ-inductive-elim Δ x_D U t_P Θ_p Θ_m (Θ_i t_i))
hole] ((Δ-inductive-elim Δ x_D U t_P Θ_p Θ_m Θ_i)
[(Δ-inductive-elim Δ D C-elim (Θ_c t_i)) (in-hole ((in-hole Θ_p Θ_m) t_i) ((elim x_D U) t_P)))
((Δ-inductive-elim Δ D C-elim Θ_c) (side-condition (term (is-inductive-argument Δ x_D t_i)))]
(in-hole C-elim t_i)) [(Δ-inductive-elim Δ x_D U t_P Θ_p Θ_m (Θ_i t_i))
(side-condition (term (is-inductive-argument Δ D t_i)))] (Δ-inductive-elim Δ x_D U t_P Θ_p Θ_m Θ_i)]
[(Δ-inductive-elim any ... (Θ_c t_i)) [(Δ-inductive-elim Δ x_D U t_P Θ_p Θ_m hole)
(Δ-inductive-elim any ... Θ_c)]) hole])
(define tt--> (define tt-->
(reduction-relation tt-redL (reduction-relation tt-redL
(--> (Δ (in-hole E ((λ (x : t_0) t_1) t_2))) (--> (Δ (in-hole E ((λ (x : t_0) t_1) t_2)))
(Δ (in-hole E (subst t_1 x t_2))) (Δ (in-hole E (subst t_1 x t_2)))
-->β) -->β)
(--> (Δ (in-hole E (elim D e_motive (e_i ...) (v_m ...) (in-hole Θv_c c)))) (--> (Δ (in-hole E (in-hole Θv ((elim D U) v_P))))
(Δ (in-hole E (in-hole Θ_mi v_mi))) (Δ (in-hole E (in-hole Θ_r (in-hole Θv_i v_mi))))
;; Find the method for constructor c_i, relying on the order of the arguments. ;; Check that Θv is valid to avoid capturing other things
(where natural (Δ-constructor-index Δ D c)) (side-condition (term (Θ-valid Δ D Θv)))
(where v_mi ,(list-ref (term (v_m ...)) (term natural))) ;; Split Θv into its components: the paramters Θv_P for x_D, the methods Θv_m for x_D, and
;; the discriminant: the constructor c_i applied to its argument Θv_i
(where Θv_p (elim-parameters Δ D Θv))
(where Θv_m (elim-methods Δ D Θv))
(where (in-hole Θv_i c_i) (elim-discriminant Δ D Θv))
;; Find the method for constructor x_ci, relying on the order of the arguments.
(where v_mi (Θ-ref Θv_m (Δ-constructor-index Δ D c_i)))
;; Generate the inductive recursion ;; Generate the inductive recursion
(where Θ_ih (Δ-inductive-elim Δ D (elim D e_motive (e_i ...) (v_m ...) hole) Θv_c)) (where Θ_r (Δ-inductive-elim Δ D U v_P Θv_p Θv_m Θv_i))
(where Θ_mi (in-hole Θ_ih Θv_c))
-->elim))) -->elim)))
(define-metafunction tt-redL (define-metafunction tt-redL
@ -396,6 +550,16 @@
(where (_ e_r) (where (_ e_r)
,(car (apply-reduction-relation* tt--> (term (Δ e)) #:cache-all? #t)))]) ,(car (apply-reduction-relation* tt--> (term (Δ e)) #:cache-all? #t)))])
(define-judgment-form tt-redL
#:mode (equivalent I I I)
#:contract (equivalent Δ t t)
[(where t_2 (reduce Δ t_0))
(where t_3 (reduce Δ t_1))
(side-condition (α-equivalent? t_2 t_3))
----------------- "≡-αβ"
(equivalent Δ t_0 t_1)])
;;; ------------------------------------------------------------------------ ;;; ------------------------------------------------------------------------
;;; Type checking and synthesis ;;; Type checking and synthesis
@ -405,24 +569,6 @@
(Γ ::= (Γ x : t))) (Γ ::= (Γ x : t)))
(define Γ? (redex-match? tt-typingL Γ)) (define Γ? (redex-match? tt-typingL Γ))
(define-judgment-form tt-typingL
#:mode (convert I I I I)
#:contract (convert Δ Γ t t)
[(side-condition ,(<= (term i_0) (term i_1)))
----------------- "≼-Unv"
(convert Δ Γ (Unv i_0) (Unv i_1))]
[(where t_2 (reduce Δ t_0))
(where t_3 (reduce Δ t_1))
(side-condition (α-equivalent? t_2 t_3))
----------------- "≼-αβ"
(convert Δ Γ t_0 t_1)]
[(convert Δ (Γ x : t_0) t_1 t_2)
----------------- "≼-Π"
(convert Δ Γ (Π (x : t_0) t_1) (Π (x : t_0) t_2))])
(define-metafunction tt-typingL (define-metafunction tt-typingL
Γ-union : Γ Γ -> Γ Γ-union : Γ Γ -> Γ
[(Γ-union Γ ) Γ] [(Γ-union Γ ) Γ]
@ -541,22 +687,16 @@
----------------- "DTR-Application" ----------------- "DTR-Application"
(type-infer Δ Γ (e_0 e_1) t_3)] (type-infer Δ Γ (e_0 e_1) t_3)]
[(type-check Δ Γ e_c (apply D e_i ...)) [(where t (Δ-elim-type Δ D U))
(type-infer Δ Γ t U_e)
(type-infer Δ Γ e_motive (name t_motive (in-hole Ξ U)))
(convert Δ Γ t_motive (Δ-motive-type Δ D U))
(where (t_m ...) (Δ-method-types Δ D e_motive))
(type-check Δ Γ e_m t_m) ...
----------------- "DTR-Elim_D" ----------------- "DTR-Elim_D"
(type-infer Δ Γ (elim D e_motive (e_i ...) (e_m ...) e_c) (type-infer Δ Γ (elim D U) t)])
(apply e_motive e_i ... e_c))])
(define-judgment-form tt-typingL (define-judgment-form tt-typingL
#:mode (type-check I I I I) #:mode (type-check I I I I)
#:contract (type-check Δ Γ e t) #:contract (type-check Δ Γ e t)
[(type-infer Δ Γ e t_0) [(type-infer Δ Γ e t_0)
(convert Δ Γ t t_0) (equivalent Δ t t_0)
----------------- "DTR-Check" ----------------- "DTR-Check"
(type-check Δ Γ e t)]) (type-check Δ Γ e t)])

View File

@ -2,7 +2,7 @@
;; This module just provide module language sugar over the redex model. ;; This module just provide module language sugar over the redex model.
(require (require
(except-in "redex-core.rkt" apply) "redex-core.rkt"
redex/reduction-semantics redex/reduction-semantics
racket/provide-syntax racket/provide-syntax
(for-syntax (for-syntax
@ -11,7 +11,7 @@
racket/syntax racket/syntax
(except-in racket/provide-transform export) (except-in racket/provide-transform export)
racket/require-transform racket/require-transform
(except-in "redex-core.rkt" apply) "redex-core.rkt"
redex/reduction-semantics)) redex/reduction-semantics))
(provide (provide
;; Basic syntax ;; Basic syntax
@ -30,10 +30,10 @@
[dep-provide provide] [dep-provide provide]
[dep-require require] [dep-require require]
[dep-lambda λ] [dep-lambda lambda]
[dep-app #%app] [dep-app #%app]
[dep-forall Π] [dep-forall forall]
[dep-inductive data] [dep-inductive data]
@ -60,10 +60,10 @@
(all-from-out racket/syntax) (all-from-out racket/syntax)
cur->datum cur->datum
cur-expand cur-expand
cur-type-infer type-infer/syn
cur-type-check? type-check/syn?
cur-normalize normalize/syn
cur-step step/syn
cur-equal?)) cur-equal?))
(begin-for-syntax (begin-for-syntax
@ -177,11 +177,10 @@
[e (parameterize ([gamma (extend-Γ/term gamma x t)]) [e (parameterize ([gamma (extend-Γ/term gamma x t)])
(cur->datum #'e))]) (cur->datum #'e))])
(term (,(syntax->datum #'b) (,x : ,t) ,e)))] (term (,(syntax->datum #'b) (,x : ,t) ,e)))]
[(elim D motive (i ...) (m ...) d) [(elim t1 t2)
(term (elim ,(cur->datum #'D) ,(cur->datum #'motive) (let* ([t1 (cur->datum #'t1)]
,(map cur->datum (syntax->list #'(i ...))) [t2 (cur->datum #'t2)])
,(map cur->datum (syntax->list #'(m ...))) (term (elim ,t1 ,t2)))]
,(cur->datum #'d)))]
[(#%app e1 e2) [(#%app e1 e2)
(term (,(cur->datum #'e1) ,(cur->datum #'e2)))])))) (term (,(cur->datum #'e1) ,(cur->datum #'e2)))]))))
(unless (or (inner-expand?) (type-infer/term reified-term)) (unless (or (inner-expand?) (type-infer/term reified-term))
@ -225,29 +224,29 @@
;; Reflection tools ;; Reflection tools
(define (cur-normalize syn) (define (normalize/syn syn)
(datum->cur (datum->cur
syn syn
(eval-cur syn))) (eval-cur syn)))
(define (cur-step syn) (define (step/syn syn)
(datum->cur (datum->cur
syn syn
(term (step ,(delta) ,(subst-bindings (cur->datum syn)))))) (term (step ,(delta) ,(subst-bindings (cur->datum syn))))))
;; Are these two terms equivalent in type-systems internal equational reasoning? ;; Are these two terms equivalent in type-systems internal equational reasoning?
(define (cur-equal? e1 e2) (define (cur-equal? e1 e2)
(and (judgment-holds (convert ,(delta) ,(gamma) ,(eval-cur e1) ,(eval-cur e2))) #t)) (and (judgment-holds (equivalent ,(delta) ,(eval-cur e1) ,(eval-cur e2))) #t))
;; TODO: Document local-env ;; TODO: Document local-env
(define (cur-type-infer syn #:local-env [env '()]) (define (type-infer/syn syn #:local-env [env '()])
(parameterize ([gamma (for/fold ([gamma (gamma)]) (parameterize ([gamma (for/fold ([gamma (gamma)])
([(x t) (in-dict env)]) ([(x t) (in-dict env)])
(extend-Γ/syn (thunk gamma) x t))]) (extend-Γ/syn (thunk gamma) x t))])
(let ([t (type-infer/term (eval-cur syn))]) (let ([t (type-infer/term (eval-cur syn))])
(and t (datum->cur syn t))))) (and t (datum->cur syn t)))))
(define (cur-type-check? syn type) (define (type-check/syn? syn type)
(type-check/term? (eval-cur syn) (eval-cur type))) (type-check/term? (eval-cur syn) (eval-cur type)))
;; Takes a Cur term syn and an arbitrary number of identifiers ls. The cur term is ;; Takes a Cur term syn and an arbitrary number of identifiers ls. The cur term is
@ -411,9 +410,8 @@
;; ;;
;; TODO: Can these be simplified further? ;; TODO: Can these be simplified further?
(define-syntax (dep-lambda syn) (define-syntax (dep-lambda syn)
(syntax-parse syn (syntax-case syn (:)
#:datum-literals (:) [(_ (x : t) e)
[(_ (x:id : t) e)
(syntax->curnel-syntax (syntax->curnel-syntax
(quasisyntax/loc syn (λ (x : t) e)))])) (quasisyntax/loc syn (λ (x : t) e)))]))
@ -424,32 +422,30 @@
(quasisyntax/loc syn (#%app e1 e2)))])) (quasisyntax/loc syn (#%app e1 e2)))]))
(define-syntax (dep-forall syn) (define-syntax (dep-forall syn)
(syntax-parse syn (syntax-case syn (:)
#:datum-literals (:) [(_ (x : t) e)
[(_ (x:id : t) e)
(syntax->curnel-syntax (syntax->curnel-syntax
(quasisyntax/loc syn (Π (x : t) e)))])) (quasisyntax/loc syn (Π (x : t) e)))]))
(define-syntax (Type syn) (define-syntax (Type syn)
(syntax-parse syn (syntax-case syn ()
[(_ i:nat) [(_ i)
(syntax->curnel-syntax (syntax->curnel-syntax
(quasisyntax/loc syn (Unv i)))] (quasisyntax/loc syn (Unv i)))]
[_ (quasisyntax/loc syn (Type 0))])) [_ (quasisyntax/loc syn (Type 0))]))
(define-syntax (dep-inductive syn) (define-syntax (dep-inductive syn)
(syntax-parse syn (syntax-case syn (:)
#:datum-literals (:) [(_ i : ti (x1 : t1) ...)
[(_ i:id : ti (x1:id : t1) ...)
(begin (begin
(extend-Δ/syn! delta #'i #'ti #'((x1 : t1) ...)) (extend-Δ/syn! delta #'i #'ti #'((x1 : t1) ...))
#'(void))])) #'(void))]))
(define-syntax (dep-elim syn) (define-syntax (dep-elim syn)
(syntax-parse syn (syntax-case syn ()
[(_ D:id motive (i ...) (m ...) e) [(_ D T)
(syntax->curnel-syntax (syntax->curnel-syntax
(quasisyntax/loc syn (elim D motive (i ...) (m ...) e)))])) (quasisyntax/loc syn (elim D T)))]))
(define-syntax-rule (dep-void) (void)) (define-syntax-rule (dep-void) (void))

View File

@ -1,2 +1,2 @@
#lang s-exp syntax/module-reader #lang s-exp syntax/module-reader
cur cur/cur

View File

@ -1,16 +1,11 @@
#lang s-exp "main.rkt" #lang s-exp "cur.rkt"
;; Olly: The OTT-Like LibrarY ;; Olly: The OTT-Like LibrarY
;; TODO: Automagically create a parser from bnf grammar ;; TODO: Automagically create a parser from bnf grammar
(require (require
"stdlib/sugar.rkt" "stdlib/sugar.rkt"
"stdlib/nat.rkt" "stdlib/nat.rkt"
;; TODO: "real-"? More like "curnel-" ;; TODO: "real-"? More like "curnel-"
(only-in (only-in "cur.rkt" [#%app real-app] [elim real-elim] [forall real-forall] [lambda real-lambda]))
"main.rkt"
[#%app real-app]
[elim real-elim]
[Π real-forall]
[λ real-lambda]))
(provide (provide
define-relation define-relation
@ -32,7 +27,7 @@
(coq-defns (format "~a~a~n" (coq-defns) str))) (coq-defns (format "~a~a~n" (coq-defns) str)))
(define (constructor-args syn) (define (constructor-args syn)
(syntax-parse (cur-type-infer syn) (syntax-parse (type-infer/syn syn)
#:datum-literals (Π :) #:datum-literals (Π :)
[(Π (x:id : t) body) [(Π (x:id : t) body)
(cons #'x (constructor-args #'body))] (cons #'x (constructor-args #'body))]
@ -95,18 +90,8 @@
(cur->coq #'t))])))) (cur->coq #'t))]))))
"")] "")]
[(Type i) "Type"] [(Type i) "Type"]
[(real-elim var:id motive (i ...) (m ...) d) [(real-elim var t)
(format (format "~a_rect" (cur->coq #'var))]
"(~a_rect ~a~a~a ~a)"
(cur->coq #'var)
(cur->coq #'motive)
(for/fold ([strs ""])
([m (syntax->list #'(m ...))])
(format "~a ~a" strs (cur->coq m)))
(for/fold ([strs ""])
([i (syntax->list #'(i ...))])
(format "~a ~a" strs (cur->coq i)))
(cur->coq #'d))]
[(real-app e1 e2) [(real-app e1 e2)
(format "(~a ~a)" (cur->coq #'e1) (cur->coq #'e2))] (format "(~a ~a)" (cur->coq #'e1) (cur->coq #'e2))]
[e:id (sanitize-id (format "~a" (syntax->datum #'e)))]))) [e:id (sanitize-id (format "~a" (syntax->datum #'e)))])))

View File

@ -1,4 +1,4 @@
#lang s-exp "../main.rkt" #lang s-exp "../cur.rkt"
(require "sugar.rkt") (require "sugar.rkt")
(provide Bool true false if not and or) (provide Bool true false if not and or)

View File

@ -1,4 +1,4 @@
#lang s-exp "../main.rkt" #lang s-exp "../cur.rkt"
(require (require
"nat.rkt" "nat.rkt"
"maybe.rkt" "maybe.rkt"

View File

@ -1,4 +1,4 @@
#lang s-exp "../main.rkt" #lang s-exp "../cur.rkt"
(require "sugar.rkt") (require "sugar.rkt")
(provide Maybe none some some/i) (provide Maybe none some some/i)
@ -9,5 +9,5 @@
(define-syntax (some/i syn) (define-syntax (some/i syn)
(syntax-case syn () (syntax-case syn ()
[(_ a) [(_ a)
(let ([a-ty (cur-type-infer #'a)]) (let ([a-ty (type-infer/syn #'a)])
#`(some #,a-ty a))])) #`(some #,a-ty a))]))

View File

@ -1,4 +1,4 @@
#lang s-exp "../main.rkt" #lang s-exp "../cur.rkt"
(require "sugar.rkt" "bool.rkt") (require "sugar.rkt" "bool.rkt")
;; TODO: override (all-defined-out) to enable exporting all these ;; TODO: override (all-defined-out) to enable exporting all these
;; properly. ;; properly.

View File

@ -1,4 +1,4 @@
#lang s-exp "../main.rkt" #lang s-exp "../cur.rkt"
(require "sugar.rkt") (require "sugar.rkt")
;; TODO: Handle multiple provide forms properly ;; TODO: Handle multiple provide forms properly
;; TODO: Handle (all-defined-out) properly ;; TODO: Handle (all-defined-out) properly
@ -31,8 +31,8 @@
(define-syntax (conj/i syn) (define-syntax (conj/i syn)
(syntax-case syn () (syntax-case syn ()
[(_ a b) [(_ a b)
(let ([a-type (cur-type-infer #'a)] (let ([a-type (type-infer/syn #'a)]
[b-type (cur-type-infer #'b)]) [b-type (type-infer/syn #'b)])
#`(conj #,a-type #,b-type a b))])) #`(conj #,a-type #,b-type a b))]))
(define thm:and-is-symmetric (define thm:and-is-symmetric
@ -71,12 +71,11 @@
(define proof:A-or-A (define proof:A-or-A
(lambda (A : Type) (c : (Or A A)) (lambda (A : Type) (c : (Or A A))
;; TODO: What should the motive be? ;; TODO: What should the motive be?
(elim Or (lambda (A : Type) (B : Type) (c : (Or A B)) A) (elim Or Type (lambda (A : Type) (B : Type) (c : (Or A B)) A)
(A A) (lambda (A : Type) (B : Type) (a : A) a)
((lambda (A : Type) (B : Type) (a : A) a) ;; TODO: How do we know B is A?
;; TODO: How do we know B is A? (lambda (A : Type) (B : Type) (b : B) b)
(lambda (A : Type) (B : Type) (b : B) b)) A A c)))
c)))
(qed thm:A-or-A proof:A-or-A) (qed thm:A-or-A proof:A-or-A)
|# |#

View File

@ -1,4 +1,4 @@
#lang s-exp "../main.rkt" #lang s-exp "../cur.rkt"
(provide (provide
-> ->
lambda lambda
@ -6,12 +6,10 @@
[-> ] [-> ]
[-> forall] [-> forall]
[-> ] [-> ]
[-> Π]
[-> Pi]
[lambda λ]) [lambda λ])
#%app #%app
define define
: elim
define-type define-type
match match
recur recur
@ -27,10 +25,10 @@
query-type) query-type)
(require (require
(only-in "../main.rkt" (only-in "../cur.rkt"
[elim real-elim]
[#%app real-app] [#%app real-app]
[λ real-lambda] [lambda real-lambda]
[Π real-Π]
[define real-define])) [define real-define]))
(begin-for-syntax (begin-for-syntax
@ -53,7 +51,7 @@
[(_ d:parameter-declaration ...+ result:result-type) [(_ d:parameter-declaration ...+ result:result-type)
(foldr (lambda (src name type r) (foldr (lambda (src name type r)
(quasisyntax/loc src (quasisyntax/loc src
(real-Π (#,name : #,type) #,r))) (forall (#,name : #,type) #,r)))
#'result #'result
(attribute d) (attribute d)
(attribute d.name) (attribute d.name)
@ -99,61 +97,13 @@
(define-syntax define-type (define-syntax define-type
(syntax-rules () (syntax-rules ()
[(_ (name (a : t) ...) body) [(_ (name (a : t) ...) body)
(define name (-> (a : t) ... body))] (define name (forall (a : t) ... body))]
[(_ name type) [(_ name type)
(define name type)])) (define name type)]))
;; Cooperates with define to allow Haskell-esque type annotations
#| TODO NB:
| This method of cooperating macros is sort of a terrible
| hack. Instead, need principled way of adding/retrieving information
| to/from current module. E.g. perhaps provide extensions an interface to
| module's term environment and inductive signature. Then, :: could add
| new "id : type" to environment, and define could extract type and use.
|#
(begin-for-syntax
(define annotation-dict (make-hash))
(define (annotation->types type-syn)
(let loop ([ls '()]
[syn type-syn])
(syntax-parse (cur-expand syn)
#:datum-literals (:)
[(real-Π (x:id : type) body)
(loop (cons #'type ls) #'body)]
[_ (reverse ls)]))))
(define-syntax (: syn)
(syntax-parse syn
[(_ name:id type:expr)
;; NB: Unhygenic; need to reuse Racket's identifiers, and make this type annotation a syntax property
(syntax-parse (cur-expand #'type)
#:datum-literals (:)
[(real-Π (x:id : type) body) (void)]
[_
(raise-syntax-error
':
"Can only declare annotations for functions, but not a function type"
syn)])
(dict-set! annotation-dict (syntax->datum #'name) (annotation->types #'type))
#'(void)]))
;; TODO: Allow inferring types as in above TODOs for lambda, forall ;; TODO: Allow inferring types as in above TODOs for lambda, forall
(define-syntax (define syn) (define-syntax (define syn)
(syntax-parse syn (syntax-case syn ()
#:datum-literals (:)
[(define (name:id x:id ...) body)
(cond
[(dict-ref annotation-dict (syntax->datum #'name)) =>
(lambda (anns)
(quasisyntax/loc syn
(real-define name (lambda #,@(for/list ([x (syntax->list #'(x ...))]
[type anns])
#`(#,x : #,type)) body))))]
[else
(raise-syntax-error
'define
"Cannot omit type annotations unless you have declared them with (: name type) form first."
syn)])]
[(define (name (x : t) ...) body) [(define (name (x : t) ...) body)
(quasisyntax/loc syn (quasisyntax/loc syn
(real-define name (lambda (x : t) ... body)))] (real-define name (lambda (x : t) ... body)))]
@ -161,67 +111,8 @@
(quasisyntax/loc syn (quasisyntax/loc syn
(real-define id body))])) (real-define id body))]))
#| (define-syntax-rule (elim t1 t2 e ...)
(begin-for-syntax ((real-elim t1 t2) e ...))
(define (type->telescope syn)
(syntax-parse (cur-expand syn)
#:literals (real-Π)
#:datum-literals (:)
[(real-Π (x:id : t) body)
(cons #'(x : t) (type->telescope #'body))]
[_ '()]))
(define (type->body syn)
(syntax-parse syn
#:literals (real-Π)
#:datum-literals (:)
[(real-Π (x:id : t) body)
(type->body #'body)]
[e #'e]))
(define (constructor-indices D syn)
(let loop ([syn syn]
[args '()])
(syntax-parse (cur-expand syn)
#:literals (real-app)
[D:id args]
[(real-app e1 e2)
(loop #'e1 (cons #'e2 args))])))
(define (inductive-index-telescope D)
(type->telescope (cur-type-infer D)))
(define (inductive-method-telescope D motive)
(for/list ([syn (cur-constructor-map D)])
(with-syntax ([(c : t) syn]
[name (gensym (format-symbol "~a-~a" #'c 'method))]
[((arg : arg-type) ...) (type->telescope #'t)]
[((rarg : rarg-type) ...) (constructor-recursive-args D #'((arg : arg-type) ...))]
[((ih : ih-type) ...) (constructor-inductive-hypotheses #'((rarg : rarg-type) ...) motive)]
[(iarg ...) (constructor-indices D (type->body #'t))]
)
#`(name : (forall (arg : arg-type) ...
(ih : ih-type) ...
(motive iarg ...)))))))
(define-syntax (elim syn)
(syntax-parse syn
[(elim D:id U e ...)
(with-syntax ([((x : t) ...) (inductive-index-telescope #'D)]
[motive (gensym 'motive)]
[y (gensym 'y)]
[disc (gensym 'disc)]
[((method : method-type) ...) (inductive-method-telescope #'D #'motive)])
#`((lambda
(motive : (forall (x : t) ... (y : (D x ...)) U))
(method : ) ...
(x : t) ...
(disc : (D x ...)) ...
(real-elim D motive (x ...) (method ...) disc))
e ...)
)
]))
|#
;; Quite fragie to give a syntactic treatment of pattern matching -> eliminator. Replace with "Elimination with a Motive" ;; Quite fragie to give a syntactic treatment of pattern matching -> eliminator. Replace with "Elimination with a Motive"
(begin-for-syntax (begin-for-syntax
@ -268,7 +159,7 @@
#:attr types #:attr types
;; TODO: Detect failure, report error/suggestions ;; TODO: Detect failure, report error/suggestions
(for/list ([e (attribute indices)]) (for/list ([e (attribute indices)])
(or (cur-type-infer e) (or (type-infer/syn e)
(raise-syntax-error (raise-syntax-error
'match 'match
(format (format
@ -289,7 +180,7 @@
(lambda (return) (lambda (return)
;; NB: unhygenic ;; NB: unhygenic
;; Normalize at compile-time, for efficiency at run-time ;; Normalize at compile-time, for efficiency at run-time
(cur-normalize (normalize/syn
#`((lambda #`((lambda
;; TODO: utteraly fragile; relines on the indices being referred to by name, not computed ;; TODO: utteraly fragile; relines on the indices being referred to by name, not computed
;; works only for simple type familes and simply matches on them ;; works only for simple type familes and simply matches on them
@ -350,7 +241,7 @@
(define/syntax-parse type:inductive-type-declaration (cur-expand type-syn)) (define/syntax-parse type:inductive-type-declaration (cur-expand type-syn))
(let ([ih-name (quasisyntax/loc src #,(format-id name-syn "ih-~a" name-syn))] (let ([ih-name (quasisyntax/loc src #,(format-id name-syn "ih-~a" name-syn))]
;; Normalize at compile-time, for efficiency at run-time ;; Normalize at compile-time, for efficiency at run-time
[ih-type (cur-normalize #`(#,motive #,@(attribute type.indices) #,name-syn))]) [ih-type (normalize/syn #`(#,motive #,@(attribute type.indices) #,name-syn))])
(dict-set! ih-dict (syntax->datum name-syn) ih-name) (dict-set! ih-dict (syntax->datum name-syn) ih-name)
(append decls (list #`(#,ih-name : #,ih-type))))))) (append decls (list #`(#,ih-name : #,ih-type)))))))
@ -362,7 +253,7 @@
(or maybe-return-type (or maybe-return-type
;; Ignore errors when trying to infer this type; other attempt might succeed ;; Ignore errors when trying to infer this type; other attempt might succeed
(with-handlers ([values (lambda _ #f)]) (with-handlers ([values (lambda _ #f)])
(cur-type-infer #:local-env (attribute p.local-env) #'b))))) (type-infer/syn #:local-env (attribute p.local-env) #'b)))))
(define-syntax-class (match-clause D motive) (define-syntax-class (match-clause D motive)
(pattern (pattern
@ -398,7 +289,7 @@
(~optional (~optional
(~seq #:in ~! t) (~seq #:in ~! t)
#:defaults #:defaults
([t (or (cur-type-infer #'d) ([t (or (type-infer/syn #'d)
(raise-syntax-error (raise-syntax-error
'match 'match
"Could not infer discrimnant's type. Try using #:in to declare it." "Could not infer discrimnant's type. Try using #:in to declare it."
@ -423,9 +314,15 @@
(quasisyntax/loc syn (quasisyntax/loc syn
(elim (elim
D.inductive-name D.inductive-name
#,(or
(type-infer/syn (attribute return-type))
(raise-syntax-error
'match
"Could not infer type of motive. Sorry, you'll have to use elim."
syn))
motive motive
#,(attribute D.indices) c.method ...
(c.method ...) #,@(attribute D.indices)
d))])) d))]))
(begin-for-syntax (begin-for-syntax
@ -437,14 +334,14 @@
#:attr type (cond #:attr type (cond
[(attribute t) [(attribute t)
;; TODO: Code duplication in :: ;; TODO: Code duplication in ::
(unless (cur-type-check? #'e #'t) (unless (type-check/syn? #'e #'t)
(raise-syntax-error (raise-syntax-error
'let 'let
(format "Term ~a does not have expected type ~a. Inferred type was ~a" (format "Term ~a does not have expected type ~a. Inferred type was ~a"
(cur->datum #'e) (cur->datum #'t) (cur->datum (cur-type-infer #'e))) (cur->datum #'e) (cur->datum #'t) (cur->datum (type-infer/syn #'e)))
#'e (quasisyntax/loc #'x (x e)))) #'e (quasisyntax/loc #'x (x e))))
#'t] #'t]
[(cur-type-infer #'e)] [(type-infer/syn #'e)]
[else [else
(raise-syntax-error (raise-syntax-error
'let 'let
@ -455,29 +352,29 @@
[(let (c:let-clause ...) body) [(let (c:let-clause ...) body)
#'((lambda (c.id : c.type) ... body) c.e ...)])) #'((lambda (c.id : c.type) ... body) c.e ...)]))
;; Normally type checking will only happen if a term is actually used/appears at top-level. ;; Normally type checking will only happen if a term is actually used. This forces a term to be
;; This forces a term to be checked against a particular type. ;; checked against a particular type.
(define-syntax (:: syn) (define-syntax (:: syn)
(syntax-case syn () (syntax-case syn ()
[(_ pf t) [(_ pf t)
(begin (begin
;; TODO: Code duplication in let-clause pattern ;; TODO: Code duplication in let-clause pattern
(unless (cur-type-check? #'pf #'t) (unless (type-check/syn? #'pf #'t)
(raise-syntax-error (raise-syntax-error
':: '::
(format "Term ~a does not have expected type ~a. Inferred type was ~a" (format "Term ~a does not have expected type ~a. Inferred type was ~a"
(cur->datum #'pf) (cur->datum #'t) (cur->datum (cur-type-infer #'pf))) (cur->datum #'pf) (cur->datum #'t) (cur->datum (type-infer/syn #'pf)))
syn)) syn))
#'(void))])) #'(void))]))
(define-syntax (run syn) (define-syntax (run syn)
(syntax-case syn () (syntax-case syn ()
[(_ expr) (cur-normalize #'expr)])) [(_ expr) (normalize/syn #'expr)]))
(define-syntax (step syn) (define-syntax (step syn)
(syntax-case syn () (syntax-case syn ()
[(_ expr) [(_ expr)
(let ([t (cur-step #'expr)]) (let ([t (step/syn #'expr)])
(displayln (cur->datum t)) (displayln (cur->datum t))
t)])) t)]))
@ -493,6 +390,6 @@
(syntax-case syn () (syntax-case syn ()
[(_ term) [(_ term)
(begin (begin
(printf "\"~a\" has type \"~a\"~n" (syntax->datum #'term) (syntax->datum (cur-type-infer #'term))) (printf "\"~a\" has type \"~a\"~n" (syntax->datum #'term) (syntax->datum (type-infer/syn #'term)))
;; Void is undocumented and a hack, but sort of works ;; Void is undocumented and a hack, but sort of works
#'(void))])) #'(void))]))

View File

@ -1,4 +1,4 @@
#lang s-exp "../../main.rkt" #lang s-exp "../../cur.rkt"
(require (require
(for-syntax racket/syntax)) (for-syntax racket/syntax))
(provide (provide
@ -220,7 +220,7 @@
[pf (proof-state-proof ps)]) [pf (proof-state-proof ps)])
(unless (proof-state-proof-complete? ps) (unless (proof-state-proof-complete? ps)
(raise-syntax-error 'qed "Proof contains holes" (pf (current-hole-pretty-symbol)))) (raise-syntax-error 'qed "Proof contains holes" (pf (current-hole-pretty-symbol))))
(unless (cur-type-check? pf t) (unless (type-check/syn? pf t)
(raise-syntax-error 'qed "Invalid proof" pf t)) (raise-syntax-error 'qed "Invalid proof" pf t))
pf))) pf)))

View File

@ -1,4 +1,4 @@
#lang s-exp "../../main.rkt" #lang s-exp "../../cur.rkt"
(require (require
"base.rkt" "base.rkt"
(prefix-in basic: "standard.rkt") (prefix-in basic: "standard.rkt")

View File

@ -1,4 +1,4 @@
#lang s-exp "../../main.rkt" #lang s-exp "../../cur.rkt"
(require (require
"base.rkt" "base.rkt"
(for-syntax racket/syntax)) (for-syntax racket/syntax))
@ -22,7 +22,7 @@
[(forall (x:id : P:expr) body:expr) [(forall (x:id : P:expr) body:expr)
(let* ([ps (proof-state-extend-env ps name #'P)] (let* ([ps (proof-state-extend-env ps name #'P)]
[ps (proof-state-current-goal-set ps #'body)] [ps (proof-state-current-goal-set ps #'body)]
[ps (proof-state-fill-proof-hole ps (lambda (x) #`(λ (#,name : P) #,x)))]) [ps (proof-state-fill-proof-hole ps (lambda (x) #`(lambda (#,name : P) #,x)))])
ps)] ps)]
[_ (error 'intro "Can only intro when current goal is of the form (∀ (x : P) body)")])) [_ (error 'intro "Can only intro when current goal is of the form (∀ (x : P) body)")]))

View File

@ -1,4 +1,4 @@
#lang s-exp "../main.rkt" #lang s-exp "../cur.rkt"
(require (require
"nat.rkt" "nat.rkt"
"bool.rkt" "bool.rkt"
@ -38,7 +38,7 @@
#`(define-syntax (#,name syn) #`(define-syntax (#,name syn)
(syntax-case syn () (syntax-case syn ()
[(_ arg args (... ...)) [(_ arg args (... ...))
#`(#,(format-id syn "~a-~a" '#,name (cur-type-infer #'arg)) #`(#,(format-id syn "~a-~a" '#,name (type-infer/syn #'arg))
arg arg
args (... ...))]))))])) args (... ...))]))))]))
@ -57,7 +57,7 @@
#`(begin #`(begin
#,@(for/list ([def (syntax->list #'(defs ...))]) #,@(for/list ([def (syntax->list #'(defs ...))])
(let-values ([(name body) (process-def def)]) (let-values ([(name body) (process-def def)])
(unless (cur-type-check? (unless (type-check/syn?
body body
#`(#,(dict-ref #`(#,(dict-ref
(dict-ref typeclasses (syntax->datum #'class)) (dict-ref typeclasses (syntax->datum #'class))

View File

@ -3,5 +3,5 @@
(define deps '("base" ("redex-lib" #:version "1.11"))) (define deps '("base" ("redex-lib" #:version "1.11")))
(define build-deps '()) (define build-deps '())
(define pkg-desc "implementation (no documentation, tests) part of \"cur\".") (define pkg-desc "implementation (no documentation, tests) part of \"cur\".")
(define version "0.4") (define version "0.2")
(define pkg-authors '(wilbowma)) (define pkg-authors '(wilbowma))

View File

@ -41,12 +41,11 @@
"\\| 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 (cur->coq (let ([t (cur->coq
#'(elim nat (lambda (x : nat) nat) #'(elim nat Type (lambda (x : nat) nat) z
() (lambda (x : nat) (ih-x : nat) ih-x)
(z (lambda (x : nat) (ih-x : nat) ih-x))
e))]) e))])
(check-regexp-match (check-regexp-match
"\\(nat_rect \\(fun x : nat => nat\\) z \\(fun x : nat => \\(fun ih_x : nat => ih_x\\)\\) e\\)" "\\(\\(\\(\\(nat_rect \\(fun x : nat => nat\\)\\) z\\) \\(fun x : nat => \\(fun ih_x : nat => ih_x\\)\\)\\) e\\)"
t)) t))
(check-regexp-match (check-regexp-match
"Definition thm_plus_commutes := \\(forall n : nat, \\(forall m : nat, \\(\\(\\(== nat\\) \\(\\(plus n\\) m\\)\\) \\(\\(plus m\\) n\\)\\)\\)\\).\n" "Definition thm_plus_commutes := \\(forall n : nat, \\(forall m : nat, \\(\\(\\(== nat\\) \\(\\(plus n\\) m\\)\\) \\(\\(plus m\\) n\\)\\)\\)\\).\n"

View File

@ -1,24 +0,0 @@
#lang cur
(require
cur/stdlib/sugar
rackunit)
(data Nat : Type
(z : Nat)
(s : (Π (x : Nat) Nat)))
(plus . : . (-> Nat Nat Nat))
(define (plus n m)
(match n
[z m]
[(s (x : Nat))
(s (recur x))]))
(check-equal?
(plus z z)
z)
(check-equal?
(plus (s z) z)
(s z))

View File

@ -81,6 +81,23 @@
(Π (a : S) (Π (b : B) ((and S) B))) (Π (a : S) (Π (b : B) ((and S) B)))
(subst (Π (a : A) (Π (b : B) ((and A) B))) A S)))) (subst (Π (a : A) (Π (b : B) ((and A) B))) A S))))
;; Various accessor tests
;; ------------------------------------------------------------------------
(check-equal?
(term (Δ-key-by-constructor ,Δ zero))
(term nat))
(check-equal?
(term (Δ-key-by-constructor ,Δ s))
(term nat))
(check-equal?
(term (Δ-ref-constructor-map ,Δ nat))
(term ((zero : nat) (s : (Π (x : nat) nat)))))
(check-equal?
(term (Δ-ref-constructor-map ,sigma false))
(term ()))
;; Telescope tests ;; Telescope tests
;; ------------------------------------------------------------------------ ;; ------------------------------------------------------------------------
;; Are these telescopes the same when filled with alpha-equivalent, and equivalently renamed, termed ;; Are these telescopes the same when filled with alpha-equivalent, and equivalently renamed, termed
@ -98,10 +115,41 @@
(term (Δ-ref-parameter-Ξ ,Δ4 and)) (term (Δ-ref-parameter-Ξ ,Δ4 and))
(term (Π (A : Type) (Π (B : Type) hole)))) (term (Π (A : Type) (Π (B : Type) hole))))
(check-telescope-equiv?
(term (Ξ-compose
(Π (x : t_0) (Π (y : t_1) hole))
(Π (z : t_2) (Π (a : t_3) hole))))
(term (Π (x : t_0) (Π (y : t_1) (Π (z : t_2) (Π (a : t_3) hole))))))
(check-telescope-equiv?
(term (Δ-methods-telescope ,Δ nat (λ (x : nat) nat)))
(term (Π (m-zero : ((λ (x : nat) nat) zero))
(Π (m-s : (Π (x : nat) (Π (x-ih : ((λ (x : nat) nat) x)) ((λ (x : nat) nat) (s x))))) hole))))
(check-telescope-equiv?
(term (Δ-methods-telescope ,Δ nat P))
(term (Π (m-zero : (P zero))
(Π (m-s : (Π (x : nat) (Π (ih-x : (P x)) (P (s x)))))
hole))))
(check-telescope-equiv?
(term (Δ-methods-telescope ,Δ nat (λ (x : nat) nat)))
(term (Π (m-zero : ((λ (x : nat) nat) zero))
(Π (m-s : (Π (x : nat) (Π (ih-x : ((λ (x : nat) nat) x)) ((λ (x : nat) nat) (s x)))))
hole))))
(check-telescope-equiv?
(term (Δ-methods-telescope ,Δ4 and (λ (A : Type) (λ (B : Type) (λ (x : ((and A) B)) true)))))
(term (Π (m-conj : (Π (A : Type) (Π (B : Type) (Π (a : A) (Π (b : B)
((((λ (A : Type) (λ (B : Type) (λ (x : ((and A) B)) true)))
A)
B)
((((conj A) B) a) b)))))))
hole)))
(check-true (x? (term false))) (check-true (x? (term false)))
(check-true (Ξ? (term hole))) (check-true (Ξ? (term hole)))
(check-true (t? (term (λ (y : false) (Π (x : Type) x))))) (check-true (t? (term (λ (y : false) (Π (x : Type) x)))))
(check-true (redex-match? ttL ((x : t) ...) (term ()))) (check-true (redex-match? ttL ((x : t) ...) (term ())))
(check-telescope-equiv?
(term (Δ-methods-telescope ,sigma false (λ (y : false) (Π (x : Type) x))))
(term hole))
;; Tests for inductive elimination ;; Tests for inductive elimination
;; ------------------------------------------------------------------------ ;; ------------------------------------------------------------------------
@ -109,32 +157,21 @@
(check-true (check-true
(redex-match? tt-ctxtL (in-hole Θ_i (hole (in-hole Θ_r zero))) (term (hole zero)))) (redex-match? tt-ctxtL (in-hole Θ_i (hole (in-hole Θ_r zero))) (term (hole zero))))
(check-telescope-equiv? (check-telescope-equiv?
(term (Δ-inductive-elim ,Δ nat (term (Δ-inductive-elim ,Δ nat Type (λ (x : nat) nat) hole
(elim nat (λ (x : nat) nat) () ((hole (s zero)) (λ (x : nat) (λ (ih-x : nat) (s (s x)))))
((s zero) (λ (x : nat) (λ (ih-x : nat) (s (s x)))))
hole)
(hole zero))) (hole zero)))
(term (hole (elim nat (λ (x : nat) nat) (term (hole (((((elim nat Type) (λ (x : nat) nat))
() (s zero))
((s zero) (λ (x : nat) (λ (ih-x : nat) (s (s x)))))
(λ (x : nat) (λ (ih-x : nat) (s (s x))))) zero))))
zero))))
(check-telescope-equiv? (check-telescope-equiv?
(term (Δ-inductive-elim ,Δ nat (term (Δ-inductive-elim ,Δ nat Type (λ (x : nat) nat) hole
(elim nat (λ (x : nat) nat) () ((hole (s zero)) (λ (x : nat) (λ (ih-x : nat) (s (s x)))))
((s zero) (λ (x : nat) (λ (ih-x : nat) (s (s x)))))
hole)
(hole (s zero)))) (hole (s zero))))
(term (hole (elim nat (λ (x : nat) nat) () (term (hole (((((elim nat Type) (λ (x : nat) nat))
((s zero) (λ (x : nat) (λ (ih-x : nat) (s (s x))))) (s zero))
(s zero))))) (λ (x : nat) (λ (ih-x : nat) (s (s x)))))
(check-telescope-equiv? (s zero)))))
(term (Δ-inductive-elim ,Δ nat
(elim nat (λ (x : nat) nat) ()
((s zero) (λ (x : nat) (λ (ih-x : nat) (s (s x)))))
hole)
hole))
(term hole))
;; Tests for dynamic semantics ;; Tests for dynamic semantics
;; ------------------------------------------------------------------------ ;; ------------------------------------------------------------------------
@ -142,8 +179,6 @@
(check-true (v? (term (λ (x_0 : (Unv 0)) x_0)))) (check-true (v? (term (λ (x_0 : (Unv 0)) x_0))))
(check-true (v? (term (refl Nat)))) (check-true (v? (term (refl Nat))))
(check-true (v? (term ((refl Nat) z)))) (check-true (v? (term ((refl Nat) z))))
(check-true (v? (term zero)))
(check-true (v? (term (s zero))))
;; TODO: Move equivalence up here, and use in these tests. ;; TODO: Move equivalence up here, and use in these tests.
(check-equiv? (term (reduce (Unv 0))) (term (Unv 0))) (check-equiv? (term (reduce (Unv 0))) (term (Unv 0)))
@ -153,71 +188,63 @@
(term (Π (x : t) (Unv 0)))) (term (Π (x : t) (Unv 0))))
(check-not-equiv? (term (reduce (Π (x : t) ((Π (x_0 : t) (x_0 x)) x)))) (check-not-equiv? (term (reduce (Π (x : t) ((Π (x_0 : t) (x_0 x)) x))))
(term (Π (x : t) (x x)))) (term (Π (x : t) (x x))))
(check-equiv? (term (reduce ,Δ (((((elim nat Type) (λ (x : nat) nat))
(check-equal? (term (Δ-constructor-index ,Δ nat zero)) 0) (s zero))
(check-equiv? (term (reduce ,Δ (elim nat (λ (x : nat) nat) (λ (x : nat) (λ (ih-x : nat)
() (s (s x)))))
((s zero) zero)))
(λ (x : nat) (λ (ih-x : nat) (s (s x)))))
zero)))
(term (s zero))) (term (s zero)))
(check-equiv? (term (reduce ,Δ (elim nat (λ (x : nat) nat) (check-equiv? (term (reduce ,Δ (((((elim nat Type) (λ (x : nat) nat))
() (s zero))
((s zero) (λ (x : nat) (λ (ih-x : nat)
(λ (x : nat) (λ (ih-x : nat) (s (s x))))) (s (s x)))))
(s zero)))) (s zero))))
(term (s (s zero)))) (term (s (s zero))))
(check-equiv? (term (reduce ,Δ (elim nat (λ (x : nat) nat) (check-equiv? (term (reduce ,Δ (((((elim nat Type) (λ (x : nat) nat))
() (s zero))
((s zero) (λ (x : nat) (λ (ih-x : nat) (s (s x)))))
(λ (x : nat) (λ (ih-x : nat) (s (s x)))))
(s (s (s zero)))))) (s (s (s zero))))))
(term (s (s (s (s zero)))))) (term (s (s (s (s zero))))))
(check-equiv? (check-equiv?
(term (reduce ,Δ (term (reduce ,Δ
(elim nat (λ (x : nat) nat) (((((elim nat Type) (λ (x : nat) nat))
() (s (s zero)))
((s (s zero)) (λ (x : nat) (λ (ih-x : nat) (s ih-x))))
(λ (x : nat) (λ (ih-x : nat) (s ih-x)))) (s (s zero)))))
(s (s zero)))))
(term (s (s (s (s zero)))))) (term (s (s (s (s zero))))))
(check-equiv? (check-equiv?
(term (step ,Δ (term (step ,Δ
(elim nat (λ (x : nat) nat) (((((elim nat Type) (λ (x : nat) nat))
() (s (s zero)))
((s (s zero)) (λ (x : nat) (λ (ih-x : nat) (s ih-x))))
(λ (x : nat) (λ (ih-x : nat) (s ih-x)))) (s (s zero)))))
(s (s zero)))))
(term (term
(((λ (x : nat) (λ (ih-x : nat) (s ih-x))) (((λ (x : nat) (λ (ih-x : nat) (s ih-x)))
(s zero)) (s zero))
(elim nat (λ (x : nat) nat) (((((elim nat Type) (λ (x : nat) nat))
() (s (s zero)))
((s (s zero)) (λ (x : nat) (λ (ih-x : nat) (s ih-x))))
(λ (x : nat) (λ (ih-x : nat) (s ih-x)))) (s zero)))))
(s zero)))))
(check-equiv? (check-equiv?
(term (step ,Δ (step ,Δ (term (step ,Δ (step ,Δ
(((λ (x : nat) (λ (ih-x : nat) (s ih-x))) (((λ (x : nat) (λ (ih-x : nat) (s ih-x)))
(s zero)) (s zero))
(elim nat (λ (x : nat) nat) (((((elim nat Type) (λ (x : nat) nat))
() (s (s zero)))
((s (s zero)) (λ (x : nat) (λ (ih-x : nat) (s ih-x))))
(λ (x : nat) (λ (ih-x : nat) (s ih-x)))) (s zero))))))
(s zero))))))
(term (term
((λ (ih-x1 : nat) (s ih-x1)) ((λ (ih-x1 : nat) (s ih-x1))
(((λ (x : nat) (λ (ih-x : nat) (s ih-x))) (((λ (x : nat) (λ (ih-x : nat) (s ih-x)))
zero) zero)
(elim nat (λ (x : nat) nat) (((((elim nat Type) (λ (x : nat) nat))
() (s (s zero)))
((s (s zero)) (λ (x : nat) (λ (ih-x : nat) (s ih-x))))
(λ (x : nat) (λ (ih-x : nat) (s ih-x)))) zero)))))
zero)))))
(define-syntax-rule (check-equivalent e1 e2) (define-syntax-rule (check-equivalent e1 e2)
(check-holds (convert e1 e2))) (check-holds (equivalent e1 e2)))
(check-equivalent (check-equivalent
(λ (x : Type) x) (λ (y : Type) y)) (λ (x : Type) x) (λ (y : Type) y))
(check-equivalent (check-equivalent
@ -316,42 +343,28 @@
U)) U))
;; ---- Elim ;; ---- Elim
;; TODO: Clean up/Reorganize these tests ;; TODO: Clean up/Reorganize these tests
(check-true
(redex-match? tt-typingL
(in-hole Θ_m (((elim x_D U) e_D) e_P))
(term ((((elim truth Type) T) (Π (x : truth) (Unv 1))) (Unv 0)))))
(define Δtruth (term ( (truth : (Unv 0) ((T : truth)))))) (define Δtruth (term ( (truth : (Unv 0) ((T : truth))))))
(check-holds (type-infer ,Δtruth truth (in-hole Ξ U))) (check-holds (type-infer ,Δtruth truth (in-hole Ξ U)))
(check-holds (type-infer ,Δtruth T (in-hole Θ_ai truth))) (check-holds (type-infer ,Δtruth T (in-hole Θ_ai truth)))
(check-holds (type-infer ,Δtruth (λ (x : truth) (Unv 1)) (check-holds (type-infer ,Δtruth (λ (x : truth) (Unv 1))
(in-hole Ξ (Π (x : (in-hole Θ truth)) U)))) (in-hole Ξ (Π (x : (in-hole Θ truth)) U))))
(check-equiv? (check-telescope-equiv?
(term (Δ-motive-type ,Δtruth truth (Unv 2))) (term (Δ-methods-telescope ,Δtruth truth (λ (x : truth) (Unv 1))))
(term (Π (x : truth) (Unv 2)))) (term (Π (m-T : ((λ (x : truth) (Unv 1)) T)) hole)))
(check-holds (type-infer ,Δtruth (elim truth Type) t))
(check-holds (type-check ( (truth : (Unv 0) ((T : truth))))
(check-holds (type-check ,Δtruth (Unv 0) ,(car (term (Δ-method-types ,Δtruth truth (λ (x : truth) (Unv 1)))))))
(check-holds (type-check ,Δtruth (λ (x : truth) (Unv 1)) (Π (x : truth) (Unv 2))))
(check-equiv?
(term (apply (λ (x : truth) (Unv 1)) T))
(term ((λ (x : truth) (Unv 1)) T)))
(check-holds
(convert ,Δtruth (apply (λ (x : truth) (Unv 1)) T) (Unv 1)))
(check-holds (type-infer ,Δtruth
(elim truth (λ (x : truth) (Unv 1)) ((((elim truth (Unv 2)) (λ (x : truth) (Unv 1))) (Unv 0))
() ((Unv 0)) T) T)
t))
(check-holds (type-check ,Δtruth
(elim truth (λ (x : truth) (Unv 1))
() ((Unv 0)) T)
(Unv 1))) (Unv 1)))
(check-not-holds (type-check ( (truth : (Unv 0) ((T : truth)))) (check-not-holds (type-check ( (truth : (Unv 0) ((T : truth))))
(elim truth Type () (Type) T) ((((elim truth (Unv 1)) Type) Type) T)
(Unv 1))) (Unv 1)))
(check-holds (check-holds
(type-infer (Π (x2 : (Unv 0)) (Unv 0)) U)) (type-infer (Π (x2 : (Unv 0)) (Unv 0)) U))
@ -369,54 +382,47 @@
(check-holds (type-check ,Δ syn ...))) (check-holds (type-check ,Δ syn ...)))
(nat-test (Π (x : nat) nat) (Unv 0)) (nat-test (Π (x : nat) nat) (Unv 0))
(nat-test (λ (x : nat) x) (Π (x : nat) nat)) (nat-test (λ (x : nat) x) (Π (x : nat) nat))
(nat-test (elim nat (λ (x : nat) nat) () (nat-test (((((elim nat Type) (λ (x : nat) nat)) zero)
(zero (λ (x : nat) (λ (ih-x : nat) x))) (λ (x : nat) (λ (ih-x : nat) x))) zero)
zero)
nat) nat)
(nat-test nat (Unv 0)) (nat-test nat (Unv 0))
(nat-test zero nat) (nat-test zero nat)
(nat-test s (Π (x : nat) nat)) (nat-test s (Π (x : nat) nat))
(nat-test (s zero) nat) (nat-test (s zero) nat)
;; TODO: Meta-function auto-currying and such
(check-holds (check-holds
(type-infer ,Δ (λ (x : nat) (type-infer ,Δ ((((elim nat (Unv 0)) (λ (x : nat) nat))
(elim nat (λ (x : nat) nat) zero)
() (λ (x : nat) (λ (ih-x : nat) x)))
(zero
(λ (x : nat) (λ (ih-x : nat) x)))
x))
t)) t))
(nat-test (elim nat (λ (x : nat) nat) (nat-test (((((elim nat (Unv 0)) (λ (x : nat) nat))
() zero)
(zero (λ (x : nat) (λ (ih-x : nat) x))) (λ (x : nat) (λ (ih-x : nat) x)))
zero) zero)
nat) nat)
(nat-test (elim nat (λ (x : nat) nat) (nat-test (((((elim nat (Unv 0)) (λ (x : nat) nat))
() (s zero))
((s zero) (λ (x : nat) (λ (ih-x : nat) (s (s x))))) (λ (x : nat) (λ (ih-x : nat) (s (s x)))))
zero) zero)
nat) nat)
(nat-test (elim nat (λ (x : nat) nat) (nat-test (((((elim nat Type) (λ (x : nat) nat))
() (s zero))
((s zero) (λ (x : nat) (λ (ih-x : nat) (s (s x))))) (λ (x : nat) (λ (ih-x : nat) (s (s x))))) zero)
zero)
nat) nat)
(nat-test ( n : nat) (nat-test ( n : nat)
(elim nat (λ (x : nat) nat) (((((elim nat (Unv 0)) (λ (x : nat) nat)) zero) (λ (x : nat) (λ (ih-x : nat) x))) n)
()
(zero (λ (x : nat) (λ (ih-x : nat) x)))
n)
nat) nat)
(check-holds (check-holds
(type-check (,Δ (bool : (Unv 0) ((btrue : bool) (bfalse : bool)))) (type-check (,Δ (bool : (Unv 0) ((btrue : bool) (bfalse : bool))))
( n2 : nat) ( n2 : nat)
(elim nat (λ (x : nat) bool) (((((elim nat (Unv 0)) (λ (x : nat) bool))
() btrue)
(btrue (λ (x : nat) (λ (ih-x : bool) bfalse))) (λ (x : nat) (λ (ih-x : bool) bfalse)))
n2) n2)
bool)) bool))
(check-not-holds (check-not-holds
(type-check ,Δ (type-check ,Δ
(elim nat nat () ((s zero)) zero) ((((elim nat (Unv 0)) nat) (s zero)) zero)
nat)) nat))
(define lam (term (λ (nat : (Unv 0)) nat))) (define lam (term (λ (nat : (Unv 0)) nat)))
(check-equivalent (check-equivalent
@ -475,15 +481,15 @@
(in-hole Ξ (Π (x : (in-hole Θ_Ξ and)) U_P)))) (in-hole Ξ (Π (x : (in-hole Θ_Ξ and)) U_P))))
(check-holds (check-holds
(type-check (,Δ4 (true : (Unv 0) ((tt : true)))) (type-check (,Δ4 (true : (Unv 0) ((tt : true))))
(elim and ((((((elim and (Unv 0))
(λ (A : Type) (λ (B : Type) (λ (x : ((and A) B)) (λ (A : Type) (λ (B : Type) (λ (x : ((and A) B))
true))) true))))
(true true) (λ (A : (Unv 0))
((λ (A : (Unv 0)) (λ (B : (Unv 0))
(λ (B : (Unv 0)) (λ (a : A)
(λ (a : A) (λ (b : B) tt)))))
(λ (b : B) tt))))) true) true)
((((conj true) true) tt) tt)) ((((conj true) true) tt) tt))
true)) true))
(check-true (Γ? (term ((( P : (Unv 0)) Q : (Unv 0)) ab : ((and P) Q))))) (check-true (Γ? (term ((( P : (Unv 0)) Q : (Unv 0)) ab : ((and P) Q)))))
(check-holds (check-holds
@ -501,7 +507,7 @@
((and B) A)))) ((and B) A))))
(in-hole Ξ (Π (x : (in-hole Θ and)) U)))) (in-hole Ξ (Π (x : (in-hole Θ and)) U))))
(check-holds (check-holds
(convert ,Δ4 (equivalent ,Δ4
(Π (A : (Unv 0)) (Π (B : (Unv 0)) (Π (x : ((and A) B)) (Unv 0)))) (Π (A : (Unv 0)) (Π (B : (Unv 0)) (Π (x : ((and A) B)) (Unv 0))))
(Π (P : (Unv 0)) (Π (Q : (Unv 0)) (Π (x : ((and P) Q)) (Unv 0)))))) (Π (P : (Unv 0)) (Π (Q : (Unv 0)) (Π (x : ((and P) Q)) (Unv 0))))))
(check-holds (check-holds
@ -512,15 +518,14 @@
(check-holds (check-holds
(type-check ,Δ4 (type-check ,Δ4
((( P : (Unv 0)) Q : (Unv 0)) ab : ((and P) Q)) ((( P : (Unv 0)) Q : (Unv 0)) ab : ((and P) Q))
(elim and ((((((elim and (Unv 0))
(λ (A : Type) (λ (B : Type) (λ (x : ((and A) B)) (λ (A : Type) (λ (B : Type) (λ (x : ((and A) B))
((and B) A)))) ((and B) A)))))
(P Q) (λ (A : (Unv 0))
((λ (A : (Unv 0)) (λ (B : (Unv 0))
(λ (B : (Unv 0)) (λ (a : A)
(λ (a : A) (λ (b : B) ((((conj B) A) b) a))))))
(λ (b : B) ((((conj B) A) b) a)))))) P) Q) ab)
ab)
((and Q) P))) ((and Q) P)))
(check-holds (check-holds
(type-check (,Δ4 (true : (Unv 0) ((tt : true)))) (type-check (,Δ4 (true : (Unv 0) ((tt : true))))
@ -533,14 +538,14 @@
t)) t))
(check-holds (check-holds
(type-check (,Δ4 (true : (Unv 0) ((tt : true)))) (type-check (,Δ4 (true : (Unv 0) ((tt : true))))
(elim and ((((((elim and (Unv 0))
(λ (A : Type) (λ (B : Type) (λ (x : ((and A) B)) (λ (A : Type) (λ (B : Type) (λ (x : ((and A) B))
((and B) A)))) ((and B) A)))))
(true true) (λ (A : (Unv 0))
((λ (A : (Unv 0))
(λ (B : (Unv 0)) (λ (B : (Unv 0))
(λ (a : A) (λ (a : A)
(λ (b : B) ((((conj B) A) b) a)))))) (λ (b : B) ((((conj B) A) b) a))))))
true) true)
((((conj true) true) tt) tt)) ((((conj true) true) tt) tt))
((and true) true))) ((and true) true)))
(define gamma (term ( temp863 : pre))) (define gamma (term ( temp863 : pre)))
@ -563,18 +568,21 @@
(check-holds (check-holds
(type-infer ,sigma (,gamma x : false) (λ (y : false) (Π (x : Type) x)) (type-infer ,sigma (,gamma x : false) (λ (y : false) (Π (x : Type) x))
(in-hole Ξ (Π (x : (in-hole Θ false)) U)))) (in-hole Ξ (Π (x : (in-hole Θ false)) U))))
(check-true
(redex-match? tt-typingL
((in-hole Θ_m ((elim x_D U) e_P)) e_D)
(term (((elim false (Unv 1)) (λ (y : false) (Π (x : Type) x)))
x))))
(check-holds (check-holds
(type-check ,sigma (,gamma x : false) (type-check ,sigma (,gamma x : false)
(elim false (λ (y : false) (Π (x : Type) x)) () () x) (((elim false (Unv 0)) (λ (y : false) (Π (x : Type) x))) x)
(Π (x : (Unv 0)) x))) (Π (x : (Unv 0)) x)))
;; nat-equal? tests ;; nat-equal? tests
(define zero? (define zero?
(term (λ (n : nat) (term ((((elim nat Type) (λ (x : nat) bool))
(elim nat (λ (x : nat) bool) () true)
(true (λ (x : nat) (λ (x_ih : bool) false))) (λ (x : nat) (λ (x_ih : bool) false)))))
n))))
(check-holds (check-holds
(type-check ,Δ ,zero? (Π (x : nat) bool))) (type-check ,Δ ,zero? (Π (x : nat) bool)))
(check-equal? (check-equal?
@ -584,12 +592,9 @@
(term (reduce ,Δ (,zero? (s zero)))) (term (reduce ,Δ (,zero? (s zero))))
(term false)) (term false))
(define ih-equal? (define ih-equal?
(term (λ (ih : nat) (term ((((elim nat Type) (λ (x : nat) bool))
(elim nat (λ (x : nat) bool) false)
() (λ (x : nat) (λ (y : bool) (x_ih x))))))
(false
(λ (x : nat) (λ (y : bool) (x_ih x))))
ih))))
(check-holds (check-holds
(type-check ,Δ ( x_ih : (Π (x : nat) bool)) (type-check ,Δ ( x_ih : (Π (x : nat) bool))
,ih-equal? ,ih-equal?
@ -601,13 +606,10 @@
(check-holds (check-holds
(type-infer ,Δ (λ (x : nat) (Π (x : nat) bool)) (Π (x : nat) (Unv 0)))) (type-infer ,Δ (λ (x : nat) (Π (x : nat) bool)) (Π (x : nat) (Unv 0))))
(define nat-equal? (define nat-equal?
(term (λ (n : nat) (term ((((elim nat Type) (λ (x : nat) (Π (x : nat) bool)))
(elim nat (λ (x : nat) (Π (x : nat) bool)) ,zero?)
() (λ (x : nat) (λ (x_ih : (Π (x : nat) bool))
(,zero? ,ih-equal?)))))
(λ (x : nat) (λ (x_ih : (Π (x : nat) bool))
,ih-equal?)))
n))))
(check-holds (check-holds
(type-check ,Δ ( nat-equal? : (Π (x-D«4158» : nat) ((λ (x«4159» : nat) (Π (x«4160» : nat) bool)) x-D«4158»))) (type-check ,Δ ( nat-equal? : (Π (x-D«4158» : nat) ((λ (x«4159» : nat) (Π (x«4160» : nat) bool)) x-D«4158»)))
((nat-equal? zero) zero) ((nat-equal? zero) zero)
@ -629,12 +631,19 @@
(check-true (Δ? Δ=)) (check-true (Δ? Δ=))
(define refl-elim (define refl-elim
(term (elim == (λ (A1 : (Unv 0)) (λ (x1 : A1) (λ (y1 : A1) (λ (p2 : (((== A1) x1) y1)) nat)))) (term (((((((elim == (Unv 0)) (λ (A1 : (Unv 0)) (λ (x1 : A1) (λ (y1 : A1) (λ (p2 : (((==
(bool true true) A1)
((λ (A1 : (Unv 0)) (λ (x1 : A1) zero))) x1)
((refl bool) true)))) y1))
nat)))))
(λ (A1 : (Unv 0)) (λ (x1 : A1) zero))) bool) true) true) ((refl bool) true))))
(check-holds (check-holds
(type-check ,Δ= ,refl-elim nat)) (type-check ,Δ= ,refl-elim nat))
(check-true
(redex-match?
tt-redL
(Δ (in-hole E (in-hole Θ ((elim x_D U) e_P))))
(term (,Δ= ,refl-elim))))
(check-true (check-true
(redex-match? (redex-match?
tt-redL tt-redL

View File

@ -32,11 +32,11 @@
(:: (lambda (A : Type) (n : Nat) (none A)) (forall (A : Type) (-> Nat (Maybe A))))) (:: (lambda (A : Type) (n : Nat) (none A)) (forall (A : Type) (-> Nat (Maybe A)))))
(check-equal? (check-equal?
(void) (void)
(:: (elim List (lambda (A : Type) (ls : (List A)) Nat) (:: (elim List Type (lambda (A : Type) (ls : (List A)) Nat)
(Bool) (lambda (A : Type) z)
((lambda (A : Type) z) (lambda (A : Type) (a : A) (ls : (List A)) (ih : Nat)
(lambda (A : Type) (a : A) (ls : (List A)) (ih : Nat) z)
z)) Bool
(nil Bool)) (nil Bool))
Nat)) Nat))

View File

@ -11,11 +11,11 @@
(:: pf:proj1 thm:proj1) (:: pf:proj1 thm:proj1)
(:: pf:proj2 thm:proj2) (:: pf:proj2 thm:proj2)
(check-equal? (check-equal?
(elim == (λ (A : Type) (x : A) (y : A) (p : (== A x y)) Nat) (elim == Type (λ (A : Type) (x : A) (y : A) (p : (== A x y)) Nat)
(Bool (λ (A : Type) (x : A) z)
true Bool
true) true
((λ (A : Type) (x : A) z)) true
(refl Bool true)) (refl Bool true))
z) z)

View File

@ -11,7 +11,9 @@
(equal? : (forall (a : A) (b : A) Bool))) (equal? : (forall (a : A) (b : A) Bool)))
(impl (Eqv Bool) (impl (Eqv Bool)
(define (equal? (a : Bool) (b : Bool)) (define (equal? (a : Bool) (b : Bool))
(if a b (not b)))) (if a
(if b true false)
(if b false true))))
(impl (Eqv Nat) (impl (Eqv Nat)
(define equal? nat-equal?)) (define equal? nat-equal?))
(check-equal? (check-equal?

View File

@ -1,16 +0,0 @@
#lang sweet-exp cur
require
cur/stdlib/sugar
cur/stdlib/bool
cur/stdlib/nat
rackunit
check-equal?
if true false true
false
define + plus
check-equal?
{z + s(z)}
s(z)

View File

@ -1,7 +1,7 @@
#lang info #lang info
(define collection 'multi) (define collection 'multi)
(define deps '()) (define deps '())
(define build-deps '("base" "rackunit-lib" ("cur-lib" #:version "0.4") "sweet-exp")) (define build-deps '("base" "rackunit-lib" ("cur-lib" #:version "0.2")))
(define update-implies '("cur-lib")) (define update-implies '("cur-lib"))
(define pkg-desc "Tests for \"cur\".") (define pkg-desc "Tests for \"cur\".")
(define pkg-authors '(wilbowma)) (define pkg-authors '(wilbowma))