Here's a reasonable version of a miz3 interface for HOL Light. Thanks to Vince, Freek and Petros for helping me out!
I believe this is the end of this parser-based discussion, so allow me to summarize. It's good for formal proofs to readable, especially if you want to attract mathematicians. John has always pushed for readable proofs, and writes in his purple FOL book that we should really be doing both declarative and procedural proofs, as neither is powerful enough. But it's also be nice for the Ocaml interface code to be readable, so it can be modified. I think my code below is much more readable that John's mizar.ml or Freek's masterpiece miz3.ml, whose interface I have tried to emulate. -- Best, Bill #load "str.cma";; let parse_qproof s = (String.sub s 1 (String.length s - 1));; 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 thmlist_tactics = ref([]:(string*(thm list -> tactic))list);; let thm_tactics = ref([]:(string*thm_tactic)list);; let tactics = ref([]:(string*tactic)list);; let tac_tactics = ref([]:(string*(tactic -> tactic))list);; thmlist_tactics := [ "fol",MESON_TAC; "SIMP_TAC",SIMP_TAC; "REWRITE_TAC",REWRITE_TAC; "SET_TAC",SET_TAC; "NUM_RING_thmTAC",NUM_RING_thmTAC; "ARITH_thmTAC",ARITH_thmTAC ];; thm_tactics := [ "MATCH_MP_TAC",MATCH_MP_TAC; "MP_TAC",MP_TAC; ];; tactics := [ "arithmetic",ARITH_TAC; "REAL_ARITH_TAC",REAL_ARITH_TAC ];; tac_tactics := [ "so",so ];; let (make_env: goal -> (string * pretype) list) = fun (asl,w) -> map ((fun (s,ty) -> s,pretype_of_type ty) o dest_var) (freesl (w::(map (concl o snd) asl)));; let parse_env_string env s = (term_of_preterm o retypecheck env) ((fst o parse_preterm o lex o explode) s);; let (subgoal_THEN: string -> thm_tactic -> tactic) = fun stm ttac (asl,w) -> let wa = parse_env_string (make_env (asl,w)) stm in let meta,gl,just = ttac (ASSUME wa) (asl,w) in meta,(asl,wa)::gl,fun i l -> PROVE_HYP (hd l) (just i (tl l));; let subgoal_TAC s stm prfs = match prfs with p::ps -> (warn (ps <> []) "subgoal_TAC: additional subproofs ignored"; subgoal_THEN stm (LABEL_TAC s) THENL [p; ALL_TAC]) | [] -> failwith "subgoal_TAC: no subproof given";; let (exists_TAC: string -> tactic) = fun stm (asl,w) -> let env = make_env (asl,w) in EXISTS_TAC (parse_env_string env stm) (asl,w);; let (X_gen_TAC: string -> tactic) = fun svar (asl,w) -> let vartype = (snd o dest_var o fst o dest_forall) w in X_GEN_TAC (mk_var (svar,vartype)) (asl,w);; let consider vars_t prfs lab = let noSuchThat = Str.bounded_split (Str.regexp "[ \t\n]+such[ \t\n]+that[ \t\n]+") vars_t 2 in let vars = hd noSuchThat and t = hd (tl noSuchThat) in match prfs with p::ps -> (warn (ps <> []) "consider: additional subproofs ignored"; subgoal_THEN ("?" ^ vars ^ ". " ^ t) (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 subgoal_TAC "" (list_mk_string_disj sDisjlist) tac THEN FIRST_X_ASSUM (DESTRUCT_TAC sDestruct);; let raa lab st tac = subgoal_THEN (st ^ " ==> F") (LABEL_TAC lab) THENL [INTRO_TAC lab; tac];; let CleanMathFontsForHOL_Light s = let s = Str.global_replace (Str.regexp "⇒") "==>" s in let s = Str.global_replace (Str.regexp "⇔") "<=>" s in let s = Str.global_replace (Str.regexp "∧ ") "/\\ " s in let s = Str.global_replace (Str.regexp "∨") "\\/" s in let s = Str.global_replace (Str.regexp "¬") "~" s in let s = Str.global_replace (Str.regexp "∀") "!" s in let s = Str.global_replace (Str.regexp "∃") "?" s in Str.global_replace (Str.regexp "λ") "\\" s;; let StringRegexpEqual r s = Str.string_match r s 0 && s = Str.matched_string s;; let rec ConvertToHOL s = if StringRegexpEqual (Str.regexp "[ \t\n]*\([^ \t\n]*\)[ \t\n]*") s then let tac = (Str.matched_group 1 s) in assoc tac !tactics else if StringRegexpEqual (Str.regexp "[ \t\n]*\([^ \t\n]*\)[ \t\n]*\([^ \t\n]*\)[ \t\n]*") s then let ttac = (Str.matched_group 1 s) and thm = (Str.matched_group 2 s) in if mem ttac (map fst !thm_tactics) && mem thm (map fst !theorems) then (assoc ttac !thm_tactics) (assoc thm !theorems) else if mem ttac (map fst !tac_tactics) && mem thm (map fst !tactics) then (assoc ttac !tac_tactics) (assoc thm !tactics) else ALL_TAC else if StringRegexpEqual (Str.regexp "[ \t\n]*INTRO_TAC \([^][]*\)") s then let labstring = (Str.matched_group 1 s) in INTRO_TAC (Str.global_replace (Str.regexp ",") ";" labstring) else if StringRegexpEqual (Str.regexp "[ \t\n]*exists_TAC \([^][]*\)") s then exists_TAC (Str.matched_group 1 s) else if StringRegexpEqual (Str.regexp "[ \t\n]*consider[ \t\n]+\([^][]+[ \t\n]+such[ \t\n]+that[ \t\n]+[^][]+[ \t\n]+\)\[\([^][]*\)\][ \t\n]+by[ \t\n]+\([^!]*\)[ \t\n]*") s then let vars_t = Str.matched_group 1 s and lab = Str.matched_group 2 s and tac = Str.matched_group 3 s in consider vars_t [ConvertToHOL tac] lab else if StringRegexpEqual (Str.regexp "[ \t\n]*\([^ \t\n]+\)\([ \t\n]+[^[]+[ \t\n]+\)\[\([^]]*\)\][ \t\n]*") s && mem (Str.matched_group 1 s) (map fst !thmlist_tactics) then let ttac = assoc (Str.matched_group 1 s) !thmlist_tactics and labs = Str.matched_group 2 s and listofThms = map (fun ts -> assoc ts !theorems) (Str.split (Str.regexp "[ \t\n]*,[ \t\n]*") (Str.matched_group 3 s)) in if Str.string_match (Str.regexp "[^-]*[ \t\n]+-[ \t\n]+") labs 0 then let labs_minus = Str.global_replace (Str.regexp "[ \t\n]+-") "" labs in so (HYP ttac labs_minus listofThms) else HYP ttac labs listofThms else if StringRegexpEqual (Str.regexp "\([^][]+\)\[\([^][]*\)\][ \t\n]+by[ \t\n]+\([^!]+\)[ \t\n]*") s then let statement = Str.matched_group 1 s and lab = Str.matched_group 2 s and tac = Str.matched_group 3 s in subgoal_TAC lab statement [ConvertToHOL tac] else ALL_TAC;; let organizeTHEN s = let rec THENify listofString = match listofString with [] -> ALL_TAC | hd::tl -> (ConvertToHOL hd) THEN (THENify tl) in THENify (Str.split (Str.regexp "[ \t\n]*;[ \t\n]*") s);; let StringToTacticsProof s = try let start = Str.search_forward (Str.regexp "[ \t\n]*case_split[ \t\n]+") s 0 in organizeTHEN (Str.string_before s start) THEN let s = (Str.string_after s (Str.match_end())) in if StringRegexpEqual (Str.regexp "\([^][]+\)[ \t\n]+\[\([^][]+\)\][ \t\n]+by[ \t\n]+\([^!]+\)![ \t\n]+suppose[ \t\n]+\(\(.\|\n\)+\)") s then let sDestruct = Str.matched_group 1 s and disjs = Str.matched_group 2 s and tac = Str.matched_group 3 s and tacs = Str.matched_group 4 s in let listofDisj = Str.split (Str.regexp "[ \t\n]*!,[ \t\n]*") disjs and listofTac = Str.split (Str.regexp "[ \t\n]*suppose[ \t\n]*") tacs in (case_split sDestruct listofDisj [ConvertToHOL tac]) THENL (map organizeTHEN listofTac) else ALL_TAC with Not_found -> organizeTHEN s;; let theorem s = let sl = Str.split (Str.regexp "[ \t\n]*proof[ \t\n]*") (CleanMathFontsForHOL_Light s) in prove (parse_env_string [] (hd sl), StringToTacticsProof (hd (tl sl)));; (* Two versions of proofs in the HOL Light tutorial: the axiom of choice on p 93, then the p 81 readable proof of the irrationality of sqrt 2. *) let AXIOM_OF_CHOICE = theorem `; ∀P. (∀x. ∃y. P x y) ==> ∃f. ∀x. P x (f x) proof INTRO_TAC ∀P, H1 ; exists_TAC \x. @y. P x y ; fol H1 [] `;; let NSQRT_2 = theorem `; ∀p q. p * p = 2 * q * q ⇒ q = 0 proof MATCH_MP_TAC num_WF; INTRO_TAC ∀p, A, ∀q, B; EVEN(p * p) ⇔ EVEN(2 * q * q) [] by fol B []; EVEN(p) [] by fol - [ARITH, EVEN_MULT]; consider m such that p = 2 * m [C] by fol - [EVEN_EXISTS]; case_split qp | pq [q < p !, p <= q] by arithmetic! suppose q * q = 2 * m * m ⇒ m = 0 [] by fol qp A []; NUM_RING_thmTAC - B C [] suppose p * p <= q * q [] by fol - [LE_MULT2]; q * q = 0 [] by ARITH_thmTAC - B []; NUM_RING_thmTAC - [] `;; (* tutorial proofs for comparison: let AXIOM_OF_CHOICE = prove (`(!x:A. ?y:B. P x y) ==> ?f. !x. P x (f x)`, STRIP_TAC THEN EXISTS_TAC `\x:A. @y:B. P x y` THEN ASM_MESON_TAC[]);; let NSQRT_2 = prove (`!p q. p * p = 2 * q * q ==> q = 0`, suffices_to_prove `!p. (!m. m < p ==> (!q. m * m = 2 * q * q ==> q = 0)) ==> (!q. p * p = 2 * q * q ==> q = 0)` (MATCH_ACCEPT_TAC num_WF) THEN fix [`p:num`] THEN assume("A") `!m. m < p ==> !q. m * m = 2 * q * q ==> q = 0` THEN fix [`q:num`] THEN assume("B") `p * p = 2 * q * q` THEN so have `EVEN(p * p) <=> EVEN(2 * q * q)` (trivial) THEN so have `EVEN(p)` (using [ARITH; EVEN_MULT] trivial) THEN so consider (`m:num`,"C",`p = 2 * m`) (using [EVEN_EXISTS] trivial) THEN cases ("D",`q < p \/ p <= q`) (arithmetic) THENL [so have `q * q = 2 * m * m ==> m = 0` (by ["A"] trivial) THEN so we’re finished (by ["B"; "C"] algebra); so have `p * p <= q * q` (using [LE_MULT2] trivial) THEN so have `q * q = 0` (by ["B"] arithmetic) THEN so we’re finished (algebra)]);; *) ------------------------------------------------------------------------------ Learn Graph Databases - Download FREE O'Reilly Book "Graph Databases" is the definitive new guide to graph databases and their applications. This 200-page book is written by three acclaimed leaders in the field. The early access version is available now. Download your free book today! http://p.sf.net/sfu/neotech_d2d_may _______________________________________________ hol-info mailing list hol-info@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/hol-info