Michael and Petros, thanks to your help, I wrote a tactics script for 
REACHABLE_INVARIANT from p 67 of the HOL tutorial using the explicitly 
sequential definition reachable of 65.  Here's a simpler version of it, using 
STRIP_TAC, EXISTS_TAC, and extra type annotations as you taught me to: 

let addN = new_definition
  `!p p' n.
  addN p p' n <=> ?s. 
  s 0 = p /\ s n = p' /\ 
  (!m. m < n ==> s (SUC m) = SUC (s m))`;;

let addN_CLAUSES = prove
 (`! p p'. (addN p p' 0 <=>  p = p') /\
  !n. addN p p' (SUC n) <=> ?q. addN p q n /\ (SUC q) = p'`,
  REPEAT STRIP_TAC THEN EQ_TAC THEN ASM_SIMP_TAC[addN; LT] 
  THENL [MESON_TAC[]; DISCH_TAC; STRIP_TAC; STRIP_TAC] THENL
  [EXISTS_TAC `\m:num. p':num` THEN SIMP_TAC[];
  EXISTS_TAC `(s:num->num) n`;
  EXISTS_TAC `\m:num. if m < SUC n then s m else p':num`] THEN 
  REPEAT STRIP_TAC THEN ASM_MESON_TAC[LT_0; LT_REFL; LT; LT_SUC]);;

I like my tactics script (maybe someone can suggest a better), but I wish I had 
been able to define variables and give them labels, as I did in the miz3 proof 
below with "consider".  EXISTS_TAC worked fine, but if you need to use a 
defined variable more than once, it would look awkward to EXISTS_TAC it every 
time you used it.  One could argue that this is ugly and hard to read
`(\m. if m < SUC n then s m else p') (SUC m) =
 SUC ((\m. if m < SUC n then s m else p') m)`
and that it would be nicer to call this function "t" and write instead 
t (SUC m) = SUC (t m),
as I essentially do in my miz3 proof.  I'm sure this can be done in HOL 
tactics, I just haven't figured it out yet.  

I did answer two beginner questions I posted earlier: how can you see the 
entire goalstack, and how you debug a tactics script?  More precisely, how can 
you produce a tactics script when THEN works differently than it does in a 
interactive proof and you have to use THENLs?  The answer is that you can 
gradually turn an interactive proof g & e proof into a tactics script, because 
a tactics script is "really" just an interactive proof with one e-command.  
I'll use my tactics script above as an example.  It's basically this 
"interactive" proof:

g `! p p'. (addN p p' 0 <=>  p = p') /\
  !n. addN p p' (SUC n) <=> ?q. addN p q n /\ (SUC q) = p'`;;
e(REPEAT STRIP_TAC THEN EQ_TAC THEN ASM_SIMP_TAC[addN; LT] 
  THENL [MESON_TAC[]; DISCH_TAC; STRIP_TAC; STRIP_TAC] THENL
  [EXISTS_TAC `\m:num. p':num` THEN SIMP_TAC[];
  EXISTS_TAC `(s:num->num) n`;
  EXISTS_TAC `\m:num. if m < SUC n then s m else p':num`] THEN 
  REPEAT STRIP_TAC THEN ASM_MESON_TAC[LT_0; LT_REFL; LT; LT_SUC]);;
let addN_CLAUSES = top_thm();;

I took a interactive proof with lots of e-commands and gradually built an 
interactive proof with only one e-command.  You can see how I built it by 
evaluating a top chunk, e.g. 

g `! p p'. (addN p p' 0 <=>  p = p') /\
  !n. addN p p' (SUC n) <=> ?q. addN p q n /\ (SUC q) = p'`;;
e(REPEAT STRIP_TAC THEN EQ_TAC THEN ASM_SIMP_TAC[addN; LT] 
  THENL [MESON_TAC[]; DISCH_TAC; STRIP_TAC; STRIP_TAC]);;

val it : goalstack = 3 subgoals (3 total)

  0 [`s 0 = p`]
  1 [`s n = q`]
  2 [`!m. m < n ==> s (SUC m) = SUC (s m)`]
  3 [`SUC q = p'`]

`?s. s 0 = p /\
     s (SUC n) = p' /\
     (!m. m = n \/ m < n ==> s (SUC m) = SUC (s m))`

  0 [`s 0 = p`]
  1 [`s (SUC n) = p'`]
  2 [`!m. m = n \/ m < n ==> s (SUC m) = SUC (s m)`]

`?q. (?s. s 0 = p /\ s n = q /\ (!m. m < n ==> s (SUC m) = SUC (s m))) /\
     SUC q = p'`

  0 [`p = p'`]

`?s. s 0 = p'`

So there exactly 3 goals, and each of them requires plugging in a variable, so 
that requires 3 EXISTS_TAC.  We can easily write all 3 EXISTS_TACs at once and 
put them into the tactics script with THENL:

THENL
  [EXISTS_TAC `\m:num. p':num` THEN SIMP_TAC[];
  EXISTS_TAC `(s:num->num) n`;
  EXISTS_TAC `\m:num. if m < SUC n then s m else p':num`] 

Paste that into the big e-command and evaluate it, and you'll we see there are 
2 goals, as the SIMP_TAC[] finished the first goal.  As both goals need 
STRIP_TAC-ing, I just use 
THEN REPEAT STRIP_TAC  
and now I have 6 goals, all of which are solved by ASM_MESON_TAC[] and some of 
the arith.ml LT theorems.  So I can finish the proof interactively (and it is 
sure cool to know the whole goalstack!):

e(ASM_MESON_TAC[]);;
e(ASM_MESON_TAC[]);;
e(ASM_MESON_TAC[LT_0]);;
e(ASM_MESON_TAC[LT_REFL]);;
e(ASM_MESON_TAC[LT_REFL; LT]);;
e(ASM_MESON_TAC[LT_SUC; LT]);;

val it : goalstack = No subgoals
Yay!  And then I can tactify this with last step with 

THENL
[ASM_MESON_TAC[]; ASM_MESON_TAC[]; ASM_MESON_TAC[LT_0]; ASM_MESON_TAC[LT_REFL]; 
ASM_MESON_TAC[LT_REFL; LT]; ASM_MESON_TAC[LT_SUC; LT]]

but as John explains, why not just use all the LT theorems for all 6 cases, and 
then we have my 
THEN ASM_MESON_TAC[LT_0; LT_REFL; LT; LT_SUC].  Now John explains a lot about 
interactive proof vs tactics scripts, but somehow I missed the point that with 
a "one e-command" version of tactics script you can see whole goalstack, and if 
you would just solve all the goals simultaneously, instead of working one goal 
at a time, then you'd build your tactics script as you go.  Of course I 
probably wouldn't do that, but here's my 4-pass compiler to turn a interactive 
proof vs tactics scripts:

First make the interactive proof with the g-command on top and each e-command 
on it's own line and no blank lines.  Then after you're done, evaluate all the 
commands again from the top, and insert blank lines and TABs to indicate when 
you switch over to a new goal. Now take a 3rd pass and incrementally build an 
interactive proof with just one huge e-command underneath the g-command.  Just 
steal the top-most lines and put them in a THENL which goes at the end of the 
huge e-command.  You have to run it every time to make sure you didn't goof up 
which goals you were working one.  And then of course we must replace the 
`;;<RET>e( with let THM_NAM = prove and a ,.  

Is this all completely obvious?  I didn't know it.  Maybe someone has a better 
way to do it.  Anyway, it was a lot of fun writing this script! 

-- 
Best,
Bill 

#load "unix.cma";;
loadt "miz3/miz3.ml";;
horizon := 0;;
timeout := 50;;

let addN_THM = thm `;
  !p p'. (addN p p' 0 <=>  p = p') /\
  !n. addN p p' (SUC n) <=> ?q. addN p q n /\ SUC q = p'

  proof
    let p p' be num;
    p = p'  ==>  addN p p' 0
    proof
      assume p = p'     [pp'];
      consider s such that s = \m:num. p;
    qed     by -, pp', addN, LT;
    addN p p' 0  <=>  p = p'     [Clause0] by addN, -;
    !n. addN p p' (SUC n)  ==>  ? q. addN p q n  /\ SUC q = p'     [Imp1]
    proof
      let n be num;
      assume addN p p' (SUC n);
      consider s such that
      s 0 = p /\ s (SUC n) = p' /\ ! m. m < SUC n ==> SUC (s m) = s (SUC m)     
[SUCnDef] by -, addN;
      consider q such that q = s n     [qDef];
      SUC q = p'     [qp'] by -, SUCnDef, LT;
      s 0 = p  /\  s n = q  /\  !m. m < n ==> SUC (s m) = s (SUC m)     by 
qDef, LT, SUCnDef;
    qed     by -, qp', addN;
    !n. (?q. addN p q n  /\ SUC q = p')  ==>  addN p p' (SUC n)
    proof
      let n be num;
      assume ? q. addN p q n  /\ SUC q = p';
      consider q such that
      addN p q n  /\ SUC q = p'     [Assump] by -;
      consider s such that
      s 0 = p /\ s n = q /\ !m. m < n ==> SUC (s m) = s (SUC m)     [nDef] by 
-, addN;
      consider t such that
      t = \m. if m < SUC n then s m else p'     [tDef];
      t 0 = p /\ t (SUC n) = p'     [tBotTop] by -, nDef, LT_0, LT_REFL;
      ! m. m < (SUC n)  ==>  SUC (t m) = t (SUC m) 
      proof
        let m be num;
        assume m < SUC n     [mAss];
        m = n \/ m < n     by -, LT;
        cases by -;
        suppose m < n;
          SUC (s m) = s (SUC m)  /\  t m = s m  /\  t (SUC m) = s (SUC m)     
by -, LT, LT_SUC, tDef, nDef;  
        qed     by -, nDef;
        suppose m = n;
        qed     by -, LT, tDef, nDef, Assump, tBotTop; 
      end;                    
    qed     by tDef, tBotTop, -, addN;
    ! n. addN p p' (SUC n)  <=>  ? q. addN p q n  /\ SUC q = p' by Imp1, -;
  qed     by Clause0, -;
`;;

------------------------------------------------------------------------------
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

Reply via email to