Chapter 3 - Definitional Equality and Propositional Equality


Require Import Base.
Require Import Omega.
Set Implicit Arguments.
Unset Strict Implicit.

3.1 Conversion Principle


Goal ~~True.
Proof.
  change (¬True False).
  change (~(True False)).
  change (~~True).
  hnf.
  change (~~True).
  cbv.
  change (~~True).
  simpl.
  pattern True.
  pattern not at 2.
  hnf.
  exact (fun ff I).
  Show Proof.
Qed.

Inductive demo (X : Type) (x : X) : Prop :=
| demoI : demo x.

Goal demo plus.
Proof.
  unfold plus.
  unfold plus.
  fold plus.
  apply demoI.
Qed.

Goal demo (fun x : natx).
Proof.
  change (demo (fun y : naty)).
  change (demo (fun myname : natmyname)).
  apply demoI.
Qed.

Section Demo.
  Variable n : nat.

  Goal demo (5+n+n).
  Proof.
    change (demo (2+3+n+n)).
    simpl.
    change (demo (10+n-5+n)).
    pattern n at 1.
    hnf.
    simpl.
    apply demoI.
  Qed.

  Variable X : Type.
  Variable f : X X X.

  Goal demo f.
  Proof.
    change (demo (fun xf x)).
    cbv.
    change (demo (fun x yf x y)).
    cbv.
    apply demoI.
  Qed.

End Demo.

3.2 Disjointness and Injectivity of Constructors


Goal false true.
Proof.
  intros A.
  change (if false then True else False).
  rewrite A.
  exact I.
Qed.

Lemma disjoint_O_S n :
  0 S n.
Proof.
  intros A.
  change (match 0 with 0 ⇒ False | _True end).
  rewrite A.
  exact I.
Qed.

Lemma injective_S x y :
  S x = S y x = y.
Proof.
  intros A.
  change (pred (S x) = pred (S y)).
  rewrite A.
  reflexivity.
Qed.

Goal x, S x 0.
Proof. intros x A. discriminate A. Qed.

Goal x y, S x = S y x = y.
Proof. intros x y A. injection A. auto. Qed.

(* Exercise 3.2.1 *)
Goal (X: Type) (x:X),
       Some x None.
Abort.

Goal (X: Type) (x: X) (A: list X),
       x :: A nil.
Abort.

(* Exercise 3.2.2 *)
Goal (X Y: Type) (x x' : X) (y y' : Y),
       (x,y) = (x',y') x=x' y = y'.
Abort.

Goal (X : Type) (x x' : X) (A A' : list X),
       x::A = x'::A' x=x' A = A'.
Abort.

(* Exercise 3.2.3 *)
Goal x, negb x x.
Abort.

Goal x, S x x.
Abort.

Goal x y z, x + y = x + z y = z.
Abort.

Goal x y : nat, x = y x y.
Abort.

(* Exercise 3.2.4 *)
Goal (X : Type) (f : list X X), A B, f A = f B A = B.
Abort.

(* Exercise 3.2.5 *)
Goal False True.
Abort.

(* Exercise 3.2.6 *)
Goal (f : nat nat nat) x,
       (fun xf x x) f x.
Abort.

3.3 Leibniz Equality


Definition leibniz_eq (X : Type) (x y : X) : Prop :=
   p : X Prop, p x p y.

Notation "x == y" := (leibniz_eq x y) (at level 70, no associativity).

Lemma leibniz_refl X (x : X) :
  x == x.
Proof. hnf. auto. Qed.

Lemma leibniz_sym X (x y : X) :
  x == y y == x.
Proof.
  unfold leibniz_eq. intros A p.
  apply (A (fun zp z p x)).
  auto.
Qed.

Lemma leibniz_agrees X (x y : X) :
  x == y x = y.
Proof.
  split ; intros A.
  - apply (A (fun zx=z)). reflexivity.
  - rewrite A. apply leibniz_refl.
Qed.

Lemma leibniz_rewrite X (x y : X) (p : X Prop) :
  x == y p y p x.
Proof. intros A. apply (leibniz_sym A). Qed.

Lemma leibniz_plus_assoc x y z :
  (x + y) + z == x + (y + z).
Proof.
  induction x ; simpl.
  - apply leibniz_refl.
  - pattern (x+y+z). apply (leibniz_rewrite IHx). apply leibniz_refl.
Qed.

(* Exercise 3.3.1 *)
Goal x y, x + y == y + x.
Abort.

(* Exercise 3.3.2 *)
Lemma leibniz_rewrite_lr X (x y : X) (p : X Prop) :
  x == y p y p x.
Abort.

Lemma leibniz_rewrite_rl X (x y : X) (p : X Prop) :
       x == y p x p y.
Abort.

3.4 By Name Specification of Implicit Arguments


About leibniz_sym.

Goal X (x y : X) (p : X Prop),
       x == y p y p x.
Proof.
  intros X x y p A.
  Check leibniz_sym A.
  Check leibniz_sym A (p:=p).
  Check @leibniz_sym X x y A p.
  Check @leibniz_sym _ _ _ A p.
  exact (leibniz_sym A (p:=p)).
  Show Proof.
Qed.

3.5 Local Definitions


Compute let x := 2 in x + x.

Compute let x := 2 in let x := x + x in x.

Compute let f := plus 3 in f 7.

Check let X := nat in (fun x : Xx) 2.

(* This check is supposed to result in an error:
Check (fun X => (fun x : X => x) 2) nat.
*)


3.6 Proof of nat <> bool


Goal bool nat.
Proof.
  pose (p X := x y z : X, x=y x=z y=z).
  assert (H: ¬p nat).
  { intros B. specialize (B 0 1 2). destruct B as [B|[B|B]] ; discriminate B. }
  intros A. apply H. rewrite <- A.
  intros [|] [|] [|] ; auto.
Qed.

(* Exercise 3.6.1 *)
Goal bool option bool.
Abort.

Goal option bool prod bool bool.
Abort.

Goal bool False.
Abort.

3.7 Cantor's Theorem


Definition surjective (X Y : Type) (f : X Y) : Prop := y, x, f x = y.

Lemma Cantor X :
  ¬ f : X X Prop, surjective f.
Proof.
  intros [f A].
  pose (g x := ¬ f x x).
  specialize (A g).
  destruct A as [x A].
  assert (H: ¬ (g x ¬ g x)) by tauto.
  apply H. unfold g at 1. rewrite A. tauto.
Qed.

(* Exercise 3.7.1 *)

Goal ¬ f : nat nat nat, surjective f.
Abort.

Goal ¬ f : bool bool bool, surjective f.
Abort.

(* Exercise 3.7.2 *)

Lemma Cantor_generalized X Y :
  ( N : Y Y, y, N y y)
  ¬ f : X X Y, surjective f.
Abort.

(* Exercise 3.7.3 *)

Lemma Cantor_neq X Y (f : X X Y) (N : Y Y) :
 ( y, N y y) h, x, f x h.
Abort.

(* Exercise 3.7.4 *)

Definition injective (X Y : Type) (f : X Y) : Prop := x x' : X, f x = f x' x = x'.

Goal X Y : Type, f : X Y, ( g : Y X, y, f (g y) = y) surjective f.
Abort.

Goal X Y : Type, f : X Y, ( g : Y X, x, g (f x) = x) injective f.
Abort.

(* Exercise 3.7.5 *)

Goal X, ¬ f : (X Prop) X, injective f.
Proof.
  intros X [f A].
  pose (p x := h, f h = x ¬ h x).
  (* ... *)
Abort.

3.8 Kaminski's Equation


Goal (f : bool bool) (x : bool), f (f (f x)) = f x.
Proof. intros f x. destruct x, (f true) eqn:A, (f false) eqn:B ; congruence. Qed.

Lemma destruct_eqn_bool (p : bool Prop) (x : bool) :
  (x = true p true) (x = false p false) p x.
Proof. destruct x ; auto. Qed.

Goal (f : bool bool) (x : bool), f (f (f x)) = f x.
Proof.
  destruct x ;
  pattern (f true) ; apply destruct_eqn_bool ;
  pattern (f false) ; apply destruct_eqn_bool ;
  congruence.
Qed.

(* Exercise 3.8.1 *)

Goal (f g : bool bool) (x : bool), f (f (f (g x))) = f (g (g (g x))).
Abort.

3.9 Boolean Equality Tests


Fixpoint nat_eqb (x y : nat) : bool :=
  match x, y with
    | O, Otrue
    | S x', S y'nat_eqb x' y'
    | _, _false
  end.

Lemma nat_eqb_agrees x y :
  nat_eqb x y = true x = y.
Proof.
  revert y.
  induction x ; intros [|y] ; split ; simpl ; intros A ; try congruence.
  - f_equal. apply IHx, A.
  - apply IHx. congruence.
Qed.

(* Exercise 3.9.1 *)

(* Definition bool_eqb (x y: bool) : bool :=
 (* ... *) *)


(* Exercise 3.9.2 *)

(* Fixpoint list_eqb (X: Type) (X_eqb: X -> X -> bool) (A B: list X) :=
 (* ... *)

Lemma list_eqb_agrees X (X_eqb : X -> X -> bool) (A B : list X) :
  (forall x y, X_eqb x y = true <-> x = y) ->
  (list_eqb X_eqb A B = true <-> A = B). *)