Petros, I really like your fix of my code, and it's even nicer than Ramana's,
although I need to understand why his CHOOSE_TAC(ASSUME t) works. Your fix
SUBGOAL_THEN `?m. p = 2 * m` CHOOSE_TAC
is especially appealing to me, because you're usage just substitutes CHOOSE_TAC
for ASSUME_TAC, as e.g. in
SUBGOAL_THEN `EVEN p` ASSUME_TAC
I don't understand that usage yet, but I'm used it by now.
I have a new HOL Light proof runs faster because I added an extra step, and I
eliminated an embarrassment (see below) by using John's trick !x. 2 * x <= x
==> x = 0 from his earlier proof:
g `!p q. p * p = 2 * q * q ==> q = 0`;;
e(MATCH_MP_TAC num_WF);;
e(REPEAT STRIP_TAC);;
e(SUBGOAL_THEN `?m. p = 2 * m` CHOOSE_TAC);;
e(ASM_MESON_TAC[EVEN_EXISTS;EVEN_MULT]);;
e(DISJ_CASES_TAC(ARITH_RULE `q < p \/ p <= q`));;
e(SUBGOAL_THEN `q * q = 2 * m * m ==> m = 0` ASSUME_TAC);;
e(ASM_MESON_TAC[]);;
e(SUBGOAL_THEN `q * q = 2 * m * m` ASSUME_TAC);;
e(SUBGOAL_THEN `p = 2 * m /\ p * p = 2 * q * q ==> q * q = 2 * m * m`
ASSUME_TAC);;
e(CONV_TAC NUM_RING);;
e(ASM_MESON_TAC[]);;
e(SUBGOAL_THEN `m = 0` ASSUME_TAC);;
e(ASM_MESON_TAC[]);;
e(SUBGOAL_THEN `q * q = 0` ASSUME_TAC);;
e(ASM_MESON_TAC[MULT_CLAUSES]);;
e(ASM_MESON_TAC[MULT_EQ_0]);;
e(SUBGOAL_THEN `p * p <= q * q` ASSUME_TAC);;
e(ASM_MESON_TAC[LE_MULT2]);;
e(SUBGOAL_THEN `!x. 2 * x <= x ==> x = 0` ASSUME_TAC);;
e(ARITH_TAC);;
e(ASM_MESON_TAC[LTE_CASES; LE_MULT2; MULT_EQ_0]);;
I think you're saying that I can't avoid using two lines per statement: first
state the statement as a subgoal, and then prove it on the next line. So
that's fine. But I find these 3 lines embarrassing:
e(SUBGOAL_THEN `p = 2 * m /\ p * p = 2 * q * q ==> q * q = 2 * m * m`
ASSUME_TAC);;
e(CONV_TAC NUM_RING);;
e(ASM_MESON_TAC[]);;
At this point my assumption-list and goal is
0 [`!m. m < p ==> (!q. m * m = 2 * q * q ==> q = 0)`]
1 [`p * p = 2 * q * q`]
2 [`p = 2 * m`]
3 [`q < p`]
4 [`q * q = 2 * m * m ==> m = 0`]
`q * q = 2 * m * m`
It's obvious that assumptions 1 & 2 imply the goal, and NUM_RING can prove it.
So intead of these 3 lines, I wanted to write
e(ASM_MESON_TAC[NUM_RING]);;
But I can't do that, because NUM_RING isn't a theorem. I had a similar
embarrassing problem with ARITH_TAC, but John's trick got rid of it.
BTW I don't actually need ARITH_TAC for John's trick, as this miz3 proof shows:
let _THM = thm `;
thus !x. 2 * x <= x ==> x = 0
proof
let x be num;
assume 2 * x <= x;
2 <= 1 \/ x = 0 by -, MULT_CLAUSES, LE_MULT_RCANCEL;
qed by -, LT, TWO, LET_ANTISYM;
`;;
BTW I realized that
e(DISCH_THEN(CHOOSE_TAC));;
has the same effect as something that seems a lot simpler to me:
e(SIMP_TAC[LEFT_IMP_EXISTS_THM]);;
e(STRIP_TAC THEN DISCH_TAC);;
This is quite simple:
LEFT_IMP_EXISTS_THM;;
val it : thm = |- !P Q. (?x. P x) ==> Q <=> (!x. P x ==> Q)
And it makes me wonder if the way HOL tactics evolved had to do with what was
simple and appealing in the Lambda Calculus...
--
Best,
Bill
------------------------------------------------------------------------------
LogMeIn Rescue: Anywhere, Anytime Remote support for IT. Free Trial
Remotely access PCs and mobile devices and provide instant support
Improve your efficiency, and focus on delivering more value-add services
Discover what IT Professionals Know. Rescue delivers
http://p.sf.net/sfu/logmein_12329d2d
_______________________________________________
hol-info mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/hol-info