Indprop2
Reasoning about minima
Exercise: 4 stars, standard, optional (le_exercises)
Here are a number of facts about the ≤ and < relations that we are going to need later in the course. The proofs make good practice exercises.
Lemma le_trans : ∀ m n o, m ≤ n → n ≤ o → m ≤ o.
Proof.
(* FILL IN HERE *) Admitted.
(* GRADE_THEOREM 0.25: le_trans *)
Theorem O_le_n : ∀ n,
0 ≤ n.
Proof.
(* FILL IN HERE *) Admitted.
(* GRADE_THEOREM 0.25: O_le_n *)
Theorem n_le_m__Sn_le_Sm : ∀ n m,
n ≤ m → S n ≤ S m.
Proof.
(* FILL IN HERE *) Admitted.
(* GRADE_THEOREM 0.25: n_le_m__Sn_le_Sm *)
Theorem Sn_le_Sm__n_le_m : ∀ n m,
S n ≤ S m → n ≤ m.
Proof.
(* FILL IN HERE *) Admitted.
(* GRADE_THEOREM 0.25: Sn_le_Sm__n_le_m *)
Lemma leb_nm__leb_mn : ∀ (n m : nat),
leb n m = false → leb m n = true.
Proof.
(* FILL IN HERE *) Admitted.
(* GRADE_THEOREM 0.25: leb_nm__leb_mn *)
Lemma leb_spec : ∀ (n m : nat),
leb n m = true ∨ (leb n m = false ∧ leb m n = true).
Proof.
(* FILL IN HERE *) Admitted.
(* GRADE_THEOREM 0.25: leb_spec *)
Proof.
(* FILL IN HERE *) Admitted.
(* GRADE_THEOREM 0.25: le_trans *)
Theorem O_le_n : ∀ n,
0 ≤ n.
Proof.
(* FILL IN HERE *) Admitted.
(* GRADE_THEOREM 0.25: O_le_n *)
Theorem n_le_m__Sn_le_Sm : ∀ n m,
n ≤ m → S n ≤ S m.
Proof.
(* FILL IN HERE *) Admitted.
(* GRADE_THEOREM 0.25: n_le_m__Sn_le_Sm *)
Theorem Sn_le_Sm__n_le_m : ∀ n m,
S n ≤ S m → n ≤ m.
Proof.
(* FILL IN HERE *) Admitted.
(* GRADE_THEOREM 0.25: Sn_le_Sm__n_le_m *)
Lemma leb_nm__leb_mn : ∀ (n m : nat),
leb n m = false → leb m n = true.
Proof.
(* FILL IN HERE *) Admitted.
(* GRADE_THEOREM 0.25: leb_nm__leb_mn *)
Lemma leb_spec : ∀ (n m : nat),
leb n m = true ∨ (leb n m = false ∧ leb m n = true).
Proof.
(* FILL IN HERE *) Admitted.
(* GRADE_THEOREM 0.25: leb_spec *)
We can even view leb_nm__leb_mn as a specialization of leb_spec:
Lemma leb_nm__leb_mn' : ∀ (n m : nat),
leb n m = false → leb m n = true.
Proof.
(* FILL IN HERE *) Admitted.
(* GRADE_THEOREM 0.25: leb_nm__leb_mn' *)
Theorem leb_complete : ∀ n m,
leb n m = true → n ≤ m.
Proof.
(* FILL IN HERE *) Admitted.
(* GRADE_THEOREM 0.25: leb_complete *)
Theorem le_plus_l : ∀ a b,
a ≤ a + b.
Proof.
(* FILL IN HERE *) Admitted.
(* GRADE_THEOREM 0.25: le_plus_l *)
Theorem plus_lt : ∀ n1 n2 m,
n1 + n2 < m →
n1 < m ∧ n2 < m.
Proof.
unfold lt.
(* FILL IN HERE *) Admitted.
Lemma minus_Sn_m: ∀ n m : nat,
m ≤ n → S (n - m) = S n - m.
Proof.
(* FILL IN HERE *) Admitted.
(* GRADE_THEOREM 0.25: minus_Sn_m *)
Theorem lt_S : ∀ n m,
n < m →
n < S m.
Proof.
(* FILL IN HERE *) Admitted.
(* GRADE_THEOREM 0.25: lt_S *)
leb n m = false → leb m n = true.
Proof.
(* FILL IN HERE *) Admitted.
(* GRADE_THEOREM 0.25: leb_nm__leb_mn' *)
Theorem leb_complete : ∀ n m,
leb n m = true → n ≤ m.
Proof.
(* FILL IN HERE *) Admitted.
(* GRADE_THEOREM 0.25: leb_complete *)
Theorem le_plus_l : ∀ a b,
a ≤ a + b.
Proof.
(* FILL IN HERE *) Admitted.
(* GRADE_THEOREM 0.25: le_plus_l *)
Theorem plus_lt : ∀ n1 n2 m,
n1 + n2 < m →
n1 < m ∧ n2 < m.
Proof.
unfold lt.
(* FILL IN HERE *) Admitted.
Lemma minus_Sn_m: ∀ n m : nat,
m ≤ n → S (n - m) = S n - m.
Proof.
(* FILL IN HERE *) Admitted.
(* GRADE_THEOREM 0.25: minus_Sn_m *)
Theorem lt_S : ∀ n m,
n < m →
n < S m.
Proof.
(* FILL IN HERE *) Admitted.
(* GRADE_THEOREM 0.25: lt_S *)
Hint: The next one may be easiest to prove by induction on m.
Hint: This theorem can easily be proved without using induction.
Theorem leb_true_trans : ∀ n m o,
leb n m = true → leb m o = true → leb n o = true.
Proof.
(* FILL IN HERE *) Admitted.
(* GRADE_THEOREM 0.25: leb_true_trans *)
☐
leb n m = true → leb m o = true → leb n o = true.
Proof.
(* FILL IN HERE *) Admitted.
(* GRADE_THEOREM 0.25: leb_true_trans *)
☐
Exercise: 2 stars, standard (min3_min)
Lemma min3_min : ∀ n1 n2 n3,
min3 n1 n2 n3 ≤ n1 ∧
min3 n1 n2 n3 ≤ n2 ∧
min3 n1 n2 n3 ≤ n3.
Proof.
(* FILL IN HERE *) Admitted.
☐
min3 n1 n2 n3 ≤ n1 ∧
min3 n1 n2 n3 ≤ n2 ∧
min3 n1 n2 n3 ≤ n3.
Proof.
(* FILL IN HERE *) Admitted.
☐
Exercise: 3 stars, standard, optional (min3_leb)
Lemma min3_leb : ∀ n1 n2 n3 m,
n1 ≤ m ∨ n2 ≤ m ∨ n3 ≤ m →
min3 n1 n2 n3 ≤ m.
Proof.
(* FILL IN HERE *) Admitted.
n1 ≤ m ∨ n2 ≤ m ∨ n3 ≤ m →
min3 n1 n2 n3 ≤ m.
Proof.
(* FILL IN HERE *) Admitted.
A hint.
Check argmin3_min3.
Lemma argmin3_min : ∀ {A:Type} cost (o1 o2 o3:A),
cost (argmin3 cost o1 o2 o3) ≤ cost o1 ∧
cost (argmin3 cost o1 o2 o3) ≤ cost o2 ∧
cost (argmin3 cost o1 o2 o3) ≤ cost o3.
Proof.
(* FILL IN HERE *) Admitted.
Lemma argmin3_leb : ∀ {A:Type} cost (o1 o2 o3:A) other,
cost o1 ≤ cost other ∨ cost o2 ≤ cost other ∨ cost o3 ≤ cost other →
cost (argmin3 cost o1 o2 o3) ≤ cost other.
Proof.
(* FILL IN HERE *) Admitted.
☐
Lemma argmin3_min : ∀ {A:Type} cost (o1 o2 o3:A),
cost (argmin3 cost o1 o2 o3) ≤ cost o1 ∧
cost (argmin3 cost o1 o2 o3) ≤ cost o2 ∧
cost (argmin3 cost o1 o2 o3) ≤ cost o3.
Proof.
(* FILL IN HERE *) Admitted.
Lemma argmin3_leb : ∀ {A:Type} cost (o1 o2 o3:A) other,
cost o1 ≤ cost other ∨ cost o2 ≤ cost other ∨ cost o3 ≤ cost other →
cost (argmin3 cost o1 o2 o3) ≤ cost other.
Proof.
(* FILL IN HERE *) Admitted.
☐
In and All
- If l is the empty list, then x cannot occur on it, so the property "x appears in l" is simply false.
- Otherwise, l has the form x' :: l'. In this case, x occurs in l if either it is equal to x' or it occurs in l'.
Inductive In {A : Type} : A → list A → Prop :=
| In_here (x:A) (l:list A) : In x (x::l)
| In_cons (x y:A) (l:list A) (H: In x l) : In x (y::l).
Example In_example_1 : In 4 [1; 2; 3; 4; 5].
Proof.
(* WORKED IN CLASS *)
apply In_cons.
apply In_cons.
apply In_cons.
apply In_here.
Qed.
Example In_example_2 :
∀ n, In n [2; 4] →
∃ n', n = 2 × n'.
Proof.
(* WORKED IN CLASS *)
intros n HIn.
inversion HIn as [x l' | x y l' HRest].
- ∃ 1. reflexivity.
- inversion HRest as [x' l'' | x' y' l'' []].
∃ 2. reflexivity.
Qed.
| In_here (x:A) (l:list A) : In x (x::l)
| In_cons (x y:A) (l:list A) (H: In x l) : In x (y::l).
Example In_example_1 : In 4 [1; 2; 3; 4; 5].
Proof.
(* WORKED IN CLASS *)
apply In_cons.
apply In_cons.
apply In_cons.
apply In_here.
Qed.
Example In_example_2 :
∀ n, In n [2; 4] →
∃ n', n = 2 × n'.
Proof.
(* WORKED IN CLASS *)
intros n HIn.
inversion HIn as [x l' | x y l' HRest].
- ∃ 1. reflexivity.
- inversion HRest as [x' l'' | x' y' l'' []].
∃ 2. reflexivity.
Qed.
(Notice the use of the empty pattern to discharge the last case
en passant.)
We can also prove more generic, higher-level lemmas about In.
Note, in the next, how In starts out applied to a variable and
only gets expanded when we do case analysis on this variable:
Lemma In_map :
∀ (A B : Type) (f : A → B) (l : list A) (x : A),
In x l →
In (f x) (map f l).
Proof.
(* Let A, B, f, l, and x be given. WTP In x l → In (f x) (map f l). *)
intros A B f l x HIn.
(* We go by induction on _how we know_ In x l *)
induction HIn as [ y l' | y z l' HRest IH].
- apply In_here.
- simpl map.
apply In_cons.
apply IH.
Qed.
∀ (A B : Type) (f : A → B) (l : list A) (x : A),
In x l →
In (f x) (map f l).
Proof.
(* Let A, B, f, l, and x be given. WTP In x l → In (f x) (map f l). *)
intros A B f l x HIn.
(* We go by induction on _how we know_ In x l *)
induction HIn as [ y l' | y z l' HRest IH].
- apply In_here.
- simpl map.
apply In_cons.
apply IH.
Qed.
Lemma In_map_iff :
∀ (A B : Type) (f : A → B) (l : list A) (y : B),
In y (map f l) ↔
∃ x, f x = y ∧ In x l.
Proof.
intros A B f l y. split.
(* FILL IN HERE *) Admitted.
☐
∀ (A B : Type) (f : A → B) (l : list A) (y : B),
In y (map f l) ↔
∃ x, f x = y ∧ In x l.
Proof.
intros A B f l y. split.
(* FILL IN HERE *) Admitted.
☐
Lemma In_app_iff : ∀ A l l' (a:A),
In a (l++l') ↔ In a l ∨ In a l'.
Proof.
(* FILL IN HERE *) Admitted.
☐
In a (l++l') ↔ In a l ∨ In a l'.
Proof.
(* FILL IN HERE *) Admitted.
☐
Fixpoint flat_map {X Y: Type} (f: X → list Y) (l: list X)
: (list Y) :=
match l with
| [] ⇒ []
| h :: t ⇒ (f h) ++ (flat_map f t)
end.
Lemma In_flat_map:
∀ (A B : Type) (f : A → list B) (l : list A) (y : B),
In y (flat_map f l) → (∃ x : A, In y (f x) ∧ In x l).
Proof.
(* FILL IN HERE *) Admitted.
☐
: (list Y) :=
match l with
| [] ⇒ []
| h :: t ⇒ (f h) ++ (flat_map f t)
end.
Lemma In_flat_map:
∀ (A B : Type) (f : A → list B) (l : list A) (y : B),
In y (flat_map f l) → (∃ x : A, In y (f x) ∧ In x l).
Proof.
(* FILL IN HERE *) Admitted.
☐
Exercise: 3 stars, standard, especially useful (All_In)
All, below, is to forallb as In is to member from the sorting chapter.
Inductive All {T : Type} : (T → Prop) → list T → Prop :=
| All_nil (P:T → Prop) : All P []
| All_cons (P:T → Prop) (t:T) (l:list T) (H1: P t) (H2:All P l) : All P (t::l).
Lemma All_In :
∀ T (P : T → Prop) (l : list T),
(∀ x, In x l → P x) ↔
All P l.
Proof.
(* FILL IN HERE *) Admitted.
☐
| All_nil (P:T → Prop) : All P []
| All_cons (P:T → Prop) (t:T) (l:list T) (H1: P t) (H2:All P l) : All P (t::l).
Lemma All_In :
∀ T (P : T → Prop) (l : list T),
(∀ x, In x l → P x) ↔
All P l.
Proof.
(* FILL IN HERE *) Admitted.
☐
Fixpoint forallb {X : Type} (test : X → bool) (l : list X) : bool :=
match l with
| [] ⇒ true
| x :: l' ⇒ andb (test x) (forallb test l')
end.
match l with
| [] ⇒ true
| x :: l' ⇒ andb (test x) (forallb test l')
end.
Prove the theorem below, which relates forallb to the All
property of the above exercise.
Theorem forallb_true_iff : ∀ X test (l : list X),
forallb test l = true ↔ All (fun x ⇒ test x = true) l.
Proof.
(* FILL IN HERE *) Admitted.
☐
forallb test l = true ↔ All (fun x ⇒ test x = true) l.
Proof.
(* FILL IN HERE *) Admitted.
☐
Case study: getting natset right
Fixpoint is_setlike (l : natset) : bool :=
match l with
| [] ⇒ true
| x :: l' ⇒ negb (member x l') && is_setlike l'
end.
Fixpoint intersection (l1 l2 : natset) : natset :=
match l1 with
| [] ⇒ []
| x::l1' ⇒ if member x l2
then x::intersection l1' l2
else intersection l1' l2
end.
Fixpoint subset (l1 l2 : natset) : bool :=
match l1 with
| [] ⇒ true
| x::l1' ⇒ member x l2 && subset l1' l2
end.
match l with
| [] ⇒ true
| x :: l' ⇒ negb (member x l') && is_setlike l'
end.
Fixpoint intersection (l1 l2 : natset) : natset :=
match l1 with
| [] ⇒ []
| x::l1' ⇒ if member x l2
then x::intersection l1' l2
else intersection l1' l2
end.
Fixpoint subset (l1 l2 : natset) : bool :=
match l1 with
| [] ⇒ true
| x::l1' ⇒ member x l2 && subset l1' l2
end.
We can characterize those natsets which are setlike using an
inductive predicate.
Inductive setlike : natset → Prop :=
| setlike_nil : setlike []
| setlike_cons (x:nat) (l:natset) (Hin: ¬ In x l) (H: setlike l) : setlike (x :: l).
| setlike_nil : setlike []
| setlike_cons (x:nat) (l:natset) (Hin: ¬ In x l) (H: setlike l) : setlike (x :: l).
Exercise: 2 stars, standard (setlike_egs)
Let's get a feel for the setlike predicate. It's always important to have positive examples---things that should satisfy the property, like setlike_eg1---as well as negative examples---things that should not satisfy the property, like setlike_eg2.
Example setlike_eg1 :
setlike [1;2;3;4].
Proof.
(* FILL IN HERE *) Admitted.
Example setlike_eg2 :
¬ setlike [1;2;3;4;1].
Proof.
(* FILL IN HERE *) Admitted.
☐
setlike [1;2;3;4].
Proof.
(* FILL IN HERE *) Admitted.
Example setlike_eg2 :
¬ setlike [1;2;3;4;1].
Proof.
(* FILL IN HERE *) Admitted.
☐
Exercise: 3 stars, standard, optional (In_member_iff)
The member function returns true exactly when the In predicate holds. This is good practice about inductive proof; it's needed for the next few exercises (but you can do them without doing this proof!).Exercise: 2 stars, standard (is_setlike__setlike)
We should, as always, double check our ideas. We have a setlike predicate on sets defined inductively and an is_setlike function defined recursively. Do these notions coincide?
Lemma is_setlike__setlike : ∀ l,
is_setlike l = true ↔ setlike l.
Proof.
(* FILL IN HERE *) Admitted.
☐
is_setlike l = true ↔ setlike l.
Proof.
(* FILL IN HERE *) Admitted.
☐
Lemma insert_preserves_setlike : ∀ x l,
setlike l →
setlike (set_insert x l).
Proof.
(* FILL IN HERE *) Admitted.
☐
setlike l →
setlike (set_insert x l).
Proof.
(* FILL IN HERE *) Admitted.
☐
Lemma union_preserves_setlike : ∀ l1 l2,
setlike l1 →
setlike l2 →
setlike (union l1 l2).
Proof.
(* FILL IN HERE *) Admitted.
☐
setlike l1 →
setlike l2 →
setlike (union l1 l2).
Proof.
(* FILL IN HERE *) Admitted.
☐
Exercise: 4 stars, standard, optional (union_intersection_dist)
The setlike predicate isn't just useful for checking that we've implemented our operations correctly---sometimes we need to use setlike in proofs!
Lemma union_intersection_dist : ∀ l1 l2 l3,
setlike l1 → setlike l2 → setlike l3 →
intersection (union l1 l2) l3 =
union (intersection l1 l3) (intersection l2 l3).
Proof.
(* FILL IN HERE *) Admitted.
☐
setlike l1 → setlike l2 → setlike l3 →
intersection (union l1 l2) l3 =
union (intersection l1 l3) (intersection l2 l3).
Proof.
(* FILL IN HERE *) Admitted.
☐
(* 2022-01-12 10:20 *)