quox/examples/nat.quox

131 lines
3.9 KiB
Plaintext
Raw Normal View History

2023-04-18 18:42:40 -04:00
load "misc.quox";
load "bool.quox";
load "either.quox";
namespace nat {
2023-11-03 12:42:44 -04:00
#[compile-scheme "(lambda (n) (cons n 'erased))"]
2023-07-22 15:26:20 -04:00
def dup! : (n : ) → [ω. Sing n] =
2023-04-01 13:16:30 -04:00
λ n ⇒
2023-07-22 15:26:20 -04:00
case n return n' ⇒ [ω. Sing n'] of {
zero ⇒ [(zero, [δ _ ⇒ zero])];
succ n, 1.d ⇒
appω (Sing n) (Sing (succ n))
(sing.app n (λ n ⇒ succ n)) d
2023-04-01 13:16:30 -04:00
};
2023-07-22 15:26:20 -04:00
def dup : → [ω.] =
λ n ⇒ appω (Sing n) (sing.val n) (dup! n);
2023-11-03 12:42:44 -04:00
#[compile-scheme "(lambda% (m n) (+ m n))"]
def plus : =
2023-04-01 13:16:30 -04:00
λ m n ⇒
case m return of {
2023-04-01 13:16:30 -04:00
zero ⇒ n;
succ _, 1.p ⇒ succ p
};
2023-11-03 12:42:44 -04:00
#[compile-scheme "(lambda% (m n) (* m n))"]
def timesω : → ω. =
2023-04-01 13:16:30 -04:00
λ m n ⇒
case m return of {
2023-04-01 13:16:30 -04:00
zero ⇒ zero;
succ _, 1.t ⇒ plus n t
};
def times : =
λ m n ⇒ case dup n return of { [n] ⇒ timesω m n };
2023-04-01 13:16:30 -04:00
def pred : = λ n ⇒ case n return of { zero ⇒ zero; succ n ⇒ n };
2023-04-01 13:16:30 -04:00
2023-04-18 18:42:40 -04:00
def pred-succ : ω.(n : ) → pred (succ n) ≡ n : =
λ n ⇒ δ 𝑖 ⇒ n;
2023-04-17 15:44:16 -04:00
def0 succ-inj : (m n : ) → succ m ≡ succ n : → m ≡ n : =
2023-04-18 18:42:40 -04:00
λ m n eq ⇒ δ 𝑖 ⇒ pred (eq @𝑖);
2023-11-05 09:38:38 -05:00
#[compile-scheme "(lambda% (m n) (max 0 (- m n)))"]
def minus : =
λ m n ⇒
(case n return of {
zero ⇒ λ m ⇒ m;
succ _, f ⇒ λ m ⇒ f (pred m)
}) m;
2023-04-18 18:42:40 -04:00
def0 IsSucc : → ★ =
λ n ⇒ case n return ★ of { zero ⇒ False; succ _ ⇒ True };
2023-04-18 18:42:40 -04:00
def isSucc? : ω.(n : ) → Dec (IsSucc n) =
λ n ⇒
caseω n return n' ⇒ Dec (IsSucc n') of {
zero ⇒ No (IsSucc zero) (λ v ⇒ v);
succ n ⇒ Yes (IsSucc (succ n)) 'true
};
def zero-not-succ : 0.(m : ) → Not (zero ≡ succ m : ) =
λ m eq ⇒ coe (𝑖 ⇒ IsSucc (eq @𝑖)) @1 @0 'true;
2023-04-18 18:42:40 -04:00
def succ-not-zero : 0.(m : ) → Not (succ m ≡ zero : ) =
λ m eq ⇒ coe (𝑖 ⇒ IsSucc (eq @𝑖)) 'true;
2023-04-18 18:42:40 -04:00
def0 not-succ-self : (m : ) → Not (m ≡ succ m : ) =
2023-04-18 18:42:40 -04:00
λ m ⇒
case m return m' ⇒ Not (m' ≡ succ m' : ) of {
2023-04-18 18:42:40 -04:00
zero ⇒ zero-not-succ 0;
succ n, ω.ih ⇒ λ eq ⇒ ih (succ-inj n (succ n) eq)
}
2023-11-03 12:42:44 -04:00
#[compile-scheme "(lambda% (m n) (if (= m n) Yes No))"]
2023-04-18 18:42:40 -04:00
def eq? : DecEq =
λ m ⇒
caseω m
return m' ⇒ ω.(n : ) → Dec (m' ≡ n : )
of {
zero ⇒ λ n ⇒
caseω n return n' ⇒ Dec (zero ≡ n' : ) of {
zero ⇒ Yes (zero ≡ zero : ) (δ _ ⇒ zero);
succ n' ⇒ No (zero ≡ succ n' : ) (λ eq ⇒ zero-not-succ n' eq)
};
succ m', ω.ih ⇒ λ n ⇒
caseω n return n' ⇒ Dec (succ m' ≡ n' : ) of {
zero ⇒ No (succ m' ≡ zero : ) (λ eq ⇒ succ-not-zero m' eq);
succ n' ⇒
dec.elim (m' ≡ n' : ) (λ _ ⇒ Dec (succ m' ≡ succ n' : ))
(λ y ⇒ Yes (succ m' ≡ succ n' : ) (δ 𝑖 ⇒ succ (y @𝑖)))
(λ n ⇒ No (succ m' ≡ succ n' : ) (λ eq ⇒ n (succ-inj m' n' eq)))
(ih n')
}
};
2023-04-23 11:33:32 -04:00
def eqb : ω. → ω. → Bool = λ m n ⇒ dec.bool (m ≡ n : ) (eq? m n);
2023-04-18 18:42:40 -04:00
def0 plus-zero : (m : ) → m ≡ plus m 0 : =
2023-04-18 18:42:40 -04:00
λ m ⇒
case m return m' ⇒ m' ≡ plus m' 0 : of {
2023-04-18 18:42:40 -04:00
zero ⇒ δ _ ⇒ zero;
succ _, ω.ih ⇒ δ 𝑖 ⇒ succ (ih @𝑖)
};
def0 plus-succ : (m n : ) → succ (plus m n) ≡ plus m (succ n) : =
2023-04-18 18:42:40 -04:00
λ m n ⇒
case m return m' ⇒ succ (plus m' n) ≡ plus m' (succ n) : of {
2023-04-18 18:42:40 -04:00
zero ⇒ δ _ ⇒ succ n;
succ _, ω.ih ⇒ δ 𝑖 ⇒ succ (ih @𝑖)
};
def0 plus-comm : (m n : ) → plus m n ≡ plus n m : =
2023-04-18 18:42:40 -04:00
λ m n ⇒
case m return m' ⇒ plus m' n ≡ plus n m' : of {
2023-04-18 18:42:40 -04:00
zero ⇒ plus-zero n;
succ m', ω.ih ⇒
trans (succ (plus m' n)) (succ (plus n m')) (plus n (succ m'))
𝑖 ⇒ succ (ih @𝑖))
(plus-succ n m')
};
}