diff --git a/nbe-test.rkt b/nbe-test.rkt index 68208df..300a90b 100644 --- a/nbe-test.rkt +++ b/nbe-test.rkt @@ -83,7 +83,7 @@ `(succ ,a)) (check-equal? (normalize `(app ,tm-id ,tm-id)) tm-id) -(check βη-eq? `(app ,tm-id U) 'U) +(check βη-eq? `(app ,tm-id (U 0)) '(U 0)) (check-equal? (normalize `(app (app (app ,tm-pair ,tm-id) ,tm-fst) ,tm-snd)) tm-fst) (check-equal? (normalize `(app (app (app ,tm-pair ,tm-id) ,tm-fst) ,tm-fst)) tm-id) (check-equal? (normalize (tm-app tm-snd (tm-app tm-pair tm-id tm-fst) tm-fst)) tm-fst) @@ -97,10 +97,5 @@ (tm-pnat 12000)) (check βη-eq? (tm-padd (tm-pnat 10000) (tm-pnat 2000)) (tm-pnat 12000)) (check βη-eq? (tm-abs (tm-app (tm-var 1) (tm-var 0))) (tm-app tm-id (tm-var 0))) -(check βη-eq? `(Π U (Π (var 0) ,(tm-app tm-id '(var 1)))) '(Π U (Π (var 0) (var 1)))) -(check-false (βη-eq? '(succ zero) '(var 0))) -(check βη-eq? (tm-app (tm-var 0) (tm-var 1)) (tm-app (tm-var 0) (tm-var 1))) -(check βη-eq? (tm-ind (tm-var 0) (tm-var 1) (tm-var 2)) (tm-ind (tm-var 0) (tm-var 1) (tm-var 2))) -(check-false (βη-eq? (tm-abs (tm-app (tm-var 1) (tm-var 0))) (tm-app tm-id (tm-var 1)))) -(check-false (βη-eq? (tm-app (tm-var 0) (tm-var 0)) (tm-ind (tm-var 0) 'zero 'zero))) -(check-false (βη-eq? 'U '(var 0))) +(check βη-eq? `(Π (U 0) (Π (var 0) ,(tm-app tm-id '(var 1)))) '(Π (U 0) (Π (var 0) (var 1)))) +(check-false (βη-eq? '(U 0) '(var 0))) diff --git a/nbe.rkt b/nbe.rkt index cf227be..2c309dd 100644 --- a/nbe.rkt +++ b/nbe.rkt @@ -1,8 +1,9 @@ #lang typed/racket +;; Grammar (Λ) +;; t := λ t | app t t | i (define-type denv (-> V (Promise D))) (define-type V Nonnegative-Integer) - (define-type Term (∪ 'zero 'nat (List 'succ Term) @@ -11,32 +12,14 @@ (List 'app Term Term) (List 'ind Term Term Term) (List 'Π Term Term) - 'U)) - -(define-type Neu (∪ (List 'ind Neu Norm Norm) - (List 'var V) - (List 'app Neu Norm))) - -(define-type Norm (∪ Neu - 'zero - 'nat - (List 'λ Norm) - 'U - (List 'succ Norm) - (List 'Π Norm Norm))) - -(: embed (-> Neu Term)) -(define (embed a) a) - -(: embed-norm (-> Norm Term)) -(define (embed-norm a) a) + (List 'U V))) (define-type D (∪ 'zero (List 'Π (Promise D) (-> (Promise D) D)) (List 'succ (Promise D)) (List 'fun (-> (Promise D) D)) (List 'neu D-ne) - 'U)) + (List 'U V))) (define-type D-ne (∪ (List 'app D-ne D) (List 'idx V) @@ -75,7 +58,7 @@ (: interp (-> Term denv D)) (define (interp a ρ) (match a - ['U a] + [`(U ,_) a] [`(Π ,A ,B) `(Π ,(delay (interp A ρ)) ,(interp-fun B ρ))] [`(var ,i) (force (ρ i))] ['zero 'zero] @@ -87,46 +70,13 @@ [`(λ ,a) (list 'fun (interp-fun a ρ))] [`(app ,a ,b) (ap a b ρ)])) -(: open-dom (-> V (-> (Promise D) D) D)) -(define (open-dom n f) - (f (delay `(neu (idx ,n))))) - -(: open-dom2 (-> V (-> (Promise D) (Promise D) D) D)) -(define (open-dom2 n f) - (f (delay `(neu (idx ,n))) (delay `(neu (idx ,(add1 n)))))) - -(: compare (-> V D D Boolean)) -(define (compare n a0 a1) - (match (list a0 a1) - [`((Π ,A0 ,B0) (Π ,A1 ,B1)) - (and (compare n (force A0) (force A1)) - (compare (add1 n) (open-dom n B0) (open-dom n B1)))] - ['(nat nat) #t] - ['(U U) #t] - ['(zero zero) #t] - [`((succ ,a) (succ ,b)) (compare n (force a) (force b))] - [`((fun ,f) (neu ,u)) (compare (add1 n) (open-dom n f) `(neu (app ,u (neu (idx ,n)))))] - [`((neu ,_) (fun ,_)) (compare n a1 a0)] - [`((neu ,a) (neu ,b)) (compare-neu n a b)] - [_ #f])) - -(: compare-neu (-> V D-ne D-ne Boolean)) -(define (compare-neu n a0 a1) - (match (list a0 a1) - [`((idx ,i) (idx ,j)) (eqv? i j)] - [`((app ,u0 ,v0) (app ,u1 ,v1)) (and (compare-neu n u0 u1) (compare n v0 v1))] - [`((ind ,a0 ,b0 ,c0) (ind ,a1 ,b1 ,c1)) (and (compare-neu n a0 a1) - (compare n b0 b1) - (compare (+ n 2) (open-dom2 n c0) (open-dom2 n c1)))] - [_ #f])) - -(: reify (-> V D Norm)) +(: reify (-> V D Term)) (define (reify n a) (match a [`(Π ,A ,B) `(Π ,(reify n (force A)) ,(reify (+ n 1) (B (delay `(neu (idx ,n))))))] ['zero 'zero] [`(succ ,a) `(succ ,(reify n (force a)))] - ['U a] + [`(U ,_) a] [`(fun ,f) (list 'λ (reify (+ n 1) (f (delay `(neu (idx ,n))))))] [`(neu ,a) (reify-neu n a)])) @@ -137,7 +87,7 @@ (error "variable to index conversion failed") ret))) -(: reify-neu (-> V D-ne Neu)) +(: reify-neu (-> V D-ne Term)) (define (reify-neu n a) (match a [`(ind ,a ,b ,c) (list 'ind @@ -156,7 +106,7 @@ (define (scope a) (match a [`(Π ,A ,B) (max (scope A) (- (scope B) 2))] - ['U 0] + [`(U ,_) 0] ['zero 0] [`(succ ,a) (scope a)] (`(ind ,a ,b ,c) (max (scope a) (scope b) (- (scope c) 2))) @@ -165,10 +115,6 @@ [`(app ,a ,b) (max (scope a) (scope b))] [`(var ,i) (+ i 1)])) -(: interp-with-scope (-> V Term D)) -(define (interp-with-scope n a) - (interp a (λ (x) (delay (idsub n x))))) - (: normalize (-> Term Term)) (define (normalize a) (let ([sa (scope a)]) @@ -181,7 +127,7 @@ (: subst (-> (-> V Term) Term Term)) (define (subst ρ a) (match a - ['U a] + [`(U ,_) a] [`(Π ,A ,B) `(Π ,(subst ρ A) ,(subst (up 1 ρ) B))] [`(var ,i) (ρ i)] [`(app ,a ,b) `(app ,(subst ρ a) ,(subst ρ b))] @@ -197,11 +143,10 @@ (subst (ext idsub-tm b) a)) ;; Coquand's algorithm but for β-normal forms -;; Subsumed by the compare function (: η-eq? (-> Term Term Boolean)) (define (η-eq? a b) (match (list a b) - ['(U U) #t ] + [`((U ,i) (U ,j)) (eqv? i j) ] [`((Π ,A0 ,B0) (Π ,A1 ,B1)) (and (η-eq? A0 A1) (η-eq? B0 B1))] ['(zero zero) true] @@ -217,11 +162,10 @@ (: βη-eq? (-> Term Term Boolean)) (define (βη-eq? a b) - (let ([n (max (scope a) (scope b))]) - (compare n (interp a (λ (x) (delay (idsub n x)))) (interp b (λ (x) (delay (idsub n x))))))) + (η-eq? (normalize a) (normalize b))) (: β-eq? (-> Term Term Boolean)) (define (β-eq? a b) (equal? (normalize a) (normalize b))) -(provide reify interp normalize β-eq? Term D D-ne V βη-eq? ext subst1 subst idsub-tm) +(provide reify interp normalize β-eq? Term D V βη-eq?) diff --git a/type-checker.rkt b/type-checker.rkt deleted file mode 100644 index 5b42c9c..0000000 --- a/type-checker.rkt +++ /dev/null @@ -1,34 +0,0 @@ -#lang typed/racket - -(require "nbe.rkt") - -(define-type context (Immutable-HashTable V Term)) - -(: context-len (-> context V)) -(define (context-len Γ) - (hash-count Γ)) - -(: context-ext (-> context Term context)) -(define (context-ext Γ A) - (hash-set Γ (context-len Γ) A)) - -(: context-get (-> context V Term)) -(define (context-get Γ i) - (if (< i (context-len Γ)) - (subst (λ (j) `(var ,(+ i j 1))) (hash-ref Γ (- (context-len Γ) (add1 i)))) - (error "context-get: out of bound"))) - -(: context-empty context) -(define context-empty (hash)) - -(: synth (-> context Term Term)) -(define (synth Γ a) - (match a - [`(var ,i) (context-get Γ i)] - [`(app ,a ,b) - (let ([A (synth Γ a)] - [D (interp-with-scope (context-len Γ) A)]))])) - -(: check (-> context Term D Boolean)) -(define (check Γ a A) - (error "unimplemented"))