1(* hh_write module: write a given problem to various TPTP formats: 2 fof, tff1, thf0 and full thf *) 3 4open Lib;; 5open Fusion;; 6open Basics;; 7open Bool;; 8open Equal;; 9open Hl_parser;; 10open Pervasives;; 11open Tactics;; 12open Simp;; 13(*open Theorems;;*) 14open Hh_symbols;; 15open Hh_tac;; 16 17module Sm = Map.Make(struct type t = string let compare = compare end);; 18module Tmm = Map.Make(struct type t = term let compare = compare end);; 19 20let variant_name_hash s used = 21 try let i = Hashtbl.find used s in 22 let rec new_name s i = 23 let si = s ^ string_of_int i in 24 if Hashtbl.mem used si then new_name s (i + 1) 25 else (Hashtbl.replace used si 0; Hashtbl.replace used si (i + 1); si) 26 in new_name s i 27 with Not_found -> Hashtbl.replace used s 0; s 28 29let variant_name_map s used = 30 try let i = Sm.find s used in 31 let rec new_name s i = 32 let si = s ^ string_of_int i in 33 if Sm.mem si used then new_name s (i + 1) 34 else (si, Sm.add s (i + 1) (Sm.add si 0 used)) 35 in new_name s i 36 with Not_found -> (s, Sm.add s 0 used) 37 38let print_vartype t = 39 let s = String.copy (dest_vartype t) in 40 escape_tyvar s 41 42let os = output_string;; 43let rec oiter oc fn sep = function 44 [] -> () 45 | [e] -> fn oc e 46 | h :: t -> fn oc h; os oc sep; oiter oc fn sep t;; 47 48let string_list_of_string str sep = 49 let rec slos_aux str ans = 50 if str = "" then ans else 51 try 52 let first_space = String.index str sep in 53 if first_space = 0 then 54 slos_aux (String.sub str 1 (String.length str - 1)) ans 55 else 56 slos_aux 57 (String.sub str (first_space + 1)(String.length str - 1 - first_space)) 58 ((String.sub str 0 (first_space)) :: ans) 59 with 60 Not_found -> 61 List.rev (str :: ans) 62 in slos_aux str [] 63;; 64 65let rec chop_listnok acc n = function 66 [] -> (List.rev acc, []) 67 | h :: t -> if n = 0 then (List.rev acc, h :: t) else chop_listnok (h :: acc) (n - 1) t;; 68 69let rec chop_listn acc n = function 70 [] -> failwith "chop_listn" 71 | h :: t -> if n = 0 then (List.rev acc, h :: t) else chop_listn (h :: acc) (n - 1) t;; 72 73(* The HO-funtype `:(A -> B) list` will be lost *) 74let name_tscs_mono_fold ho (tys, cs, used) tm () = 75 let ctys = if not ho then [type_of tm] else striplist dest_fun_ty (type_of tm) in 76 let rec name_ty ty = 77 if Hashtbl.mem tys ty then () else 78 let n = 79 if is_type ty then 80 let s, stys = dest_type ty in 81 List.iter name_ty stys; 82 String.concat "" (escape_const s :: (map (fun x -> Hashtbl.find tys x) stys)) 83 else print_vartype ty in 84 let n = variant_name_hash n used in Hashtbl.replace tys ty n 85 in 86 List.iter name_ty ctys; 87 if Hashtbl.mem cs tm || is_var tm then () else 88 let n = escape_const (fst (dest_const tm)) in 89 let n = variant_name_hash n used in 90 Hashtbl.replace cs tm n 91;; 92 93let name_tscs_poly_fold (tys, cs, used) tm () = 94 let rec name_ty ty = 95 if is_type ty then 96 let s, stys = dest_type ty in 97 (if Hashtbl.mem tys s then () else 98 Hashtbl.replace tys s (variant_name_hash (escape_const s) used)); 99 List.iter name_ty stys; 100 else 101 let s = dest_vartype ty in 102 (if Hashtbl.mem tys s then () else 103 Hashtbl.replace tys s (variant_name_hash (print_vartype ty) used)); 104 in 105 name_ty (type_of tm); 106 if is_var tm then 107 let s = fst (dest_var tm) in 108 if Hashtbl.mem cs ("`" ^ s) then () else 109 let n = variant_name_hash (escape_const s) used in 110 Hashtbl.replace cs ("`" ^ s) n 111 else 112 let s, _ = dest_const tm in 113 if Hashtbl.mem cs s then () else 114 let n = variant_name_hash (escape_const s) used in 115 Hashtbl.replace cs s n 116;; 117 118let rec fold_cs_vs fn tm sofar = 119 try let l,r = try dest_forall tm with Failure _ -> 120 try dest_exists tm with Failure _ -> 121 dest_abs tm in 122 fold_cs_vs fn r (fold_cs_vs fn l sofar) 123 with Failure _ -> try 124 let l,r = try dest_conj tm with Failure _ -> 125 try dest_disj tm with Failure _ -> 126 try dest_eq tm with Failure _ -> 127 dest_imp tm in 128 fold_cs_vs fn r (fold_cs_vs fn l sofar) 129 with Failure _ -> try 130 let tm = dest_neg tm in fold_cs_vs fn tm sofar 131 with Failure _ -> try 132 let l, r = dest_comb tm in 133 fold_cs_vs fn r (fold_cs_vs fn l sofar) 134 with Failure _ -> fn tm sofar;; 135 136let name_tscs_mono ho data tm = 137 fold_cs_vs (name_tscs_mono_fold ho data) tm ();; 138let name_tscs_poly data tm = 139 fold_cs_vs (name_tscs_poly_fold data) tm ();; 140 141let is_fun_ty = function Tyapp("fun",[ty1;ty2]) -> true | _ -> false;; 142 143let rec oty_mono ts order oc ty = 144 if is_fun_ty ty then 145 match order with 146 0 -> os oc (Hashtbl.find ts ty) 147 | 1 -> 148 let t1, t2 = dest_fun_ty ty in 149 os oc "("; oty_mono ts 0 oc t1; os oc " > "; oty_mono ts 0 oc t2; os oc ")" 150 | _ -> 151 let args, res = splitlist dest_fun_ty ty in 152 os oc "("; oiter oc (oty_mono ts (order - 1)) " > " args; os oc " > "; 153 oty_mono ts (order - 1) oc res; os oc ")" 154 else os oc (Hashtbl.find ts ty);; 155 156let rec oty_poly ts order oc ty = 157 (* try is needed for constant types in TFF *) 158 if is_vartype ty then os oc (try Hashtbl.find ts (dest_vartype ty) with Not_found -> print_vartype ty) else 159 let pr_br ty = 160 let (s, tys) = dest_type ty in 161 if order < 0 then begin 162 if tys <> [] then os oc "("; 163 os oc (Hashtbl.find ts s); 164 List.iter (fun ty -> os oc " @ "; oty_poly ts order oc ty) tys; 165 if tys <> [] then os oc ")"; 166 end else begin 167 os oc (Hashtbl.find ts s); 168 if tys = [] then () else (os oc "("; oiter oc (oty_poly ts 0) "," tys; os oc ")") 169 end in 170 if is_fun_ty ty then 171 (match order with 172 0 -> pr_br ty 173 | 1 -> 174 let args, res = splitlist dest_fun_ty ty in 175 (match args with 176 [a] -> oty_poly ts 0 oc a; os oc " > "; oty_poly ts 0 oc res 177 | _ -> os oc "("; oiter oc (oty_poly ts 0) " * " args; os oc " > "; oty_poly ts 0 oc res) 178 | _ -> 179 let args, res = splitlist dest_fun_ty ty in 180 os oc "("; oiter oc (oty_poly ts (order - 1)) " > " args; os oc " > "; 181 oty_poly ts (order - 1) oc res; os oc ")") 182 else pr_br ty;; 183 184let inst_const tm = 185 if is_const tm then 186 let (n, ty) = dest_const tm in 187 let gty = get_const_type n in 188 let inst = type_match gty ty [] in 189 let rinst = map (fun (a, b) -> (b, a)) inst in 190 let tvs = tyvars gty in 191 map (fun x -> assoc x rinst) tvs 192 else [];; 193 194let rec tff_tm oc (bnd, used) cs ts tm = 195 if is_var tm then begin 196 os oc (try Tmm.find tm bnd with Not_found -> Hashtbl.find cs ("`" ^ (o fst dest_var) tm)) 197 end else begin 198 let (f, args) = strip_comb tm in 199 os oc (Hashtbl.find cs (fst (dest_const f))); 200 let insts = inst_const f in 201 if args <> [] || insts <> [] then begin 202 os oc "("; 203 oiter oc (fun oc ty -> oty_poly ts 0 oc ty) "," insts; 204 (if args <> [] && insts <> [] then os oc "," else ()); 205 oiter oc (fun oc e -> tff_tm oc (bnd, used) cs ts e) "," args; 206 os oc ")" 207 end 208 end;; 209 210let bindv v (bnd, used) = 211 if Tmm.mem v bnd then (bnd, used) else 212 let n = escape_var (fst (dest_var v)) in 213 let (n, used) = variant_name_map n used in 214 (Tmm.add v n bnd, used) 215;; 216 217let pr_bs_poly oc order bnd ts bs = 218 (os oc "["; oiter oc (fun oc v -> os oc (Tmm.find v bnd); os oc ":"; oty_poly ts order oc (type_of v)) "," bs; 219 os oc "]:");; 220 221let rec tff_pred oc (bnd, used) cs ts tm = 222 if is_forall tm then 223 let bs, bod = strip_forall tm in 224 let (bnd, used) = rev_itlist bindv bs (bnd, used) in 225 os oc "!"; pr_bs_poly oc 0 bnd ts bs; tff_pred oc (bnd, used) cs ts bod 226 else if is_exists tm then 227 let bs, bod = strip_exists tm in 228 let (bnd, used) = rev_itlist bindv bs (bnd, used) in 229 os oc "?"; pr_bs_poly oc 0 bnd ts bs; tff_pred oc (bnd, used) cs ts bod 230 else if is_conj tm then 231 (os oc "("; oiter oc (fun oc e -> tff_pred oc (bnd, used) cs ts e) " & " (conjuncts tm); os oc ")") 232 else if is_disj tm then 233 (os oc "("; oiter oc (fun oc e -> tff_pred oc (bnd, used) cs ts e) " | " (disjuncts tm); os oc ")") 234 else if is_imp tm then let l, r = dest_imp tm in 235 (os oc "("; tff_pred oc (bnd, used) cs ts l; os oc " => "; 236 tff_pred oc (bnd, used) cs ts r; os oc ")") 237 else if is_neg tm then 238 let t = dest_neg tm in (os oc "~ ("; tff_pred oc (bnd,used) cs ts t; os oc ")") 239 else if is_eq tm then let l,r = dest_eq tm in 240 if must_pred l || must_pred r then 241 (os oc "("; tff_pred oc (bnd, used) cs ts l; os oc " <=> "; 242 tff_pred oc (bnd, used) cs ts r; os oc ")") 243 else 244 (tff_tm oc (bnd, used) cs ts l; os oc " = "; tff_tm oc (bnd, used) cs ts r) 245 else 246 (os oc "p("; tff_tm oc (bnd, used) cs ts tm; os oc ")");; 247 248let tff_pred oc cs ts used_map t = 249 let tvs = type_vars_in_term t in 250 let stvs = map dest_vartype tvs in 251 let used_map = itlist (fun s m -> Sm.add s 0 m) stvs used_map in 252 (if tvs <> [] then (os oc "!["; oiter oc (fun oc e -> oty_poly ts 0 oc e; os oc " : $tType") "," tvs; os oc "]: ")); 253 tff_pred oc (Tmm.empty, used_map) cs ts t 254;; 255 256let pr_bs_mono oc order bnd ts bs = 257 (os oc "["; oiter oc (fun oc v -> os oc (Tmm.find v bnd); os oc ":"; oty_mono ts order oc (type_of v)) "," bs; 258 os oc "]:");; 259 260let rec thf_tm oc (bnd, used) cs ts tm = 261 if is_forall tm then 262 let bs, bod = strip_forall tm in 263 let (bnd, used) = rev_itlist bindv bs (bnd, used) in 264 os oc "!"; pr_bs_mono oc (-1) bnd ts bs; thf_tm oc (bnd, used) cs ts bod 265 else if is_exists tm then 266 let bs, bod = strip_exists tm in 267 let (bnd, used) = rev_itlist bindv bs (bnd, used) in 268 os oc "?"; pr_bs_mono oc (-1) bnd ts bs; thf_tm oc (bnd, used) cs ts bod 269 else if is_abs tm then 270 let bs, bod = strip_abs tm in 271 let (bnd, used) = rev_itlist bindv bs (bnd, used) in 272 os oc "^"; pr_bs_mono oc (-1) bnd ts bs; thf_tm oc (bnd, used) cs ts bod 273 else if is_conj tm then 274 (os oc "("; oiter oc (fun oc e -> thf_tm oc (bnd, used) cs ts e) " & " (conjuncts tm); os oc ")") 275 else if is_disj tm then 276 (os oc "("; oiter oc (fun oc e -> thf_tm oc (bnd, used) cs ts e) " | " (disjuncts tm); os oc ")") 277 else if is_imp tm then let l, r = dest_imp tm in 278 (os oc "("; thf_tm oc (bnd, used) cs ts l; os oc " => "; 279 thf_tm oc (bnd, used) cs ts r; os oc ")") 280 else if is_neg tm then 281 let t = dest_neg tm in (os oc "~ ("; thf_tm oc (bnd,used) cs ts t; os oc ")") 282 else if is_eq tm then let l,r = dest_eq tm in 283 (os oc "("; thf_tm oc (bnd, used) cs ts l; 284 os oc (if type_of l = bool_ty then " <=> " else " = "); 285 thf_tm oc (bnd, used) cs ts r; os oc ")") 286 else if is_comb tm then let hop, args = strip_comb tm in 287 (os oc "("; oiter oc (fun oc e -> thf_tm oc (bnd, used) cs ts e) " @ " (hop :: args); os oc ")") 288 else if is_const tm then os oc (Hashtbl.find cs tm) 289 else os oc (try Tmm.find tm bnd with Not_found -> failwith "thf_tm");; 290 291let output_gs oc (asms, gl) = 292 let iter (s, thm) = os oc "% Assm ["; os oc s; os oc "]: "; os oc (lstring_of_term (concl thm)); os oc "\n" in 293 List.iter iter asms; 294 os oc "% Goal: "; os oc (lstring_of_term gl); os oc "\n";; 295 296let oi oc i = os oc (string_of_int i);; 297 298let thf_gl oc ls asms gl n = 299 let ts, cs, used = Hashtbl.create 20, Hashtbl.create 50, Hashtbl.create 50 in 300 Hashtbl.add used "lambda" 0; (* LeoII throws syntax errors with 'lambda' *) 301 List.iter (name_tscs_mono true (ts, cs, used)) (gl :: asms); 302 let ohdr s1 s2 = os oc "thf("; os oc s1; os oc ", "; os oc s2; os oc ", " in 303 let otl () = os oc ").\n" in 304 os oc "% TYPES\n"; 305 Hashtbl.remove ts (parse_type "bool"); 306 Hashtbl.iter (fun _ ty -> ohdr ty "type"; os oc ty; os oc " : $tType"; otl ()) ts; 307 Hashtbl.add ts (parse_type "bool") "$o"; 308 os oc "% CONSTS\n"; 309 Hashtbl.remove cs (parse_term "T"); Hashtbl.remove cs (parse_term "F"); 310 Hashtbl.iter (fun t s -> ohdr s "type"; os oc s; os oc " : "; oty_mono ts (-1) oc (type_of t); otl ()) cs; 311 Hashtbl.add cs (parse_term "T") "$true"; Hashtbl.add cs (parse_term "F") "$false"; 312 os oc "% AXIOMS\n"; 313 List.iter2 (fun n t -> ohdr n "axiom"; thf_tm oc (Tmm.empty, Sm.empty) cs ts t; otl ()) ls asms; 314 ohdr n "conjecture"; thf_tm oc (Tmm.empty, Sm.empty) cs ts gl; otl () 315;; 316 317let rec thff_tm oc (bnd, used) cs ts tm = 318 if is_forall tm then 319 let bs, bod = strip_forall tm in 320 let (bnd, used) = rev_itlist bindv bs (bnd, used) in 321 os oc "!"; pr_bs_poly oc (-1) bnd ts bs; thff_tm oc (bnd, used) cs ts bod 322 else if is_exists tm then 323 let bs, bod = strip_exists tm in 324 let (bnd, used) = rev_itlist bindv bs (bnd, used) in 325 os oc "?"; pr_bs_poly oc (-1) bnd ts bs; thff_tm oc (bnd, used) cs ts bod 326 else if is_abs tm then 327 let bs, bod = strip_abs tm in 328 let (bnd, used) = rev_itlist bindv bs (bnd, used) in 329 os oc "^"; pr_bs_poly oc (-1) bnd ts bs; thff_tm oc (bnd, used) cs ts bod 330 else if is_conj tm then 331 (os oc "("; oiter oc (fun oc e -> thff_tm oc (bnd, used) cs ts e) " & " (conjuncts tm); os oc ")") 332 else if is_disj tm then 333 (os oc "("; oiter oc (fun oc e -> thff_tm oc (bnd, used) cs ts e) " | " (disjuncts tm); os oc ")") 334 else if is_imp tm then let l, r = dest_imp tm in 335 (os oc "("; thff_tm oc (bnd, used) cs ts l; os oc " => "; 336 thff_tm oc (bnd, used) cs ts r; os oc ")") 337 else if is_neg tm then 338 let t = dest_neg tm in (os oc "~ ("; thff_tm oc (bnd,used) cs ts t; os oc ")") 339 else if is_eq tm then let l,r = dest_eq tm in 340 (os oc "("; thff_tm oc (bnd, used) cs ts l; 341 os oc (if type_of l = bool_ty then " <=> " else " = "); 342 thff_tm oc (bnd, used) cs ts r; os oc ")") 343 else if is_comb tm then let hop, args = strip_comb tm in 344 (os oc "("; oiter oc (fun oc e -> thff_tm oc (bnd, used) cs ts e) " @ " (hop :: args); os oc ")") 345 else if is_const tm then begin 346 let insts = inst_const tm in 347 if insts <> [] then os oc "("; 348 os oc (Hashtbl.find cs (fst (dest_const tm))); 349 if insts <> [] then (List.iter (fun ty -> os oc " @ "; oty_poly ts (-1) oc ty) insts; os oc ")"); 350 end 351 else os oc (try Tmm.find tm bnd with Not_found -> failwith "thff_tm");; 352 353 354let thff_pred oc used_map cs ts tm = 355 let tvs = type_vars_in_term tm in 356 (if tvs <> [] then (os oc "!["; oiter oc (fun oc e -> oty_poly ts (-1) oc e; os oc ":$tType") "," tvs; os oc "]: ")); 357 thff_tm oc (Tmm.empty, used_map) cs ts tm 358;; 359 360let used_to_map h = Hashtbl.fold Sm.add h Sm.empty;; 361 362let otyquant oc ts tys = 363 if tys <> [] then begin 364 os oc "!>["; oiter oc (fun oc t -> os oc (print_vartype t); os oc ":$tType") 365 "," tys; os oc "]: " end;; 366 367let thff_gl oc ls asms gl = 368 let ts, cs, used = Hashtbl.create 20, Hashtbl.create 50, Hashtbl.create 50 in 369 List.iter (name_tscs_poly (ts, cs, used)) (gl :: asms); 370 let ohdr s1 s2 = os oc "thf("; os oc s1; os oc ", "; os oc s2; os oc ", " in 371 let otl () = os oc ").\n" in 372 os oc "% TYPES\n"; 373 Hashtbl.remove ts "bool"; 374 Hashtbl.remove ts "fun"; 375 Hashtbl.iter (fun t s -> 376 try 377 let ar = get_type_arity t in 378 ohdr t "type"; os oc s; os oc ":"; 379 let rec prty n = if n = 0 then os oc "$tType" else (os oc "$tType > "; prty (n - 1)) in 380 prty ar; otl () 381 with Failure _ -> ()) ts; (* Failure in get_type_arity for ` *) 382 Hashtbl.add ts "bool" "$o"; 383 os oc "% CONSTS\n"; 384 Hashtbl.remove cs "T"; Hashtbl.remove cs "F"; 385 (* only print constants and not types *) 386 Hashtbl.iter (fun t s -> if t.[0] <> '`' then (ohdr s "type"; os oc s; os oc " : "; 387 let ty = get_const_type t in 388 let tvs = tyvars ty in 389 otyquant oc ts tvs; 390 oty_poly ts (-1) oc ty; otl ())) cs; 391 Hashtbl.add cs "T" "$true"; Hashtbl.add cs "F" "$false"; 392 os oc "% AXIOMS\n"; 393 let used_map = used_to_map used in 394 List.iter2 (fun n t -> ohdr n "axiom"; thff_pred oc used_map cs ts t; otl ()) ls asms; 395 (* Something is wrong here (I may have erased something) *) 396 ohdr ("c") "conjecture"; thff_pred oc used_map cs ts gl; otl () 397;; 398 399 400let rec oty_isa ts oc ty = 401 if is_vartype ty then (os oc "'"; os oc (try Hashtbl.find ts (dest_vartype ty) 402 with Not_found -> print_vartype ty)) else 403 let (s, tys) = dest_type ty in 404 (if tys = [] then () else (os oc "("; oiter oc (oty_isa ts) "," tys; os oc ")")); 405 os oc (Hashtbl.find ts s);; 406 407let pr_bs_isa oc bnd ts bs = 408 os oc "("; 409 oiter oc (fun oc v -> os oc (Tmm.find v bnd); os oc "::"; oty_isa ts oc (type_of v)) ") (" bs; 410 os oc ").";; 411 412let rec otm_isa oc (bnd, used) cs ts tm = 413 if is_forall tm then 414 let bs, bod = strip_forall tm in 415 let (bnd, used) = rev_itlist bindv bs (bnd, used) in 416 os oc "(ALL"; pr_bs_isa oc bnd ts bs; otm_isa oc (bnd, used) cs ts bod; os oc ")" 417 else if is_exists tm then 418 let bs, bod = strip_exists tm in 419 let (bnd, used) = rev_itlist bindv bs (bnd, used) in 420 os oc "(EX"; pr_bs_isa oc bnd ts bs; otm_isa oc (bnd, used) cs ts bod; os oc ")" 421 else if is_abs tm then 422 let bs, bod = strip_abs tm in 423 let (bnd, used) = rev_itlist bindv bs (bnd, used) in 424 os oc "(%"; pr_bs_isa oc bnd ts bs; otm_isa oc (bnd, used) cs ts bod; os oc ")" 425 else if is_conj tm then 426 (os oc "("; oiter oc (fun oc e -> otm_isa oc (bnd, used) cs ts e) " & " (conjuncts tm); os oc ")") 427 else if is_disj tm then 428 (os oc "("; oiter oc (fun oc e -> otm_isa oc (bnd, used) cs ts e) " | " (disjuncts tm); os oc ")") 429 else if is_imp tm then let l, r = dest_imp tm in 430 (os oc "("; otm_isa oc (bnd, used) cs ts l; os oc " --> "; 431 otm_isa oc (bnd, used) cs ts r; os oc ")") 432 else if is_neg tm then 433 let t = dest_neg tm in (os oc "(~"; otm_isa oc (bnd,used) cs ts t; os oc ")") 434 else if is_eq tm then let l,r = dest_eq tm in 435 (os oc "("; otm_isa oc (bnd, used) cs ts l; os oc " = "; 436 otm_isa oc (bnd, used) cs ts r; os oc ")") 437 else if is_comb tm then let hop, args = strip_comb tm in 438 (os oc "("; oiter oc (fun oc e -> otm_isa oc (bnd, used) cs ts e) " " (hop :: args); os oc ")") 439 else if is_const tm then os oc (Hashtbl.find cs (fst (dest_const tm))) 440 else os oc (try Tmm.find tm bnd with Not_found -> failwith ("tm_isa:" ^ (fst (dest_var tm))));; 441 442let hash_to_list h = Hashtbl.fold (fun a b l -> (a,b) :: l) h [];; 443 444let isa_fix_names h u = 445 let l = Hashtbl.fold (fun a b c -> (a, b) :: c) h [] in 446 let itr (k, v) = 447 if v.[String.length v - 1] = '_' then 448 let n = variant_name_hash v u in 449 Hashtbl.replace h k n 450 in List.iter itr l 451;; 452 453let isa_gl oc names asms gl = 454 os oc "theory Bla imports \"~~/src/HOL/TPTP/ATP_Problem_Import\" begin\n"; 455 let ts, cs, used = Hashtbl.create 20, Hashtbl.create 50, Hashtbl.create 50 in 456 Hashtbl.add used "bool" 0; Hashtbl.add used "fun" 0; 457 Hashtbl.add used "True" 0; Hashtbl.add used "False" 0; 458 Hashtbl.add used "in" 0; 459 List.iter (name_tscs_poly (ts, cs, used)) (gl :: asms); 460 isa_fix_names ts used; isa_fix_names cs used; 461 Hashtbl.remove ts "bool"; Hashtbl.remove ts "fun"; 462 Hashtbl.remove cs "T"; Hashtbl.remove cs "F"; 463 Hashtbl.iter (fun hty sty -> 464 try 465 let a = get_type_arity hty in 466 os oc "typedecl "; 467 (if a > 0 then (os oc "("; os oc 468 (String.concat "," (Array.to_list (Array.init a (fun i -> "'" ^ (String.make 1 (Char.chr (65 + i))))))); os oc ") ") else ()); 469 os oc sty; os oc "\n" 470 with Failure "find" -> () 471 ) ts; 472 Hashtbl.replace ts "bool" "bool"; Hashtbl.replace ts "fun" "fun"; 473 os oc "axiomatization\n"; 474 oiter oc (fun oc (t, s) -> os oc s; os oc " :: \""; oty_isa ts oc (get_const_type t); os oc "\"\n") "and " (hash_to_list cs); 475 Hashtbl.replace cs "T" "True"; Hashtbl.replace cs "F" "False"; 476 os oc "axiomatization where\n"; 477 oiter oc (fun oc (n, t) -> os oc n; os oc ": \""; otm_isa oc (Tmm.empty, Sm.empty) cs ts t; os oc "\"\n") "and " (zip (rev names) asms); 478 os oc "lemma conjecture:\n \""; 479 otm_isa oc (Tmm.empty, Sm.empty) cs ts gl; os oc "\"\n" 480;; 481 482 483let fileno = ref 0;; 484 485let rec fullsplitlist dest x = 486 try let l,r = dest x in 487 let ls = fullsplitlist dest r in (l::ls) 488 with Failure _ -> ([x]);; 489 490let rec otff_funtype oc ts t min = 491 if min = 0 then oty_poly ts 0 oc t else 492 let tys = fullsplitlist dest_fun_ty t in 493 let (tys1, tys2) = chop_listn [] min tys in 494 let ty2 = end_itlist mk_fun_ty tys2 in 495 os oc "("; (if List.length tys1 > 1 then os oc "(" else ()); 496 oiter oc (fun oc e -> oty_poly ts 0 oc e) " * " tys1; 497 (if List.length tys1 > 1 then os oc ")" else ()); 498 os oc " > "; oty_poly ts 0 oc ty2; os oc ")" 499;; 500 501let funtys_of_tm tm = 502 let mergel l = setify (List.concat l) in 503 let tys tm = map type_of (find_terms (fun x -> is_var x || is_const x) tm) in 504 let rec funtypes t = 505 if is_vartype t then [] else 506 let (s, l) = dest_type t in 507 mergel ([s]::(map funtypes l)) in 508 mergel (map funtypes (tys tm)) 509;; 510 511let funtys_of_tms tms = setify (List.concat (map funtys_of_tm tms));; 512 513let tff_gl_mk_hash terms = 514 let ts, cs, used = Hashtbl.create 20, Hashtbl.create 50, Hashtbl.create 50 in 515 Hashtbl.add used "p" 0; Hashtbl.add cs "happ" "i"; Hashtbl.add used "i" 0; 516 Hashtbl.add ts "fun" "fn"; Hashtbl.add used "fn" 0; Hashtbl.add used "fun" 0; 517 List.iter (name_tscs_poly (ts, cs, used)) terms; 518 (ts,cs,used_to_map used) 519;; 520 521let tff_gl_hash oc names name asms gl (ts,cs,used) = 522 let ohdr s1 s2 = os oc "tff("; os oc s1; os oc ", "; os oc s2; os oc ", " in 523 let otl () = os oc ").\n" in 524 os oc "% TYPES\n"; 525 List.iter (fun t -> 526 let s = Hashtbl.find ts t in 527 ohdr t "type"; os oc s; os oc ":"; 528 begin match get_type_arity t with 529 0 -> os oc "$tType" 530 | 1 -> os oc "$tType > $tType" 531 | n -> os oc "("; oiter oc (fun oc _ -> os oc "$tType") " * " (Array.to_list (Array.make n ())); 532 os oc ") > $tType" end; otl ()) (funtys_of_tms (gl::asms)); 533 os oc "% CONSTS\n"; 534 ohdr "cp" "type"; os oc "p : (bool > $o)"; otl (); 535 let output_const (c, argno) = 536 let ty = get_const_type c in let tvs = tyvars ty in 537 ohdr c "type"; os oc (Hashtbl.find cs c); os oc ":"; 538 otyquant oc ts tvs; otff_funtype oc ts ty argno; otl () 539 in 540 List.iter output_const (fst (get_mindata (asms, gl))); 541 os oc "% AXIOMS\n"; 542 List.iter2 (fun n t -> ohdr n "axiom"; tff_pred oc cs ts used t; otl ()) names asms; 543 ohdr (escape_thm name) "conjecture"; tff_pred oc cs ts used gl; otl (); 544;; 545 546let tff_gl oc names name asms gl = 547 let tcu = tff_gl_mk_hash (gl :: asms) in 548 tff_gl_hash oc names name asms gl tcu 549;; 550 551let oorig oc n ls ts gl g2 = 552 output_string oc ("% ORIGINAL: " ^ n ^ "\n"); 553 List.iter2 (fun n t -> 554 output_string oc ("% Assm: " ^ n ^ ": " ^ lstring_of_term (concl t) ^ "\n")) ls ts; 555 output_string oc ("% Goal: " ^ lstring_of_term gl ^ "\n"); 556 output_string oc "% PROCESSED\n"; 557 output_gs oc g2 558;; 559 560let rec fof_tm oc (bnd, used) cs ts tm = 561 if is_var tm then begin 562 os oc "s("; oty_poly ts 0 oc (type_of tm); os oc ","; os oc ( 563 try Tmm.find tm bnd with Not_found -> Hashtbl.find cs ("`" ^ (o fst dest_var) tm)); 564 os oc ")" 565 end else begin 566 let (f, args) = strip_comb tm in 567 os oc "s("; oty_poly ts 0 oc (type_of tm); os oc ","; os oc ( 568 try Hashtbl.find cs (fst (dest_const f)) with _ -> Hashtbl.find cs ("`" ^ (o fst dest_var) f)); 569 (if args <> [] then 570 (os oc "("; oiter oc (fun oc e -> fof_tm oc (bnd, used) cs ts e) "," args; os oc ")")); 571 os oc ")" 572 end;; 573 574(* Type unsafe version, currently not used *) 575let rec fof_tm_unsafe oc (bnd, used) cs ts tm = 576 if is_var tm then os oc (Tmm.find tm bnd) 577 else 578 let (f, args) = strip_comb tm in 579 os oc (Hashtbl.find cs (fst (dest_const f))); 580 (if args <> [] then 581 (os oc "("; oiter oc (fun oc e -> fof_tm_unsafe oc (bnd, used) cs ts e) "," args; os oc ")"));; 582 583let rec fof_pred oc (bnd, used) cs ts tm = 584 if is_forall tm then 585 let vs, bod = strip_forall tm in 586 let (bnd, used) = rev_itlist bindv vs (bnd, used) in 587 os oc "![";oiter oc (fun oc v -> os oc (Tmm.find v bnd)) ", " vs;os oc "]: ";fof_pred oc (bnd, used) cs ts bod 588 else if is_exists tm then 589 let vs, bod = strip_exists tm in 590 let (bnd, used) = rev_itlist bindv vs (bnd, used) in 591 os oc "?[";oiter oc (fun oc v -> os oc (Tmm.find v bnd)) ", " vs;os oc "]: ";fof_pred oc (bnd, used) cs ts bod 592 else if is_conj tm then let l, r = dest_conj tm in 593 (os oc "("; fof_pred oc (bnd, used) cs ts l; os oc " & "; fof_pred oc (bnd, used) cs ts r; os oc ")") 594 else if is_disj tm then let l, r = dest_disj tm in 595 (os oc "("; fof_pred oc (bnd, used) cs ts l; os oc " | "; fof_pred oc (bnd, used) cs ts r; os oc ")") 596 else if is_imp tm then let l, r = dest_imp tm in 597 (os oc "("; fof_pred oc (bnd, used) cs ts l; os oc " => "; fof_pred oc (bnd, used) cs ts r; os oc ")") 598 else if is_neg tm then 599 let t = dest_neg tm in (os oc "~ ("; fof_pred oc (bnd,used) cs ts t; os oc ")") 600 else if is_eq tm then let l,r = dest_eq tm in 601 if must_pred l || must_pred r then 602 (os oc "("; fof_pred oc (bnd, used) cs ts l; os oc " <=> "; 603 fof_pred oc (bnd, used) cs ts r; os oc ")") 604 else 605 (fof_tm oc (bnd, used) cs ts l; os oc " = "; fof_tm oc (bnd, used) cs ts r) 606 else 607 (os oc "p("; fof_tm oc (bnd, used) cs ts tm; os oc ")");; 608 609let fof_pred oc cs ts used_map t = 610 let tvs = type_vars_in_term t in 611 (if tvs <> [] then (os oc "!["; oiter oc (fun oc e -> oty_poly ts 0 oc e) "," tvs; os oc "]: ")); 612 fof_pred oc (Tmm.empty, used_map) cs ts t 613;; 614 615let fof_gl_hash oc names name asms gl (ts,cs,used) = 616 let ohdr s1 s2 = os oc "fof("; os oc s1; os oc ", "; os oc s2; os oc ", " in 617 let otl () = os oc ").\n" in 618 List.iter2 (fun n t -> ohdr n "axiom"; fof_pred oc cs ts used t; otl ()) names asms; 619 ohdr (escape_thm name) "conjecture"; fof_pred oc cs ts used gl; otl (); 620;; 621 622let fof_gl_mk_hash terms = 623 let ts, cs, used = Hashtbl.create 20, Hashtbl.create 50, Hashtbl.create 50 in 624 Hashtbl.add used "p" 0; Hashtbl.add used "s" 0; 625 Hashtbl.add cs "happ" "i"; Hashtbl.add used "i" 0; 626 List.iter (name_tscs_poly (ts, cs, used)) terms; 627 (ts,cs,used_to_map used) 628;; 629 630let fof_gl oc names name asms gl = 631 let (ts,cs,used) = fof_gl_mk_hash (gl :: asms) in 632 fof_gl_hash oc names name asms gl (ts,cs,used); 633 (ts,cs) 634;; 635 636let pRE_HH_TAC = 637 eVERY_ASSUM (fun th -> if frees(concl th) = [] 638 then aLL_TAC else uNDISCH_TAC (concl th)) ++++ 639 www (fun (asl,w) -> mAP_EVERY (fun v -> sPEC_TAC(v,v)) (frees w)) 640;; 641 642let pREP_HH_TAC names need_mono ths = 643 pURE_REWRITE_TAC [eXISTS_UNIQUE_THM; eXISTS_UNIQUE_DEF] ++++ 644 ((if need_mono then pOLY_ASSUME_TAC else lABEL_ASSUME_TAC) (rev names) (rev ths)) ++++ 645 rULE_ASSUM_TAC (pURE_REWRITE_RULE [eXISTS_UNIQUE_THM; eXISTS_UNIQUE_DEF]) 646;; 647 648let pREP_TFF_TAC = 649 let tOP_DEPTH_CONV c tm = genvarreset (); tOP_DEPTH_CONV c tm in 650(* sELECT_ELIM_TAC ++++*) 651 cONV_TAC(tOP_SWEEP_QCONV eLIM_LAMBDA_EQ) ++++ 652 rULE_ASSUM_TAC (cONV_RULE (tOP_SWEEP_QCONV eLIM_LAMBDA_EQ)) ++++ 653 cONV_TAC(tHENC (tOP_DEPTH_CONV bETA_CONV) (tHENC lAMBDA_ELIM_CONV2 lAMBDA_ELIM_CONV)) ++++ 654 rULE_ASSUM_TAC((cONV_RULE(tHENC (tOP_DEPTH_CONV bETA_CONV) (tHENC lAMBDA_ELIM_CONV2 lAMBDA_ELIM_CONV)))) 655;; 656 657let write_atp_proof filen (ts, names) n gl = 658 let (_, [g], _) = mk_goalstate ([],gl) in 659 begin match (pREP_HH_TAC names false ts ++++ pREP_TFF_TAC ++++ fOL_IT_TAC) g with 660 (_, [g2], _) -> 661 let oc = open_out filen in 662 oorig oc n names ts gl g2; 663 let names = map fst (fst g2) in 664 ignore (fof_gl oc names n (map (o concl snd) (fst g2)) (snd g2)); 665 (*tff_gl oc names (map (o concl snd) (fst g2)) (snd g2);*) 666 close_out oc; 667 | _ -> failwith ("PREP_HH_TAC created more goals: " ^ n) 668 end;; 669 670let write_thf_proof filen (ts, names) n gl = 671 let (_, [g], _) = mk_goalstate ([],gl) in 672 begin match (pREP_HH_TAC names true ts) g with 673 (_, [g2], _) -> 674 let oc = open_out filen in 675 oorig oc n names ts gl g2; 676 ignore (thf_gl oc (map fst (fst g2)) (map (o concl snd) (fst g2)) (snd g2) n); 677 close_out oc 678 | _ -> failwith "PREP_HH_TAC created more goals" 679 end;; 680 681let write_isa_proof filen (ts, names) n gl = 682 let (_, [g], _) = mk_goalstate ([],gl) in 683 begin match (www(fun (asl,w) -> mAP_EVERY (fun v -> sPEC_TAC(v,v)) (frees w)) ++++ 684 lABEL_ASSUME_TAC names (map (o gEN_ALL dISCH_ALL) ts)) g with 685 (_, [g2], _) -> 686 let oc = open_out filen in 687 isa_gl oc names (map (o concl snd) (fst g2)) (snd g2); 688 close_out oc 689 | _ -> failwith "PREP_HH_TAC created more goals" 690 end 691;; 692 693let rec cut_list md n = function 694 [] -> [] 695 | h :: t -> if n mod md = 0 then h :: (cut_list md (n + 1) t) else cut_list md (n + 1) t;; 696 697let normalize_th th = gEN_ALL (dISCH_ALL th);; 698