(* Commented because of naming conflicts with the Base library:
Inductive list (X : Type) : Type :=
| nil : list X
| cons : X -> list X -> list X.
Notation "x '::' A" := (cons x A) (at level 60).
*)
Check list.
Check nil.
Check cons.
Goal ∀ (X: Type) (x: X) (A: list X), cons x A = x :: A.
Proof. reflexivity. Qed.
Goal ∀ (X: Type) (x y: X) (A: list X), cons x (cons y A) = x :: y :: A.
Proof. reflexivity. Qed.
(* Commented because of naming conflicts with the Base library:
Fixpoint length (X: Type) (A: list X) :=
match A with
| => 0
|x :: A => S (length A)
end.
Notation "| A |" := (length A) (at level 65).
Fixpoint app (X: Type) (A B: list X) :=
match A with
| => B
|x :: A => x :: (app A B)
end.
Notation "| A ++ B |" := (app A B) (at level 70).
Fixpoint rev (X: Type) (A: list X) :=
match A with
| =>
|x :: A => rev A ++ x
end.
Fixpoint map (X Y: Type) (f: X -> Y) (A: list X) :=
match A with
| =>
|x :: A => f x :: map f A
end.
Fixpoint list_prod (X Y: Type) (A: list X) (B: list Y) :=
match A with
| =>
|a :: A => map (pair a) B ++ (list_prod A B)
end. *)
Compute (list_prod [1;2] [5;6;7]).
Goal ∀ (X: Type) (A B: list X), |A ++ B| = |A| + |B|.
Proof.
intros X A B. induction A as [|x A IHA].
- reflexivity.
- simpl. rewrite IHA. reflexivity.
Qed.
(* Exercise 8.2.2 *)
Lemma list_cycle (X : Type) (A : list X) x :
x::A ≠ A.
Abort.
(* Exercise 8.2.3 *)
Section Ex23.
Variable X Y: Type.
Variable x: X.
Variable A B C: list X.
Variable f: X → Y.
Lemma app_nil_r:
A ++ nil = A.
Abort.
Lemma app_assoc:
A ++ (B ++ C) = (A ++ B) ++ C.
Abort.
Lemma rev_app_distr:
rev (A ++ B) = rev B ++ rev A.
Abort.
Lemma map_app:
map f (A ++ B) = (map f A) ++ (map f B).
Abort.
Lemma app_length:
|A ++ B| = |A| + |B|.
Abort.
Lemma rev_length:
|rev A| = |A|.
Abort.
Lemma map_length:
|map f A| = |A|.
Abort.
Lemma prod_length:
|list_prod A B| = |A| × |B|.
Abort.
Lemma rev_involutive:
rev (rev A) = A.
Abort.
Lemma rev_unit:
rev (A ++ [x]) = x :: rev A.
Abort.
End Ex23.
(* Exercise 8.2.4 *)
Fixpoint revi (X: Type) (A B: list X) :=
match A with
|[] ⇒ B
|x :: A ⇒ revi A (x :: B)
end.
Goal ∀ (X: Type) (A B: list X),
revi A B = rev A ++ B.
Abort.
Goal ∀ (X: Type) (A: list X),
rev A = revi A nil.
Abort.
(* Exercise 8.2.5 *)
(* Definition lengthi (X: Type) : list X -> nat -> nat :=
Goal forall (X: Type) (A:list X),
length A = lengthi A. *)
(* Commented because of naming conflicts with the Base library:
Fixpoint In (X: Type) (a: X) (A: list X) :=
match A with
| => False
|x :: A => x = a \/ In a A
end.
Notation "x 'el' A" := (In x A) (at level 70).
*)
(* Exercise 8.3.1 *)
Goal ∀ (A B C: list nat), ¬ (3 el []) ∧ 2 el A ++ (1 :: 2 :: B) ++ C.
Abort.
(* Exercise 8.3.2 *)
Section Ex32.
Variable X: Type.
Variable x y: X.
Variable A B: list X.
Lemma in_eq:
x el x :: A.
Abort.
Lemma in_cons:
x el A → x el y :: A.
Abort.
Lemma in_or_app:
x el A ∨ x el B → x el A ++ B.
Abort.
Lemma in_nil:
¬ (x el []).
Abort.
Lemma in_sing:
x el [y] → x = y.
Abort.
Lemma in_cons_neq:
x el y::A → x ≠ y → x el A.
Abort.
Lemma not_in_cons:
¬ x el y :: A → x ≠ y ∧ ¬ x el A.
Abort.
End Ex32.
(* Exercise 8.3.3 *)
Section Ex33.
Lemma in_app_iff (X : Type) (A B: list X) (x :X):
x el A ++ B ↔ x el A ∨ x el B.
Abort.
Lemma in_rev_iff (X: Type) (x: X) (A: list X):
x el rev A ↔ x el A.
Abort.
Lemma in_map_iff (X Y: Type) (f: X → Y) (x: Y) (A: list X):
x el map f A ↔ ∃ y, f y = x ∧ y el A.
Abort.
Lemma in_prod_iff (X Y: Type) (A: list X) (B: list Y) (a: X) (b: Y):
(a, b) el list_prod A B ↔ a el A ∧ b el B.
Abort.
End Ex33.
(* Exercise 8.3.4 *)
(* Inductive con (* ... *)
Definition con_ind (* ... *)
Goal forall (X: Type) (A B C: list X),
con A B C <-> A ++ B = C.
*)
(* Commented because of naming conflicts with the Base library:
Definition incl (X: Type) (xs ys: list X) :=
forall a, a el xs -> a el ys.
Notation "A <<= B" := (incl A B) (at level 70).
Definition equi (X: Type) (xs ys: list X) :=
xs <<= ys /\ ys <<= xs.
Notation "A === B" := (equi A B) (at level 70).
*)
Goal ∀ A B C, A <<= B → 2 :: A ++ 3 :: A <<= C ++ 3 :: 2 :: B.
Proof.
auto 7.
Qed.
Goal ∀ X (x y : X) A B, x::A ++ [y] ++ A ++ B === A ++ [y;x] ++ A ++ B.
Proof.
intros X x y A B. simpl. rewrite equi_swap. rewrite equi_shift at 1. reflexivity.
Qed.
Goal ∀ (A B C D : list nat), A <<= B → B <<= C → C <<= D → A <<= D.
Proof.
intros A B C D F G H. rewrite F. rewrite G. exact H.
Qed.
(* Exercise 8.4.2 *)
Section Ex42.
Variable X: Type.
Implicit Types A B C: list X.
Lemma incl_refl A:
A <<= A.
Abort.
Lemma incl_tl x A B:
A <<= B → A <<= x::B.
Abort.
Lemma incl_cons x A B:
x el B → A <<= B → x :: A <<= B.
Abort.
Lemma incl_appl A B C:
A <<= B → A <<= B ++ C.
Abort.
Lemma incl_appr A B C:
A <<= C → A <<= B ++ C.
Abort.
Lemma incl_app A B C:
A <<= C → B <<= C → A ++ B <<= C.
Abort.
Lemma incl_nil A:
nil <<= A.
Abort.
Lemma incl_nil_eq A :
A <<= nil → A=nil.
Abort.
Lemma incl_shift x A B :
A <<= B → x::A <<= x::B.
Abort.
Lemma incl_lcons x A B :
x::A <<= B ↔ x el B ∧ A <<= B.
Abort.
Lemma incl_sing x A y :
x::A <<= [y] → x = y ∧ A <<= [y].
Abort.
Lemma incl_rcons x A B :
A <<= x::B → ¬ x el A → A <<= B.
Abort.
Lemma incl_lrcons x A B :
x::A <<= x::B → ¬ x el A → A <<= B.
Abort.
Lemma incl_app_left A B C :
A ++ B <<= C → A <<= C ∧ B <<= C.
Abort.
Lemma incl_map A B Y (f: X → Y):
A <<= B → map f A <<= map f B.
Abort.
Lemma equi_push x A :
x el A → A === x::A.
Abort.
Lemma equi_dup x A :
x::A === x::x::A.
Abort.
Lemma equi_swap x y A:
x::y::A === y::x::A.
Abort.
Lemma equi_shift x A B :
x::A++B === A++x::B.
Abort.
Lemma equi_rotate x A :
x::A === A++[x].
Abort.
End Ex42.
(* Exercise 8.4.4 Don't be confused by the syntax of instances. The proofs just work as usual lemmas! *)
Instance incl_preorder X :
PreOrder (@incl X).
Proof.
constructor.
Abort.
Instance equi_Equivalence X :
Equivalence (@equi X).
Proof.
constructor.
Abort.
(* Exercise 8.4.4 *)
Instance incl_equi_proper X :
Proper (@equi X ==> @equi X ==> iff) (@incl X).
Proof.
hnf.
Abort.
Instance cons_incl_proper X x :
Proper (@incl X ==> @incl X) (@cons X x).
Proof.
hnf.
Abort.
Instance cons_equi_proper X x :
Proper (@equi X ==> @equi X) (@cons X x).
Proof.
hnf.
Abort.
(* Exercise 8.4.5 *)
(* Inductive mem (X: Type) (x : X) : list X -> Prop := (* ... *)
Goal forall (X: Type) (x: X) (A: list X), mem x A <-> x el A. *)
(* Commented because of naming conflicts with the Base library:
Definition disjoint A B :=
~ exists x, x el A /\ x el B.
*)
(* Exercise 8.5.1 *)
Section Disjoint.
Variable X: Type.
Implicit Types A B: list X.
Lemma disjoint_forall A B :
disjoint A B ↔ ∀ x, x el A → ¬ x el B.
Abort.
Lemma disjoint_symm A B :
disjoint A B → disjoint B A.
Abort.
Lemma disjoint_incl A B B' :
B' <<= B → disjoint A B → disjoint A B'.
Abort.
Lemma disjoint_nil B :
disjoint nil B.
Abort.
Lemma disjoint_nil' A :
disjoint A nil.
Abort.
Lemma disjoint_cons x A B :
disjoint (x::A) B ↔ ¬ x el B ∧ disjoint A B.
Abort.
Lemma disjoint_app A B C :
disjoint (A ++ B) C ↔ disjoint A C ∧ disjoint B C.
Abort.
End Disjoint.
Print list_eq_dec.
Print list_in_dec.
Print list_forall_dec.
Print list_exists_dec.
Goal ∀ X A B (p : X → Prop),
eq_dec X → (∀ x, dec (p x)) → dec (A=B ∨ ∀ x, x el A → ∃ y, y el B ∧ (y el A ∨ ¬ p x)).
Proof. auto. Qed.
Instance iff_dec (X Y : Prop) :
dec X → dec Y → dec (X ↔ Y).
Proof. unfold dec; tauto. Qed.
(* Exercise 8.6.1 *)
Goal ∀ X (A B : list X), eq_dec X → dec (A === B).
Abort.
(* Exercise 8.6.2 *)
Goal ∀ X A B (p : X → Prop),
eq_dec X → (∀ x, dec (p x)) → dec (A=B ∨ ∀ x, x el A → ∃ y, y el B ∧ (y el A ∨ ¬ p x)).
Abort.
(* Exercise 8.6.3 *)
Instance list_eq_dec X :
eq_dec X → eq_dec (list X).
Abort.
Instance list_in_dec (X : Type) (x : X) (A : list X) :
eq_dec X → dec (x el A).
Abort.
Instance list_forall_dec X A (p : X → Prop) :
(∀ x, dec (p x)) → dec (∀ x, x el A → p x).
Abort.
Instance list_exists_dec X A (p : X → Prop) :
(∀ x, dec (p x)) → dec (∃ x, x el A ∧ p x).
Abort.
(* Exercise 8.6.4 *)
Lemma list_sigma_forall X A (p : X → Prop) (p_dec : ∀ x, dec (p x)) :
{x | x el A ∧ p x} + {∀ x, x el A → ¬ p x}.
Abort.
Lemma list_exists_DM X A (p : X → Prop) :
(∀ x, dec (p x)) →
¬ (∀ x, x el A → ¬ p x) → ∃ x, x el A ∧ p x.
Abort.
Lemma list_exists_not_incl X (A B : list X) :
eq_dec X →
¬ A <<= B → ∃ x, x el A ∧ ¬ x el B.
Abort.
Lemma list_cc X (p : X → Prop) A :
(∀ x, dec (p x)) →
(∃ x, x el A ∧ p x) → {x | x el A ∧ p x}.
Abort.
(* Commented because of naming conflicts with the Base library:
Definition filter (X : Type) (p : X -> Prop) (p_dec : forall x, dec (p x)) : list X -> list X :=
fix f A := match A with
| nil => nil
| x::A' => if decision (p x) then x :: f A' else f A'
end.
Arguments filter {X} p {p_dec} A.
Definition decision (X : Prop) (D : dec X) : dec X := D.
Arguments decision X {D}.
*)
Compute filter (fun x ⇒ 3 ≤ x ≤ 7) [1;2;3;4;5;6;7;8;9].
Lemma in_filter_iff X (p : X → Prop) {p_dec : ∀ x, dec (p x)} x A :
x el filter p A ↔ x el A ∧ p x.
Proof.
induction A as [|y A]; simpl.
- tauto.
- decide (p y) as [B|B]; simpl; rewrite IHA; intuition; subst; tauto.
Qed.
(* Exercise 8.7.1 *)
Section FilterLemmas.
Variable X : Type.
Variable p q: X → Prop.
Context {p_dec : ∀ x, dec (p x)}.
Context {q_dec : ∀ x, dec (q x)}.
Goal ∀ x A,
x el filter p A ↔ x el A ∧ p x.
Abort.
Lemma filter_incl A :
filter p A <<= A.
Abort.
Lemma filter_mono A B :
A <<= B → filter p A <<= filter p B.
Abort.
Lemma filter_pq_mono A :
(∀ x, x el A → p x → q x) → filter p A <<= filter q A.
Abort.
Lemma filter_pq_eq A :
(∀ x, x el A → (p x ↔ q x)) → filter p A = filter q A.
Abort.
Lemma filter_id A :
(∀ x, x el A → p x) → filter p A = A.
Abort.
Lemma filter_app A B :
filter p (A ++ B) = filter p A ++ filter p B.
Abort.
Lemma filter_fst x A :
p x → filter p (x::A) = x::filter p A.
Abort.
Lemma filter_fst' x A :
¬ p x → filter p (x::A) = filter p A.
Abort.
End FilterLemmas.
(* Exercise 8.7.2 *)
(* Fixpoint inter (X: Type) (A B: list X) : list X :=
(* ... *)
Goal forall (X: Type) (x: X) (A B: list X),
x el inter A B <-> x el A /\ x el B.
Abort. *)
(* Commented because of naming conflicts with the Base library:
Variable X : Type.
Context {eq_X_dec : eq_dec X}.
Definition rem (A : list X) (x : X) : list X :=
filter (fun z => z <> x) A.
*)
(* Exercise 8.8.1 *)
Section Removal.
Variable X : Type.
Context {eq_X_dec : eq_dec X}.
Lemma in_rem_iff x A y :
x el rem A y ↔ x el A ∧ x ≠ y.
Abort.
Lemma rem_not_in x y A :
x = y ∨ ¬ x el A → ¬ x el rem A y.
Abort.
Lemma rem_incl A x :
rem A x <<= A.
Abort.
Lemma rem_mono A B x :
A <<= B → rem A x <<= rem B x.
Abort.
Lemma rem_inclr A B x :
A <<= B → ¬ x el A → A <<= rem B x.
Abort.
Lemma rem_cons A B x :
A <<= B → rem (x::A) x <<= B.
Abort.
Lemma rem_cons' A B x y :
x el B → rem A y <<= B → rem (x::A) y <<= B.
Abort.
Lemma rem_app x A B :
x el A → B <<= A ++ rem B x.
Abort.
Lemma rem_app' x A B C :
rem A x <<= C → rem B x <<= C → rem (A ++ B) x <<= C.
Abort.
Lemma rem_in x y A :
x el rem A y → x el A.
Abort.
Lemma rem_neq x y A :
x ≠ y → x el A → x el rem A y.
Abort.
Lemma rem_equi x A :
x::A === x::rem A x.
Abort.
Lemma rem_reorder x A :
x el A → A === x :: rem A x.
Abort.
Lemma rem_comm A x y :
rem (rem A x) y = rem (rem A y) x.
Abort.
Lemma rem_fst x A :
rem (x::A) x = rem A x.
Abort.
Lemma rem_fst' x y A :
x ≠ y → rem (x::A) y = x::rem A y.
Abort.
Lemma rem_id x A :
¬ x el A → rem A x = A.
Abort.
End Removal.
(* Commented because of naming conflicts with the Base library:
Variable X : Type.
Context { eq_X_dec : eq_dec X }.
Implicit Types A B : list X.
Fixpoint card A :=
match A with
| nil => 0
| x::A => if decision (x el A) then card A else 1 + card A
end.
*)
Print card.
(* Exercise 8.9.2 *)
Section Ex92.
Variable X : Type.
Context { eq_X_dec : eq_dec X }.
Implicit Types A : list X.
Lemma card_in_rem x A :
x el A → card A = 1 + card (rem A x).
Abort.
End Ex92.
(* Exercise 8.9.3 *)
Section Ex93.
Variable X : Type.
Context { eq_X_dec : eq_dec X }.
Implicit Types A : list X.
Lemma card_le A B :
A <<= B → card A ≤ card B.
Abort.
End Ex93.
(* Commented because of naming conflicts with the Base library:
Inductive dupfree (X : Type) : list X -> Prop :=
| dupfreeN : dupfree nil
| dupfreeC x A : ~ x el A -> dupfree A -> dupfree (x::A).
Fixpoint undup (X: Type) (H: eq_dec X) (A : list X) : list X :=
match A with
| nil => nil
| x::A' => if decision (x el A') then undup H A' else x :: undup H A'
end.
*)
(* Exercise 8.10.1 *)
Section Dupfree.
Variable X: Type.
Context {eq_X_dec : eq_dec X}.
Implicit Type A: list X.
Lemma dupfree_card A:
dupfree A → card A = |A|.
Abort.
Lemma dupfree_dec A :
dec (dupfree A).
Abort.
Lemma dupfree_undup A :
dupfree (undup A).
Abort.
Lemma undup_id_equi A :
undup A === A.
Abort.
End Dupfree.
(* Exercise 8.10.2 *)
Section Dupfree2.
Variable X: Type.
Context {eq_X_dec : eq_dec X}.
Implicit Type A: list X.
Lemma dupfree_app A B :
disjoint A B → dupfree A → dupfree B → dupfree (A++B).
Abort.
Lemma dupfree_map Y A (f : X → Y) :
(∀ x y, x el A → y el A → f x = f y → x=y) →
dupfree A → dupfree (map f A).
Abort.
Lemma dupfree_filter p (p_dec : ∀ x, dec (p x)) A :
dupfree A → dupfree (filter p A).
Abort.
End Dupfree2.
(* Commented because of naming conflicts with the Base library:
Fixpoint power (X: Type) (U : list X ) : list (list X) :=
match U with
| nil => nil
| x :: U' => power U' ++ map (cons x) (power U')
end.
Definition rep (X: Type) (H: eq_dec X) (A U : list X) : list X :=
filter (fun x => x el A) U.
*)
(* Exercise 8.11.1 *)
Section PowerRep.
Variable X : Type.
Context {eq_X_dec : eq_dec X}.
Implicit Types A U: list X.
Lemma power_incl A U :
A el power U → A <<= U.
Abort.
Lemma power_nil U :
nil el power U.
Abort.
Lemma rep_power A U :
rep A U el power U.
Abort.
Lemma rep_incl A U :
rep A U <<= A.
Abort.
Lemma rep_in x A U :
A <<= U → x el A → x el rep A U.
Abort.
Lemma rep_equi A U :
A <<= U → rep A U === A.
Abort.
Lemma rep_mono A B U :
A <<= B → rep A U <<= rep B U.
Abort.
Lemma rep_eq A B U :
A === B → rep A U = rep B U.
Abort.
Lemma rep_injective A B U :
A <<= U → B <<= U → rep A U = rep B U → A === B.
Abort.
Lemma rep_idempotent A U :
rep (rep A U) U = rep A U.
Abort.
Lemma dupfree_power U :
dupfree U → dupfree (power U).
Abort.
Lemma dupfree_in_power U A :
A el power U → dupfree U → dupfree A.
Abort.
Lemma rep_dupfree A U :
dupfree U → A el power U → rep A U = A.
Abort.
Lemma power_extensional A B U :
dupfree U → A el power U → B el power U → A === B → A = B.
Abort.
End PowerRep.