
elim now runs. Parts of the stdlib have been converted to use elim, but it's complicated to program with. Need to implement case and fix in terms of elim, I think.
48 lines
1.3 KiB
Racket
48 lines
1.3 KiB
Racket
#lang s-exp "../redex-curnel.rkt"
|
|
(require "sugar.rkt" "bool.rkt")
|
|
;; TODO: override (all-defined-out) to enable exporting all these
|
|
;; properly.
|
|
(provide nat z s add1 sub1 plus )
|
|
(module+ test
|
|
(require rackunit))
|
|
|
|
(data nat : Type
|
|
(z : nat)
|
|
;; TODO: Can't use -> syntax here due to issues with names
|
|
(s : (forall (x : nat) nat)))
|
|
|
|
(define (add1 (n : nat)) (s n))
|
|
(module+ test
|
|
(check-equal? (add1 (s z)) (s (s z))))
|
|
|
|
(define (sub1 (n : nat))
|
|
(case* nat n (lambda (x : nat) nat)
|
|
[z z]
|
|
[(s (x : nat)) IH: ((ih-x : nat)) x]))
|
|
(module+ test
|
|
(check-equal? (sub1 (s z)) z))
|
|
|
|
(define (plus (n1 : nat) (n2 : nat))
|
|
(case* nat n1 (lambda (x : nat) nat)
|
|
[z n2]
|
|
[(s (x : nat)) IH: ((ih-x : nat))
|
|
(s ih-x)]))
|
|
(module+ test
|
|
(check-equal? (plus z z) z)
|
|
(check-equal? (plus (s (s z)) (s (s z))) (s (s (s (s z))))))
|
|
|
|
(define (nat-equal? (n1 : nat) (n2 : nat) : bool)
|
|
(case* nat n1 (lambda (x : nat) bool)
|
|
[z (case* nat n2 (lambda (x : nat) bool)
|
|
[z btrue]
|
|
[(s (x : nat)) IH: ((ih-x : bool)) bfalse])]
|
|
[(s (x : nat)) IH: ((ih-x : bool))
|
|
(case* nat n2 (lambda (x : nat) bool)
|
|
[z bfalse]
|
|
[(s (x : nat)) IH: ((ih-x : bool))
|
|
ih-x])]))
|
|
(module+ test
|
|
(check-equal? btrue (nat-equal? z z))
|
|
(check-equal? bfalse (nat-equal? z (s z)))
|
|
(check-equal? btrue (nat-equal? (s z) (s z))))
|