Check nat_ind.
Goal ∀ n, n + 0 = n.
Proof.
apply (nat_ind (fun n ⇒ n + 0 = n)).
- reflexivity.
- intros n IHn. simpl. f_equal. exact IHn.
Qed.
Goal ∀ n m, n + S m = S (n + m).
Proof.
intros n m. revert n.
apply (nat_ind (fun n ⇒ n + S m = S (n + m))) ; simpl.
- reflexivity.
- intros n IHn. f_equal. exact IHn.
Qed.
Definition nat_ind (p : nat → Prop) (basis : p 0) (step : ∀ n, p n → p (S n))
: ∀ n, p n := fix f n := match n return p n with
| 0 ⇒ basis
| S n' ⇒ step n' (f n')
end.
(* Exercise 4.1 *)
Goal ∀ n m, n + S m = S (n + m).
Abort.
(* Exercise 4.2 *)
(*Definition list_ind (X: Type) (p: list X -> Prop) (basis: p nil) (step: forall (x:X) (A: list X), p A -> p (x ::A)): forall A: list X, p A := *)
Goal ∀ (X: Type) (x y z: list X), x ++ (y ++ z) = (x ++ y) ++ z.
Abort.
Check list_ind.
Definition prec (p : nat → Type) (x : p 0) (f : ∀ n, p n → p (S n))
: ∀ n, p n := fix F n := match n return p n with
| 0 ⇒ x
| S n' ⇒ f n' (F n')
end.
Check fun p : nat → Prop ⇒ prec (p:= p).
Lemma nat_ind' (p : nat → Prop) :
p 0 → (∀ n, p n → p (S n)) → ∀ n, p n.
Proof. exact (prec (p:=p)). Qed.
Definition add := prec (fun y ⇒ y) (fun _ r y ⇒ S (r y)).
Compute add 3 7.
Goal ∀ x y, add x y = x + y.
Proof. intros x y. induction x ; simpl ; congruence. Qed.
Goal ∀ X f x n ,
Nat.iter n f x = prec (p:= fun _ ⇒ X) x (fun _ ⇒ f) n.
Proof. induction n ; simpl ; congruence. Qed.
(* Exercise 4.2.1 *)
Goal prec = nat_rect.
Abort.
(* Exercise 4.2.2 *)
Goal ∀ (p: nat → Prop) (x: p 0) (f: ∀ n, p n → p (S n)),
prec x f 0 = x.
Abort.
Goal ∀ (p: nat → Prop) (x: p 0) (f: ∀ n, p n → p (S n)) (n: nat),
prec x f (S n) = f n (prec x f n).
Abort.
(* Exercise 4.2.3 *)
(*Definition mult' : nat -> nat -> nat := fun n m => prec (* ... *)
Goal forall n m, mult n m = mult' n m.
Abort. *)
(* Definition fact' : nat -> nat := prec (* ... *).
Goal forall n, fact n = fact' n.
Abort. *)
(* Exercise 4.2.4 *)
(* Definition pred' : nat -> nat := (* ... *) *)
(* Goal forall n, pred n = pred' n.
Abort. *)
(*Definition pred (x : nat) : nat := prec (* ... *) *)
(* Exercise 4.2.5 *)
(*Goal forall X x f n,
match n with O => x |S n' => f n' end = prec (* ... *). *)
Lemma size_induction X (f : X → nat) (p : X → Prop) :
(∀ x, (∀ y, f y < f x → p y) → p x) →
∀ x, p x.
Proof.
intros step x. apply step.
assert (G: ∀ n y, f y < n → p y).
{ intros n. induction n.
- intros y B. exfalso. omega.
- intros y B. apply step. intros z C. apply IHn. omega. }
apply G.
Qed.
(* Exercise 4.3.1 *)
Lemma complete_induction (p : nat → Prop) :
(∀ x, (∀ y, y < x → p y) → p x) → ∀ x, p x.
Abort.
(* Exercise 4.3.2 *)
(* Definition lt : nat -> nat -> Prop := *)
Lemma lt_tran x y z : lt x y → lt y (S z) → lt x z.
Abort.
Definition addition (f : nat → nat → nat) : Prop :=
∀ x y,
f x 0 = x ∧
f x (S y) = f (S x) y.
Lemma addition_existence :
addition plus.
Proof. intros x y. omega. Qed.
Lemma addition_uniqueness f g :
addition f → addition g → ∀ x y, f x y = g x y.
Proof.
intros A B x y. revert x. induction y ; intros x.
- destruct (A x 0) as [A' _]. destruct (B x 0) as [B' _]. congruence.
- destruct (A x y) as [_ A']. destruct (B x y) as [_ B']. specialize (IHy (S x)). congruence.
Qed.
Definition ackermann (f : nat → nat → nat) : Prop :=
∀ m n,
f O n = S n ∧
f (S m) O = f m 1 ∧
f (S m) (S n) = f m (f (S m) n).
Definition ack : nat → nat → nat :=
fix f m := match m with
| O ⇒ S
| S m' ⇒ fix g n := match n with
| O ⇒ f m' 1
| S n' ⇒ f m' (g n')
end
end.
Goal ackermann ack.
Proof. unfold ackermann. auto. Qed.
Goal ∀ f g x y, ackermann f → ackermann g → f x y = g x y.
Proof.
intros f g x y A B. revert y. induction x ; intros y.
- destruct (A 0 y) as [C _]. destruct (B 0 y) as [D _]. congruence.
- induction y.
+ destruct (A x 0) as [_ [C _]]. destruct (B x 0) as [_ [D _]]. congruence.
+ destruct (A x y) as [_ [_ C]]. destruct (B x y) as [_ [_ D]]. congruence.
Qed.
(* Exercise 4.4.1 *)
(* Definition multiplication (f : nat -> nat -> nat) : Prop := (* ... *)
Goal multiplication mult.
Abort. *)
(* Definition subtraction (f: nat -> nat -> nat): Prop := (* ... *)
Goal subtraction minus.
Abort. *)
(* Exercise 4.4.2 *)
(*Definition ack' : nat -> nat -> nat := prec (* ... *)
Goal ackermann ack'.
*)
(* Exercise 4.4.3 *)
Definition primitive_recursion
(r : ∀ p : nat → Type, p 0 → (∀ n, p n → p (S n)) → ∀ n, p n)
: Prop :=
∀ p x f n,
let r := r p x f in
r 0 = x ∧
r (S n) = f n (r n).
Goal primitive_recursion prec.
Abort.
(* Exercise 4.4.4 *)
(* Definition nat_iteration (* ... *)
Goal nat_iteration Nat.iter.
(* Show uniqueness of the above specfication. *)
*)