Here's a question about free variables and REWRITE_TAC (and other 
thmlist->tactics).  Almost every usage of USE_THEN in the HOL Light sources is 
of the form

USE_THEN label MATCH_MP_TAC

Here's an example of a labeled assumption used in thmlist of MESON_TAC:

let NSQRT_2 = prove
 (`!p q. p * p = 2 * q * q ==> q = 0`,
  MATCH_MP_TAC num_WF THEN REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN
  INTRO_TAC "!p q; lose; need" THEN FIRST_ASSUM(MP_TAC o AP_TERM `EVEN`) THEN
  REWRITE_TAC[EVEN_MULT; ARITH] THEN REWRITE_TAC[EVEN_EXISTS] THEN
  DISCH_THEN(X_CHOOSE_THEN `m:num` SUBST_ALL_TAC) THEN
  FIRST_X_ASSUM(MP_TAC o SPECL [`q:num`; `m:num`]) THEN
  ASM_REWRITE_TAC [ARITH_RULE
   `q < 2 * m ==> q * q = 2 * m * m ==> m = 0 <=>
    (2 * m) * 2 * m = 2 * q * q ==> 2 * m <= q`] THEN
  USE_THEN "need" (fun thm -> 
  MESON_TAC[LE_MULT2; MULT_EQ_0; ARITH_RULE `2 * x <= x <=> x = 0`; thm]));;

         0..0..1..3..9..22..48..204..698..2758..solved at 8153
val NSQRT_2 : thm = |- !p q. p * p = 2 * q * q ==> q = 0

The code is slightly modified from page 75 of the HOL Light tutorial, with 
REPEAT STRIP_TAC replaced by an INTRO_TAC and ASM_MESON_TAC replaced by a 
USE_THEN-powered MESON_TAC.  But this blows up if I give a label for the 
ARITH_RULE result and then USE that as well:

let NSQRT_2 = prove
 (`!p q. p * p = 2 * q * q ==> q = 0`,
  MATCH_MP_TAC num_WF THEN REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN
  INTRO_TAC "!p q; lose; need" THEN FIRST_ASSUM(MP_TAC o AP_TERM `EVEN`) THEN
  REWRITE_TAC[EVEN_MULT; ARITH] THEN REWRITE_TAC[EVEN_EXISTS] THEN
  DISCH_THEN(X_CHOOSE_THEN `m:num` SUBST_ALL_TAC) THEN
  FIRST_X_ASSUM(MP_TAC o SPECL [`q:num`; `m:num`]) THEN
  ASM_REWRITE_TAC[ARITH_RULE
   `q < 2 * m ==> q * q = 2 * m * m ==> m = 0 <=>
    (2 * m) * 2 * m = 2 * q * q ==> 2 * m <= q`] THEN
  SUBGOAL_TAC "EZarith" `2 * x <= x <=> x = 0` [ARITH_TAC] THEN
  USE_THEN "need" (fun thm1 -> 
  USE_THEN "EZarith" (fun thm2 -> 
  MESON_TAC [LE_MULT2; MULT_EQ_0; thm1; thm2])));;

MESON_TAC hangs, and I let it go up to 9,277,022.  There's an easy fix, though: 
quantify the free variable x in "EZarith".  Now it works: 

let NSQRT_2 = prove
 (`!p q. p * p = 2 * q * q ==> q = 0`,
  MATCH_MP_TAC num_WF THEN REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN
  INTRO_TAC "!p q; lose; need" THEN FIRST_ASSUM(MP_TAC o AP_TERM `EVEN`) THEN
  REWRITE_TAC[EVEN_MULT; ARITH] THEN REWRITE_TAC[EVEN_EXISTS] THEN
  DISCH_THEN(X_CHOOSE_THEN `m:num` SUBST_ALL_TAC) THEN
  FIRST_X_ASSUM(MP_TAC o SPECL [`q:num`; `m:num`]) THEN
  ASM_REWRITE_TAC[ARITH_RULE
   `q < 2 * m ==> q * q = 2 * m * m ==> m = 0 <=>
    (2 * m) * 2 * m = 2 * q * q ==> 2 * m <= q`] THEN
  SUBGOAL_TAC "EZarith" `!x. 2 * x <= x <=> x = 0` [ARITH_TAC] THEN
  USE_THEN "need" (fun thm1 -> 
  USE_THEN "EZarith" (fun thm2 -> 
  MESON_TAC [LE_MULT2; MULT_EQ_0; thm1; thm2])));;

That works fine, and it was worth doing, to show that two different labeled 
assumptions can both be USE-ed in the same thmlist->tactic.  

Why was the free variable x OK when the result was proved by ARITH_RULE in the 
MESON_TAC thm list, but not OK when the result was proved externally and then 
referred to by label? 

I claim this problem is not caused by USE_THEN, as it comes up in the original 
version of NSQRT_2:

let NSQRT_2 = prove
 (`!p q. p * p = 2 * q * q ==> q = 0`,
  MATCH_MP_TAC num_WF THEN REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN
  REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o AP_TERM `EVEN`) THEN
  REWRITE_TAC[EVEN_MULT; ARITH] THEN REWRITE_TAC[EVEN_EXISTS] THEN
  DISCH_THEN(X_CHOOSE_THEN `m:num` SUBST_ALL_TAC) THEN
  FIRST_X_ASSUM(MP_TAC o SPECL [`q:num`; `m:num`]) THEN
  ASM_REWRITE_TAC[ARITH_RULE
   `q < 2 * m ==> q * q = 2 * m * m ==> m = 0 <=>
    (2 * m) * 2 * m = 2 * q * q ==> 2 * m <= q`] THEN
  SUBGOAL_TAC "EZarith" `!x. 2 * x <= x <=> x = 0` [ARITH_TAC] THEN
  ASM_MESON_TAC[LE_MULT2; MULT_EQ_0]);;

That works fine, but it hangs if take out the universal quantifier in "EZarith":

let NSQRT_2 = prove
 (`!p q. p * p = 2 * q * q ==> q = 0`,
  MATCH_MP_TAC num_WF THEN REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN
  REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o AP_TERM `EVEN`) THEN
  REWRITE_TAC[EVEN_MULT; ARITH] THEN REWRITE_TAC[EVEN_EXISTS] THEN
  DISCH_THEN(X_CHOOSE_THEN `m:num` SUBST_ALL_TAC) THEN
  FIRST_X_ASSUM(MP_TAC o SPECL [`q:num`; `m:num`]) THEN
  ASM_REWRITE_TAC[ARITH_RULE
   `q < 2 * m ==> q * q = 2 * m * m ==> m = 0 <=>
    (2 * m) * 2 * m = 2 * q * q ==> 2 * m <= q`] THEN
  SUBGOAL_TAC "EZarith" `2 * x <= x <=> x = 0` [ARITH_TAC] THEN
  ASM_MESON_TAC[LE_MULT2; MULT_EQ_0]);;

The reason I brought up USE_THEN is that what I really is labeled assumptions 
used as arguments of MESON to create an argument of REWRITE_TAC (or some other 
thm_list->tactic).  So let's define 

let USE_TltacThmlistThmTerm tltac thmlist label term = USE_THEN label 
  (fun thm -> tltac (thmlist @ [MESON [thm] term]));;

I know this code works in contrived examples like this, where I use MESON in 
the thm list to prove the result using itself: 

let NSQRT_2 = prove
 (`!p q. p * p = 2 * q * q ==> q = 0`,
  MATCH_MP_TAC num_WF THEN REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN
  INTRO_TAC "!p q; lose; need" THEN FIRST_ASSUM(MP_TAC o AP_TERM `EVEN`) THEN
  REWRITE_TAC[EVEN_MULT; ARITH] THEN REWRITE_TAC[EVEN_EXISTS] THEN
  DISCH_THEN(X_CHOOSE_THEN `m:num` SUBST_ALL_TAC) THEN
  FIRST_X_ASSUM(MP_TAC o SPECL [`q:num`; `m:num`]) THEN
  ASM_REWRITE_TAC[ARITH_RULE
   `q < 2 * m ==> q * q = 2 * m * m ==> m = 0 <=>
    (2 * m) * 2 * m = 2 * q * q ==> 2 * m <= q`] THEN
  SUBGOAL_TAC "EZarith" `!x. 2 * x <= x <=> x = 0` [ARITH_TAC] THEN
  USE_THEN "need" (fun thm1 -> 
  USE_THEN "EZarith" (fun thm2 -> 
  USE_TltacThmlistThmTerm MESON_TAC [LE_MULT2; MULT_EQ_0; thm1]
  "EZarith" `2 * x <= x <=> x = 0`)));;

And notice that I was able to take off the universal quantifier at the bottom, 
but not in the subgoal "EZarith".  To compound the mystery, let's run this 
interactively:


g `!p q. p * p = 2 * q * q ==> q = 0`;;
e(MATCH_MP_TAC num_WF THEN REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN
  INTRO_TAC "!p q; lose; need" THEN FIRST_ASSUM(MP_TAC o AP_TERM `EVEN`) THEN
  REWRITE_TAC[EVEN_MULT; ARITH] THEN REWRITE_TAC[EVEN_EXISTS] THEN
  DISCH_THEN(X_CHOOSE_THEN `m:num` SUBST_ALL_TAC) THEN
  FIRST_X_ASSUM(MP_TAC o SPECL [`q:num`; `m:num`]) THEN
  ASM_REWRITE_TAC[ARITH_RULE
   `q < 2 * m ==> q * q = 2 * m * m ==> m = 0 <=>
    (2 * m) * 2 * m = 2 * q * q ==> 2 * m <= q`] THEN
  SUBGOAL_TAC "EZarith" `!x. 2 * x <= x <=> x = 0` [ARITH_TAC]);;

e(USE_THEN "need" (fun thm1 -> 
  USE_THEN "EZarith" (fun thm2 -> 
  USE_TltacThmlistThmTerm MESON_TAC [LE_MULT2; MULT_EQ_0; thm1]
  "EZarith" `2 * x <= x <=> x = 0`)));;


  0 [`(2 * m) * 2 * m = 2 * q * q`] (need)
  1 [`!x. 2 * x <= x <=> x = 0`] (EZarith)

`2 * m <= q ==> q = 0`
       0..0..1..solved at 4
0..0..1..solved at 4
0..0..1..3..9..22..48..204..698..2758..solved at 8153
val it : goalstack = No subgoals

Notice that the theorem labeled "need" has two free variables.  Why is a free 
variable with EZarith a problem?

-- 
Best,
Bill 

------------------------------------------------------------------------------
Android apps run on BlackBerry 10
Introducing the new BlackBerry 10.2.1 Runtime for Android apps.
Now with support for Jelly Bean, Bluetooth, Mapview and more.
Get your Android app in front of a whole new audience.  Start now.
http://pubads.g.doubleclick.net/gampad/clk?id=124407151&iu=/4140/ostg.clktrk
_______________________________________________
hol-info mailing list
hol-info@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/hol-info

Reply via email to