diff --git a/doc/lean/calc.md b/doc/lean/calc.md new file mode 100644 index 000000000..8a8674aae --- /dev/null +++ b/doc/lean/calc.md @@ -0,0 +1,82 @@ +Calculational Proofs +==================== + +A calculational proof is just a chain of intermediate results that are +meant to be composed by basic principles such as the transitivity of +`=`. In Lean, a calculation proof starts with the keyword `calc`, and has +the following syntax + + calc _0 'op_1' _1 ':' _1 + '...' 'op_2' _2 ':' _2 + ... + '...' 'op_n' _n ':' _n + +Each `_i` is a proof for `_{i-1} op_i _i`. +Recall that proofs are also expressions in Lean. The `_i` +may also be of the form `{ }`, where `` is a proof +for some equality `a = b`. The form `{ }` is just syntax sugar +for + + Subst (Refl _{i-1}) + +That is, we are claiming we can obtain `_i` by replacing `a` with `b` +in `_{i-1}`. + +Here is an example + +```lean + Variables a b c d e : Nat. + Axiom Ax1 : a = b. + Axiom Ax2 : b = c + 1. + Axiom Ax3 : c = d. + Axiom Ax4 : e = 1 + d. + + Theorem T : a = e + := calc a = b : Ax1 + ... = c + 1 : Ax2 + ... = d + 1 : { Ax3 } + ... = 1 + d : Nat::PlusComm d 1 + ... = e : Symm Ax4. +``` + +The proof expressions `_i` do not need to be explicitly provided. +We can use `by ` or `by ` to (try to) automatically construct the +proof expression using the given tactic or solver. + +Even when tactics and solvers are not used, we can still use the elaboration engine to fill +gaps in our calculational proofs. In the previous examples, we can use `_` as arguments for the +`Nat::PlusComm` theorem. The Lean elaboration engine will infer `d` and `1` for us. +Here is the same example using placeholders. + +```lean + Theorem T' : a = e + := calc a = b : Ax1 + ... = c + 1 : Ax2 + ... = d + 1 : { Ax3 } + ... = 1 + d : Nat::PlusComm _ _ + ... = e : Symm Ax4. +``` + +We can also use the operators `=>`, `⇒`, `<=>`, `⇔` and `≠` in calculational proofs. +Here is an example. + +```lean + Theorem T2 (a b c : Nat) (H1 : a = b) (H2 : b = c + 1) : a ≠ 0 + := calc a = b : H1 + ... = c + 1 : H2 + ... ≠ 0 : Nat::SuccNeZero _. +``` + +The Lean `let` construct can also be used to build calculational-like proofs. + +```lean + Variable P : Nat → Nat → Bool. + Variable f : Nat → Nat. + Axiom Axf (a : Nat) : f (f a) = a. + + Theorem T3 (a b : Nat) (H : P (f (f (f (f a)))) (f (f b))) : P a b + := let s1 : P (f (f a)) (f (f b)) := Subst H (Axf a), + s2 : P a (f (f b)) := Subst s1 (Axf a), + s3 : P a b := Subst s2 (Axf b) + in s3. +``` \ No newline at end of file diff --git a/src/builtin/obj/Nat.olean b/src/builtin/obj/Nat.olean index 5a341daf3..5eab6eba9 100644 Binary files a/src/builtin/obj/Nat.olean and b/src/builtin/obj/Nat.olean differ