Chapter 7 - Inductive Predicates


Require Import Base.

7.1 Nonparametric Arguments and Linerization


Inductive zero : nat → Prop :=
| zeroI : zero 0.

Lemma zero_iff x :
  zero x ↔ x = 0.
Proof.
  split ; intros A.
  - destruct A. reflexivity.
  - subst x. constructor.
Qed.

Goal ¬ zero 2.
Proof. intros A. remember 2 as x. destruct A. discriminate Heqx. Qed.

(* Exercise 7.1.1 *)
Goal zero 0.
Abort.

Goal ¬ zero 7.
Abort.

Goal ∀ x, ¬ zero (S x).
Abort.

(* Exercise 7.1.2 *)
Goal ∀ x, (zero x) + (¬ zero x).
Abort.

(* Exercise 7.1.3 *)
Lemma remember (X: Type) (p: X → Type) (x: X):
  (∀ y, y = x → p y) → p x.
Abort.

Goal ∀ x, ¬ zero (S x).
Abort.

(* Exercise 7.1.4 *)
Goal ∀ x, zero x ↔ ∀ p: nat → Prop, p 0 → p x.
Abort.

(* Exericse 7.1.5 *)
(* Fixpoint zerob : nat -> bool :=
  (* ... *)

Goal forall x, zero x <-> zerob x = true. 
*)


(* Exercise 7.1.6 *)
(* Define leo.

Goal forall x, leo x <-> x <= 1. 

Characterize leo impredicatively and prove the correctness. 

Characterize leo with a boolean test leob: nat -> bool and prove the correctness of the characterization *)


7.2 Even


Inductive even : nat → Prop :=
| evenO : even 0
| evenS x : even x → even (S (S x)).

Lemma even_iff x :
  even x ↔ ∃ k, x = 2×k.
Proof.
  split ; intros A.
  - induction A.
    + ∃ 0. reflexivity.
    + destruct IHA as [k IHA]. subst x. ∃ (S k). simpl. omega.
  - destruct A as [k A]. subst x. induction k ; simpl.
    + constructor.
    + replace (S(k+S(k+0))) with (S (S (2×k))) by omega.
      constructor. exact IHk.
Qed.

Goal ¬ even 3.
Proof.
  intros A. remember 3 as x. destruct A.
  - discriminate Heqx.
  - destruct A ; discriminate Heqx.
Qed.

Lemma even_descent x :
  even (S (S x)) → even x.
Proof.
  intros A. remember (S (S x)) as y.
  destruct A as [|y A].
  - discriminate Heqy.
  - congruence.
Qed.

(* Exericse 7.2.1 *)
Goal even 6.
Abort.

Goal ¬ even 5.
Abort.

(* Exercise 7.2.2 *)
Goal ∀ x y, even x → even y → even (x+y).
Abort.

Goal ∀ x y, even x → even (x+y) → even y.
Abort.

Goal ∀ x, even x → even (S x) → False.
Abort.

(* Exercise 7.2.3 *)
Lemma even_inv x : even x → x = 0 ∨ ∃ x', x = S (S x') ∧ even x'.
Abort.

(* Exercise 7.2.4 *)
Goal ∀ x, even x ↔ ∀ p : nat → Prop, p 0 → (∀ y, p y → p (S (S y))) → p x.
Abort.

(* Exercise 7.2.5 *)
Lemma even_succ x : (¬ even x → even (S x)) ∧ (¬ even (S x) → even x).
Abort.

(* Exercise 7.2.6 *)
Goal ∀ x, even x → ¬ even (S x).
Abort.

(* Exercise 7.2.7 *)
Goal ∀ x, {even x} + {¬ even x}.
Abort.

(* Exercise 7.2.8 *)
Inductive even' (x : nat) : Prop :=
| even'O : x=0 → even' x
| even'S y : even' y → x = S (S y) → even' x.

Goal ¬ even' 3.
Abort.

Goal ∀ x, even' x ↔ even x.
Abort.

(* Exercise 7.2.9 *)
Fixpoint evenb (x : nat) : bool :=
  match x with
    | 0 ⇒ true
    | S (S x') ⇒ evenb x'
    | _ ⇒ false
  end.

Lemma evenb_even x : (evenb x = true → even x) ∧ (evenb (S x) = true → even (S x)).
Abort.

7.3 Less or Equal


(* These definitions lead to name collisions with the Base library and thus have been commented: *)
(*Inductive le (x : nat) : nat -> Prop :=
| le_n : le x x
| le_S y : le x y -> le x (S y).


Notation "x <= y" := (le x y) (at level 70).
*)


Lemma le_iff x y :
  x ≤ y ↔ ∃ k, k + x = y.
Proof.
  split.
  - intros A. induction A as [|y A].
    + ∃ 0. reflexivity.
    + destruct IHA as [k B]. ∃ (S k). simpl. congruence.
  - intros [k A]. subst y. induction k ; simpl.
    + constructor.
    + constructor. exact IHk.
Qed.

Lemma le_O x : 0 ≤ x.
Admitted. (* Proof as exercise! *)

Lemma le_SS x y : x ≤ y → S x ≤ S y.
Admitted. (* Proof as exercise! *)

Lemma le_Strans x y : S x ≤ y → x ≤ y.
Admitted. (* Proof as exercise! *)

Lemma le_zero x :
  x ≤ 0 → x = 0.
Proof.
  intros A. remember 0 as y. destruct A as [|y A].
  - reflexivity.
  - discriminate Heqy.
Qed.

Lemma le_SS' x y :
  S x ≤ S y → x ≤ y.
Proof.
  intros A. remember (S y) as y'. induction A as [|y' A].
  - injection Heqy'. intros A. subst y. constructor.
  - injection Heqy'. intros B. subst y'. apply le_Strans, A.
Qed.

Definition le_dec x y : dec (x ≤ y).
  revert y. induction x ; intros y.
  - left. apply le_O.
  - destruct y.
    + right. intros A. apply le_zero in A. discriminate A.
    + destruct (IHx y) as [A|A].
      × left. apply le_SS, A.
      × right. intros B. apply A, le_SS', B.
Defined.

(* Exercise 7.3.2 *)
Lemma le_inv x y : x ≤ y → x = y ∨ ∃ y', y = S y' ∧ x ≤ y'.
Abort.

(* Exercise 7.3.3 - Do not use omega. *)
Lemma le_trans x y z : x ≤ y → y ≤ z → x ≤ z.
Abort.

(* Exericse 7.3.4 - Do not use omega. *)
Goal ∀ x y, S x ≤ y → x ≠ y.
Abort.

(* Exercise 7.3.5 - Do not use omega. *)
Goal ∀ x y, x ≤ y → y ≤ x → x=y.
Abort.

(* Exercise 7.3.6 - Do not use omega. *)
Goal ∀ x y, x ≤ y ↔ leb x y = true.
Abort.

7.4 Equality


(* We need to disable these definitions because of conflicts with Base definitions *)
(*
Inductive eq (X : Type) (x : X) : X -> Prop :=
| eq_refl : eq x x.


Notation "x = y" := (eq x y) (at level 70).
*)


Lemma Leibniz (X : Type) (x y : X) :
  x = y ↔ ∀ p : X → Prop, p x → p y.
Proof.
  split ; intros A.
  - destruct A. auto.
  - apply (A (fun z ⇒ x = z)). constructor.
Qed.

7.5 Exceptions from the Elim Restriction


Definition cast (X : Type) (x y : X) (f : X → Type) : x = y → f x → f y.
  intros A B. destruct A. exact B.
Defined.

Definition fin (n : nat) : Type := Nat.iter n option False.

Goal ∀ n, fin n → fin (n+0).
Proof. intros n. apply cast. omega. Qed.

(* Exercise 7.5.1 *)
Goal ∀ X Y : Prop, X ∧ Y → prod X Y.
Abort.

(* Exercise 7.5.3 *)
Definition exfalso : False → ∀ X: Type, X.
Abort.

(* Exercise 7.5.4 *)
Goal ∀ (X : Type) (x y : X), (∀ p : X → Prop, p x → p y) → ∀ p : X → Type, p x → p y.
Abort.

7.6 Safe and Nonuniform Parameters


Inductive safe (p : nat → Prop) (n : nat) : Prop :=
| safeB : p n → safe p n
| safeS : safe p (S n) → safe p n.

Lemma safe_dclosed k n p :
  k ≤ n → safe p n → safe p k.
Proof.
  intros A B. induction A as [|n A].
  - exact B.
  - apply IHA. right. exact B.
Qed.

Lemma safe_iff p n :
  safe p n ↔ ∃ k, n ≤ k ∧ p k.
Proof.
  split ; intros A.
  - induction A as [n B|n A].
    + ∃ n. auto.
    + destruct IHA as [k [B C]].
      ∃ k. split. omega. exact C.
  - destruct A as [k [A B]].
    apply (safe_dclosed A). left. exact B.
Qed.

(* Exercise 7.6.1 *)
Inductive least (p : nat → Prop) (n : nat) : nat → Prop :=
| leastB : p n → least p n n
| leastS k : ¬ p n → least p (S n) k → least p n k.

Lemma least_correct1 p n k : least p n k → p k.
Abort.

Lemma least_correct2 p n k : least p n k → n ≤ k.
Abort.

Lemma least_correct3 p n k : least p n k → ∀ k', n ≤ k' → p k' → k ≤ k'.
Abort.

Lemma least_correct4 p n k : (∀ x, dec (p x)) → p (n+k) → ∃ k', least p n k'.
Abort.

Lemma least_correct p n k (p_dec : ∀ x, dec (p x)) :
  least p n k ↔ p k ∧ n ≤ k ∧ ∀ k', n ≤ k' → p k' → k ≤ k'.
Abort.

7.7 Constructive Choice for Nat


Section First.
Variable p : nat → Prop.
Variable p_dec : ∀ n, dec (p n).

Fixpoint first (n : nat) (A : safe p n) : {k | p k} :=
  match p_dec n with
    | left B ⇒ exist p n B
    | right B ⇒ first match A with
                        | safeB C ⇒ match B C with end
                        | safeS A' ⇒ A'
                      end
  end.

Lemma cc_nat : (∃ x, p x) → {x | p x}.
Proof.
  intros A. apply first with (n:=0).
  destruct A as [n A].
  apply safe_dclosed with (n:=n). omega. left. exact A.
Qed.

End First.

(* Exercise 7.7.1 Write a constructive choice function for bool. *)
Definition cc_bool (p : bool → Prop) (p_dec : ∀ x, dec (p x)) : (∃ x, p x) → {x | p x}.
Proof.
Abort.

(* Exercise 7.7.2 *)
Section Second.

Variable p : nat → Prop.
Variable p_dec : ∀ n, dec (p n).

Fixpoint first1 (n : nat) (A : safe p n) : {k | p k ∧ k ≥ n}.
  Abort.

Fixpoint first2 (n : nat) (A : safe p n) : {k | p k ∧ k ≥ n ∧ ∀ k', n ≤ k' → p k' → k ≤ k'}.
  Abort.

End Second.

(* Exercise 7.7.3 *)
Definition cc_fin (n : nat) (p : fin n → Prop) (p_dec : ∀ x, dec (p x))
  : (∃ x, p x) → {x | p x}.
Abort.

7.8 Technical Summary


Print least.

Check least.
Check leastB.
Check leastS.

7.9 Induction Lemmas


Print even.
Check even_ind.

Print le.
Check le_ind.

(* Exercise 7.9.1  Complete the following definitions of the induction lemmas for even and le.*)
(* Definition even_ind' (p : nat -> Prop) (r1 : p 0) (r2 : forall x, even x -> p x -> p (S (S x))) 
  : forall x, even x -> p x := (* ... *).

Definition le_ind' (x : nat) (p : nat -> Prop) (r1 : p x) (r2 : forall y, le x y -> p y -> p (S y))
  : forall y, le x y -> p y :=  (* ... *). *)