Tony Johnson wrote:
> How would I go about proving something simple like this?
> 1 + 2 + 3 + \dots + n = \frac{n(n+1)}{2}
First you need to define your summation.
Life is usually easiest if you define things by pattern-matching
recursion:
val sum_def = Define`
(sum 0 = 0) /\
(sum (SUC n) = SUC n + sum n)
`;
Such a definition is a prime candidate for automatic rewriting, so I
would then add the definition to the built-in simpset
val _ = export_rewrites ["sum_def"]
Then you get to state your theorem. Proving things with DIV is
usually a pain, so I recast by multiplying both sides by two:
val sum_form = store_thm(
"sum_form",
``2 * sum n = n * (n + 1)``,
<tactic>)
What's the <tactic>? First an induction
Induct_on `n` THEN ...
Following induction steps by rewriting is usually safe, so
Induct_on `n` THEN SRW_TAC [][]
This eliminates the base case automatically and gives the goal
2 * (SUC n + sum n) = SUC n * (SUC n + 1)
-------------------------------------------
2 * sum n = n * (n + 1)
where the formula below the line is the inductive hypothesis.
The IH would apply as a rewrite if the multiplication had been pushed
into the addition. This is the theorem
arithmeticTheory.LEFT_ADD_DISTRIB. Let's assume you have done an
open arithmeticTheory
so that we don't have to use fully-qualified names everywhere.
Then, we can modify our tactic to be
Induct_on `n` THEN SRW_TAC [][LEFT_ADD_DISTRIB] THEN ...
This gives
2 * SUC n + (n * n + n) = SUC n * SUC n + SUC n
-------------------------------------------------
2 * sum n = n * (n + 1)
The IH has been applied and now our goal is pure arithmetic. As it
stands it is not a useful instance of a Presburger formula because of
the n * n and the SUC n * SUC n. But the latter can be expanded to a
formula including the former with the use of the standard
MULT_CLAUSES, which includes the conjuncts
|- SUC n * m = n * m + m
|- n * SUC m = n + n * m
So, we modify the tactic to be
Induct_on `n` THEN SRW_TAC [][LEFT_ADD_DISTRIB, MULT_CLAUSES] THEN
...
This gives a goal of
2 + 2 * n + (n * n + n) = n + n * n + (SUC n + 1)
---------------------------------------------------
2 * sum n = n * (n + 1)
This is now a good instance of a Presburger formula (with n*n
substituted out for an arbitrary variable), meaning that DECIDE_TAC
will solve it.
So our final tactic is
Induct_on `n` THEN SRW_TAC [][LEFT_ADD_DISTRIB, MULT_CLAUSES] THEN
DECIDE_TAC
and the final proof looks like
val sum_form = store_thm(
"sum_form",
``2 * sum n = n * (n + 1)``,
Induct_on `n` THEN SRW_TAC [][LEFT_ADD_DISTRIB, MULT_CLAUSES] THEN
DECIDE_TAC)
The form with division can subsequently be done (in a slightly hacky way) as
val sum_form_div = store_thm(
"sum_form_div",
``sum n = n * (n + 1) DIV 2``,
SRW_TAC [][Once EQ_SYM_EQ] THEN MATCH_MP_TAC DIV_UNIQUE THEN
Q.EXISTS_TAC `0` THEN SRW_TAC [][GSYM sum_form, MULT_COMM]);
Michael.
------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now. http://p.sf.net/sfu/bobj-july
_______________________________________________
hol-info mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/hol-info