(`!n a b.
~(a n = &0) /\ (b n = &0) /\ (!m. sum(0..m) a = b m)
==> ?d.
MATCH_MP_TAC
num_WF THEN X_GEN_TAC `n:num` THEN
DISCH_THEN(LABEL_TAC "*") THEN
REPEAT STRIP_TAC THEN ASM_CASES_TAC `n = 0` THENL
[FIRST_X_ASSUM(MP_TAC o SPEC `0`) THEN
ASM_REWRITE_TAC[
SUM_SING_NUMSEG] THEN
ASM_MESON_TAC[];
ALL_TAC] THEN
FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (ARITH_RULE
`~(n = 0) ==> n = 1 \/ 2 <= n`))
THENL
[FIRST_X_ASSUM SUBST_ALL_TAC THEN EXISTS_TAC `1` THEN
CONV_TAC NUM_REDUCE_CONV THEN
CONV_TAC(ONCE_DEPTH_CONV NUMSEG_CONV) THEN
REWRITE_TAC[
VARIATION_2;
OPPOSITE_SIGNS] THEN
FIRST_X_ASSUM(fun th -> MP_TAC(SPEC `0` th) THEN MP_TAC(SPEC `1` th)) THEN
SIMP_TAC[num_CONV `1`;
SUM_CLAUSES_NUMSEG] THEN
CONV_TAC NUM_REDUCE_CONV THEN COND_CASES_TAC THEN REWRITE_TAC[] THEN
ASM_ARITH_TAC;
ALL_TAC] THEN
SUBGOAL_THEN `?p. 1 < p /\ p <= n /\ ~(a p = &0)` MP_TAC THENL
[ASM_MESON_TAC[ARITH_RULE `2 <= n ==> 1 < n`;
LE_REFL];
GEN_REWRITE_TAC LAND_CONV [
num_WOP] THEN
REWRITE_TAC[TAUT `a ==> ~(b /\ c /\ ~d) <=> a /\ b /\ c ==> d`] THEN
STRIP_TAC] THEN
REMOVE_THEN "*" (MP_TAC o SPEC `n - 1`) THEN
ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN DISCH_THEN(MP_TAC o SPECL
[`(\i. if i + 1 = 1 then a 0 + a 1 else a(i + 1)):num->real`;
`(\i. b(i + 1)):num->real`]) THEN
ASM_SIMP_TAC[ARITH_RULE `2 <= n ==> ~(n = 1) /\ n - 1 + 1 = n`] THEN
REWRITE_TAC[GSYM(SPEC `1`
VARIATION_OFFSET)] THEN ANTS_TAC THENL
[X_GEN_TAC `m:num` THEN MATCH_MP_TAC
EQ_TRANS THEN
EXISTS_TAC `sum(0..m+1) a` THEN CONJ_TAC THENL
[SIMP_TAC[
SUM_CLAUSES_LEFT;
LE_0; ARITH_RULE `0 + 1 <= n + 1`] THEN
CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[REAL_ADD_ASSOC] THEN
AP_TERM_TAC THEN REWRITE_TAC[ARITH_RULE `2 = 1 + 1`;
SUM_OFFSET] THEN
MATCH_MP_TAC
SUM_EQ_NUMSEG THEN ARITH_TAC;
ASM_REWRITE_TAC[]];
ABBREV_TAC `a':num->real = \m. if m = 1 then a 0 + a 1 else a m` THEN
ASM_SIMP_TAC[ARITH_RULE
`2 <= n ==> n - 1 + 1 = n /\ n - 1 - 1 + 1 = n - 1`] THEN
CONV_TAC NUM_REDUCE_CONV] THEN
SUBGOAL_THEN
`variation (1..n) a' = variation {1,p} a' + variation (p..n) a /\
variation (0..n) a = variation {0,1,p} a + variation (p..n) a`
(CONJUNCTS_THEN SUBST1_TAC)
THENL
[CONJ_TAC THEN MATCH_MP_TAC
EQ_TRANS THENL
[EXISTS_TAC `variation(1..p) a' + variation(p..n) a'`;
EXISTS_TAC `variation(0..p) a + variation(p..n) a`] THEN
(CONJ_TAC THENL
[MATCH_MP_TAC
VARIATION_SPLIT_NUMSEG THEN EXPAND_TAC "a'" THEN
REWRITE_TAC[
IN_NUMSEG] THEN ASM_ARITH_TAC;
BINOP_TAC THENL
[MATCH_MP_TAC
VARIATION_SUBSET; MATCH_MP_TAC
VARIATION_EQ] THEN
EXPAND_TAC "a'" THEN REWRITE_TAC[
INSERT_SUBSET;
EMPTY_SUBSET] THEN
REWRITE_TAC[
IN_NUMSEG] THEN TRY(GEN_TAC THEN ASM_ARITH_TAC) THEN
(CONJ_TAC THENL [ASM_ARITH_TAC; REWRITE_TAC[
IN_DIFF]]) THEN
REWRITE_TAC[
IN_NUMSEG;
IN_INSERT;
NOT_IN_EMPTY] THEN
REPEAT STRIP_TAC THEN TRY COND_CASES_TAC THEN
TRY(FIRST_X_ASSUM MATCH_MP_TAC) THEN ASM_ARITH_TAC]);
ALL_TAC] THEN
DISCH_THEN(X_CHOOSE_THEN `d:num` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
REWRITE_TAC[GSYM
INT_OF_NUM_EQ; GSYM
INT_OF_NUM_ADD] THEN
DISCH_THEN(ASSUME_TAC o MATCH_MP (INT_ARITH
`a + b:int = c + d ==> c = (a + b) - d`)) THEN
REWRITE_TAC[INT_ARITH `a + b:int = c + d <=> d = (a + b) - c`] THEN
ASM_CASES_TAC `a 0 + a 1 = &0` THENL
[SUBGOAL_THEN `!i. 0 < i /\ i < p ==> b i = &0` ASSUME_TAC THENL
[REPEAT STRIP_TAC THEN
FIRST_X_ASSUM(SUBST1_TAC o SYM o SPEC `i:num`) THEN
ASM_SIMP_TAC[
SUM_CLAUSES_LEFT;
LE_0;
ARITH_RULE `0 < i ==> 0 + 1 <= i`] THEN
CONV_TAC NUM_REDUCE_CONV THEN
ASM_REWRITE_TAC[REAL_ADD_ASSOC; REAL_ADD_LID] THEN
MATCH_MP_TAC
SUM_EQ_0_NUMSEG THEN REPEAT STRIP_TAC THEN
FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC;
ALL_TAC] THEN
SUBGOAL_THEN `(b:num->real) p = a p` ASSUME_TAC THENL
[FIRST_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [GSYM th]) THEN
SIMP_TAC[
SUM_CLAUSES_RIGHT; ASSUME `1 < p`;
ARITH_RULE `1 < p ==> 0 < p /\ 0 <= p`] THEN
ASM_REWRITE_TAC[
REAL_EQ_ADD_RCANCEL_0] THEN
FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC;
ALL_TAC] THEN
SUBGOAL_THEN `variation(0..n) b = variation {0,p} b + variation(1..n) b`
SUBST1_TAC THENL
[MATCH_MP_TAC
EQ_TRANS THEN
EXISTS_TAC `variation(0..p) b + variation(p..n) b` THEN CONJ_TAC THENL
[MATCH_MP_TAC
VARIATION_SPLIT_NUMSEG THEN REWRITE_TAC[
IN_NUMSEG] THEN
CONJ_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
FIRST_ASSUM(SUBST1_TAC o SYM o SPEC `p:num`) THEN
SIMP_TAC[
SUM_CLAUSES_RIGHT; ASSUME `1 < p`;
ARITH_RULE `1 < p ==> 0 < p /\ 0 <= p`] THEN
ASM_REWRITE_TAC[] THEN
FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
`~(ap = &0) ==> s = &0 ==> ~(s + ap = &0)`)) THEN
FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC;
BINOP_TAC THENL [ALL_TAC; CONV_TAC SYM_CONV] THEN
MATCH_MP_TAC
VARIATION_SUBSET THEN
REWRITE_TAC[
SUBSET;
IN_DIFF;
IN_NUMSEG;
IN_INSERT;
NOT_IN_EMPTY] THEN
(CONJ_TAC THENL [ASM_ARITH_TAC; REPEAT STRIP_TAC]) THEN
FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC];
ALL_TAC];
SUBGOAL_THEN `variation(0..n) b = variation {0,1} b + variation(1..n) b`
SUBST1_TAC THENL
[MATCH_MP_TAC
EQ_TRANS THEN
EXISTS_TAC `variation(0..1) b + variation(1..n) b` THEN CONJ_TAC THENL
[MATCH_MP_TAC
VARIATION_SPLIT_NUMSEG THEN REWRITE_TAC[
IN_NUMSEG] THEN
CONJ_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
FIRST_ASSUM(SUBST1_TAC o SYM o SPEC `1`) THEN
SIMP_TAC[
SUM_CLAUSES_NUMSEG; num_CONV `1`] THEN
CONV_TAC NUM_REDUCE_CONV THEN ASM_REWRITE_TAC[];
AP_THM_TAC THEN AP_TERM_TAC THEN MATCH_MP_TAC
VARIATION_SUBSET THEN
REWRITE_TAC[
SUBSET;
IN_DIFF;
IN_NUMSEG;
IN_INSERT;
NOT_IN_EMPTY] THEN
ARITH_TAC];
SUBGOAL_THEN `(b:num->real) 1 = a 0 + a 1` ASSUME_TAC THENL
[FIRST_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [GSYM th]) THEN
SIMP_TAC[num_CONV `1`;
SUM_CLAUSES_NUMSEG] THEN
CONV_TAC NUM_REDUCE_CONV;
ALL_TAC]]] THEN
REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `0`)) THEN CONV_TAC NUM_REDUCE_CONV THEN
REWRITE_TAC[
SUM_SING_NUMSEG] THEN DISCH_TAC THEN
ASM_REWRITE_TAC[GSYM
INT_OF_NUM_ADD] THEN
ASM_SIMP_TAC[
VARIATION_3; ARITH;
OPPOSITE_SIGNS] THEN COND_CASES_TAC THEN
REWRITE_TAC[
VARIATION_2;
OPPOSITE_SIGNS;
REAL_LT_REFL] THEN
EXPAND_TAC "a'" THEN CONV_TAC NUM_REDUCE_CONV THEN
ASM_SIMP_TAC[ARITH_RULE `1 < p ==> ~(p = 1)`;
REAL_LT_REFL] THEN
REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN
CONV_TAC NUM_REDUCE_CONV THEN
CONV_TAC(BINDER_CONV(RAND_CONV(RAND_CONV INT_POLY_CONV))) THEN
REWRITE_TAC[INT_ARITH `x:int = y + --z <=> x + z = y`] THEN
REWRITE_TAC[
INT_OF_NUM_ADD;
INT_OF_NUM_EQ] THEN
ONCE_REWRITE_TAC[
CONJ_SYM] THEN ASM_REWRITE_TAC[
UNWIND_THM2] THEN
ASM_REWRITE_TAC[
ODD_ADD;
ARITH_ODD;
ARITH_EVEN] THEN ASM_REAL_ARITH_TAC);;