Lazy Nat
This s a lazified version of the natural number that allow one to delay computation until demanded. This is useful for large natural numbers (often upper bounds) where only a small number of terms are actually need for compuation.
Convert a nat to a lazy nat
Fixpoint LazifyNat (n : N) {struct n} : LazyNat :=
match n with
| O => LazyO
| S p => LazyS (fun _ => (LazifyNat p))
end.
match n with
| O => LazyO
| S p => LazyS (fun _ => (LazifyNat p))
end.
Definition LazyPred (n:LazyNat) : LazyNat :=
match n with
| LazyO => LazyO
| LazyS n' => (n' tt)
end.
Lemma LazifyPred : forall n, LazifyNat (pred n) = LazyPred (LazifyNat n).
match n with
| LazyO => LazyO
| LazyS n' => (n' tt)
end.
Lemma LazifyPred : forall n, LazifyNat (pred n) = LazyPred (LazifyNat n).
Fixpoint LazyPlus (n m : LazyNat) {struct n} : LazyNat :=
match n with
| LazyO => m
| LazyS p => LazyS (fun _ => LazyPlus (p tt) m)
end.
Lemma LazifyPlus : forall n m, (LazifyNat (n + m) = LazyPlus (LazifyNat n) (LazifyNat m))%nat.
match n with
| LazyO => m
| LazyS p => LazyS (fun _ => LazyPlus (p tt) m)
end.
Lemma LazifyPlus : forall n m, (LazifyNat (n + m) = LazyPlus (LazifyNat n) (LazifyNat m))%nat.
Fixpoint Pmult_LazyNat (x:positive) (pow2:LazyNat) {struct x} : LazyNat :=
match x with
| xI x' => (LazyPlus pow2 (Pmult_LazyNat x' (LazyPlus pow2 pow2)))%nat
| xO x' => Pmult_LazyNat x' (LazyPlus pow2 pow2)%nat
| xH => pow2
end.
Lemma LazifyPmult_LazyNat : forall x pow2, LazifyNat (Pmult_nat x pow2) = Pmult_LazyNat x (LazifyNat pow2).
match x with
| xI x' => (LazyPlus pow2 (Pmult_LazyNat x' (LazyPlus pow2 pow2)))%nat
| xO x' => Pmult_LazyNat x' (LazyPlus pow2 pow2)%nat
| xH => pow2
end.
Lemma LazifyPmult_LazyNat : forall x pow2, LazifyNat (Pmult_nat x pow2) = Pmult_LazyNat x (LazifyNat pow2).
Convert a positive to a lazy nat. This is the most common way of
generating lazy nats.
Definition LazyNat_of_P (x:positive) := Pmult_LazyNat x (LazyS (fun _ => LazyO)).
Lemma LazifyNat_of_P : forall x, LazifyNat (nat_of_P x) = LazyNat_of_P x.
Fixpoint Pplus_LazyNat (p:positive)(n:LazyNat) {struct n} : positive :=
match n with
| LazyO => p
| (LazyS n') => (Pplus_LazyNat (Psucc p) (n' tt))
end.
Lemma LazifyNat_of_P : forall x, LazifyNat (nat_of_P x) = LazyNat_of_P x.
Fixpoint Pplus_LazyNat (p:positive)(n:LazyNat) {struct n} : positive :=
match n with
| LazyO => p
| (LazyS n') => (Pplus_LazyNat (Psucc p) (n' tt))
end.