1 (* Title: HOL/Tools/ATP/atp_problem_generate.ML
2 Author: Fabian Immler, TU Muenchen
4 Author: Jasmin Blanchette, TU Muenchen
6 Translation of HOL to FOL for Metis and Sledgehammer.
9 signature ATP_PROBLEM_GENERATE =
11 type ('a, 'b) ho_term = ('a, 'b) ATP_Problem.ho_term
12 type connective = ATP_Problem.connective
13 type ('a, 'b, 'c) formula = ('a, 'b, 'c) ATP_Problem.formula
14 type atp_format = ATP_Problem.atp_format
15 type formula_kind = ATP_Problem.formula_kind
16 type 'a problem = 'a ATP_Problem.problem
18 datatype scope = Global | Local | Assum | Chained
20 General | Induction | Intro | Inductive | Elim | Simp | Def
21 type stature = scope * status
23 datatype polymorphism = Polymorphic | Raw_Monomorphic | Mangled_Monomorphic
24 datatype strictness = Strict | Non_Strict
25 datatype granularity = All_Vars | Positively_Naked_Vars | Ghost_Type_Arg_Vars
28 Noninf_Nonmono_Types of strictness * granularity |
29 Fin_Nonmono_Types of granularity |
35 val hide_lamsN : string
38 val combs_and_liftingN : string
39 val combs_or_liftingN : string
40 val lam_liftingN : string
41 val keep_lamsN : string
42 val schematic_var_prefix : string
43 val fixed_var_prefix : string
44 val tvar_prefix : string
45 val tfree_prefix : string
46 val const_prefix : string
47 val type_const_prefix : string
48 val class_prefix : string
49 val lam_lifted_prefix : string
50 val lam_lifted_mono_prefix : string
51 val lam_lifted_poly_prefix : string
52 val skolem_const_prefix : string
53 val old_skolem_const_prefix : string
54 val new_skolem_const_prefix : string
55 val combinator_prefix : string
56 val type_decl_prefix : string
57 val sym_decl_prefix : string
58 val guards_sym_formula_prefix : string
59 val tags_sym_formula_prefix : string
60 val fact_prefix : string
61 val conjecture_prefix : string
62 val helper_prefix : string
63 val class_rel_clause_prefix : string
64 val arity_clause_prefix : string
65 val tfree_clause_prefix : string
66 val lam_fact_prefix : string
67 val typed_helper_suffix : string
68 val untyped_helper_suffix : string
69 val predicator_name : string
70 val app_op_name : string
71 val type_guard_name : string
72 val type_tag_name : string
73 val native_type_prefix : string
74 val prefixed_predicator_name : string
75 val prefixed_app_op_name : string
76 val prefixed_type_tag_name : string
77 val ascii_of : string -> string
78 val unascii_of : string -> string
79 val unprefix_and_unascii : string -> string -> string option
80 val proxy_table : (string * (string * (thm * (string * string)))) list
81 val proxify_const : string -> (string * string) option
82 val invert_const : string -> string
83 val unproxify_const : string -> string
84 val new_skolem_var_name_from_const : string -> string
85 val atp_irrelevant_consts : string list
86 val atp_schematic_consts_of : term -> typ list Symtab.table
87 val is_type_enc_higher_order : type_enc -> bool
88 val polymorphism_of_type_enc : type_enc -> polymorphism
89 val level_of_type_enc : type_enc -> type_level
90 val is_type_enc_quasi_sound : type_enc -> bool
91 val is_type_enc_fairly_sound : type_enc -> bool
92 val type_enc_from_string : strictness -> string -> type_enc
93 val adjust_type_enc : atp_format -> type_enc -> type_enc
95 connective -> ('a, 'b, 'c) formula list -> ('a, 'b, 'c) formula
96 val unmangled_const : string -> string * (string, 'b) ho_term list
97 val unmangled_const_name : string -> string list
98 val helper_table : ((string * bool) * thm list) list
99 val trans_lams_from_string :
100 Proof.context -> type_enc -> string -> term list -> term list * term list
102 val prepare_atp_problem :
103 Proof.context -> atp_format -> formula_kind -> formula_kind -> type_enc
104 -> bool -> string -> bool -> bool -> bool -> term list -> term
105 -> ((string * stature) * term) list
106 -> string problem * string Symtab.table * (string * stature) list vector
107 * (string * term) list * int Symtab.table
108 val atp_problem_selection_weights : string problem -> (string * real) list
109 val atp_problem_term_order_info : string problem -> (string * int) list
112 structure ATP_Problem_Generate : ATP_PROBLEM_GENERATE =
118 type name = string * string
120 datatype scope = Global | Local | Assum | Chained
121 datatype status = General | Induction | Intro | Inductive | Elim | Simp | Def
122 type stature = scope * status
126 Higher_Order of thf_flavor
127 datatype polymorphism = Polymorphic | Raw_Monomorphic | Mangled_Monomorphic
128 datatype strictness = Strict | Non_Strict
129 datatype granularity = All_Vars | Positively_Naked_Vars | Ghost_Type_Arg_Vars
130 datatype type_level =
132 Noninf_Nonmono_Types of strictness * granularity |
133 Fin_Nonmono_Types of granularity |
138 Native of order * polymorphism * type_level |
139 Guards of polymorphism * type_level |
140 Tags of polymorphism * type_level
142 fun is_type_enc_native (Native _) = true
143 | is_type_enc_native _ = false
144 fun is_type_enc_higher_order (Native (Higher_Order _, _, _)) = true
145 | is_type_enc_higher_order _ = false
147 fun polymorphism_of_type_enc (Native (_, poly, _)) = poly
148 | polymorphism_of_type_enc (Guards (poly, _)) = poly
149 | polymorphism_of_type_enc (Tags (poly, _)) = poly
151 fun level_of_type_enc (Native (_, _, level)) = level
152 | level_of_type_enc (Guards (_, level)) = level
153 | level_of_type_enc (Tags (_, level)) = level
155 fun granularity_of_type_level (Noninf_Nonmono_Types (_, grain)) = grain
156 | granularity_of_type_level (Fin_Nonmono_Types grain) = grain
157 | granularity_of_type_level _ = All_Vars
159 fun is_type_level_quasi_sound All_Types = true
160 | is_type_level_quasi_sound (Noninf_Nonmono_Types _) = true
161 | is_type_level_quasi_sound _ = false
162 val is_type_enc_quasi_sound = is_type_level_quasi_sound o level_of_type_enc
164 fun is_type_level_fairly_sound (Fin_Nonmono_Types _) = true
165 | is_type_level_fairly_sound level = is_type_level_quasi_sound level
166 val is_type_enc_fairly_sound = is_type_level_fairly_sound o level_of_type_enc
168 fun is_type_level_monotonicity_based (Noninf_Nonmono_Types _) = true
169 | is_type_level_monotonicity_based (Fin_Nonmono_Types _) = true
170 | is_type_level_monotonicity_based _ = false
172 val no_lamsN = "no_lams" (* used internally; undocumented *)
173 val hide_lamsN = "hide_lams"
174 val liftingN = "lifting"
176 val combs_and_liftingN = "combs_and_lifting"
177 val combs_or_liftingN = "combs_or_lifting"
178 val keep_lamsN = "keep_lams"
179 val lam_liftingN = "lam_lifting" (* legacy *)
181 (* It's still unclear whether all TFF1 implementations will support type
182 signatures such as "!>[A : $tType] : $o", with ghost type variables. *)
183 val avoid_first_order_ghost_type_vars = false
185 val bound_var_prefix = "B_"
186 val all_bound_var_prefix = "A_"
187 val exist_bound_var_prefix = "E_"
188 val schematic_var_prefix = "V_"
189 val fixed_var_prefix = "v_"
190 val tvar_prefix = "T_"
191 val tfree_prefix = "t_"
192 val const_prefix = "c_"
193 val type_const_prefix = "tc_"
194 val native_type_prefix = "n_"
195 val class_prefix = "cl_"
197 (* Freshness almost guaranteed! *)
198 val atp_prefix = "ATP" ^ Long_Name.separator
199 val atp_weak_prefix = "ATP:"
201 val lam_lifted_prefix = atp_weak_prefix ^ "Lam"
202 val lam_lifted_mono_prefix = lam_lifted_prefix ^ "m"
203 val lam_lifted_poly_prefix = lam_lifted_prefix ^ "p"
205 val skolem_const_prefix = atp_prefix ^ "Sko"
206 val old_skolem_const_prefix = skolem_const_prefix ^ "o"
207 val new_skolem_const_prefix = skolem_const_prefix ^ "n"
209 val combinator_prefix = "COMB"
211 val type_decl_prefix = "ty_"
212 val sym_decl_prefix = "sy_"
213 val guards_sym_formula_prefix = "gsy_"
214 val tags_sym_formula_prefix = "tsy_"
215 val uncurried_alias_eq_prefix = "unc_"
216 val fact_prefix = "fact_"
217 val conjecture_prefix = "conj_"
218 val helper_prefix = "help_"
219 val class_rel_clause_prefix = "clar_"
220 val arity_clause_prefix = "arity_"
221 val tfree_clause_prefix = "tfree_"
223 val lam_fact_prefix = "ATP.lambda_"
224 val typed_helper_suffix = "_T"
225 val untyped_helper_suffix = "_U"
227 val predicator_name = "pp"
228 val app_op_name = "aa"
229 val type_guard_name = "gg"
230 val type_tag_name = "tt"
232 val prefixed_predicator_name = const_prefix ^ predicator_name
233 val prefixed_app_op_name = const_prefix ^ app_op_name
234 val prefixed_type_tag_name = const_prefix ^ type_tag_name
236 (*Escaping of special characters.
237 Alphanumeric characters are left unchanged.
238 The character _ goes to __
239 Characters in the range ASCII space to / go to _A to _P, respectively.
240 Other characters go to _nnn where nnn is the decimal ASCII code.*)
241 val upper_a_minus_space = Char.ord #"A" - Char.ord #" "
243 fun stringN_of_int 0 _ = ""
244 | stringN_of_int k n =
245 stringN_of_int (k - 1) (n div 10) ^ string_of_int (n mod 10)
247 fun ascii_of_char c =
248 if Char.isAlphaNum c then
250 else if c = #"_" then
252 else if #" " <= c andalso c <= #"/" then
253 "_" ^ String.str (Char.chr (Char.ord c + upper_a_minus_space))
255 (* fixed width, in case more digits follow *)
256 "_" ^ stringN_of_int 3 (Char.ord c)
258 val ascii_of = String.translate ascii_of_char
260 (** Remove ASCII armoring from names in proof files **)
262 (* We don't raise error exceptions because this code can run inside a worker
263 thread. Also, the errors are impossible. *)
266 fun un rcs [] = String.implode(rev rcs)
267 | un rcs [#"_"] = un (#"_" :: rcs) [] (* ERROR *)
268 (* Three types of _ escapes: __, _A to _P, _nnn *)
269 | un rcs (#"_" :: #"_" :: cs) = un (#"_" :: rcs) cs
270 | un rcs (#"_" :: c :: cs) =
271 if #"A" <= c andalso c<= #"P" then
272 (* translation of #" " to #"/" *)
273 un (Char.chr (Char.ord c - upper_a_minus_space) :: rcs) cs
275 let val digits = List.take (c :: cs, 3) handle General.Subscript => [] in
276 case Int.fromString (String.implode digits) of
277 SOME n => un (Char.chr n :: rcs) (List.drop (cs, 2))
278 | NONE => un (c :: #"_" :: rcs) cs (* ERROR *)
280 | un rcs (c :: cs) = un (c :: rcs) cs
281 in un [] o String.explode end
283 (* If string s has the prefix s1, return the result of deleting it,
285 fun unprefix_and_unascii s1 s =
286 if String.isPrefix s1 s then
287 SOME (unascii_of (String.extract (s, size s1, NONE)))
292 [("c_False", (@{const_name False}, (@{thm fFalse_def},
293 ("fFalse", @{const_name ATP.fFalse})))),
294 ("c_True", (@{const_name True}, (@{thm fTrue_def},
295 ("fTrue", @{const_name ATP.fTrue})))),
296 ("c_Not", (@{const_name Not}, (@{thm fNot_def},
297 ("fNot", @{const_name ATP.fNot})))),
298 ("c_conj", (@{const_name conj}, (@{thm fconj_def},
299 ("fconj", @{const_name ATP.fconj})))),
300 ("c_disj", (@{const_name disj}, (@{thm fdisj_def},
301 ("fdisj", @{const_name ATP.fdisj})))),
302 ("c_implies", (@{const_name implies}, (@{thm fimplies_def},
303 ("fimplies", @{const_name ATP.fimplies})))),
304 ("equal", (@{const_name HOL.eq}, (@{thm fequal_def},
305 ("fequal", @{const_name ATP.fequal})))),
306 ("c_All", (@{const_name All}, (@{thm fAll_def},
307 ("fAll", @{const_name ATP.fAll})))),
308 ("c_Ex", (@{const_name Ex}, (@{thm fEx_def},
309 ("fEx", @{const_name ATP.fEx}))))]
311 val proxify_const = AList.lookup (op =) proxy_table #> Option.map (snd o snd)
313 (* Readable names for the more common symbolic functions. Do not mess with the
314 table unless you know what you are doing. *)
315 val const_trans_table =
316 [(@{type_name Product_Type.prod}, "prod"),
317 (@{type_name Sum_Type.sum}, "sum"),
318 (@{const_name False}, "False"),
319 (@{const_name True}, "True"),
320 (@{const_name Not}, "Not"),
321 (@{const_name conj}, "conj"),
322 (@{const_name disj}, "disj"),
323 (@{const_name implies}, "implies"),
324 (@{const_name HOL.eq}, "equal"),
325 (@{const_name All}, "All"),
326 (@{const_name Ex}, "Ex"),
327 (@{const_name If}, "If"),
328 (@{const_name Set.member}, "member"),
329 (@{const_name Meson.COMBI}, combinator_prefix ^ "I"),
330 (@{const_name Meson.COMBK}, combinator_prefix ^ "K"),
331 (@{const_name Meson.COMBB}, combinator_prefix ^ "B"),
332 (@{const_name Meson.COMBC}, combinator_prefix ^ "C"),
333 (@{const_name Meson.COMBS}, combinator_prefix ^ "S")]
335 |> fold (Symtab.update o swap o snd o snd o snd) proxy_table
337 (* Invert the table of translations between Isabelle and ATPs. *)
338 val const_trans_table_inv =
339 const_trans_table |> Symtab.dest |> map swap |> Symtab.make
340 val const_trans_table_unprox =
342 |> fold (fn (_, (isa, (_, (_, atp)))) => Symtab.update (atp, isa)) proxy_table
344 val invert_const = perhaps (Symtab.lookup const_trans_table_inv)
345 val unproxify_const = perhaps (Symtab.lookup const_trans_table_unprox)
348 case Symtab.lookup const_trans_table c of
352 fun ascii_of_indexname (v, 0) = ascii_of v
353 | ascii_of_indexname (v, i) = ascii_of v ^ "_" ^ string_of_int i
355 fun make_bound_var x = bound_var_prefix ^ ascii_of x
356 fun make_all_bound_var x = all_bound_var_prefix ^ ascii_of x
357 fun make_exist_bound_var x = exist_bound_var_prefix ^ ascii_of x
358 fun make_schematic_var v = schematic_var_prefix ^ ascii_of_indexname v
359 fun make_fixed_var x = fixed_var_prefix ^ ascii_of x
361 fun make_schematic_type_var (x, i) =
362 tvar_prefix ^ (ascii_of_indexname (unprefix "'" x, i))
363 fun make_fixed_type_var x = tfree_prefix ^ (ascii_of (unprefix "'" x))
365 (* "HOL.eq" and choice are mapped to the ATP's equivalents *)
367 val choice_const = (fst o dest_Const o HOLogic.choice_const) Term.dummyT
368 fun default c = const_prefix ^ lookup_const c
370 fun make_fixed_const _ @{const_name HOL.eq} = tptp_old_equal
371 | make_fixed_const (SOME (Native (Higher_Order THF_With_Choice, _, _))) c =
372 if c = choice_const then tptp_choice else default c
373 | make_fixed_const _ c = default c
376 fun make_fixed_type_const c = type_const_prefix ^ lookup_const c
378 fun make_type_class clas = class_prefix ^ ascii_of clas
380 fun new_skolem_var_name_from_const s =
381 let val ss = s |> space_explode Long_Name.separator in
382 nth ss (length ss - 2)
385 (* These are either simplified away by "Meson.presimplify" (most of the time) or
386 handled specially via "fFalse", "fTrue", ..., "fequal". *)
387 val atp_irrelevant_consts =
388 [@{const_name False}, @{const_name True}, @{const_name Not},
389 @{const_name conj}, @{const_name disj}, @{const_name implies},
390 @{const_name HOL.eq}, @{const_name If}, @{const_name Let}]
392 val atp_monomorph_bad_consts =
393 atp_irrelevant_consts @
394 (* These are ignored anyway by the relevance filter (unless they appear in
395 higher-order places) but not by the monomorphizer. *)
396 [@{const_name all}, @{const_name "==>"}, @{const_name "=="},
397 @{const_name Trueprop}, @{const_name All}, @{const_name Ex},
398 @{const_name Ex1}, @{const_name Ball}, @{const_name Bex}]
400 fun add_schematic_const (x as (_, T)) =
401 Monomorph.typ_has_tvars T ? Symtab.insert_list (op =) x
402 val add_schematic_consts_of =
403 Term.fold_aterms (fn Const (x as (s, _)) =>
404 not (member (op =) atp_monomorph_bad_consts s)
405 ? add_schematic_const x
407 fun atp_schematic_consts_of t = add_schematic_consts_of t Symtab.empty
409 (** Definitions and functions for FOL clauses and formulas for TPTP **)
411 (** Isabelle arities **)
413 type arity_atom = name * name * name list
415 val type_class = the_single @{sort type}
419 prem_atoms : arity_atom list,
420 concl_atom : arity_atom}
422 fun add_prem_atom tvar =
423 fold (fn s => s <> type_class ? cons (`make_type_class s, `I tvar, []))
425 (* Arity of type constructor "tcon :: (arg1, ..., argN) res" *)
426 fun make_axiom_arity_clause (tcons, name, (cls, args)) =
428 val tvars = map (prefix tvar_prefix o string_of_int) (1 upto length args)
429 val tvars_srts = ListPair.zip (tvars, args)
432 prem_atoms = [] |> fold (uncurry add_prem_atom) tvars_srts,
433 concl_atom = (`make_type_class cls, `make_fixed_type_const tcons,
437 fun arity_clause _ _ (_, []) = []
438 | arity_clause seen n (tcons, ("HOL.type", _) :: ars) = (* ignore *)
439 arity_clause seen n (tcons, ars)
440 | arity_clause seen n (tcons, (ar as (class, _)) :: ars) =
441 if member (op =) seen class then
442 (* multiple arities for the same (tycon, class) pair *)
443 make_axiom_arity_clause (tcons,
444 lookup_const tcons ^ "___" ^ ascii_of class ^ "_" ^ string_of_int n,
446 arity_clause seen (n + 1) (tcons, ars)
448 make_axiom_arity_clause (tcons, lookup_const tcons ^ "___" ^
449 ascii_of class, ar) ::
450 arity_clause (class :: seen) n (tcons, ars)
452 fun multi_arity_clause [] = []
453 | multi_arity_clause ((tcons, ars) :: tc_arlists) =
454 arity_clause [] 1 (tcons, ars) @ multi_arity_clause tc_arlists
456 (* Generate all pairs (tycon, class, sorts) such that tycon belongs to class in
457 theory thy provided its arguments have the corresponding sorts. *)
458 fun type_class_pairs thy tycons classes =
460 val alg = Sign.classes_of thy
461 fun domain_sorts tycon = Sorts.mg_domain alg tycon o single
462 fun add_class tycon class =
463 cons (class, domain_sorts tycon class)
464 handle Sorts.CLASS_ERROR _ => I
465 fun try_classes tycon = (tycon, fold (add_class tycon) classes [])
466 in map try_classes tycons end
468 (*Proving one (tycon, class) membership may require proving others, so iterate.*)
469 fun iter_type_class_pairs _ _ [] = ([], [])
470 | iter_type_class_pairs thy tycons classes =
472 fun maybe_insert_class s =
473 (s <> type_class andalso not (member (op =) classes s))
475 val cpairs = type_class_pairs thy tycons classes
477 [] |> fold (fold (fold (fold maybe_insert_class) o snd) o snd) cpairs
478 val (classes', cpairs') = iter_type_class_pairs thy tycons newclasses
479 in (classes' @ classes, union (op =) cpairs' cpairs) end
481 fun make_arity_clauses thy tycons =
482 iter_type_class_pairs thy tycons ##> multi_arity_clause
485 (** Isabelle class relations **)
487 type class_rel_clause =
492 (* Generate all pairs (sub, super) such that sub is a proper subclass of super
494 fun class_pairs _ [] _ = []
495 | class_pairs thy subs supers =
497 val class_less = Sorts.class_less (Sign.classes_of thy)
498 fun add_super sub super = class_less (sub, super) ? cons (sub, super)
499 fun add_supers sub = fold (add_super sub) supers
500 in fold add_supers subs [] end
502 fun make_class_rel_clause (sub, super) =
503 {name = sub ^ "_" ^ super, subclass = `make_type_class sub,
504 superclass = `make_type_class super}
506 fun make_class_rel_clauses thy subs supers =
507 map make_class_rel_clause (class_pairs thy subs supers)
509 (* intermediate terms *)
511 IConst of name * typ * typ list |
513 IApp of iterm * iterm |
514 IAbs of (name * typ) * iterm
516 fun ityp_of (IConst (_, T, _)) = T
517 | ityp_of (IVar (_, T)) = T
518 | ityp_of (IApp (t1, _)) = snd (dest_funT (ityp_of t1))
519 | ityp_of (IAbs ((_, T), tm)) = T --> ityp_of tm
521 (*gets the head of a combinator application, along with the list of arguments*)
522 fun strip_iterm_comb u =
524 fun stripc (IApp (t, u), ts) = stripc (t, u :: ts)
526 in stripc (u, []) end
528 fun atomic_types_of T = fold_atyps (insert (op =)) T []
530 val tvar_a_str = "'a"
531 val tvar_a = TVar ((tvar_a_str, 0), HOLogic.typeS)
532 val tvar_a_name = (make_schematic_type_var (tvar_a_str, 0), tvar_a_str)
533 val itself_name = `make_fixed_type_const @{type_name itself}
534 val TYPE_name = `(make_fixed_const NONE) @{const_name TYPE}
535 val tvar_a_atype = AType (tvar_a_name, [])
536 val a_itself_atype = AType (itself_name, [tvar_a_atype])
538 fun new_skolem_const_name s num_T_args =
539 [new_skolem_const_prefix, s, string_of_int num_T_args]
542 fun robust_const_type thy s =
543 if s = app_op_name then
544 Logic.varifyT_global @{typ "('a => 'b) => 'a => 'b"}
545 else if String.isPrefix lam_lifted_prefix s then
546 Logic.varifyT_global @{typ "'a => 'b"}
548 (* Old Skolems throw a "TYPE" exception here, which will be caught. *)
549 s |> Sign.the_const_type thy
551 val robust_const_ary =
553 fun ary (Type (@{type_name fun}, [_, T])) = 1 + ary T
555 in ary oo robust_const_type end
557 (* This function only makes sense if "T" is as general as possible. *)
558 fun robust_const_typargs thy (s, T) =
559 if s = app_op_name then
560 let val (T1, T2) = T |> domain_type |> dest_funT in [T1, T2] end
561 else if String.isPrefix old_skolem_const_prefix s then
562 [] |> Term.add_tvarsT T |> rev |> map TVar
563 else if String.isPrefix lam_lifted_prefix s then
564 if String.isPrefix lam_lifted_poly_prefix s then
565 let val (T1, T2) = T |> dest_funT in [T1, T2] end
569 (s, T) |> Sign.const_typargs thy
571 (* Converts an Isabelle/HOL term (with combinators) into an intermediate term.
572 Also accumulates sort infomation. *)
573 fun iterm_from_term thy type_enc bs (P $ Q) =
575 val (P', P_atomics_Ts) = iterm_from_term thy type_enc bs P
576 val (Q', Q_atomics_Ts) = iterm_from_term thy type_enc bs Q
577 in (IApp (P', Q'), union (op =) P_atomics_Ts Q_atomics_Ts) end
578 | iterm_from_term thy type_enc _ (Const (c, T)) =
579 (IConst (`(make_fixed_const (SOME type_enc)) c, T,
580 robust_const_typargs thy (c, T)),
582 | iterm_from_term _ _ _ (Free (s, T)) =
583 (IConst (`make_fixed_var s, T, []), atomic_types_of T)
584 | iterm_from_term _ type_enc _ (Var (v as (s, _), T)) =
585 (if String.isPrefix Meson_Clausify.new_skolem_var_prefix s then
587 val Ts = T |> strip_type |> swap |> op ::
588 val s' = new_skolem_const_name s (length Ts)
589 in IConst (`(make_fixed_const (SOME type_enc)) s', T, Ts) end
591 IVar ((make_schematic_var v, s), T), atomic_types_of T)
592 | iterm_from_term _ _ bs (Bound j) =
593 nth bs j |> (fn (_, (name, T)) => (IConst (name, T, []), atomic_types_of T))
594 | iterm_from_term thy type_enc bs (Abs (s, T, t)) =
596 fun vary s = s |> AList.defined (op =) bs s ? vary o Symbol.bump_string
598 val name = `make_bound_var s
599 val (tm, atomic_Ts) =
600 iterm_from_term thy type_enc ((s, (name, T)) :: bs) t
601 in (IAbs ((name, T), tm), union (op =) atomic_Ts (atomic_types_of T)) end
603 (* "_query", "_bang", and "_at" are for the ASCII-challenged Metis and
605 val queries = ["?", "_query"]
606 val bangs = ["!", "_bang"]
607 val ats = ["@", "_at"]
609 fun try_unsuffixes ss s =
610 fold (fn s' => fn NONE => try (unsuffix s') s | some => some) ss NONE
612 fun try_nonmono constr suffixes fallback s =
613 case try_unsuffixes suffixes s of
615 (case try_unsuffixes suffixes s of
616 SOME s => (constr Positively_Naked_Vars, s)
618 case try_unsuffixes ats s of
619 SOME s => (constr Ghost_Type_Arg_Vars, s)
620 | NONE => (constr All_Vars, s))
623 fun type_enc_from_string strictness s =
624 (case try (unprefix "poly_") s of
625 SOME s => (SOME Polymorphic, s)
627 case try (unprefix "raw_mono_") s of
628 SOME s => (SOME Raw_Monomorphic, s)
630 case try (unprefix "mono_") s of
631 SOME s => (SOME Mangled_Monomorphic, s)
634 |> try_nonmono Fin_Nonmono_Types bangs
635 |> try_nonmono (curry Noninf_Nonmono_Types strictness) queries)
636 |> (fn (poly, (level, core)) =>
637 case (core, (poly, level)) of
638 ("native", (SOME poly, _)) =>
639 (case (poly, level) of
640 (Polymorphic, All_Types) =>
641 Native (First_Order, Polymorphic, All_Types)
642 | (Mangled_Monomorphic, _) =>
643 if granularity_of_type_level level = All_Vars then
644 Native (First_Order, Mangled_Monomorphic, level)
647 | _ => raise Same.SAME)
648 | ("native_higher", (SOME poly, _)) =>
649 (case (poly, level) of
650 (Polymorphic, All_Types) =>
651 Native (Higher_Order THF_With_Choice, Polymorphic, All_Types)
652 | (_, Noninf_Nonmono_Types _) => raise Same.SAME
653 | (Mangled_Monomorphic, _) =>
654 if granularity_of_type_level level = All_Vars then
655 Native (Higher_Order THF_With_Choice, Mangled_Monomorphic,
659 | _ => raise Same.SAME)
660 | ("guards", (SOME poly, _)) =>
661 if poly = Mangled_Monomorphic andalso
662 granularity_of_type_level level = Ghost_Type_Arg_Vars then
666 | ("tags", (SOME poly, _)) =>
667 if granularity_of_type_level level = Ghost_Type_Arg_Vars then
671 | ("args", (SOME poly, All_Types (* naja *))) =>
672 Guards (poly, Const_Arg_Types)
673 | ("erased", (NONE, All_Types (* naja *))) =>
674 Guards (Polymorphic, No_Types)
675 | _ => raise Same.SAME)
676 handle Same.SAME => error ("Unknown type encoding: " ^ quote s ^ ".")
678 fun adjust_order THF_Without_Choice (Higher_Order _) =
679 Higher_Order THF_Without_Choice
680 | adjust_order _ type_enc = type_enc
682 fun adjust_type_enc (THF (TPTP_Polymorphic, _, flavor))
683 (Native (order, poly, level)) =
684 Native (adjust_order flavor order, poly, level)
685 | adjust_type_enc (THF (TPTP_Monomorphic, _, flavor))
686 (Native (order, _, level)) =
687 Native (adjust_order flavor order, Mangled_Monomorphic, level)
688 | adjust_type_enc (TFF (TPTP_Monomorphic, _)) (Native (_, _, level)) =
689 Native (First_Order, Mangled_Monomorphic, level)
690 | adjust_type_enc (DFG DFG_Sorted) (Native (_, _, level)) =
691 Native (First_Order, Mangled_Monomorphic, level)
692 | adjust_type_enc (TFF _) (Native (_, poly, level)) =
693 Native (First_Order, poly, level)
694 | adjust_type_enc format (Native (_, poly, level)) =
695 adjust_type_enc format (Guards (poly, level))
696 | adjust_type_enc CNF_UEQ (type_enc as Guards stuff) =
697 (if is_type_enc_fairly_sound type_enc then Tags else Guards) stuff
698 | adjust_type_enc _ type_enc = type_enc
702 @{const Not} $ t1 => is_fol_term t1
703 | Const (@{const_name All}, _) $ Abs (_, _, t') => is_fol_term t'
704 | Const (@{const_name All}, _) $ t1 => is_fol_term t1
705 | Const (@{const_name Ex}, _) $ Abs (_, _, t') => is_fol_term t'
706 | Const (@{const_name Ex}, _) $ t1 => is_fol_term t1
707 | @{const HOL.conj} $ t1 $ t2 => is_fol_term t1 andalso is_fol_term t2
708 | @{const HOL.disj} $ t1 $ t2 => is_fol_term t1 andalso is_fol_term t2
709 | @{const HOL.implies} $ t1 $ t2 => is_fol_term t1 andalso is_fol_term t2
710 | Const (@{const_name HOL.eq}, Type (_, [@{typ bool}, _])) $ t1 $ t2 =>
711 is_fol_term t1 andalso is_fol_term t2
712 | _ => not (exists_subterm (fn Abs _ => true | _ => false) t)
714 fun simple_translate_lambdas do_lambdas ctxt t =
715 if is_fol_term t then
721 @{const Not} $ t1 => @{const Not} $ trans Ts t1
722 | (t0 as Const (@{const_name All}, _)) $ Abs (s, T, t') =>
723 t0 $ Abs (s, T, trans (T :: Ts) t')
724 | (t0 as Const (@{const_name All}, _)) $ t1 =>
725 trans Ts (t0 $ eta_expand Ts t1 1)
726 | (t0 as Const (@{const_name Ex}, _)) $ Abs (s, T, t') =>
727 t0 $ Abs (s, T, trans (T :: Ts) t')
728 | (t0 as Const (@{const_name Ex}, _)) $ t1 =>
729 trans Ts (t0 $ eta_expand Ts t1 1)
730 | (t0 as @{const HOL.conj}) $ t1 $ t2 =>
731 t0 $ trans Ts t1 $ trans Ts t2
732 | (t0 as @{const HOL.disj}) $ t1 $ t2 =>
733 t0 $ trans Ts t1 $ trans Ts t2
734 | (t0 as @{const HOL.implies}) $ t1 $ t2 =>
735 t0 $ trans Ts t1 $ trans Ts t2
736 | (t0 as Const (@{const_name HOL.eq}, Type (_, [@{typ bool}, _])))
738 t0 $ trans Ts t1 $ trans Ts t2
740 if not (exists_subterm (fn Abs _ => true | _ => false) t) then t
741 else t |> Envir.eta_contract |> do_lambdas ctxt Ts
742 val (t, ctxt') = Variable.import_terms true [t] ctxt |>> the_single
743 in t |> trans [] |> singleton (Variable.export_terms ctxt' ctxt) end
745 fun do_cheaply_conceal_lambdas Ts (t1 $ t2) =
746 do_cheaply_conceal_lambdas Ts t1
747 $ do_cheaply_conceal_lambdas Ts t2
748 | do_cheaply_conceal_lambdas Ts (Abs (_, T, t)) =
749 Const (lam_lifted_poly_prefix ^ serial_string (),
750 T --> fastype_of1 (T :: Ts, t))
751 | do_cheaply_conceal_lambdas _ t = t
753 fun concealed_bound_name j = atp_weak_prefix ^ string_of_int j
754 fun conceal_bounds Ts t =
755 subst_bounds (map (Free o apfst concealed_bound_name)
756 (0 upto length Ts - 1 ~~ Ts), t)
757 fun reveal_bounds Ts =
758 subst_atomic (map (fn (j, T) => (Free (concealed_bound_name j, T), Bound j))
759 (0 upto length Ts - 1 ~~ Ts))
761 fun do_introduce_combinators ctxt Ts t =
762 let val thy = Proof_Context.theory_of ctxt in
763 t |> conceal_bounds Ts
765 |> Meson_Clausify.introduce_combinators_in_cterm
766 |> prop_of |> Logic.dest_equals |> snd
769 (* A type variable of sort "{}" will make abstraction fail. *)
770 handle THM _ => t |> do_cheaply_conceal_lambdas Ts
771 val introduce_combinators = simple_translate_lambdas do_introduce_combinators
773 fun constify_lifted (t $ u) = constify_lifted t $ constify_lifted u
774 | constify_lifted (Abs (s, T, t)) = Abs (s, T, constify_lifted t)
775 | constify_lifted (Free (x as (s, _))) =
776 (if String.isPrefix lam_lifted_prefix s then Const else Free) x
777 | constify_lifted t = t
779 fun lift_lams_part_1 ctxt type_enc =
780 map close_form #> rpair ctxt
781 #-> Lambda_Lifting.lift_lambdas
782 (SOME ((if polymorphism_of_type_enc type_enc = Polymorphic then
783 lam_lifted_poly_prefix
785 lam_lifted_mono_prefix) ^ "_a"))
786 Lambda_Lifting.is_quantifier
789 fun lift_lams_part_2 ctxt (facts, lifted) =
791 (* Lambda-lifting sometimes leaves some lambdas around; we need some way to get rid
793 |> pairself (map (introduce_combinators ctxt))
794 |> pairself (map constify_lifted)
795 (* Requires bound variables not to clash with any schematic variables (as
796 should be the case right after lambda-lifting). *)
797 |>> map (open_form (unprefix close_form_prefix))
798 ||> map (open_form I)
800 fun lift_lams ctxt = lift_lams_part_2 ctxt oo lift_lams_part_1 ctxt
802 fun intentionalize_def (Const (@{const_name All}, _) $ Abs (_, _, t)) =
804 | intentionalize_def (Const (@{const_name HOL.eq}, _) $ t $ u) =
806 fun lam T t = Abs (Name.uu, T, t)
807 val (head, args) = strip_comb t ||> rev
808 val head_T = fastype_of head
810 val arg_Ts = head_T |> binder_types |> take n |> rev
811 val u = u |> subst_atomic (args ~~ map Bound (0 upto n - 1))
812 in HOLogic.eq_const head_T $ head $ fold lam arg_Ts u end
813 | intentionalize_def t = t
815 type translated_formula =
819 iformula : (name, typ, iterm) formula,
820 atomic_types : typ list}
822 fun update_iformula f ({name, stature, kind, iformula, atomic_types}
823 : translated_formula) =
824 {name = name, stature = stature, kind = kind, iformula = f iformula,
825 atomic_types = atomic_types} : translated_formula
827 fun fact_lift f ({iformula, ...} : translated_formula) = f iformula
829 fun insert_type thy get_T x xs =
830 let val T = get_T x in
831 if exists (type_instance thy T o get_T) xs then xs
832 else x :: filter_out (type_generalization thy T o get_T) xs
835 (* The Booleans indicate whether all type arguments should be kept. *)
836 datatype type_arg_policy =
837 Explicit_Type_Args of bool (* infer_from_term_args *) |
841 fun type_arg_policy monom_constrs type_enc s =
842 let val poly = polymorphism_of_type_enc type_enc in
843 if s = type_tag_name then
844 if poly = Mangled_Monomorphic then Mangled_Type_Args
845 else Explicit_Type_Args false
846 else case type_enc of
847 Native (_, Polymorphic, _) => Explicit_Type_Args false
848 | Tags (_, All_Types) => No_Type_Args
850 let val level = level_of_type_enc type_enc in
851 if level = No_Types orelse s = @{const_name HOL.eq} orelse
852 (s = app_op_name andalso level = Const_Arg_Types) then
854 else if poly = Mangled_Monomorphic then
856 else if member (op =) monom_constrs s andalso
857 granularity_of_type_level level = Positively_Naked_Vars then
861 (level = All_Types orelse
862 granularity_of_type_level level = Ghost_Type_Arg_Vars)
866 (* Make atoms for sorted type variables. *)
867 fun generic_add_sorts_on_type (_, []) = I
868 | generic_add_sorts_on_type ((x, i), s :: ss) =
869 generic_add_sorts_on_type ((x, i), ss)
870 #> (if s = the_single @{sort HOL.type} then
873 insert (op =) (`make_type_class s, `make_fixed_type_var x)
875 insert (op =) (`make_type_class s,
876 (make_schematic_type_var (x, i), x)))
877 fun add_sorts_on_tfree (TFree (s, S)) = generic_add_sorts_on_type ((s, ~1), S)
878 | add_sorts_on_tfree _ = I
879 fun add_sorts_on_tvar (TVar z) = generic_add_sorts_on_type z
880 | add_sorts_on_tvar _ = I
882 fun type_class_formula type_enc class arg =
883 AAtom (ATerm (class, arg ::
885 Native (First_Order, Polymorphic, _) =>
886 if avoid_first_order_ghost_type_vars then [ATerm (TYPE_name, [arg])]
889 fun formulas_for_types type_enc add_sorts_on_typ Ts =
890 [] |> level_of_type_enc type_enc <> No_Types ? fold add_sorts_on_typ Ts
891 |> map (fn (class, name) =>
892 type_class_formula type_enc class (ATerm (name, [])))
894 fun mk_aconns c phis =
895 let val (phis', phi') = split_last phis in
896 fold_rev (mk_aconn c) phis' phi'
898 fun mk_ahorn [] phi = phi
899 | mk_ahorn phis psi = AConn (AImplies, [mk_aconns AAnd phis, psi])
900 fun mk_aquant _ [] phi = phi
901 | mk_aquant q xs (phi as AQuant (q', xs', phi')) =
902 if q = q' then AQuant (q, xs @ xs', phi') else AQuant (q, xs, phi)
903 | mk_aquant q xs phi = AQuant (q, xs, phi)
905 fun close_universally add_term_vars phi =
907 fun add_formula_vars bounds (AQuant (_, xs, phi)) =
908 add_formula_vars (map fst xs @ bounds) phi
909 | add_formula_vars bounds (AConn (_, phis)) =
910 fold (add_formula_vars bounds) phis
911 | add_formula_vars bounds (AAtom tm) = add_term_vars bounds tm
912 in mk_aquant AForall (add_formula_vars [] phi []) phi end
914 fun add_term_vars bounds (ATerm (name as (s, _), tms)) =
915 (if is_tptp_variable s andalso
916 not (String.isPrefix tvar_prefix s) andalso
917 not (member (op =) bounds name) then
918 insert (op =) (name, NONE)
921 #> fold (add_term_vars bounds) tms
922 | add_term_vars bounds (AAbs ((name, _), tm)) =
923 add_term_vars (name :: bounds) tm
924 fun close_formula_universally phi = close_universally add_term_vars phi
926 fun add_iterm_vars bounds (IApp (tm1, tm2)) =
927 fold (add_iterm_vars bounds) [tm1, tm2]
928 | add_iterm_vars _ (IConst _) = I
929 | add_iterm_vars bounds (IVar (name, T)) =
930 not (member (op =) bounds name) ? insert (op =) (name, SOME T)
931 | add_iterm_vars bounds (IAbs (_, tm)) = add_iterm_vars bounds tm
932 fun close_iformula_universally phi = close_universally add_iterm_vars phi
934 val fused_infinite_type_name = "ATP.fused_inf" (* shouldn't clash *)
935 val fused_infinite_type = Type (fused_infinite_type_name, [])
937 fun tvar_name (x as (s, _)) = (make_schematic_type_var x, s)
939 fun ho_term_from_typ type_enc =
941 fun term (Type (s, Ts)) =
942 ATerm (case (is_type_enc_higher_order type_enc, s) of
943 (true, @{type_name bool}) => `I tptp_bool_type
944 | (true, @{type_name fun}) => `I tptp_fun_type
945 | _ => if s = fused_infinite_type_name andalso
946 is_type_enc_native type_enc then
947 `I tptp_individual_type
949 `make_fixed_type_const s,
951 | term (TFree (s, _)) = ATerm (`make_fixed_type_var s, [])
952 | term (TVar (x, _)) = ATerm (tvar_name x, [])
955 fun ho_term_for_type_arg type_enc T =
956 if T = dummyT then NONE else SOME (ho_term_from_typ type_enc T)
958 (* This shouldn't clash with anything else. *)
959 val uncurried_alias_sep = "\000"
960 val mangled_type_sep = "\001"
962 val ascii_of_uncurried_alias_sep = ascii_of uncurried_alias_sep
964 fun generic_mangled_type_name f (ATerm (name, [])) = f name
965 | generic_mangled_type_name f (ATerm (name, tys)) =
966 f name ^ "(" ^ space_implode "," (map (generic_mangled_type_name f) tys)
968 | generic_mangled_type_name _ _ = raise Fail "unexpected type abstraction"
970 fun mangled_type type_enc =
971 generic_mangled_type_name fst o ho_term_from_typ type_enc
973 fun make_native_type s =
974 if s = tptp_bool_type orelse s = tptp_fun_type orelse
975 s = tptp_individual_type then
978 native_type_prefix ^ ascii_of s
980 fun ho_type_from_ho_term type_enc pred_sym ary =
982 fun to_mangled_atype ty =
983 AType ((make_native_type (generic_mangled_type_name fst ty),
984 generic_mangled_type_name snd ty), [])
985 fun to_poly_atype (ATerm (name, tys)) = AType (name, map to_poly_atype tys)
986 | to_poly_atype _ = raise Fail "unexpected type abstraction"
988 if polymorphism_of_type_enc type_enc = Polymorphic then to_poly_atype
989 else to_mangled_atype
990 fun to_afun f1 f2 tys = AFun (f1 (hd tys), f2 (nth tys 1))
991 fun to_fo 0 ty = if pred_sym then bool_atype else to_atype ty
992 | to_fo ary (ATerm (_, tys)) = to_afun to_atype (to_fo (ary - 1)) tys
993 | to_fo _ _ = raise Fail "unexpected type abstraction"
994 fun to_ho (ty as ATerm ((s, _), tys)) =
995 if s = tptp_fun_type then to_afun to_ho to_ho tys else to_atype ty
996 | to_ho _ = raise Fail "unexpected type abstraction"
997 in if is_type_enc_higher_order type_enc then to_ho else to_fo ary end
999 fun ho_type_from_typ type_enc pred_sym ary =
1000 ho_type_from_ho_term type_enc pred_sym ary
1001 o ho_term_from_typ type_enc
1003 fun aliased_uncurried ary (s, s') =
1004 (s ^ ascii_of_uncurried_alias_sep ^ string_of_int ary, s' ^ string_of_int ary)
1005 fun unaliased_uncurried (s, s') =
1006 case space_explode uncurried_alias_sep s of
1008 | [s1, s2] => (s1, unsuffix s2 s')
1009 | _ => raise Fail "ill-formed explicit application alias"
1011 fun raw_mangled_const_name type_name ty_args (s, s') =
1013 fun type_suffix f g =
1014 fold_rev (curry (op ^) o g o prefix mangled_type_sep o type_name f)
1016 in (s ^ type_suffix fst ascii_of, s' ^ type_suffix snd I) end
1017 fun mangled_const_name type_enc =
1018 map_filter (ho_term_for_type_arg type_enc)
1019 #> raw_mangled_const_name generic_mangled_type_name
1021 val parse_mangled_ident =
1022 Scan.many1 (not o member (op =) ["(", ")", ","]) >> implode
1024 fun parse_mangled_type x =
1025 (parse_mangled_ident
1026 -- Scan.optional ($$ "(" |-- Scan.optional parse_mangled_types [] --| $$ ")")
1028 and parse_mangled_types x =
1029 (parse_mangled_type ::: Scan.repeat ($$ "," |-- parse_mangled_type)) x
1031 fun unmangled_type s =
1032 s |> suffix ")" |> raw_explode
1033 |> Scan.finite Symbol.stopper
1034 (Scan.error (!! (fn _ => raise Fail ("unrecognized mangled type " ^
1035 quote s)) parse_mangled_type))
1038 fun unmangled_const_name s =
1039 (s, s) |> unaliased_uncurried |> fst |> space_explode mangled_type_sep
1040 fun unmangled_const s =
1041 let val ss = unmangled_const_name s in
1042 (hd ss, map unmangled_type (tl ss))
1045 fun introduce_proxies_in_iterm type_enc =
1047 fun tweak_ho_quant ho_quant T [IAbs _] = IConst (`I ho_quant, T, [])
1048 | tweak_ho_quant ho_quant (T as Type (_, [p_T as Type (_, [x_T, _]), _]))
1050 (* Eta-expand "!!" and "??", to work around LEO-II 1.2.8 parser
1051 limitation. This works in conjuction with special code in
1052 "ATP_Problem" that uses the syntactic sugar "!" and "?" whenever
1054 IAbs ((`I "P", p_T),
1055 IApp (IConst (`I ho_quant, T, []),
1056 IAbs ((`I "X", x_T),
1057 IApp (IConst (`I "P", p_T, []),
1058 IConst (`I "X", x_T, [])))))
1059 | tweak_ho_quant _ _ _ = raise Fail "unexpected type for quantifier"
1060 fun intro top_level args (IApp (tm1, tm2)) =
1061 IApp (intro top_level (tm2 :: args) tm1, intro false [] tm2)
1062 | intro top_level args (IConst (name as (s, _), T, T_args)) =
1063 (case proxify_const s of
1065 if top_level orelse is_type_enc_higher_order type_enc then
1066 case (top_level, s) of
1067 (_, "c_False") => IConst (`I tptp_false, T, [])
1068 | (_, "c_True") => IConst (`I tptp_true, T, [])
1069 | (false, "c_Not") => IConst (`I tptp_not, T, [])
1070 | (false, "c_conj") => IConst (`I tptp_and, T, [])
1071 | (false, "c_disj") => IConst (`I tptp_or, T, [])
1072 | (false, "c_implies") => IConst (`I tptp_implies, T, [])
1073 | (false, "c_All") => tweak_ho_quant tptp_ho_forall T args
1074 | (false, "c_Ex") => tweak_ho_quant tptp_ho_exists T args
1076 if is_tptp_equal s andalso length args = 2 then
1077 IConst (`I tptp_equal, T, [])
1079 (* Eta-expand partially applied THF equality, because the
1080 LEO-II and Satallax parsers complain about not being able to
1081 infer the type of "=". *)
1082 let val i_T = domain_type T in
1083 IAbs ((`I "X", i_T),
1084 IAbs ((`I "Y", i_T),
1085 IApp (IApp (IConst (`I tptp_equal, T, []),
1086 IConst (`I "X", i_T, [])),
1087 IConst (`I "Y", i_T, []))))
1089 | _ => IConst (name, T, [])
1091 IConst (proxy_base |>> prefix const_prefix, T, T_args)
1092 | NONE => if s = tptp_choice then tweak_ho_quant tptp_choice T args
1093 else IConst (name, T, T_args))
1094 | intro _ _ (IAbs (bound, tm)) = IAbs (bound, intro false [] tm)
1096 in intro true [] end
1098 fun mangle_type_args_in_const type_enc (name as (s, _)) T_args =
1099 case unprefix_and_unascii const_prefix s of
1100 NONE => (name, T_args)
1102 case type_arg_policy [] type_enc (invert_const s'') of
1103 Mangled_Type_Args => (mangled_const_name type_enc T_args name, [])
1104 | _ => (name, T_args)
1105 fun mangle_type_args_in_iterm type_enc =
1106 if polymorphism_of_type_enc type_enc = Mangled_Monomorphic then
1108 fun mangle (IApp (tm1, tm2)) = IApp (mangle tm1, mangle tm2)
1109 | mangle (tm as IConst (_, _, [])) = tm
1110 | mangle (IConst (name, T, T_args)) =
1111 mangle_type_args_in_const type_enc name T_args
1112 |> (fn (name, T_args) => IConst (name, T, T_args))
1113 | mangle (IAbs (bound, tm)) = IAbs (bound, mangle tm)
1119 fun chop_fun 0 T = ([], T)
1120 | chop_fun n (Type (@{type_name fun}, [dom_T, ran_T])) =
1121 chop_fun (n - 1) ran_T |>> cons dom_T
1122 | chop_fun _ T = ([], T)
1124 fun filter_const_type_args _ _ _ [] = []
1125 | filter_const_type_args thy s ary T_args =
1127 val U = robust_const_type thy s
1128 val arg_U_vars = fold Term.add_tvarsT (U |> chop_fun ary |> fst) []
1129 val U_args = (s, U) |> robust_const_typargs thy
1132 |> map (fn (U, T) =>
1133 if member (op =) arg_U_vars (dest_TVar U) then dummyT else T)
1135 handle TYPE _ => T_args
1137 fun filter_type_args_in_const _ _ _ _ _ [] = []
1138 | filter_type_args_in_const thy monom_constrs type_enc ary s T_args =
1139 case unprefix_and_unascii const_prefix s of
1141 if level_of_type_enc type_enc = No_Types orelse s = tptp_choice then []
1145 val s'' = invert_const s''
1146 fun filter_T_args false = T_args
1147 | filter_T_args true = filter_const_type_args thy s'' ary T_args
1149 case type_arg_policy monom_constrs type_enc s'' of
1150 Explicit_Type_Args infer_from_term_args =>
1151 filter_T_args infer_from_term_args
1152 | No_Type_Args => []
1153 | Mangled_Type_Args => raise Fail "unexpected (un)mangled symbol"
1155 fun filter_type_args_in_iterm thy monom_constrs type_enc =
1157 fun filt ary (IApp (tm1, tm2)) = IApp (filt (ary + 1) tm1, filt 0 tm2)
1158 | filt ary (IConst (name as (s, _), T, T_args)) =
1159 filter_type_args_in_const thy monom_constrs type_enc ary s T_args
1160 |> (fn T_args => IConst (name, T, T_args))
1161 | filt _ (IAbs (bound, tm)) = IAbs (bound, filt 0 tm)
1165 fun iformula_from_prop ctxt type_enc eq_as_iff =
1167 val thy = Proof_Context.theory_of ctxt
1168 fun do_term bs t atomic_Ts =
1169 iterm_from_term thy type_enc bs (Envir.eta_contract t)
1170 |>> (introduce_proxies_in_iterm type_enc
1171 #> mangle_type_args_in_iterm type_enc #> AAtom)
1172 ||> union (op =) atomic_Ts
1173 fun do_quant bs q pos s T t' =
1175 val s = singleton (Name.variant_list (map fst bs)) s
1176 val universal = Option.map (q = AExists ? not) pos
1178 s |> `(case universal of
1179 SOME true => make_all_bound_var
1180 | SOME false => make_exist_bound_var
1181 | NONE => make_bound_var)
1183 do_formula ((s, (name, T)) :: bs) pos t'
1184 #>> mk_aquant q [(name, SOME T)]
1185 ##> union (op =) (atomic_types_of T)
1187 and do_conn bs c pos1 t1 pos2 t2 =
1188 do_formula bs pos1 t1 ##>> do_formula bs pos2 t2 #>> uncurry (mk_aconn c)
1189 and do_formula bs pos t =
1191 @{const Trueprop} $ t1 => do_formula bs pos t1
1192 | @{const Not} $ t1 => do_formula bs (Option.map not pos) t1 #>> mk_anot
1193 | Const (@{const_name All}, _) $ Abs (s, T, t') =>
1194 do_quant bs AForall pos s T t'
1195 | (t0 as Const (@{const_name All}, _)) $ t1 =>
1196 do_formula bs pos (t0 $ eta_expand (map (snd o snd) bs) t1 1)
1197 | Const (@{const_name Ex}, _) $ Abs (s, T, t') =>
1198 do_quant bs AExists pos s T t'
1199 | (t0 as Const (@{const_name Ex}, _)) $ t1 =>
1200 do_formula bs pos (t0 $ eta_expand (map (snd o snd) bs) t1 1)
1201 | @{const HOL.conj} $ t1 $ t2 => do_conn bs AAnd pos t1 pos t2
1202 | @{const HOL.disj} $ t1 $ t2 => do_conn bs AOr pos t1 pos t2
1203 | @{const HOL.implies} $ t1 $ t2 =>
1204 do_conn bs AImplies (Option.map not pos) t1 pos t2
1205 | Const (@{const_name HOL.eq}, Type (_, [@{typ bool}, _])) $ t1 $ t2 =>
1206 if eq_as_iff then do_conn bs AIff NONE t1 NONE t2 else do_term bs t
1208 in do_formula [] end
1210 fun presimplify_term thy t =
1211 if exists_Const (member (op =) Meson.presimplified_consts o fst) t then
1212 t |> Skip_Proof.make_thm thy
1213 |> Meson.presimplify
1218 fun preprocess_abstractions_in_terms trans_lams facts =
1220 val (facts, lambda_ts) =
1221 facts |> map (snd o snd) |> trans_lams
1222 |>> map2 (fn (name, (kind, _)) => fn t => (name, (kind, t))) facts
1224 map2 (fn t => fn j =>
1225 ((lam_fact_prefix ^ Int.toString j, (Global, Def)), (Axiom, t)))
1226 lambda_ts (1 upto length lambda_ts)
1227 in (facts, lam_facts) end
1229 (* Metis's use of "resolve_tac" freezes the schematic variables. We simulate the
1230 same in Sledgehammer to prevent the discovery of unreplayable proofs. *)
1233 fun freeze (t $ u) = freeze t $ freeze u
1234 | freeze (Abs (s, T, t)) = Abs (s, T, freeze t)
1235 | freeze (Var ((s, i), T)) =
1236 Free (atp_weak_prefix ^ s ^ "_" ^ string_of_int i, T)
1238 in t |> exists_subterm is_Var t ? freeze end
1240 fun presimp_prop ctxt type_enc t =
1242 val thy = Proof_Context.theory_of ctxt
1243 val t = t |> Envir.beta_eta_contract
1244 |> transform_elim_prop
1245 |> Object_Logic.atomize_term thy
1246 val need_trueprop = (fastype_of t = @{typ bool})
1248 t |> need_trueprop ? HOLogic.mk_Trueprop
1249 |> not (is_type_enc_higher_order type_enc) ? extensionalize_term ctxt
1250 |> presimplify_term thy
1251 |> HOLogic.dest_Trueprop
1253 handle TERM _ => @{const True}
1255 fun make_formula ctxt type_enc eq_as_iff name stature kind t =
1257 val (iformula, atomic_Ts) =
1258 iformula_from_prop ctxt type_enc eq_as_iff (SOME (kind <> Conjecture)) t
1260 |>> close_iformula_universally
1262 {name = name, stature = stature, kind = kind, iformula = iformula,
1263 atomic_types = atomic_Ts}
1266 (* Satallax prefers "=" to "<=>" *)
1267 fun is_format_eq_as_iff FOF = true
1268 | is_format_eq_as_iff (TFF _) = true
1269 | is_format_eq_as_iff (DFG _) = true
1270 | is_format_eq_as_iff _ = false
1272 fun make_fact ctxt format type_enc eq_as_iff ((name, stature), t) =
1273 case t |> make_formula ctxt type_enc
1274 (eq_as_iff andalso is_format_eq_as_iff format) name
1276 formula as {iformula = AAtom (IConst ((s, _), _, _)), ...} =>
1277 if s = tptp_true then NONE else SOME formula
1278 | formula => SOME formula
1280 fun s_not_prop (@{const Trueprop} $ t) = @{const Trueprop} $ s_not t
1281 | s_not_prop _ = @{prop True} (* "t" is too meta for "metis" *)
1283 | s_not_prop (@{const "==>"} $ t $ @{prop False}) = t
1284 | s_not_prop t = @{const "==>"} $ t $ @{prop False}
1287 fun make_conjecture ctxt format type_enc =
1288 map (fn ((name, stature), (kind, t)) =>
1289 t |> kind = Conjecture ? s_not
1290 |> make_formula ctxt type_enc (is_format_eq_as_iff format) name
1293 (** Finite and infinite type inference **)
1295 fun tvar_footprint thy s ary =
1296 (case unprefix_and_unascii const_prefix s of
1298 s |> invert_const |> robust_const_type thy |> chop_fun ary |> fst
1299 |> map (fn T => Term.add_tvarsT T [] |> map fst)
1303 fun ghost_type_args thy s ary =
1304 if is_tptp_equal s then
1308 val footprint = tvar_footprint thy s ary
1309 val eq = (s = @{const_name HOL.eq})
1310 fun ghosts _ [] = []
1311 | ghosts seen ((i, tvars) :: args) =
1312 ghosts (union (op =) seen tvars) args
1313 |> (eq orelse exists (fn tvar => not (member (op =) seen tvar)) tvars)
1316 if forall null footprint then
1319 0 upto length footprint - 1 ~~ footprint
1320 |> sort (rev_order o list_ord Term_Ord.indexname_ord o pairself snd)
1324 type monotonicity_info =
1325 {maybe_finite_Ts : typ list,
1326 surely_finite_Ts : typ list,
1327 maybe_infinite_Ts : typ list,
1328 surely_infinite_Ts : typ list,
1329 maybe_nonmono_Ts : typ list}
1331 (* These types witness that the type classes they belong to allow infinite
1332 models and hence that any types with these type classes is monotonic. *)
1333 val known_infinite_types =
1334 [@{typ nat}, HOLogic.intT, HOLogic.realT, @{typ "nat => bool"}]
1336 fun is_type_kind_of_surely_infinite ctxt strictness cached_Ts T =
1337 strictness <> Strict andalso is_type_surely_infinite ctxt true cached_Ts T
1339 (* Finite types such as "unit", "bool", "bool * bool", and "bool => bool" are
1340 dangerous because their "exhaust" properties can easily lead to unsound ATP
1341 proofs. On the other hand, all HOL infinite types can be given the same
1342 models in first-order logic (via Löwenheim-Skolem). *)
1344 fun should_encode_type _ (_ : monotonicity_info) All_Types _ = true
1345 | should_encode_type ctxt {maybe_finite_Ts, surely_infinite_Ts,
1346 maybe_nonmono_Ts, ...}
1347 (Noninf_Nonmono_Types (strictness, grain)) T =
1348 let val thy = Proof_Context.theory_of ctxt in
1349 grain = Ghost_Type_Arg_Vars orelse
1350 (exists (type_intersect thy T) maybe_nonmono_Ts andalso
1351 not (exists (type_instance thy T) surely_infinite_Ts orelse
1352 (not (member (type_equiv thy) maybe_finite_Ts T) andalso
1353 is_type_kind_of_surely_infinite ctxt strictness surely_infinite_Ts
1356 | should_encode_type ctxt {surely_finite_Ts, maybe_infinite_Ts,
1357 maybe_nonmono_Ts, ...}
1358 (Fin_Nonmono_Types grain) T =
1359 let val thy = Proof_Context.theory_of ctxt in
1360 grain = Ghost_Type_Arg_Vars orelse
1361 (exists (type_intersect thy T) maybe_nonmono_Ts andalso
1362 (exists (type_generalization thy T) surely_finite_Ts orelse
1363 (not (member (type_equiv thy) maybe_infinite_Ts T) andalso
1364 is_type_surely_finite ctxt T)))
1366 | should_encode_type _ _ _ _ = false
1368 fun should_guard_type ctxt mono (Guards (_, level)) should_guard_var T =
1369 should_guard_var () andalso should_encode_type ctxt mono level T
1370 | should_guard_type _ _ _ _ _ = false
1372 fun is_maybe_universal_var (IConst ((s, _), _, _)) =
1373 String.isPrefix bound_var_prefix s orelse
1374 String.isPrefix all_bound_var_prefix s
1375 | is_maybe_universal_var (IVar _) = true
1376 | is_maybe_universal_var _ = false
1379 Top_Level of bool option |
1380 Eq_Arg of bool option |
1383 fun should_tag_with_type _ _ _ (Top_Level _) _ _ = false
1384 | should_tag_with_type ctxt mono (Tags (_, level)) site u T =
1385 if granularity_of_type_level level = All_Vars then
1386 should_encode_type ctxt mono level T
1388 (case (site, is_maybe_universal_var u) of
1389 (Eq_Arg _, true) => should_encode_type ctxt mono level T
1391 | should_tag_with_type _ _ _ _ _ _ = false
1393 fun fused_type ctxt mono level =
1395 val should_encode = should_encode_type ctxt mono level
1396 fun fuse 0 T = if should_encode T then T else fused_infinite_type
1397 | fuse ary (Type (@{type_name fun}, [T1, T2])) =
1398 fuse 0 T1 --> fuse (ary - 1) T2
1399 | fuse _ _ = raise Fail "expected function type"
1402 (** predicators and application operators **)
1405 {pred_sym : bool, min_ary : int, max_ary : int, types : typ list,
1408 fun default_sym_tab_entries type_enc =
1409 (make_fixed_const NONE @{const_name undefined},
1410 {pred_sym = false, min_ary = 0, max_ary = 0, types = [],
1411 in_conj = false}) ::
1412 ([tptp_false, tptp_true]
1413 |> map (rpair {pred_sym = true, min_ary = 0, max_ary = 0, types = [],
1414 in_conj = false})) @
1415 ([tptp_equal, tptp_old_equal]
1416 |> map (rpair {pred_sym = true, min_ary = 2, max_ary = 2, types = [],
1418 |> not (is_type_enc_higher_order type_enc)
1419 ? cons (prefixed_predicator_name,
1420 {pred_sym = true, min_ary = 1, max_ary = 1, types = [],
1423 datatype app_op_level =
1426 Sufficient_App_Op_And_Predicator |
1427 Full_App_Op_And_Predicator
1429 fun sym_table_for_facts ctxt type_enc app_op_level conjs facts =
1431 val thy = Proof_Context.theory_of ctxt
1432 fun consider_var_ary const_T var_T max_ary =
1435 if ary = max_ary orelse type_instance thy var_T T orelse
1436 type_instance thy T var_T then
1439 iter (ary + 1) (range_type T)
1440 in iter 0 const_T end
1441 fun add_universal_var T (accum as ((bool_vars, fun_var_Ts), sym_tab)) =
1442 if (app_op_level = Sufficient_App_Op andalso can dest_funT T) orelse
1443 (app_op_level = Sufficient_App_Op_And_Predicator andalso
1444 (can dest_funT T orelse T = @{typ bool})) then
1448 (app_op_level = Sufficient_App_Op_And_Predicator andalso
1449 body_type T = @{typ bool})
1450 fun repair_min_ary {pred_sym, min_ary, max_ary, types, in_conj} =
1451 {pred_sym = pred_sym andalso not bool_vars',
1452 min_ary = fold (fn T' => consider_var_ary T' T) types min_ary,
1453 max_ary = max_ary, types = types, in_conj = in_conj}
1455 fun_var_Ts |> can dest_funT T ? insert_type thy I T
1457 if bool_vars' = bool_vars andalso
1458 pointer_eq (fun_var_Ts', fun_var_Ts) then
1461 ((bool_vars', fun_var_Ts'), Symtab.map (K repair_min_ary) sym_tab)
1465 fun add_iterm_syms conj_fact top_level tm
1466 (accum as ((bool_vars, fun_var_Ts), sym_tab)) =
1467 let val (head, args) = strip_iterm_comb tm in
1469 IConst ((s, _), T, _) =>
1470 if String.isPrefix bound_var_prefix s orelse
1471 String.isPrefix all_bound_var_prefix s then
1472 add_universal_var T accum
1473 else if String.isPrefix exist_bound_var_prefix s then
1476 let val ary = length args in
1477 ((bool_vars, fun_var_Ts),
1478 case Symtab.lookup sym_tab s of
1479 SOME {pred_sym, min_ary, max_ary, types, in_conj} =>
1482 pred_sym andalso top_level andalso not bool_vars
1483 val types' = types |> insert_type thy I T
1484 val in_conj = in_conj orelse conj_fact
1486 if (app_op_level = Sufficient_App_Op orelse
1487 app_op_level = Sufficient_App_Op_And_Predicator)
1488 andalso not (pointer_eq (types', types)) then
1489 fold (consider_var_ary T) fun_var_Ts min_ary
1493 Symtab.update (s, {pred_sym = pred_sym,
1494 min_ary = Int.min (ary, min_ary),
1495 max_ary = Int.max (ary, max_ary),
1496 types = types', in_conj = in_conj})
1501 val pred_sym = top_level andalso not bool_vars
1503 case unprefix_and_unascii const_prefix s of
1505 (if String.isSubstring uncurried_alias_sep s then
1507 else case try (robust_const_ary thy
1509 o unmangled_const_name) s of
1510 SOME ary0 => Int.min (ary0, ary)
1514 case app_op_level of
1516 | Full_App_Op_And_Predicator => 0
1517 | _ => fold (consider_var_ary T) fun_var_Ts ary
1519 Symtab.update_new (s,
1520 {pred_sym = pred_sym, min_ary = min_ary,
1521 max_ary = ary, types = [T], in_conj = conj_fact})
1525 | IVar (_, T) => add_universal_var T accum
1526 | IAbs ((_, T), tm) =>
1527 accum |> add_universal_var T |> add_iterm_syms conj_fact false tm
1529 |> fold (add_iterm_syms conj_fact false) args
1531 fun add_fact_syms conj_fact =
1532 K (add_iterm_syms conj_fact true) |> formula_fold NONE |> fact_lift
1534 ((false, []), Symtab.empty)
1535 |> fold (add_fact_syms true) conjs
1536 |> fold (add_fact_syms false) facts
1538 |> fold Symtab.update (default_sym_tab_entries type_enc)
1541 fun min_ary_of sym_tab s =
1542 case Symtab.lookup sym_tab s of
1543 SOME ({min_ary, ...} : sym_info) => min_ary
1545 case unprefix_and_unascii const_prefix s of
1547 let val s = s |> unmangled_const_name |> hd |> invert_const in
1548 if s = predicator_name then 1
1549 else if s = app_op_name then 2
1550 else if s = type_guard_name then 1
1555 (* True if the constant ever appears outside of the top-level position in
1556 literals, or if it appears with different arities (e.g., because of different
1557 type instantiations). If false, the constant always receives all of its
1558 arguments and is used as a predicate. *)
1559 fun is_pred_sym sym_tab s =
1560 case Symtab.lookup sym_tab s of
1561 SOME ({pred_sym, min_ary, max_ary, ...} : sym_info) =>
1562 pred_sym andalso min_ary = max_ary
1565 val app_op = `(make_fixed_const NONE) app_op_name
1566 val predicator_combconst =
1567 IConst (`(make_fixed_const NONE) predicator_name, @{typ "bool => bool"}, [])
1569 fun list_app head args = fold (curry (IApp o swap)) args head
1570 fun predicator tm = IApp (predicator_combconst, tm)
1572 fun mk_app_op type_enc head arg =
1574 val head_T = ityp_of head
1575 val (arg_T, res_T) = dest_funT head_T
1577 IConst (app_op, head_T --> head_T, [arg_T, res_T])
1578 |> mangle_type_args_in_iterm type_enc
1579 in list_app app [head, arg] end
1581 fun firstorderize_fact thy monom_constrs type_enc sym_tab uncurried_aliases =
1583 fun do_app arg head = mk_app_op type_enc head arg
1584 fun list_app_ops head args = fold do_app args head
1585 fun introduce_app_ops tm =
1586 let val (head, args) = tm |> strip_iterm_comb ||> map introduce_app_ops in
1588 IConst (name as (s, _), T, T_args) =>
1589 if uncurried_aliases andalso String.isPrefix const_prefix s then
1591 val ary = length args
1593 name |> ary > min_ary_of sym_tab s ? aliased_uncurried ary
1594 in list_app (IConst (name, T, T_args)) args end
1596 args |> chop (min_ary_of sym_tab s)
1597 |>> list_app head |-> list_app_ops
1598 | _ => list_app_ops head args
1600 fun introduce_predicators tm =
1601 case strip_iterm_comb tm of
1602 (IConst ((s, _), _, _), _) =>
1603 if is_pred_sym sym_tab s then tm else predicator tm
1604 | _ => predicator tm
1606 not (is_type_enc_higher_order type_enc)
1607 ? (introduce_app_ops #> introduce_predicators)
1608 #> filter_type_args_in_iterm thy monom_constrs type_enc
1609 in update_iformula (formula_map do_iterm) end
1611 (** Helper facts **)
1613 val not_ffalse = @{lemma "~ fFalse" by (unfold fFalse_def) fast}
1614 val ftrue = @{lemma "fTrue" by (unfold fTrue_def) fast}
1616 (* The Boolean indicates that a fairly sound type encoding is needed. *)
1618 [(("COMBI", false), @{thms Meson.COMBI_def}),
1619 (("COMBK", false), @{thms Meson.COMBK_def}),
1620 (("COMBB", false), @{thms Meson.COMBB_def}),
1621 (("COMBC", false), @{thms Meson.COMBC_def}),
1622 (("COMBS", false), @{thms Meson.COMBS_def}),
1623 ((predicator_name, false), [not_ffalse, ftrue]),
1624 (("fFalse", false), [not_ffalse]),
1625 (("fFalse", true), @{thms True_or_False}),
1626 (("fTrue", false), [ftrue]),
1627 (("fTrue", true), @{thms True_or_False}),
1629 @{thms fNot_def [THEN Meson.iff_to_disjD, THEN conjunct1]
1630 fNot_def [THEN Meson.iff_to_disjD, THEN conjunct2]}),
1632 @{lemma "~ P | ~ Q | fconj P Q" "~ fconj P Q | P" "~ fconj P Q | Q"
1633 by (unfold fconj_def) fast+}),
1635 @{lemma "~ P | fdisj P Q" "~ Q | fdisj P Q" "~ fdisj P Q | P | Q"
1636 by (unfold fdisj_def) fast+}),
1637 (("fimplies", false),
1638 @{lemma "P | fimplies P Q" "~ Q | fimplies P Q" "~ fimplies P Q | ~ P | Q"
1639 by (unfold fimplies_def) fast+}),
1641 (* This is a lie: Higher-order equality doesn't need a sound type encoding.
1642 However, this is done so for backward compatibility: Including the
1643 equality helpers by default in Metis breaks a few existing proofs. *)
1644 @{thms fequal_def [THEN Meson.iff_to_disjD, THEN conjunct1]
1645 fequal_def [THEN Meson.iff_to_disjD, THEN conjunct2]}),
1646 (* Partial characterization of "fAll" and "fEx". A complete characterization
1647 would require the axiom of choice for replay with Metis. *)
1648 (("fAll", false), [@{lemma "~ fAll P | P x" by (auto simp: fAll_def)}]),
1649 (("fEx", false), [@{lemma "~ P x | fEx P" by (auto simp: fEx_def)}]),
1650 (("If", true), @{thms if_True if_False True_or_False})]
1651 |> map (apsnd (map zero_var_indexes))
1653 fun atype_of_type_vars (Native (_, Polymorphic, _)) = SOME atype_of_types
1654 | atype_of_type_vars _ = NONE
1656 fun bound_tvars type_enc sorts Ts =
1657 (sorts ? mk_ahorn (formulas_for_types type_enc add_sorts_on_tvar Ts))
1658 #> mk_aquant AForall
1659 (map_filter (fn TVar (x as (s, _), _) =>
1660 SOME ((make_schematic_type_var x, s),
1661 atype_of_type_vars type_enc)
1664 fun eq_formula type_enc atomic_Ts bounds pred_sym tm1 tm2 =
1665 (if pred_sym then AConn (AIff, [AAtom tm1, AAtom tm2])
1666 else AAtom (ATerm (`I tptp_equal, [tm1, tm2])))
1667 |> mk_aquant AForall bounds
1668 |> close_formula_universally
1669 |> bound_tvars type_enc true atomic_Ts
1671 val helper_rank = default_rank
1672 val min_rank = 9 * helper_rank div 10
1673 val max_rank = 4 * min_rank
1675 fun rank_of_fact_num n j = min_rank + (max_rank - min_rank) * j div n
1677 val type_tag = `(make_fixed_const NONE) type_tag_name
1679 fun should_specialize_helper type_enc t =
1680 polymorphism_of_type_enc type_enc <> Polymorphic andalso
1681 level_of_type_enc type_enc <> No_Types andalso
1682 not (null (Term.hidden_polymorphism t))
1684 fun helper_facts_for_sym ctxt format type_enc (s, {types, ...} : sym_info) =
1685 case unprefix_and_unascii const_prefix s of
1688 val thy = Proof_Context.theory_of ctxt
1689 val unmangled_s = mangled_s |> unmangled_const_name |> hd
1690 fun dub needs_fairly_sound j k =
1691 unmangled_s ^ "_" ^ string_of_int j ^ "_" ^ string_of_int k ^
1692 (if mangled_s = unmangled_s then "" else "_" ^ ascii_of mangled_s) ^
1693 (if needs_fairly_sound then typed_helper_suffix
1694 else untyped_helper_suffix)
1695 fun dub_and_inst needs_fairly_sound (th, j) =
1696 let val t = prop_of th in
1697 if should_specialize_helper type_enc t then
1698 map (fn T => specialize_type thy (invert_const unmangled_s, T) t)
1704 |> map (fn (k, t) => ((dub needs_fairly_sound j k, (Global, Def)), t))
1705 val make_facts = map_filter (make_fact ctxt format type_enc false)
1706 val fairly_sound = is_type_enc_fairly_sound type_enc
1709 |> maps (fn ((helper_s, needs_fairly_sound), ths) =>
1710 if helper_s <> unmangled_s orelse
1711 (needs_fairly_sound andalso not fairly_sound) then
1714 ths ~~ (1 upto length ths)
1715 |> maps (dub_and_inst needs_fairly_sound)
1719 fun helper_facts_for_sym_table ctxt format type_enc sym_tab =
1720 Symtab.fold_rev (append o helper_facts_for_sym ctxt format type_enc) sym_tab
1723 (***************************************************************)
1724 (* Type Classes Present in the Axiom or Conjecture Clauses *)
1725 (***************************************************************)
1727 fun set_insert (x, s) = Symtab.update (x, ()) s
1729 fun add_classes (sorts, cset) = List.foldl set_insert cset (flat sorts)
1731 (* Remove this trivial type class (FIXME: similar code elsewhere) *)
1732 fun delete_type cset = Symtab.delete_safe (the_single @{sort HOL.type}) cset
1734 fun classes_of_terms get_Ts =
1735 map (map snd o get_Ts)
1736 #> List.foldl add_classes Symtab.empty
1737 #> delete_type #> Symtab.keys
1739 val tfree_classes_of_terms = classes_of_terms Misc_Legacy.term_tfrees
1740 val tvar_classes_of_terms = classes_of_terms Misc_Legacy.term_tvars
1742 fun fold_type_constrs f (Type (s, Ts)) x =
1743 fold (fold_type_constrs f) Ts (f (s, x))
1744 | fold_type_constrs _ _ x = x
1746 (* Type constructors used to instantiate overloaded constants are the only ones
1748 fun add_type_constrs_in_term thy =
1750 fun add (Const (@{const_name Meson.skolem}, _) $ _) = I
1751 | add (t $ u) = add t #> add u
1753 x |> robust_const_typargs thy |> fold (fold_type_constrs set_insert)
1754 | add (Abs (_, _, u)) = add u
1758 fun type_constrs_of_terms thy ts =
1759 Symtab.keys (fold (add_type_constrs_in_term thy) ts Symtab.empty)
1761 fun extract_lambda_def (Const (@{const_name HOL.eq}, _) $ t $ u) =
1762 let val (head, args) = strip_comb t in
1763 (head |> dest_Const |> fst,
1764 fold_rev (fn t as Var ((s, _), T) =>
1765 (fn u => Abs (s, T, abstract_over (t, u)))
1766 | _ => raise Fail "expected Var") args u)
1768 | extract_lambda_def _ = raise Fail "malformed lifted lambda"
1770 fun trans_lams_from_string ctxt type_enc lam_trans =
1771 if lam_trans = no_lamsN then
1773 else if lam_trans = hide_lamsN then
1774 lift_lams ctxt type_enc ##> K []
1775 else if lam_trans = liftingN orelse lam_trans = lam_liftingN then
1776 lift_lams ctxt type_enc
1777 else if lam_trans = combsN then
1778 map (introduce_combinators ctxt) #> rpair []
1779 else if lam_trans = combs_and_liftingN then
1780 lift_lams_part_1 ctxt type_enc
1781 ##> maps (fn t => [t, introduce_combinators ctxt (intentionalize_def t)])
1782 #> lift_lams_part_2 ctxt
1783 else if lam_trans = combs_or_liftingN then
1784 lift_lams_part_1 ctxt type_enc
1785 ##> map (fn t => case head_of (strip_qnt_body @{const_name All} t) of
1786 @{term "op =::bool => bool => bool"} => t
1787 | _ => introduce_combinators ctxt (intentionalize_def t))
1788 #> lift_lams_part_2 ctxt
1789 else if lam_trans = keep_lamsN then
1790 map (Envir.eta_contract) #> rpair []
1792 error ("Unknown lambda translation scheme: " ^ quote lam_trans ^ ".")
1794 fun translate_formulas ctxt prem_kind format type_enc lam_trans presimp hyp_ts
1797 val thy = Proof_Context.theory_of ctxt
1798 val trans_lams = trans_lams_from_string ctxt type_enc lam_trans
1799 val fact_ts = facts |> map snd
1800 (* Remove existing facts from the conjecture, as this can dramatically
1801 boost an ATP's performance (for some reason). *)
1804 |> map (fn t => if member (op aconv) fact_ts t then @{prop True} else t)
1805 val facts = facts |> map (apsnd (pair Axiom))
1807 map (pair prem_kind) hyp_ts @ [(Conjecture, s_not_prop concl_t)]
1808 |> map (apsnd freeze_term)
1809 |> map2 (pair o rpair (Local, General) o string_of_int)
1810 (0 upto length hyp_ts)
1811 val ((conjs, facts), lam_facts) =
1813 |> presimp ? pairself (map (apsnd (apsnd (presimp_prop ctxt type_enc))))
1814 |> (if lam_trans = no_lamsN then
1818 #> preprocess_abstractions_in_terms trans_lams
1819 #>> chop (length conjs))
1820 val conjs = conjs |> make_conjecture ctxt format type_enc
1821 val (fact_names, facts) =
1823 |> map_filter (fn (name, (_, t)) =>
1824 make_fact ctxt format type_enc true (name, t)
1825 |> Option.map (pair name))
1827 val lifted = lam_facts |> map (extract_lambda_def o snd o snd)
1829 lam_facts |> map_filter (make_fact ctxt format type_enc true o apsnd snd)
1830 val all_ts = concl_t :: hyp_ts @ fact_ts
1831 val subs = tfree_classes_of_terms all_ts
1832 val supers = tvar_classes_of_terms all_ts
1833 val tycons = type_constrs_of_terms thy all_ts
1834 val (supers, arity_clauses) =
1835 if level_of_type_enc type_enc = No_Types then ([], [])
1836 else make_arity_clauses thy tycons supers
1837 val class_rel_clauses = make_class_rel_clauses thy subs supers
1839 (fact_names |> map single, union (op =) subs supers, conjs,
1840 facts @ lam_facts, class_rel_clauses, arity_clauses, lifted)
1843 val type_guard = `(make_fixed_const NONE) type_guard_name
1845 fun type_guard_iterm type_enc T tm =
1846 IApp (IConst (type_guard, T --> @{typ bool}, [T])
1847 |> mangle_type_args_in_iterm type_enc, tm)
1849 fun is_var_positively_naked_in_term _ (SOME false) _ accum = accum
1850 | is_var_positively_naked_in_term name _ (ATerm ((s, _), tms)) accum =
1851 accum orelse (is_tptp_equal s andalso member (op =) tms (ATerm (name, [])))
1852 | is_var_positively_naked_in_term _ _ _ _ = true
1854 fun is_var_ghost_type_arg_in_term thy polym_constrs name pos tm accum =
1855 is_var_positively_naked_in_term name pos tm accum orelse
1857 val var = ATerm (name, [])
1858 fun is_nasty_in_term (ATerm (_, [])) = false
1859 | is_nasty_in_term (ATerm ((s, _), tms)) =
1861 val ary = length tms
1862 val polym_constr = member (op =) polym_constrs s
1863 val ghosts = ghost_type_args thy s ary
1865 exists (fn (j, tm) =>
1866 if polym_constr then
1867 member (op =) ghosts j andalso
1868 (tm = var orelse is_nasty_in_term tm)
1870 tm = var andalso member (op =) ghosts j)
1871 (0 upto ary - 1 ~~ tms)
1872 orelse (not polym_constr andalso exists is_nasty_in_term tms)
1874 | is_nasty_in_term _ = true
1875 in is_nasty_in_term tm end
1877 fun should_guard_var_in_formula thy polym_constrs level pos phi (SOME true)
1879 (case granularity_of_type_level level of
1881 | Positively_Naked_Vars =>
1882 formula_fold pos (is_var_positively_naked_in_term name) phi false
1883 | Ghost_Type_Arg_Vars =>
1884 formula_fold pos (is_var_ghost_type_arg_in_term thy polym_constrs name) phi
1886 | should_guard_var_in_formula _ _ _ _ _ _ _ = true
1888 fun always_guard_var_in_formula _ _ _ _ _ _ _ = true
1890 fun should_generate_tag_bound_decl _ _ _ (SOME true) _ = false
1891 | should_generate_tag_bound_decl ctxt mono (Tags (_, level)) _ T =
1892 granularity_of_type_level level <> All_Vars andalso
1893 should_encode_type ctxt mono level T
1894 | should_generate_tag_bound_decl _ _ _ _ _ = false
1896 fun mk_aterm type_enc name T_args args =
1897 ATerm (name, map_filter (ho_term_for_type_arg type_enc) T_args @ args)
1899 fun do_bound_type ctxt mono type_enc =
1901 Native (_, _, level) =>
1902 fused_type ctxt mono level 0 #> ho_type_from_typ type_enc false 0 #> SOME
1905 fun tag_with_type ctxt mono type_enc pos T tm =
1906 IConst (type_tag, T --> T, [T])
1907 |> mangle_type_args_in_iterm type_enc
1908 |> ho_term_from_iterm ctxt mono type_enc pos
1909 |> (fn ATerm (s, tms) => ATerm (s, tms @ [tm])
1910 | _ => raise Fail "unexpected lambda-abstraction")
1911 and ho_term_from_iterm ctxt mono type_enc pos =
1913 fun beta_red bs (IApp (IAbs ((name, _), tm), tm')) =
1914 beta_red ((name, beta_red bs tm') :: bs) tm
1915 | beta_red bs (IApp tmp) = IApp (pairself (beta_red bs) tmp)
1916 | beta_red bs (tm as IConst (name, _, _)) =
1917 (case AList.lookup (op =) bs name of
1920 | beta_red bs (IAbs ((name, T), tm)) =
1921 IAbs ((name, T), beta_red (AList.delete (op =) name bs) tm)
1922 | beta_red _ tm = tm
1925 val (head, args) = strip_iterm_comb u
1928 Top_Level pos => pos
1933 IConst (name as (s, _), _, T_args) =>
1935 val arg_site = if is_tptp_equal s then Eq_Arg pos else Elsewhere
1936 in map (term arg_site) args |> mk_aterm type_enc name T_args end
1938 map (term Elsewhere) args |> mk_aterm type_enc name []
1939 | IAbs ((name, T), tm) =>
1940 if is_type_enc_higher_order type_enc then
1941 AAbs ((name, ho_type_from_typ type_enc true 0 T),
1944 raise Fail "unexpected lambda-abstraction"
1945 | IApp _ => raise Fail "impossible \"IApp\""
1948 if should_tag_with_type ctxt mono type_enc site u T then
1949 tag_with_type ctxt mono type_enc pos T t
1953 in term (Top_Level pos) o beta_red [] end
1954 and formula_from_iformula ctxt polym_constrs mono type_enc should_guard_var =
1956 val thy = Proof_Context.theory_of ctxt
1957 val level = level_of_type_enc type_enc
1958 val do_term = ho_term_from_iterm ctxt mono type_enc
1959 fun do_out_of_bound_type pos phi universal (name, T) =
1960 if should_guard_type ctxt mono type_enc
1961 (fn () => should_guard_var thy polym_constrs level pos phi
1962 universal name) T then
1964 |> type_guard_iterm type_enc T
1965 |> do_term pos |> AAtom |> SOME
1966 else if should_generate_tag_bound_decl ctxt mono type_enc universal T then
1968 val var = ATerm (name, [])
1969 val tagged_var = tag_with_type ctxt mono type_enc pos T var
1970 in SOME (AAtom (ATerm (`I tptp_equal, [tagged_var, var]))) end
1973 fun do_formula pos (AQuant (q, xs, phi)) =
1975 val phi = phi |> do_formula pos
1976 val universal = Option.map (q = AExists ? not) pos
1977 val do_bound_type = do_bound_type ctxt mono type_enc
1979 AQuant (q, xs |> map (apsnd (fn NONE => NONE
1980 | SOME T => do_bound_type T)),
1981 (if q = AForall then mk_ahorn else fold_rev (mk_aconn AAnd))
1983 (fn (_, NONE) => NONE
1985 do_out_of_bound_type pos phi universal (s, T))
1989 | do_formula pos (AConn conn) = aconn_map pos do_formula conn
1990 | do_formula pos (AAtom tm) = AAtom (do_term pos tm)
1993 (* Each fact is given a unique fact number to avoid name clashes (e.g., because
1994 of monomorphization). The TPTP explicitly forbids name clashes, and some of
1995 the remote provers might care. *)
1996 fun formula_line_for_fact ctxt polym_constrs prefix encode freshen pos
1997 mono type_enc rank (j, {name, stature, kind, iformula, atomic_types}) =
1998 (prefix ^ (if freshen then string_of_int j ^ "_" else "") ^ encode name, kind,
2000 |> formula_from_iformula ctxt polym_constrs mono type_enc
2001 should_guard_var_in_formula (if pos then SOME true else NONE)
2002 |> close_formula_universally
2003 |> bound_tvars type_enc true atomic_types,
2005 let val rank = rank j in
2007 Intro => isabelle_info introN rank
2008 | Inductive => isabelle_info inductiveN rank
2009 | Elim => isabelle_info elimN rank
2010 | Simp => isabelle_info simpN rank
2011 | Def => isabelle_info defN rank
2012 | _ => isabelle_info "" rank
2016 fun formula_line_for_class_rel_clause type_enc
2017 ({name, subclass, superclass, ...} : class_rel_clause) =
2018 let val ty_arg = ATerm (tvar_a_name, []) in
2019 Formula (class_rel_clause_prefix ^ ascii_of name, Axiom,
2021 [type_class_formula type_enc subclass ty_arg,
2022 type_class_formula type_enc superclass ty_arg])
2023 |> mk_aquant AForall
2024 [(tvar_a_name, atype_of_type_vars type_enc)],
2025 NONE, isabelle_info inductiveN helper_rank)
2028 fun formula_from_arity_atom type_enc (class, t, args) =
2029 ATerm (t, map (fn arg => ATerm (arg, [])) args)
2030 |> type_class_formula type_enc class
2032 fun formula_line_for_arity_clause type_enc
2033 ({name, prem_atoms, concl_atom} : arity_clause) =
2034 Formula (arity_clause_prefix ^ name, Axiom,
2035 mk_ahorn (map (formula_from_arity_atom type_enc) prem_atoms)
2036 (formula_from_arity_atom type_enc concl_atom)
2037 |> mk_aquant AForall
2038 (map (rpair (atype_of_type_vars type_enc)) (#3 concl_atom)),
2039 NONE, isabelle_info inductiveN helper_rank)
2041 fun formula_line_for_conjecture ctxt polym_constrs mono type_enc
2042 ({name, kind, iformula, atomic_types, ...} : translated_formula) =
2043 Formula (conjecture_prefix ^ name, kind,
2045 |> formula_from_iformula ctxt polym_constrs mono type_enc
2046 should_guard_var_in_formula (SOME false)
2047 |> close_formula_universally
2048 |> bound_tvars type_enc true atomic_types, NONE, [])
2050 fun type_enc_needs_free_types (Native (_, Polymorphic, _)) = true
2051 | type_enc_needs_free_types (Native _) = false
2052 | type_enc_needs_free_types _ = true
2054 fun formula_line_for_free_type j phi =
2055 Formula (tfree_clause_prefix ^ string_of_int j, Hypothesis, phi, NONE, [])
2056 fun formula_lines_for_free_types type_enc (facts : translated_formula list) =
2057 if type_enc_needs_free_types type_enc then
2060 fold (union (op =)) (map #atomic_types facts) []
2061 |> formulas_for_types type_enc add_sorts_on_tfree
2062 in map2 formula_line_for_free_type (0 upto length phis - 1) phis end
2066 (** Symbol declarations **)
2068 fun decl_line_for_class order s =
2069 let val name as (s, _) = `make_type_class s in
2070 Decl (sym_decl_prefix ^ s, name,
2071 if order = First_Order then
2072 ATyAbs ([tvar_a_name],
2073 if avoid_first_order_ghost_type_vars then
2074 AFun (a_itself_atype, bool_atype)
2078 AFun (atype_of_types, bool_atype))
2081 fun decl_lines_for_classes type_enc classes =
2083 Native (order, Polymorphic, _) => map (decl_line_for_class order) classes
2086 fun sym_decl_table_for_facts thy type_enc sym_tab (conjs, facts, extra_tms) =
2088 fun add_iterm_syms tm =
2089 let val (head, args) = strip_iterm_comb tm in
2091 IConst ((s, s'), T, T_args) =>
2093 val (pred_sym, in_conj) =
2094 case Symtab.lookup sym_tab s of
2095 SOME ({pred_sym, in_conj, ...} : sym_info) =>
2097 | NONE => (false, false)
2100 Guards _ => not pred_sym
2101 | _ => true) andalso
2102 is_tptp_user_symbol s
2105 Symtab.map_default (s, [])
2106 (insert_type thy #3 (s', T_args, T, pred_sym, length args,
2111 | IAbs (_, tm) => add_iterm_syms tm
2113 #> fold add_iterm_syms args
2115 val add_fact_syms = K add_iterm_syms |> formula_fold NONE |> fact_lift
2116 fun add_formula_var_types (AQuant (_, xs, phi)) =
2117 fold (fn (_, SOME T) => insert_type thy I T | _ => I) xs
2118 #> add_formula_var_types phi
2119 | add_formula_var_types (AConn (_, phis)) =
2120 fold add_formula_var_types phis
2121 | add_formula_var_types _ = I
2123 if polymorphism_of_type_enc type_enc = Polymorphic then [tvar_a]
2124 else fold (fact_lift add_formula_var_types) (conjs @ facts) []
2125 fun add_undefined_const T =
2128 `(make_fixed_const NONE) @{const_name undefined}
2129 |> (case type_arg_policy [] type_enc @{const_name undefined} of
2130 Mangled_Type_Args => mangled_const_name type_enc [T]
2133 Symtab.map_default (s, [])
2134 (insert_type thy #3 (s', [T], T, false, 0, false))
2136 fun add_TYPE_const () =
2137 let val (s, s') = TYPE_name in
2138 Symtab.map_default (s, [])
2140 (s', [tvar_a], @{typ "'a itself"}, false, 0, false))
2144 |> is_type_enc_fairly_sound type_enc
2145 ? (fold (fold add_fact_syms) [conjs, facts]
2146 #> fold add_iterm_syms extra_tms
2147 #> (case type_enc of
2148 Native (First_Order, Polymorphic, _) =>
2149 if avoid_first_order_ghost_type_vars then add_TYPE_const ()
2152 | _ => fold add_undefined_const (var_types ())))
2155 (* We add "bool" in case the helper "True_or_False" is included later. *)
2156 fun default_mono level =
2157 {maybe_finite_Ts = [@{typ bool}],
2158 surely_finite_Ts = [@{typ bool}],
2159 maybe_infinite_Ts = known_infinite_types,
2160 surely_infinite_Ts =
2162 Noninf_Nonmono_Types (Strict, _) => []
2163 | _ => known_infinite_types,
2164 maybe_nonmono_Ts = [@{typ bool}]}
2166 (* This inference is described in section 2.3 of Claessen et al.'s "Sorting it
2167 out with monotonicity" paper presented at CADE 2011. *)
2168 fun add_iterm_mononotonicity_info _ _ (SOME false) _ mono = mono
2169 | add_iterm_mononotonicity_info ctxt level _
2170 (IApp (IApp (IConst ((s, _), Type (_, [T, _]), _), tm1), tm2))
2171 (mono as {maybe_finite_Ts, surely_finite_Ts, maybe_infinite_Ts,
2172 surely_infinite_Ts, maybe_nonmono_Ts}) =
2173 let val thy = Proof_Context.theory_of ctxt in
2174 if is_tptp_equal s andalso exists is_maybe_universal_var [tm1, tm2] then
2176 Noninf_Nonmono_Types (strictness, _) =>
2177 if exists (type_instance thy T) surely_infinite_Ts orelse
2178 member (type_equiv thy) maybe_finite_Ts T then
2180 else if is_type_kind_of_surely_infinite ctxt strictness
2181 surely_infinite_Ts T then
2182 {maybe_finite_Ts = maybe_finite_Ts,
2183 surely_finite_Ts = surely_finite_Ts,
2184 maybe_infinite_Ts = maybe_infinite_Ts,
2185 surely_infinite_Ts = surely_infinite_Ts |> insert_type thy I T,
2186 maybe_nonmono_Ts = maybe_nonmono_Ts}
2188 {maybe_finite_Ts = maybe_finite_Ts |> insert (type_equiv thy) T,
2189 surely_finite_Ts = surely_finite_Ts,
2190 maybe_infinite_Ts = maybe_infinite_Ts,
2191 surely_infinite_Ts = surely_infinite_Ts,
2192 maybe_nonmono_Ts = maybe_nonmono_Ts |> insert_type thy I T}
2193 | Fin_Nonmono_Types _ =>
2194 if exists (type_instance thy T) surely_finite_Ts orelse
2195 member (type_equiv thy) maybe_infinite_Ts T then
2197 else if is_type_surely_finite ctxt T then
2198 {maybe_finite_Ts = maybe_finite_Ts,
2199 surely_finite_Ts = surely_finite_Ts |> insert_type thy I T,
2200 maybe_infinite_Ts = maybe_infinite_Ts,
2201 surely_infinite_Ts = surely_infinite_Ts,
2202 maybe_nonmono_Ts = maybe_nonmono_Ts |> insert_type thy I T}
2204 {maybe_finite_Ts = maybe_finite_Ts,
2205 surely_finite_Ts = surely_finite_Ts,
2206 maybe_infinite_Ts = maybe_infinite_Ts |> insert (type_equiv thy) T,
2207 surely_infinite_Ts = surely_infinite_Ts,
2208 maybe_nonmono_Ts = maybe_nonmono_Ts}
2213 | add_iterm_mononotonicity_info _ _ _ _ mono = mono
2214 fun add_fact_mononotonicity_info ctxt level
2215 ({kind, iformula, ...} : translated_formula) =
2216 formula_fold (SOME (kind <> Conjecture))
2217 (add_iterm_mononotonicity_info ctxt level) iformula
2218 fun mononotonicity_info_for_facts ctxt type_enc facts =
2219 let val level = level_of_type_enc type_enc in
2221 |> is_type_level_monotonicity_based level
2222 ? fold (add_fact_mononotonicity_info ctxt level) facts
2225 fun add_iformula_monotonic_types ctxt mono type_enc =
2227 val thy = Proof_Context.theory_of ctxt
2228 val level = level_of_type_enc type_enc
2229 val should_encode = should_encode_type ctxt mono level
2230 fun add_type T = not (should_encode T) ? insert_type thy I T
2231 fun add_args (IApp (tm1, tm2)) = add_args tm1 #> add_term tm2
2233 and add_term tm = add_type (ityp_of tm) #> add_args tm
2234 in formula_fold NONE (K add_term) end
2235 fun add_fact_monotonic_types ctxt mono type_enc =
2236 add_iformula_monotonic_types ctxt mono type_enc |> fact_lift
2237 fun monotonic_types_for_facts ctxt mono type_enc facts =
2238 let val level = level_of_type_enc type_enc in
2239 [] |> (polymorphism_of_type_enc type_enc = Polymorphic andalso
2240 is_type_level_monotonicity_based level andalso
2241 granularity_of_type_level level <> Ghost_Type_Arg_Vars)
2242 ? fold (add_fact_monotonic_types ctxt mono type_enc) facts
2245 fun formula_line_for_guards_mono_type ctxt mono type_enc T =
2246 Formula (guards_sym_formula_prefix ^
2247 ascii_of (mangled_type type_enc T),
2249 IConst (`make_bound_var "X", T, [])
2250 |> type_guard_iterm type_enc T
2252 |> formula_from_iformula ctxt [] mono type_enc
2253 always_guard_var_in_formula (SOME true)
2254 |> close_formula_universally
2255 |> bound_tvars type_enc true (atomic_types_of T),
2256 NONE, isabelle_info inductiveN helper_rank)
2258 fun formula_line_for_tags_mono_type ctxt mono type_enc T =
2259 let val x_var = ATerm (`make_bound_var "X", []) in
2260 Formula (tags_sym_formula_prefix ^
2261 ascii_of (mangled_type type_enc T),
2263 eq_formula type_enc (atomic_types_of T) [] false
2264 (tag_with_type ctxt mono type_enc NONE T x_var) x_var,
2265 NONE, isabelle_info defN helper_rank)
2268 fun problem_lines_for_mono_types ctxt mono type_enc Ts =
2271 | Guards _ => map (formula_line_for_guards_mono_type ctxt mono type_enc) Ts
2272 | Tags _ => map (formula_line_for_tags_mono_type ctxt mono type_enc) Ts
2274 fun decl_line_for_sym ctxt mono type_enc s
2275 (s', T_args, T, pred_sym, ary, _) =
2277 val thy = Proof_Context.theory_of ctxt
2281 else case unprefix_and_unascii const_prefix s of
2284 val s' = s' |> invert_const
2285 val T = s' |> robust_const_type thy
2286 in (T, robust_const_typargs thy (s', T)) end
2287 | NONE => raise Fail "unexpected type arguments"
2289 Decl (sym_decl_prefix ^ s, (s, s'),
2290 T |> fused_type ctxt mono (level_of_type_enc type_enc) ary
2291 |> ho_type_from_typ type_enc pred_sym ary
2292 |> not (null T_args)
2293 ? curry ATyAbs (map (tvar_name o fst o dest_TVar) T_args))
2296 fun honor_conj_sym_kind in_conj conj_sym_kind =
2297 if in_conj then (conj_sym_kind, conj_sym_kind = Conjecture ? mk_anot)
2300 fun formula_line_for_guards_sym_decl ctxt conj_sym_kind mono type_enc n s j
2301 (s', T_args, T, _, ary, in_conj) =
2303 val thy = Proof_Context.theory_of ctxt
2304 val (kind, maybe_negate) = honor_conj_sym_kind in_conj conj_sym_kind
2305 val (arg_Ts, res_T) = chop_fun ary T
2306 val bound_names = 1 upto ary |> map (`I o make_bound_var o string_of_int)
2308 bound_names ~~ arg_Ts |> map (fn (name, T) => IConst (name, T, []))
2310 if exists (curry (op =) dummyT) T_args then
2311 case level_of_type_enc type_enc of
2312 All_Types => map SOME arg_Ts
2314 if granularity_of_type_level level = Ghost_Type_Arg_Vars then
2315 let val ghosts = ghost_type_args thy s ary in
2316 map2 (fn j => if member (op =) ghosts j then SOME else K NONE)
2317 (0 upto ary - 1) arg_Ts
2324 Formula (guards_sym_formula_prefix ^ s ^
2325 (if n > 1 then "_" ^ string_of_int j else ""), kind,
2326 IConst ((s, s'), T, T_args)
2327 |> fold (curry (IApp o swap)) bounds
2328 |> type_guard_iterm type_enc res_T
2329 |> AAtom |> mk_aquant AForall (bound_names ~~ bound_Ts)
2330 |> formula_from_iformula ctxt [] mono type_enc
2331 always_guard_var_in_formula (SOME true)
2332 |> close_formula_universally
2333 |> bound_tvars type_enc (n > 1) (atomic_types_of T)
2335 NONE, isabelle_info inductiveN helper_rank)
2338 fun formula_lines_for_tags_sym_decl ctxt conj_sym_kind mono type_enc n s
2339 (j, (s', T_args, T, pred_sym, ary, in_conj)) =
2341 val thy = Proof_Context.theory_of ctxt
2342 val level = level_of_type_enc type_enc
2343 val grain = granularity_of_type_level level
2345 tags_sym_formula_prefix ^ s ^
2346 (if n > 1 then "_" ^ string_of_int j else "")
2347 val (kind, maybe_negate) = honor_conj_sym_kind in_conj conj_sym_kind
2348 val (arg_Ts, res_T) = chop_fun ary T
2349 val bound_names = 1 upto ary |> map (`I o make_bound_var o string_of_int)
2350 val bounds = bound_names |> map (fn name => ATerm (name, []))
2351 val cst = mk_aterm type_enc (s, s') T_args
2352 val eq = maybe_negate oo eq_formula type_enc (atomic_types_of T) [] pred_sym
2353 val should_encode = should_encode_type ctxt mono level
2354 val tag_with = tag_with_type ctxt mono type_enc NONE
2355 val add_formula_for_res =
2356 if should_encode res_T then
2359 if grain = Ghost_Type_Arg_Vars then
2360 let val ghosts = ghost_type_args thy s ary in
2361 map2 (fn (j, arg_T) => member (op =) ghosts j ? tag_with arg_T)
2362 (0 upto ary - 1 ~~ arg_Ts) bounds
2367 cons (Formula (ident_base ^ "_res", kind,
2368 eq (tag_with res_T (cst bounds)) (cst tagged_bounds),
2369 NONE, isabelle_info defN helper_rank))
2373 in [] |> not pred_sym ? add_formula_for_res end
2375 fun result_type_of_decl (_, _, T, _, ary, _) = chop_fun ary T |> snd
2377 fun rationalize_decls thy (decls as decl :: (decls' as _ :: _)) =
2379 val T = result_type_of_decl decl
2380 |> map_type_tvar (fn (z, _) => TVar (z, HOLogic.typeS))
2382 if forall (type_generalization thy T o result_type_of_decl) decls' then
2387 | rationalize_decls _ decls = decls
2389 fun problem_lines_for_sym_decls ctxt conj_sym_kind mono type_enc (s, decls) =
2391 Native _ => [decl_line_for_sym ctxt mono type_enc s (hd decls)]
2392 | Guards (_, level) =>
2394 val thy = Proof_Context.theory_of ctxt
2395 val decls = decls |> rationalize_decls thy
2396 val n = length decls
2398 decls |> filter (should_encode_type ctxt mono level
2399 o result_type_of_decl)
2401 (0 upto length decls - 1, decls)
2402 |-> map2 (formula_line_for_guards_sym_decl ctxt conj_sym_kind mono
2405 | Tags (_, level) =>
2406 if granularity_of_type_level level = All_Vars then
2409 let val n = length decls in
2410 (0 upto n - 1 ~~ decls)
2411 |> maps (formula_lines_for_tags_sym_decl ctxt conj_sym_kind mono
2415 fun problem_lines_for_sym_decl_table ctxt conj_sym_kind mono type_enc mono_Ts
2418 val syms = sym_decl_tab |> Symtab.dest |> sort_wrt fst
2419 val mono_lines = problem_lines_for_mono_types ctxt mono type_enc mono_Ts
2421 fold_rev (append o problem_lines_for_sym_decls ctxt conj_sym_kind mono
2424 in mono_lines @ decl_lines end
2426 fun pair_append (xs1, xs2) (ys1, ys2) = (xs1 @ ys1, xs2 @ ys2)
2428 fun do_uncurried_alias_lines_for_sym ctxt monom_constrs conj_sym_kind mono
2429 type_enc sym_tab0 sym_tab base_s0 types in_conj =
2433 val thy = Proof_Context.theory_of ctxt
2434 val (kind, maybe_negate) = honor_conj_sym_kind in_conj conj_sym_kind
2435 val base_name = base_s0 |> `(make_fixed_const (SOME type_enc))
2436 val T = case types of [T] => T | _ => robust_const_type thy base_s0
2437 val T_args = robust_const_typargs thy (base_s0, T)
2438 val (base_name as (base_s, _), T_args) =
2439 mangle_type_args_in_const type_enc base_name T_args
2440 val base_ary = min_ary_of sym_tab0 base_s
2441 fun do_const name = IConst (name, T, T_args)
2442 val filter_ty_args =
2443 filter_type_args_in_iterm thy monom_constrs type_enc
2444 val ho_term_of = ho_term_from_iterm ctxt mono type_enc (SOME true)
2445 val name1 as (s1, _) =
2446 base_name |> ary - 1 > base_ary ? aliased_uncurried (ary - 1)
2447 val name2 as (s2, _) = base_name |> aliased_uncurried ary
2448 val (arg_Ts, _) = chop_fun ary T
2450 1 upto ary |> map (`I o make_bound_var o string_of_int)
2451 val bounds = bound_names ~~ arg_Ts
2452 val (first_bounds, last_bound) =
2453 bounds |> map (fn (name, T) => IConst (name, T, [])) |> split_last
2455 mk_app_op type_enc (list_app (do_const name1) first_bounds) last_bound
2458 list_app (do_const name2) (first_bounds @ [last_bound])
2460 val do_bound_type = do_bound_type ctxt mono type_enc
2462 eq_formula type_enc (atomic_types_of T)
2463 (map (apsnd do_bound_type) bounds) false
2464 (ho_term_of tm1) (ho_term_of tm2)
2467 [Formula (uncurried_alias_eq_prefix ^ s2, kind, eq |> maybe_negate,
2468 NONE, isabelle_info defN helper_rank)])
2469 |> (if ary - 1 = base_ary orelse Symtab.defined sym_tab s1 then I
2470 else pair_append (do_alias (ary - 1)))
2473 fun uncurried_alias_lines_for_sym ctxt monom_constrs conj_sym_kind mono type_enc
2474 sym_tab0 sym_tab (s, {min_ary, types, in_conj, ...} : sym_info) =
2475 case unprefix_and_unascii const_prefix s of
2477 if String.isSubstring uncurried_alias_sep mangled_s then
2479 val base_s0 = mangled_s |> unmangled_const_name |> hd |> invert_const
2481 do_uncurried_alias_lines_for_sym ctxt monom_constrs conj_sym_kind mono
2482 type_enc sym_tab0 sym_tab base_s0 types in_conj min_ary
2487 fun uncurried_alias_lines_for_sym_table ctxt monom_constrs conj_sym_kind mono
2488 type_enc uncurried_aliases sym_tab0 sym_tab =
2490 |> uncurried_aliases
2493 o uncurried_alias_lines_for_sym ctxt monom_constrs conj_sym_kind
2494 mono type_enc sym_tab0 sym_tab) sym_tab
2496 val implicit_declsN = "Should-be-implicit typings"
2497 val explicit_declsN = "Explicit typings"
2498 val uncurried_alias_eqsN = "Uncurried aliases"
2499 val factsN = "Relevant facts"
2500 val class_relsN = "Class relationships"
2501 val aritiesN = "Arities"
2502 val helpersN = "Helper facts"
2503 val conjsN = "Conjectures"
2504 val free_typesN = "Type variables"
2506 (* TFF allows implicit declarations of types, function symbols, and predicate
2507 symbols (with "$i" as the type of individuals), but some provers (e.g.,
2508 SNARK) require explicit declarations. The situation is similar for THF. *)
2510 fun default_type type_enc pred_sym s =
2515 if String.isPrefix type_const_prefix s orelse
2516 String.isPrefix tfree_prefix s then
2520 | _ => individual_atype
2521 fun typ 0 = if pred_sym then bool_atype else ind
2522 | typ ary = AFun (ind, typ (ary - 1))
2525 fun nary_type_constr_type n =
2526 funpow n (curry AFun atype_of_types) atype_of_types
2528 fun undeclared_syms_in_problem type_enc problem =
2530 fun do_sym (name as (s, _)) ty =
2531 if is_tptp_user_symbol s then
2532 Symtab.default (s, (name, ty))
2535 fun do_type (AType (name, tys)) =
2536 do_sym name (fn () => nary_type_constr_type (length tys))
2538 | do_type (AFun (ty1, ty2)) = do_type ty1 #> do_type ty2
2539 | do_type (ATyAbs (_, ty)) = do_type ty
2540 fun do_term pred_sym (ATerm (name as (s, _), tms)) =
2541 do_sym name (fn _ => default_type type_enc pred_sym s (length tms))
2542 #> fold (do_term false) tms
2543 | do_term _ (AAbs ((_, ty), tm)) = do_type ty #> do_term false tm
2544 fun do_formula (AQuant (_, xs, phi)) =
2545 fold do_type (map_filter snd xs) #> do_formula phi
2546 | do_formula (AConn (_, phis)) = fold do_formula phis
2547 | do_formula (AAtom tm) = do_term true tm
2548 fun do_problem_line (Decl (_, _, ty)) = do_type ty
2549 | do_problem_line (Formula (_, _, phi, _, _)) = do_formula phi
2552 |> fold (fn (s, _) => Symtab.default (s, (("", ""), K tvar_a_atype)))
2553 (declared_syms_in_problem problem)
2554 |> fold (fold do_problem_line o snd) problem
2557 fun declare_undeclared_syms_in_atp_problem type_enc problem =
2560 Symtab.fold (fn (_, (("", ""), _)) => I (* already declared *)
2562 cons (Decl (type_decl_prefix ^ s, sym, ty ())))
2563 (undeclared_syms_in_problem type_enc problem) []
2564 in (implicit_declsN, decls) :: problem end
2566 fun exists_subdtype P =
2568 fun ex U = P U orelse
2569 (case U of Datatype.DtType (_, Us) => exists ex Us | _ => false)
2572 fun is_poly_constr (_, Us) =
2573 exists (exists_subdtype (fn Datatype.DtTFree _ => true | _ => false)) Us
2575 fun all_constrs_of_polymorphic_datatypes thy =
2579 #> (fn cs => exists is_poly_constr cs ? append cs))
2580 (Datatype.get_all thy) []
2581 |> List.partition is_poly_constr
2582 |> pairself (map fst)
2584 val app_op_and_predicator_threshold = 50
2586 fun prepare_atp_problem ctxt format conj_sym_kind prem_kind type_enc exporter
2587 lam_trans uncurried_aliases readable_names preproc
2588 hyp_ts concl_t facts =
2590 val thy = Proof_Context.theory_of ctxt
2591 val type_enc = type_enc |> adjust_type_enc format
2592 (* Forcing explicit applications is expensive for polymorphic encodings,
2593 because it takes only one existential variable ranging over "'a => 'b" to
2594 ruin everything. Hence we do it only if there are few facts (which is
2595 normally the case for "metis" and the minimizer). *)
2597 if length facts > app_op_and_predicator_threshold then
2598 if polymorphism_of_type_enc type_enc = Polymorphic then
2603 Sufficient_App_Op_And_Predicator
2605 if lam_trans = keep_lamsN andalso
2606 not (is_type_enc_higher_order type_enc) then
2607 error ("Lambda translation scheme incompatible with first-order \
2611 val (fact_names, classes, conjs, facts, class_rel_clauses, arity_clauses,
2613 translate_formulas ctxt prem_kind format type_enc lam_trans preproc hyp_ts
2615 val sym_tab0 = sym_table_for_facts ctxt type_enc app_op_level conjs facts
2616 val mono = conjs @ facts |> mononotonicity_info_for_facts ctxt type_enc
2617 val (polym_constrs, monom_constrs) =
2618 all_constrs_of_polymorphic_datatypes thy
2619 |>> map (make_fixed_const (SOME type_enc))
2620 fun firstorderize in_helper =
2621 firstorderize_fact thy monom_constrs type_enc sym_tab0
2622 (uncurried_aliases andalso not in_helper)
2623 val (conjs, facts) = (conjs, facts) |> pairself (map (firstorderize false))
2624 val sym_tab = sym_table_for_facts ctxt type_enc Min_App_Op conjs facts
2626 sym_tab |> helper_facts_for_sym_table ctxt format type_enc
2627 |> map (firstorderize true)
2629 helpers @ conjs @ facts |> monotonic_types_for_facts ctxt mono type_enc
2630 val class_decl_lines = decl_lines_for_classes type_enc classes
2631 val (uncurried_alias_eq_tms, uncurried_alias_eq_lines) =
2632 uncurried_alias_lines_for_sym_table ctxt monom_constrs conj_sym_kind mono
2633 type_enc uncurried_aliases sym_tab0 sym_tab
2634 val sym_decl_lines =
2635 (conjs, helpers @ facts, uncurried_alias_eq_tms)
2636 |> sym_decl_table_for_facts thy type_enc sym_tab
2637 |> problem_lines_for_sym_decl_table ctxt conj_sym_kind mono type_enc
2639 val num_facts = length facts
2641 map (formula_line_for_fact ctxt polym_constrs fact_prefix
2642 ascii_of (not exporter) (not exporter) mono type_enc
2643 (rank_of_fact_num num_facts))
2644 (0 upto num_facts - 1 ~~ facts)
2646 0 upto length helpers - 1 ~~ helpers
2647 |> map (formula_line_for_fact ctxt polym_constrs helper_prefix I false
2648 true mono type_enc (K default_rank))
2649 (* Reordering these might confuse the proof reconstruction code or the SPASS
2652 [(explicit_declsN, class_decl_lines @ sym_decl_lines),
2653 (uncurried_alias_eqsN, uncurried_alias_eq_lines),
2654 (factsN, fact_lines),
2656 map (formula_line_for_class_rel_clause type_enc) class_rel_clauses),
2657 (aritiesN, map (formula_line_for_arity_clause type_enc) arity_clauses),
2658 (helpersN, helper_lines),
2659 (free_typesN, formula_lines_for_free_types type_enc (facts @ conjs)),
2661 map (formula_line_for_conjecture ctxt polym_constrs mono type_enc)
2666 CNF => ensure_cnf_problem
2667 | CNF_UEQ => filter_cnf_ueq_problem
2669 | TFF (_, TPTP_Implicit) => I
2670 | THF (_, TPTP_Implicit, _) => I
2671 | _ => declare_undeclared_syms_in_atp_problem type_enc)
2672 val (problem, pool) = problem |> nice_atp_problem readable_names format
2673 fun add_sym_ary (s, {min_ary, ...} : sym_info) =
2674 min_ary > 0 ? Symtab.insert (op =) (s, min_ary)
2677 case pool of SOME the_pool => snd the_pool | NONE => Symtab.empty,
2678 fact_names |> Vector.fromList,
2680 Symtab.empty |> Symtab.fold add_sym_ary sym_tab)
2684 val conj_weight = 0.0
2685 val hyp_weight = 0.1
2686 val fact_min_weight = 0.2
2687 val fact_max_weight = 1.0
2688 val type_info_default_weight = 0.8
2690 (* Weights are from 0.0 (most important) to 1.0 (least important). *)
2691 fun atp_problem_selection_weights problem =
2693 fun add_term_weights weight (ATerm (s, tms)) =
2694 is_tptp_user_symbol s ? Symtab.default (s, weight)
2695 #> fold (add_term_weights weight) tms
2696 | add_term_weights weight (AAbs (_, tm)) = add_term_weights weight tm
2697 fun add_line_weights weight (Formula (_, _, phi, _, _)) =
2698 formula_fold NONE (K (add_term_weights weight)) phi
2699 | add_line_weights _ _ = I
2700 fun add_conjectures_weights [] = I
2701 | add_conjectures_weights conjs =
2702 let val (hyps, conj) = split_last conjs in
2703 add_line_weights conj_weight conj
2704 #> fold (add_line_weights hyp_weight) hyps
2706 fun add_facts_weights facts =
2708 val num_facts = length facts
2710 fact_min_weight + (fact_max_weight - fact_min_weight) * Real.fromInt j
2711 / Real.fromInt num_facts
2713 map weight_of (0 upto num_facts - 1) ~~ facts
2714 |> fold (uncurry add_line_weights)
2716 val get = these o AList.lookup (op =) problem
2719 |> add_conjectures_weights (get free_typesN @ get conjsN)
2720 |> add_facts_weights (get factsN)
2721 |> fold (fold (add_line_weights type_info_default_weight) o get)
2722 [explicit_declsN, class_relsN, aritiesN]
2724 |> sort (prod_ord Real.compare string_ord o pairself swap)
2727 (* Ugly hack: may make innocent victims (collateral damage) *)
2728 fun may_be_app s args = String.isPrefix app_op_name s andalso length args = 2
2729 fun may_be_predicator s =
2730 member (op =) [predicator_name, prefixed_predicator_name] s
2732 fun strip_predicator (tm as ATerm (s, [tm'])) =
2733 if may_be_predicator s then tm' else tm
2734 | strip_predicator tm = tm
2736 fun make_head_roll (ATerm (s, tms)) =
2737 if may_be_app s tms then make_head_roll (hd tms) ||> append (tl tms)
2739 | make_head_roll _ = ("", [])
2741 fun strip_up_to_predicator (AQuant (_, _, phi)) = strip_up_to_predicator phi
2742 | strip_up_to_predicator (AConn (_, phis)) = maps strip_up_to_predicator phis
2743 | strip_up_to_predicator (AAtom tm) = [strip_predicator tm]
2745 fun strip_ahorn_etc (AQuant (_, _, phi)) = strip_ahorn_etc phi
2746 | strip_ahorn_etc (AConn (AImplies, [phi1, phi2])) =
2747 strip_ahorn_etc phi2 |>> append (strip_up_to_predicator phi1)
2748 | strip_ahorn_etc phi = ([], hd (strip_up_to_predicator phi))
2750 fun strip_iff_etc (AQuant (_, _, phi)) = strip_iff_etc phi
2751 | strip_iff_etc (AConn (AIff, [phi1, phi2])) =
2752 pairself strip_up_to_predicator (phi1, phi2)
2753 | strip_iff_etc _ = ([], [])
2755 val max_term_order_weight = 2147483647
2757 fun atp_problem_term_order_info problem =
2760 Graph.default_node (s, ())
2761 #> Graph.default_node (s', ())
2762 #> Graph.add_edge_acyclic (s, s')
2763 fun add_term_deps head (ATerm (s, args)) =
2764 if is_tptp_user_symbol head then
2765 (if is_tptp_user_symbol s then perhaps (try (add_edge s head)) else I)
2766 #> fold (add_term_deps head) args
2769 | add_term_deps head (AAbs (_, tm)) = add_term_deps head tm
2770 fun add_intro_deps pred (Formula (_, role, phi, _, info)) =
2771 if pred (role, info) then
2772 let val (hyps, concl) = strip_ahorn_etc phi in
2773 case make_head_roll concl of
2774 (head, args as _ :: _) => fold (add_term_deps head) (hyps @ args)
2779 | add_intro_deps _ _ = I
2780 fun add_atom_eq_deps (SOME true) (ATerm (s, [lhs as _, rhs])) =
2781 if is_tptp_equal s then
2782 case make_head_roll lhs of
2783 (head, args as _ :: _) => fold (add_term_deps head) (rhs :: args)
2787 | add_atom_eq_deps _ _ = I
2788 fun add_eq_deps pred (Formula (_, role, phi, _, info)) =
2789 if pred (role, info) then
2790 case strip_iff_etc phi of
2792 (case make_head_roll lhs of
2793 (head, args as _ :: _) => fold (add_term_deps head) (rhs @ args)
2795 | _ => formula_fold (SOME (role <> Conjecture)) add_atom_eq_deps phi
2798 | add_eq_deps _ _ = I
2799 fun has_status status (_, info) =
2800 extract_isabelle_status info = SOME status
2801 fun is_conj (role, _) = (role = Conjecture orelse role = Hypothesis)
2804 |> fold (fold (add_eq_deps (has_status defN)) o snd) problem
2805 |> fold (fold (add_eq_deps (has_status simpN orf is_conj)) o snd) problem
2806 |> fold (fold (add_intro_deps (has_status inductiveN)) o snd) problem
2807 |> fold (fold (add_intro_deps (has_status introN)) o snd) problem
2808 fun next_weight w = if w + w <= max_term_order_weight then w + w else w + 1
2809 fun add_weights _ [] = I
2810 | add_weights weight syms =
2811 fold (AList.update (op =) o rpair weight) syms
2812 #> add_weights (next_weight weight)
2813 (fold (union (op =) o Graph.immediate_succs graph) syms [])
2815 (* Sorting is not just for aesthetics: It specifies the precedence order
2816 for the term ordering (KBO or LPO), from smaller to larger values. *)
2817 [] |> add_weights 1 (Graph.minimals graph) |> sort (int_ord o pairself snd)