Vince, I solved your parser/preterm/retypecheck exercise to fix my cases, using 
this below:

(term_of_preterm o (retypecheck [])) (end_itlist 
    (fun pt1 pt2 -> (Combp (Combp (`;\/`, pt1), pt2))) pretermDisjlist)

But I think it's much simpler to get the parser to produce strings instead of 
preterms.  So modify quotexpander in system.ml to be 

let quotexpander s =
  if s = "" then failwith "Empty quotation" else
  let c = String.sub s 0 1 in
  if c = "\"" then 
  "\""^(String.escaped (String.sub s 1 (String.length s - 1)))^"\"" else
  if c = ":" then
    "parse_type \""^
    (String.escaped (String.sub s 1 (String.length s - 1)))^"\""
  else if c = ";" then "parse_qproof \""^(String.escaped s)^"\""
  else "parse_term \""^(String.escaped s)^"\"";;

You can see that I profited from your version of quotexpander, so thanks!  So 
if the first character of a back-quoted expression is a doublequote, it will be 
treated exactly as a string minus the doublequote:

# `"X Y such that
  move (B,A,C) (B,A,X)  /\  move (B,A,X) (B',A,X) /\
  move (B',A,X) (B',A,Y)  /\  move (B',A,Y) (B',A',Y)`;;

    val it : string =
  "X Y such that\n  move (B,A,C) (B,A,X)  /\\  move (B,A,X) (B',A,X) /\\\n  
move (B',A,X) (B',A,Y)  /\\  move (B',A,Y) (B',A',Y)"

Now I can define consider and case_split (Thanks, Petros) just as I did before 
using strings, but now I don't get problems of backslashes and newlines I had 
using strings: 

# "X Y such that
  move (B,A,C) (B,A,X)  /\  move (B,A,X) (B',A,X) /\
  move (B',A,X) (B',A,Y)  /\  move (B',A,Y) (B',A',Y)";;

    val it : string =
  "X Y such that\n  move (B,A,C) (B,A,X)  /\\  move (B,A,X) (B',A,X) /move 
(B',A,X) (B',A,Y)  /\\  move (B',A,Y) (B',A',Y)"

The whole purpose of parsing is to deal with the /move error above.  I'm 
including an example below based on the HOL Light tutorial readable proof of 
the irrationality of sqrt 2.  My code also contains my solution of your 
parser/preterm/retypecheck exercise, which for simplicity borrows Freek's c = 
";" branch of quotexpander.

-- 
Best,
Bill 

(* first modify quotexpander in system.ml as above, and then run 
ocaml
#use "hol.ml";; 
*)

let consider vars_t prfs lab =
  let len = String.length vars_t in
  let rec findSuchThat = function
      n -> if String.sub vars_t n 9 = "such that" then n
      else findSuchThat (n + 1) in
  let n = findSuchThat 1 in
  let vars = String.sub vars_t 0 (n - 1) and
  t = String.sub vars_t (n + 9) (len - n - 9) in
  let tm = parse_term ("?" ^ vars ^ ". " ^ t) in
  match prfs with
   p::ps -> (warn (ps <> []) "Consider: additional subproofs ignored";
   SUBGOAL_THEN tm (DESTRUCT_TAC ("@" ^ vars ^ "." ^ lab))
   THENL [p; ALL_TAC])
   | [] -> failwith "Consider: no subproof given";;

let case_split sDestruct sDisjlist tac =
  let rec list_mk_string_disj = function
      [] -> ""
    | s::[] -> "(" ^ s ^ ")"
    | s::ls -> "(" ^ s ^ ") \\/ " ^ list_mk_string_disj ls in
  let disjthm =  parse_term (list_mk_string_disj sDisjlist) in
  SUBGOAL_TAC "" disjthm tac THEN FIRST_X_ASSUM
  (DESTRUCT_TAC sDestruct);;

let TACtoThmTactic tac = fun  ths -> MAP_EVERY MP_TAC ths THEN tac;;

let NUM_RING_thmTAC = TACtoThmTactic (CONV_TAC NUM_RING);;

let ARITH_thmTAC = TACtoThmTactic ARITH_TAC;;

let so = fun tac -> FIRST_ASSUM MP_TAC THEN tac;;

let NSQRT_2 = prove
 (`!p q. p * p = 2 * q * q ==> q = 0`,
  MATCH_MP_TAC num_WF THEN
  INTRO_TAC "!p; A; !q; B"  THEN
  SUBGOAL_TAC "" `EVEN(p * p) <=> EVEN(2 * q * q)` 
  [HYP MESON_TAC "B" []] THEN
  SUBGOAL_TAC "" `EVEN(p)` [so (MESON_TAC [ARITH; EVEN_MULT])] THEN
  consider `"m such that p = 2 * m`
  [so (MESON_TAC [EVEN_EXISTS])] "C" THEN
  case_split "qp | pq" [`"(q:num) < p`; `"p <= q`] [ARITH_TAC] THENL
  [SUBGOAL_TAC "" `q * q = 2 * m * m ==> m = 0` [HYP MESON_TAC "qp A" []] THEN
  so (HYP NUM_RING_thmTAC "B C" []);
  SUBGOAL_TAC "" `p * p <= (q:num) * q` [so (MESON_TAC [LE_MULT2 ])] THEN
  SUBGOAL_TAC "" `q * q = 0` [so (HYP ARITH_thmTAC "B" [])] THEN
  so (NUM_RING_thmTAC [])]);;

(* now a version using a solution of Vince's  parser/preterm/retypecheck 
exercise *)

let parse_qproof s = (fst o parse_preterm o lex o explode) 
  (String.sub s 1 (String.length s - 1));;

let case_split sDestruct pretermDisjlist tac =
  let disjthm = (term_of_preterm o (retypecheck [])) (end_itlist 
    (fun pt1 pt2 -> (Combp (Combp (`;\/`, pt1), pt2))) pretermDisjlist) in 
  SUBGOAL_TAC "" disjthm tac THEN FIRST_X_ASSUM
  (DESTRUCT_TAC sDestruct);;

let NSQRT_2 = prove
 (`!p q. p * p = 2 * q * q ==> q = 0`,
  MATCH_MP_TAC num_WF THEN
  INTRO_TAC "!p; A; !q; B"  THEN
  SUBGOAL_TAC "" `EVEN(p * p) <=> EVEN(2 * q * q)` 
  [HYP MESON_TAC "B" []] THEN
  SUBGOAL_TAC "" `EVEN(p)` [so (MESON_TAC [ARITH; EVEN_MULT])] THEN
  consider `"m such that p = 2 * m`
  [so (MESON_TAC [EVEN_EXISTS])] "C" THEN
  case_split "qp | pq" [`;(q:num) < p`; `;p <= q`] [ARITH_TAC] THENL
  [SUBGOAL_TAC "" `q * q = 2 * m * m ==> m = 0` [HYP MESON_TAC "qp A" []] THEN
  so (HYP NUM_RING_thmTAC "B C" []);
  SUBGOAL_TAC "" `p * p <= (q:num) * q` [so (MESON_TAC [LE_MULT2 ])] THEN
  SUBGOAL_TAC "" `q * q = 0` [so (HYP ARITH_thmTAC "B" [])] THEN
  so (NUM_RING_thmTAC [])]);;


------------------------------------------------------------------------------
Try New Relic Now & We'll Send You this Cool Shirt
New Relic is the only SaaS-based application performance monitoring service 
that delivers powerful full stack analytics. Optimize and monitor your
browser, app, & servers with just a few lines of code. Try New Relic
and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_apr
_______________________________________________
hol-info mailing list
hol-info@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/hol-info

Reply via email to