module Pa : sig val CONTEXT_TAC : ((string * pretype) list -> tactic) -> tactic val PARSE_IN_CONTEXT : (term -> tactic) -> (string -> tactic) val EXISTS_TAC : string -> tactic val SUBGOAL_THEN : string -> thm_tactic -> tactic val SUBGOAL_TAC : string -> string -> tactic list -> tactic val ASM_CASES_TAC : string -> tactic val BOOL_CASES_TAC : string -> tactic val SPEC_TAC : string * string -> tactic val SPEC : string -> thm -> thm val SPECL : string list -> thm -> thm val GEN : string -> thm -> thm val GENL : string list -> thm -> thm val X_GEN_TAC : string -> tactic val REAL_ARITH : string -> thm val REAL_FIELD : string -> thm val REAL_RING : string -> thm val ARITH_RULE : string -> thm val NUM_RING : string -> thm val INT_ARITH : string -> thm val call_with_interface : (unit -> 'a) -> (term -> 'b) -> string -> 'b end = struct let parse_preterm = fst o parse_preterm o lex o explode let CONTEXT_TAC ttac (asms,c as g) = let vs = frees c @ freesl (map (concl o snd) asms) in ttac (map (fun x -> name_of x,pretype_of_type(type_of x)) vs) g let PARSE_IN_CONTEXT ttac s = CONTEXT_TAC (fun env -> ttac (term_of_preterm (retypecheck env (parse_preterm s)))) let type_of_forall = type_of o fst o dest_forall let force_type ?(env=[]) s ty = let pty = pretype_of_type ty in term_of_preterm (retypecheck env (Typing(parse_preterm s,pty))) let BOOL_CONTEXT_TAC ttac s = CONTEXT_TAC (fun env -> ttac (force_type ~env s bool_ty)) let SUBGOAL_THEN s ttac = BOOL_CONTEXT_TAC (C SUBGOAL_THEN ttac) s let SUBGOAL_TAC l s tacs = BOOL_CONTEXT_TAC (C (SUBGOAL_TAC l) tacs) s let ASM_CASES_TAC = BOOL_CONTEXT_TAC ASM_CASES_TAC let BOOL_CASES_TAC = BOOL_CONTEXT_TAC BOOL_CASES_TAC let EXISTS_TAC s (_,c as g) = CONTEXT_TAC (fun env -> EXISTS_TAC (force_type ~env s (type_of (fst (dest_exists c))))) g let SPEC_TAC (u,x) = PARSE_IN_CONTEXT (fun u' -> SPEC_TAC (u',force_type x (type_of u'))) u let SPEC s th = SPEC (force_type s (type_of_forall (concl th))) th let SPECL tms th = try rev_itlist SPEC tms th with Failure _ -> failwith "SPECL" let GEN s th = GEN (try find ((=) s o name_of) (frees (concl th)) with _ -> parse_term s) th let GENL = itlist GEN let X_GEN_TAC s (_,c as g) = X_GEN_TAC (force_type s (type_of_forall c)) g let call_with_interface p f s = let i = !the_interface in p (); let res = f (parse_term s) in the_interface := i; res let [REAL_ARITH;REAL_FIELD;REAL_RING] = map (call_with_interface prioritize_real) [REAL_ARITH;REAL_FIELD;REAL_RING] let [ARITH_RULE;NUM_RING] = map (call_with_interface prioritize_num) [ARITH_RULE;NUM_RING] let INT_ARITH = call_with_interface prioritize_int INT_ARITH end;; module Pa = struct include Pa let COMPLEX_FIELD = call_with_interface prioritize_complex COMPLEX_FIELD;; let SIMPLE_COMPLEX_ARITH = call_with_interface prioritize_complex SIMPLE_COMPLEX_ARITH; end;; let MP_REWRITE_TAC th (_,c as g) = let [th] = mk_rewrites true th [] in let PART_MATCH = PART_MATCH (lhs o snd o strip_forall o snd o dest_imp) th in let th = ref TRUTH in ignore (find_term (fun t -> try th := PART_MATCH t; true with _ -> false) c); (SUBGOAL_THEN (lhand (concl !th)) (fun x -> REWRITE_TAC[MP !th x] THEN STRIP_ASSUME_TAC x)) g;; let CASES_REWRITE_TAC th (_,c as g) = let [th] = mk_rewrites true th [] in let PART_MATCH = PART_MATCH (lhs o snd o strip_forall o snd o dest_imp) th in let th = ref TRUTH in ignore (find_term (fun t -> try th := PART_MATCH t; true with _ -> false) c); (ASM_CASES_TAC (lhand (concl !th)) THENL [ POP_ASSUM (fun x -> REWRITE_TAC[MP !th x] THEN ASSUME_TAC x); POP_ASSUM (ASSUME_TAC o REWRITE_RULE[NOT_CLAUSES])]) g;; let wrap f x = f [x];; let CONJS xs = end_itlist CONJ xs;; let rec simp_horn_conv = let is_atomic (x,y) = if x = [] then y else failwith "" in let rec tl = function [] -> [] | _::xs -> xs in fun l -> let fixpoint = ref true in let l' = rev_itlist (fun (hs,cs) (dones,todos) -> let atomics = flat (mapfilter is_atomic (dones@todos)) in let f = filter (not o C mem atomics) in let hs' = f hs and cs' = f cs in if not (hs' = hs) or not (cs' = cs) then fixpoint := false; if (cs' = [] && cs <> []) then (dones,tl todos) else ((hs',cs')::dones),tl todos) l ([],tl l) in if !fixpoint then l else simp_horn_conv (fst l');; let horns_of_term = let strip_conj = binops `(/\)` in fun t -> map (fun t -> try let h,c = dest_imp t in strip_conj h,strip_conj c with _ -> [],[t]) (strip_conj t);; let term_of_horns = let term_of_horn = function |[],cs -> list_mk_conj cs |_,[] -> (print_endline "ici";`T`) |hs,cs -> mk_imp (list_mk_conj hs,list_mk_conj cs) in list_mk_conj o map term_of_horn;; let SIMP_HORN_CONV t = TAUT (mk_eq (t,((term_of_horns o simp_horn_conv o horns_of_term) t)));; let SIMP_HORN_TAC = REWRITE_TAC[IMP_IMP] THEN CONV_TAC (TOP_DEPTH_CONV (CHANGED_CONV SIMP_HORN_CONV));; let HINT_EXISTS_TAC = let strip_conj = binops `/\` in let P = `P:bool` in fun (hs,c as g) -> let hs = map snd hs in let vars = flat (map thm_frees hs) in let vs,c' = strip_exists c in let cs = strip_conj c' in let hyp_match c h = term_match (subtract vars vs) c (concl h), h in let (_,fosubs,_),h = tryfind (fun c -> tryfind (hyp_match c) hs) cs in let ts,vs' = unzip fosubs in let vs'' = subtract vs vs' in let th = MESON[] (mk_eq(list_mk_exists(vs,P),list_mk_exists(vs'@vs'',P))) in (REWRITE_TAC [th] THEN MAP_EVERY EXISTS_TAC ts THEN REWRITE_TAC [h]) g;; let rec fixpoint f x = let y = f x in if y = x then y else fixpoint f y;; let GIMP_IMP = GEN_ALL o REWRITE_RULE[IMP_IMP;GSYM CONJ_ASSOC] o DISCH_ALL o fixpoint (UNDISCH_ALL o SPEC_ALL);;