Compare commits

..

No commits in common. "develop" and "main" have entirely different histories.

3 changed files with 16 additions and 111 deletions

View file

@ -83,7 +83,7 @@
`(succ ,a)) `(succ ,a))
(check-equal? (normalize `(app ,tm-id ,tm-id)) tm-id) (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-snd)) tm-fst)
(check-equal? (normalize `(app (app (app ,tm-pair ,tm-id) ,tm-fst) ,tm-fst)) tm-id) (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) (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)) (tm-pnat 12000))
(check βη-eq? (tm-padd (tm-pnat 10000) (tm-pnat 2000)) (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? (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 βη-eq? `(Π (U 0) (Π (var 0) ,(tm-app tm-id '(var 1)))) '(Π (U 0) (Π (var 0) (var 1))))
(check-false (βη-eq? '(succ zero) '(var 0))) (check-false (βη-eq? '(U 0) '(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)))

82
nbe.rkt
View file

@ -1,8 +1,9 @@
#lang typed/racket #lang typed/racket
;; Grammar (Λ)
;; t := λ t | app t t | i
(define-type denv (-> V (Promise D))) (define-type denv (-> V (Promise D)))
(define-type V Nonnegative-Integer) (define-type V Nonnegative-Integer)
(define-type Term ( 'zero (define-type Term ( 'zero
'nat 'nat
(List 'succ Term) (List 'succ Term)
@ -11,32 +12,14 @@
(List 'app Term Term) (List 'app Term Term)
(List 'ind Term Term Term) (List 'ind Term Term Term)
(List 'Π Term Term) (List 'Π Term Term)
'U)) (List 'U V)))
(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)
(define-type D ( 'zero (define-type D ( 'zero
(List 'Π (Promise D) (-> (Promise D) D)) (List 'Π (Promise D) (-> (Promise D) D))
(List 'succ (Promise D)) (List 'succ (Promise D))
(List 'fun (-> (Promise D) D)) (List 'fun (-> (Promise D) D))
(List 'neu D-ne) (List 'neu D-ne)
'U)) (List 'U V)))
(define-type D-ne ( (List 'app D-ne D) (define-type D-ne ( (List 'app D-ne D)
(List 'idx V) (List 'idx V)
@ -75,7 +58,7 @@
(: interp (-> Term denv D)) (: interp (-> Term denv D))
(define (interp a ρ) (define (interp a ρ)
(match a (match a
['U a] [`(U ,_) a]
[`(Π ,A ,B) `(Π ,(delay (interp A ρ)) ,(interp-fun B ρ))] [`(Π ,A ,B) `(Π ,(delay (interp A ρ)) ,(interp-fun B ρ))]
[`(var ,i) (force (ρ i))] [`(var ,i) (force (ρ i))]
['zero 'zero] ['zero 'zero]
@ -87,46 +70,13 @@
[`(λ ,a) (list 'fun (interp-fun a ρ))] [`(λ ,a) (list 'fun (interp-fun a ρ))]
[`(app ,a ,b) (ap a b ρ)])) [`(app ,a ,b) (ap a b ρ)]))
(: open-dom (-> V (-> (Promise D) D) D)) (: reify (-> V D Term))
(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))
(define (reify n a) (define (reify n a)
(match a (match a
[`(Π ,A ,B) `(Π ,(reify n (force A)) ,(reify (+ n 1) (B (delay `(neu (idx ,n))))))] [`(Π ,A ,B) `(Π ,(reify n (force A)) ,(reify (+ n 1) (B (delay `(neu (idx ,n))))))]
['zero 'zero] ['zero 'zero]
[`(succ ,a) `(succ ,(reify n (force a)))] [`(succ ,a) `(succ ,(reify n (force a)))]
['U a] [`(U ,_) a]
[`(fun ,f) (list 'λ (reify (+ n 1) (f (delay `(neu (idx ,n))))))] [`(fun ,f) (list 'λ (reify (+ n 1) (f (delay `(neu (idx ,n))))))]
[`(neu ,a) (reify-neu n a)])) [`(neu ,a) (reify-neu n a)]))
@ -137,7 +87,7 @@
(error "variable to index conversion failed") (error "variable to index conversion failed")
ret))) ret)))
(: reify-neu (-> V D-ne Neu)) (: reify-neu (-> V D-ne Term))
(define (reify-neu n a) (define (reify-neu n a)
(match a (match a
[`(ind ,a ,b ,c) (list 'ind [`(ind ,a ,b ,c) (list 'ind
@ -156,7 +106,7 @@
(define (scope a) (define (scope a)
(match a (match a
[`(Π ,A ,B) (max (scope A) (- (scope B) 2))] [`(Π ,A ,B) (max (scope A) (- (scope B) 2))]
['U 0] [`(U ,_) 0]
['zero 0] ['zero 0]
[`(succ ,a) (scope a)] [`(succ ,a) (scope a)]
(`(ind ,a ,b ,c) (max (scope a) (scope b) (- (scope c) 2))) (`(ind ,a ,b ,c) (max (scope a) (scope b) (- (scope c) 2)))
@ -165,10 +115,6 @@
[`(app ,a ,b) (max (scope a) (scope b))] [`(app ,a ,b) (max (scope a) (scope b))]
[`(var ,i) (+ i 1)])) [`(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)) (: normalize (-> Term Term))
(define (normalize a) (define (normalize a)
(let ([sa (scope a)]) (let ([sa (scope a)])
@ -181,7 +127,7 @@
(: subst (-> (-> V Term) Term Term)) (: subst (-> (-> V Term) Term Term))
(define (subst ρ a) (define (subst ρ a)
(match a (match a
['U a] [`(U ,_) a]
[`(Π ,A ,B) `(Π ,(subst ρ A) ,(subst (up 1 ρ) B))] [`(Π ,A ,B) `(Π ,(subst ρ A) ,(subst (up 1 ρ) B))]
[`(var ,i) (ρ i)] [`(var ,i) (ρ i)]
[`(app ,a ,b) `(app ,(subst ρ a) ,(subst ρ b))] [`(app ,a ,b) `(app ,(subst ρ a) ,(subst ρ b))]
@ -197,11 +143,10 @@
(subst (ext idsub-tm b) a)) (subst (ext idsub-tm b) a))
;; Coquand's algorithm but for β-normal forms ;; Coquand's algorithm but for β-normal forms
;; Subsumed by the compare function
(: η-eq? (-> Term Term Boolean)) (: η-eq? (-> Term Term Boolean))
(define (η-eq? a b) (define (η-eq? a b)
(match (list a b) (match (list a b)
['(U U) #t ] [`((U ,i) (U ,j)) (eqv? i j) ]
[`((Π ,A0 ,B0) (Π ,A1 ,B1)) [`((Π ,A0 ,B0) (Π ,A1 ,B1))
(and (η-eq? A0 A1) (η-eq? B0 B1))] (and (η-eq? A0 A1) (η-eq? B0 B1))]
['(zero zero) true] ['(zero zero) true]
@ -217,11 +162,10 @@
(: βη-eq? (-> Term Term Boolean)) (: βη-eq? (-> Term Term Boolean))
(define (βη-eq? a b) (define (βη-eq? a b)
(let ([n (max (scope a) (scope b))]) (η-eq? (normalize a) (normalize b)))
(compare n (interp a (λ (x) (delay (idsub n x)))) (interp b (λ (x) (delay (idsub n x)))))))
(: β-eq? (-> Term Term Boolean)) (: β-eq? (-> Term Term Boolean))
(define (β-eq? a b) (define (β-eq? a b)
(equal? (normalize a) (normalize 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?)

View file

@ -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"))