Formal Software Verification

4.8. Exercises🔗

Prove each statement in Lean, replacing sorry. Download the exercise file Lecture04.lean and open it in VS Code. The file already contains the definitions of add and mul and the theorems of §4.6, so the induction exercises can build on them. Exercises 1 to 6 use only intro, apply and exact; exercises 7 to 9 use induction, simp and rw; exercise 10 is optional.

Exercise 1. Two ways of feeding hypotheses to a function. The first supplies the same premise twice; the second reorders the premises before applying.

namespace Backward theorem declaration uses `sorry`contract (a b : Prop) : (a a b) a b := sorry theorem declaration uses `sorry`pull (a b c : Prop) : a (a b c) b c := sorry end Backward

Exercise 2. An implication whose conclusion is a conjunction splits into one implication for each part.

namespace Backward theorem declaration uses `sorry`imp_into_and (a b c : Prop) : (a b) (a c) a b c := sorry end Backward

Exercise 3. Two proofs of the same statement, differing in which injection they choose.

namespace Backward theorem declaration uses `sorry`left_choice (a : Prop) : a a a := sorry -- Give a different answer than for `left_choice`: theorem declaration uses `sorry`right_choice (a : Prop) : a a a := sorry end Backward

Exercise 4. A relay of three implications carries the first hypothesis to the last conclusion.

namespace Backward theorem declaration uses `sorry`relay (a b c d : Prop) : (a b) (b c) (c d) a d := sorry end Backward

Exercise 5. A proposition together with its negation proves anything. Recall that ¬a abbreviates a → False.

namespace Backward theorem declaration uses `sorry`absurd_imp (a b : Prop) : a ¬ a b := sorry end Backward

Exercise 6. An implication out of an existential yields a universally quantified implication. This exercise proves that one direction, and the converse also holds.

namespace Backward theorem declaration uses `sorry`exists_imp {α : Type} (p : α Prop) (q : Prop) : (( x, p x) q) x, p x q := sorry end Backward

Exercise 7. One is a left identity for mul, by induction on the second argument.

namespace Backward theorem declaration uses `sorry`one_mul (n : ) : mul 1 n = n := sorry end Backward

Exercise 8. The left summand of a nested sum moves past the middle one, by rewriting with associativity and commutativity.

namespace Backward theorem declaration uses `sorry`add_left_comm (l m n : ) : add l (add m n) = add m (add l n) := sorry end Backward

Exercise 9. The right summand of a nested sum moves past the middle one.

namespace Backward theorem declaration uses `sorry`add_right_comm (l m n : ) : add (add l m) n = add (add l n) m := sorry end Backward

Exercise 10. Optional. Adding a number to itself equals multiplying it by two, and the two sides already agree by computation.

namespace Backward theorem declaration uses `sorry`two_mul (n : ) : add n n = mul n 2 := sorry end Backward