(* Commented because of naming conflicts with the Standard library:
Inductive bool : Type :=
| true : bool
| false : bool.
Definition negb (x : bool) : bool :=
match x with
| true => false
| false => true
end. *)
Check negb.
Check negb (negb true).
Compute negb (negb true).
Lemma L1 :
negb true = false.
Proof. simpl. reflexivity. Qed.
Lemma negb_negb (x : bool) :
negb (negb x) = x.
Proof.
destruct x.
- reflexivity.
- reflexivity.
Qed.
Goal ∀ (x: bool), negb (negb x) = x.
Proof.
destruct x; reflexivity.
Qed.
(* Commented because of naming conflicts with the Standard library:
Definition andb (x y : bool) : bool :=
match x with
| true => y
| false => false
end. *)
Print andb.
Lemma andb_com x y :
andb x y = andb y x.
Proof.
destruct x.
- destruct y ; reflexivity.
- destruct y ; reflexivity.
Qed.
Goal ∀ x y: bool,
andb x y = andb y x.
Proof. destruct x, y; reflexivity. Qed.
(* Exercise 1.1.1 *)
(* Definition orb (x y: bool) :=
(* ... *) *)
Goal ∀ x y: bool,
orb x y = orb y x.
Abort.
(* Formulate and prove the De Morgan Law. *)
Check andb.
Check fun x : bool ⇒ x.
Compute (fun x : bool ⇒ x) true.
Check andb true.
Compute andb true.
(* Commented because of naming conflicts with the Standard library:
Definition andb : bool -> bool -> bool :=
fun x : bool =>
fun y : bool =>
match x with
| true => y
| false => false
end.
*)
Print negb.
Print andb.
(* Commented because of naming conflicts with the Standard library:
Inductive nat : Type :=
| O : nat
| S : nat -> nat.
Definition pred (x : nat) : nat :=
match x with
| O => O
| S x' => x'
end.
*)
Print nat.
Print Nat.pred.
Compute pred (S(S O)).
(* Commented because of naming conflicts with the Standard library:
Fixpoint plus (x y : nat) : nat :=
match x with
| O => y
| S x' => S (plus x' y)
end.
*)
Print plus.
Compute plus (S O) ( S O).
Fixpoint leb (x y: nat) : bool :=
match x with
| O ⇒ true
| S x' ⇒ match y with
| O ⇒ false
| S y' ⇒ leb x' y'
end
end.
Fixpoint leb' (x y: nat) : bool :=
match x, y with
| O, _ ⇒ true
| _, O ⇒ false
| S x', S y' ⇒ leb' x' y'
end.
(* Exercise 1.3.1 *)
(* Definition mult (x y: nat) : nat :=
(* ... *) *)
Lemma plus_O x :
plus x O = x.
Proof.
induction x ; simpl.
- reflexivity.
- rewrite IHx. reflexivity.
Qed.
Lemma plus_S x y :
plus x (S y) = S (plus x y).
Proof.
induction x ; simpl.
- reflexivity.
- rewrite IHx. reflexivity.
Qed.
Lemma plus_com x y :
plus x y = plus y x.
Proof.
induction x ; simpl.
- rewrite plus_O. reflexivity.
- rewrite plus_S. rewrite IHx. reflexivity.
Qed.
Lemma plus_asso x y z :
plus (plus x y) z = plus x (plus y z).
Proof.
induction x ; simpl.
- reflexivity.
- rewrite IHx. reflexivity.
Qed.
(* Exercise 1.4.1 *)
Goal ∀ x y, plus x y = plus y x.
Proof.
induction y.
Abort.
Require Import Omega.
Lemma plus_AC x y z :
plus y (plus x z) = plus (plus z y) x.
Proof.
setoid_rewrite plus_com at 3.
setoid_rewrite plus_com at 1.
apply plus_asso.
Qed.
(* Commented because of naming conflicts with the Standard library:
Fixpoint mult (x y : nat) : nat :=
match x with
O => O
| S x' => plus y (mult x' y)
end. *)
Lemma plus_AC' x y z :
plus (plus (mult x y) (mult x z)) (plus y z) = plus (plus (mult x y) y) (plus (mult x z) z).
Proof.
rewrite plus_asso. rewrite plus_asso. f_equal.
setoid_rewrite plus_com at 1. rewrite plus_asso. f_equal.
apply plus_com.
Qed.
Example Ex1 x y z :
S (plus x (plus y z)) = S (plus (plus x y) z).
Proof. rewrite <- plus_asso. reflexivity. Qed.
(* Exercise 1.5.1 *)
Lemma mult_S' x y :
mult x (S y) = plus (mult x y) x.
Abort.
(* Exercise 1.5.2 *)
Lemma mult_O (x : nat) :
mult x O = O.
Abort.
Lemma mult_S (x y : nat) :
mult x (S y) = plus (mult x y) x.
Abort.
Lemma mult_com (x y : nat) :
mult x y = mult y x.
Abort.
Lemma mult_dist (x y z: nat) :
mult (plus x y) z = plus (mult x z) (mult y z).
Abort.
Lemma mult_asso (x y z: nat) :
mult (mult x y) z = mult x (mult y z).
Abort.
Print plus.
Compute plus O.
Compute plus (S (S O)).
Compute fun x ⇒ plus (S x).
Goal plus O = fun x ⇒ x.
Proof. compute. reflexivity. Qed.
Goal (fun x ⇒ plus (S x)) = fun x y ⇒ S (plus x y).
Proof. compute. reflexivity. Qed.
(* Commented because of naming conflicts with the Standard library:
Notation "x + y" := (plus x y) (at level 50, left associativity).
Notation "x * y" := (mult x y) (at level 40, left associativity).
*)
Lemma mult_dist' x y z :
x × (y + z) = x×y + x×z.
Proof.
induction x ; simpl.
- reflexivity.
- rewrite IHx. rewrite plus_asso. rewrite plus_asso. f_equal.
setoid_rewrite <- plus_asso at 2.
setoid_rewrite plus_com at 4.
symmetry. apply plus_asso.
Qed.
Set Printing All.
Check O + O × S O.
Unset Printing All.
(* Exercise 1.7.1 *)
Goal ∀ (x : nat),
x × O = O.
Abort.
Goal ∀ x y: nat,
x × (S y) = (x × y) + x.
Abort.
Goal ∀ x y: nat,
x × y = y × x.
Abort.
Goal ∀ x y z: nat,
(x + y) × z = (x × z) + (y × z).
Abort.
Goal ∀ x y z: nat,
(x × y) × z = x × (y × z).
Abort.
(* Exercise 1.7.2 *)
Goal ∀ x y z: nat,
x × (y × z) = x × y × z.
Abort.
(* Exercise 1.7.3 *)
Goal ∀ x,
(x + x) + x = x + (x + x).
Proof.
induction x.
Restart.
Abort.
Set Printing All.
Check 2 + 3×2.
Unset Printing All.
Locate "*".
Set Printing All.
Check if false then 0 else 1.
Unset Printing All.
Goal ∀ x y z, (x + y) + z = x + (y + z).
Proof. intros x y z. omega. Qed.
Goal ∀ x y, 2 × (x + y) = (y + x) × 2.
Proof. intros x y. omega. Qed.
(* Commented because of naming conflicts with the Standard library:
Inductive prod (X Y : Type) : Type :=
| pair : X -> Y -> prod X Y.
Arguments pair {X} {Y} _ _. *)
Check pair 0 true.
Check @pair nat.
Check @pair nat bool 0.
Set Printing All.
Check pair 0 true.
Unset Printing All.
About pair.
Set Implicit Arguments.
Unset Strict Implicit.
(* Commented because of naming conflicts with the Standard library:
Definition fst (X Y : Type) (p : prod X Y) : X :=
match p with pair x _ => x end.
Definition snd (X Y : Type) (p : prod X Y) : Y :=
match p with pair _ y => y end. *)
Compute fst (pair O true).
Compute snd (pair O true).
Lemma pair_eta (X Y : Type) (p : prod X Y) :
pair (fst p) (snd p) = p.
Proof. destruct p as [x y]. simpl. reflexivity. Qed.
Definition swap (X Y : Type) (p : X × Y) : Y × X :=
(snd p, fst p).
Compute swap (0, true).
Lemma swap_swap (X Y : Type) (p : X × Y) :
swap (swap p) = p.
Proof. destruct p as [x y]. unfold swap. simpl. reflexivity. Qed.
Check (fun x : nat × nat × nat ⇒ fst x) (1, 2, 3).
(* Exercise 1.9.1 *)
(* Definition car (* ... *)
Definition cas (* ... *)
Lemma car_spec X Y Z (f: X -> Y -> Z) x y:
car f (x,y) = f x y.
Abort.
Lemma cas_spec X Y Z (f: X * Y -> Z) x y:
cas f x y = f (x, y).
Abort. *)
(* Commented because of naming conflicts with the Standard library:
Inductive list (X : Type) : Type :=
| nil : list X
| cons : X -> list X -> list X.
Arguments nil {X}. *)
Set Printing All.
Check cons 1 nil.
Unset Printing All.
Notation "x :: y" := (cons x y) (at level 60, right associativity).
Set Printing All.
Check 1::2::nil.
Unset Printing All.
Notation "[]" := nil.
Notation "[ x ]" := (cons x nil).
Notation "[ x ; .. ; y ]" := (cons x .. (cons y nil) ..).
Set Printing All.
Check [1;2].
Unset Printing All.
(* The following tends to crash CoqIDE.
Toggle View -> Display all low-level contents instead! *)
(* Unset Printing All. *)
Fixpoint length (X : Type) (A : list X) : nat :=
match A with
| nil ⇒ O
| _ :: A' ⇒ S (length A')
end.
Notation "| A |" := (length A) (at level 70).
Fixpoint app (X : Type) (A B : list X) : list X :=
match A with
| nil ⇒ B
| x :: A' ⇒ x :: app A' B
end.
Notation "x ++ y" := (app x y) (at level 60, right associativity).
Fixpoint rev (X : Type) (A : list X) : list X :=
match A with
| nil ⇒ nil
| x :: A' ⇒ rev A' ++ [x]
end.
Compute rev [1;2;3].
Lemma app_nil (X : Type) (A : list X) :
A ++ nil = A.
Proof.
induction A as [|x A] ; simpl.
- reflexivity.
- rewrite IHA. reflexivity.
Qed.
(* Enabling these lines will mess things up in this file,
because we've defined many of the names that it imports.
In order to avoid confusion, don't enable them. *)
(*
Require Import List.
Import ListNotations.
*)
(* Exercise 1.10.1 *)
(* Needed for section 1.11 *)
Lemma app_assoc (X : Type) (A B C : list X) :
(A ++ B) ++ C = A ++ (B ++ C).
Admitted.
Lemma length_app (X : Type) (A B : list X) :
|A ++ B| = |A| + |B|.
Abort.
Lemma rev_app (X : Type) (A B : list X) :
rev (A ++ B) = rev B ++ rev A.
Abort.
Lemma rev_rev (X : Type) (A : list X) :
rev (rev A) = A.
Abort.
Fixpoint revi (X : Type) (A B : list X) : list X :=
match A with
| nil ⇒ B
| x :: A' ⇒ revi A' (x :: B)
end.
Lemma revi_rev (X : Type) (A B : list X) :
revi A B = rev A ++ B.
Proof.
revert B. induction A as [|x A] ; simpl.
- reflexivity.
- intros B. rewrite IHA. rewrite app_assoc. simpl. reflexivity.
Qed.
(* Exercise 1.11.1 *)
Lemma rev_revi (X : Type) (A : list X) :
rev A = revi A nil.
Abort.
(* Exercise 1.11.2 *)
Fixpoint lengthi (X : Type) (A : list X) (n : nat) :=
match A with
| nil ⇒ n
| _ :: A' ⇒ lengthi A' (S n)
end.
Lemma lengthi_length X (A : list X) n :
lengthi A n = |A| + n.
Abort.
Lemma length_lengthi X (A : list X) :
|A| = lengthi A 0.
Abort.
(* Exercise 1.11.3 *)
(* Fixpoint fact (n : nat) : nat :=
(* ... *)
Fixpoint facti (n a: nat) : nat :=
(* ... *)
Goal forall n, fact n = facti n 1. *)
Fixpoint iter (n : nat) (X : Type) (f : X → X) (x : X) : X :=
match n with
| 0 ⇒ x
| S n' ⇒ f (iter n' f x)
end.
Lemma iter_plus x y :
x + y = iter x S y.
Proof. induction x ; simpl ; congruence. Qed.
Lemma iter_minus x y :
x-y = iter y pred x.
Proof. induction y ; simpl ; omega. Qed.
(* Exercise 1.12.1 *)
Lemma iter_mult x y :
x × y = iter x (plus y) 0.
Abort.
(* Exercise 1.12.2 *)
Lemma iter_shift X (f : X → X) x n :
iter (S n) f x = iter n f (f x).
Abort.
(* Exercise 1.12.3 *)
(* Fixpoint power (x n: nat) :=
(* ... *)
Lemma iter_power x n:
power x n = iter n (mult x 1). *)
(* Exercise 1.12.4 *)
(* Definition step (p : nat * nat) : nat * nat :=
(* ... *)
Lemma it_fac_step n :
step (n, fac n) = (S n, fac (S n)).
Abort.
Lemma it_fac' n :
iter n step (O, S O) = (n, fac n).
Abort.
Lemma it_fac n :
fac n = snd (iter n step (O, S O)).
Abort.
*)
(* Exercise 1.12.5 *)
Definition Nat := ∀ X: Type, (X → X) → X → X.
(* Fixpoint encode (n: nat) : Nat :=
(* ... *)
Definition decode (N: Nat) : nat :=
(* ... *)
Goal forall n: nat,
decode (encode n) = n.
Abort. *)
Inductive Empty_set : Type := .
Lemma vacuous_truth (x : Empty_set) :
1 = 2.
Proof. destruct x. Qed.
Inductive option (X : Type) : Type :=
| Some : X → option X
| None : option X.
Definition fin (n : nat) : Type :=
Nat.iter n option Empty_set.
Definition a11 : fin 1 := @None Empty_set.
Definition a21: fin 2 := Some a11.
Definition a22 : fin 2 := @None (fin 1).
Definition a31: fin 3 := Some a21.
Definition a32 : fin 3 := Some a22.
Definition a33 : fin 3 := @None (fin 2).
Goal ∀ n, fin (2+n) = option (fin (S n)).
Proof. intros n. reflexivity. Qed.
Goal ∀ m n, fin (m+n) = fin (n+m).
Proof.
intros m n. f_equal. omega.
Qed.
(* For Coq to get typing right, we had to replace None by a11 in this lemma: *)
Lemma fin1 (x : fin 1):
x = a11.
Proof.
destruct x as [x|].
- simpl in x. destruct x.
- reflexivity.
Qed.
(* Exercise 1.13.1 *)
(*Definition fromBool (b: bool) : fin 2 :=
(* ... *)
Definition toBool (x: fin 2) : bool :=
(* ... *)
Lemma bool_fin b: toBool (fromBool b) = b.
Abort.
Lemma fin_bool x: fromBool (toBool x) = x.
Abort. *)
(* Exercise 1.13.2 *)
(* Definition fromNat (n: nat) : option nat :=
(* ... *)
Definition toNat (n: option nat) : nat :=
(* ... *)
Goal forall n, toNat (fromNat n) = n.
Abort.
Goal forall n, fromNat (toNat n) = n.
Abort. *)
(* Exercise 1.13.3*)
(*
Fixpoint find (X: Type) (p: X -> bool) (A: list X) : option X :=
(* ... *)
Fixpoint minus_opt (x y: nat) : option nat :=
(* ... *) *)