fix handling of atomizable conjectures without a top-level "Trueprop" (e.g. "x == (y::nat)")
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 val no_lamsN = "no_lams" (* used internally; undocumented *)
121 val hide_lamsN = "hide_lams"
122 val liftingN = "lifting"
124 val combs_and_liftingN = "combs_and_lifting"
125 val combs_or_liftingN = "combs_or_lifting"
126 val keep_lamsN = "keep_lams"
127 val lam_liftingN = "lam_lifting" (* legacy *)
129 (* It's still unclear whether all TFF1 implementations will support type
130 signatures such as "!>[A : $tType] : $o", with ghost type variables. *)
131 val avoid_first_order_ghost_type_vars = false
133 val bound_var_prefix = "B_"
134 val all_bound_var_prefix = "A_"
135 val exist_bound_var_prefix = "E_"
136 val schematic_var_prefix = "V_"
137 val fixed_var_prefix = "v_"
138 val tvar_prefix = "T_"
139 val tfree_prefix = "t_"
140 val const_prefix = "c_"
141 val type_const_prefix = "tc_"
142 val native_type_prefix = "n_"
143 val class_prefix = "cl_"
145 (* Freshness almost guaranteed! *)
146 val atp_prefix = "ATP" ^ Long_Name.separator
147 val atp_weak_prefix = "ATP:"
149 val lam_lifted_prefix = atp_weak_prefix ^ "Lam"
150 val lam_lifted_mono_prefix = lam_lifted_prefix ^ "m"
151 val lam_lifted_poly_prefix = lam_lifted_prefix ^ "p"
153 val skolem_const_prefix = atp_prefix ^ "Sko"
154 val old_skolem_const_prefix = skolem_const_prefix ^ "o"
155 val new_skolem_const_prefix = skolem_const_prefix ^ "n"
157 val combinator_prefix = "COMB"
159 val type_decl_prefix = "ty_"
160 val sym_decl_prefix = "sy_"
161 val guards_sym_formula_prefix = "gsy_"
162 val tags_sym_formula_prefix = "tsy_"
163 val uncurried_alias_eq_prefix = "unc_"
164 val fact_prefix = "fact_"
165 val conjecture_prefix = "conj_"
166 val helper_prefix = "help_"
167 val class_rel_clause_prefix = "clar_"
168 val arity_clause_prefix = "arity_"
169 val tfree_clause_prefix = "tfree_"
171 val lam_fact_prefix = "ATP.lambda_"
172 val typed_helper_suffix = "_T"
173 val untyped_helper_suffix = "_U"
175 val predicator_name = "pp"
176 val app_op_name = "aa"
177 val type_guard_name = "gg"
178 val type_tag_name = "tt"
180 val prefixed_predicator_name = const_prefix ^ predicator_name
181 val prefixed_app_op_name = const_prefix ^ app_op_name
182 val prefixed_type_tag_name = const_prefix ^ type_tag_name
184 (*Escaping of special characters.
185 Alphanumeric characters are left unchanged.
186 The character _ goes to __
187 Characters in the range ASCII space to / go to _A to _P, respectively.
188 Other characters go to _nnn where nnn is the decimal ASCII code.*)
189 val upper_a_minus_space = Char.ord #"A" - Char.ord #" "
191 fun stringN_of_int 0 _ = ""
192 | stringN_of_int k n =
193 stringN_of_int (k - 1) (n div 10) ^ string_of_int (n mod 10)
195 fun ascii_of_char c =
196 if Char.isAlphaNum c then
198 else if c = #"_" then
200 else if #" " <= c andalso c <= #"/" then
201 "_" ^ String.str (Char.chr (Char.ord c + upper_a_minus_space))
203 (* fixed width, in case more digits follow *)
204 "_" ^ stringN_of_int 3 (Char.ord c)
206 val ascii_of = String.translate ascii_of_char
208 (** Remove ASCII armoring from names in proof files **)
210 (* We don't raise error exceptions because this code can run inside a worker
211 thread. Also, the errors are impossible. *)
214 fun un rcs [] = String.implode(rev rcs)
215 | un rcs [#"_"] = un (#"_" :: rcs) [] (* ERROR *)
216 (* Three types of _ escapes: __, _A to _P, _nnn *)
217 | un rcs (#"_" :: #"_" :: cs) = un (#"_" :: rcs) cs
218 | un rcs (#"_" :: c :: cs) =
219 if #"A" <= c andalso c<= #"P" then
220 (* translation of #" " to #"/" *)
221 un (Char.chr (Char.ord c - upper_a_minus_space) :: rcs) cs
223 let val digits = List.take (c :: cs, 3) handle General.Subscript => [] in
224 case Int.fromString (String.implode digits) of
225 SOME n => un (Char.chr n :: rcs) (List.drop (cs, 2))
226 | NONE => un (c :: #"_" :: rcs) cs (* ERROR *)
228 | un rcs (c :: cs) = un (c :: rcs) cs
229 in un [] o String.explode end
231 (* If string s has the prefix s1, return the result of deleting it,
233 fun unprefix_and_unascii s1 s =
234 if String.isPrefix s1 s then
235 SOME (unascii_of (String.extract (s, size s1, NONE)))
240 [("c_False", (@{const_name False}, (@{thm fFalse_def},
241 ("fFalse", @{const_name ATP.fFalse})))),
242 ("c_True", (@{const_name True}, (@{thm fTrue_def},
243 ("fTrue", @{const_name ATP.fTrue})))),
244 ("c_Not", (@{const_name Not}, (@{thm fNot_def},
245 ("fNot", @{const_name ATP.fNot})))),
246 ("c_conj", (@{const_name conj}, (@{thm fconj_def},
247 ("fconj", @{const_name ATP.fconj})))),
248 ("c_disj", (@{const_name disj}, (@{thm fdisj_def},
249 ("fdisj", @{const_name ATP.fdisj})))),
250 ("c_implies", (@{const_name implies}, (@{thm fimplies_def},
251 ("fimplies", @{const_name ATP.fimplies})))),
252 ("equal", (@{const_name HOL.eq}, (@{thm fequal_def},
253 ("fequal", @{const_name ATP.fequal})))),
254 ("c_All", (@{const_name All}, (@{thm fAll_def},
255 ("fAll", @{const_name ATP.fAll})))),
256 ("c_Ex", (@{const_name Ex}, (@{thm fEx_def},
257 ("fEx", @{const_name ATP.fEx}))))]
259 val proxify_const = AList.lookup (op =) proxy_table #> Option.map (snd o snd)
261 (* Readable names for the more common symbolic functions. Do not mess with the
262 table unless you know what you are doing. *)
263 val const_trans_table =
264 [(@{type_name Product_Type.prod}, "prod"),
265 (@{type_name Sum_Type.sum}, "sum"),
266 (@{const_name False}, "False"),
267 (@{const_name True}, "True"),
268 (@{const_name Not}, "Not"),
269 (@{const_name conj}, "conj"),
270 (@{const_name disj}, "disj"),
271 (@{const_name implies}, "implies"),
272 (@{const_name HOL.eq}, "equal"),
273 (@{const_name All}, "All"),
274 (@{const_name Ex}, "Ex"),
275 (@{const_name If}, "If"),
276 (@{const_name Set.member}, "member"),
277 (@{const_name Meson.COMBI}, combinator_prefix ^ "I"),
278 (@{const_name Meson.COMBK}, combinator_prefix ^ "K"),
279 (@{const_name Meson.COMBB}, combinator_prefix ^ "B"),
280 (@{const_name Meson.COMBC}, combinator_prefix ^ "C"),
281 (@{const_name Meson.COMBS}, combinator_prefix ^ "S")]
283 |> fold (Symtab.update o swap o snd o snd o snd) proxy_table
285 (* Invert the table of translations between Isabelle and ATPs. *)
286 val const_trans_table_inv =
287 const_trans_table |> Symtab.dest |> map swap |> Symtab.make
288 val const_trans_table_unprox =
290 |> fold (fn (_, (isa, (_, (_, atp)))) => Symtab.update (atp, isa)) proxy_table
292 val invert_const = perhaps (Symtab.lookup const_trans_table_inv)
293 val unproxify_const = perhaps (Symtab.lookup const_trans_table_unprox)
296 case Symtab.lookup const_trans_table c of
300 fun ascii_of_indexname (v, 0) = ascii_of v
301 | ascii_of_indexname (v, i) = ascii_of v ^ "_" ^ string_of_int i
303 fun make_bound_var x = bound_var_prefix ^ ascii_of x
304 fun make_all_bound_var x = all_bound_var_prefix ^ ascii_of x
305 fun make_exist_bound_var x = exist_bound_var_prefix ^ ascii_of x
306 fun make_schematic_var v = schematic_var_prefix ^ ascii_of_indexname v
307 fun make_fixed_var x = fixed_var_prefix ^ ascii_of x
309 fun make_schematic_type_var (x, i) =
310 tvar_prefix ^ (ascii_of_indexname (unprefix "'" x, i))
311 fun make_fixed_type_var x = tfree_prefix ^ (ascii_of (unprefix "'" x))
313 (* "HOL.eq" and choice are mapped to the ATP's equivalents *)
315 val choice_const = (fst o dest_Const o HOLogic.choice_const) Term.dummyT
316 fun default c = const_prefix ^ lookup_const c
318 fun make_fixed_const _ @{const_name HOL.eq} = tptp_old_equal
319 | make_fixed_const (SOME (THF (_, _, THF_With_Choice))) c =
320 if c = choice_const then tptp_choice else default c
321 | make_fixed_const _ c = default c
324 fun make_fixed_type_const c = type_const_prefix ^ lookup_const c
326 fun make_type_class clas = class_prefix ^ ascii_of clas
328 fun new_skolem_var_name_from_const s =
329 let val ss = s |> space_explode Long_Name.separator in
330 nth ss (length ss - 2)
333 (* These are either simplified away by "Meson.presimplify" (most of the time) or
334 handled specially via "fFalse", "fTrue", ..., "fequal". *)
335 val atp_irrelevant_consts =
336 [@{const_name False}, @{const_name True}, @{const_name Not},
337 @{const_name conj}, @{const_name disj}, @{const_name implies},
338 @{const_name HOL.eq}, @{const_name If}, @{const_name Let}]
340 val atp_monomorph_bad_consts =
341 atp_irrelevant_consts @
342 (* These are ignored anyway by the relevance filter (unless they appear in
343 higher-order places) but not by the monomorphizer. *)
344 [@{const_name all}, @{const_name "==>"}, @{const_name "=="},
345 @{const_name Trueprop}, @{const_name All}, @{const_name Ex},
346 @{const_name Ex1}, @{const_name Ball}, @{const_name Bex}]
348 fun add_schematic_const (x as (_, T)) =
349 Monomorph.typ_has_tvars T ? Symtab.insert_list (op =) x
350 val add_schematic_consts_of =
351 Term.fold_aterms (fn Const (x as (s, _)) =>
352 not (member (op =) atp_monomorph_bad_consts s)
353 ? add_schematic_const x
355 fun atp_schematic_consts_of t = add_schematic_consts_of t Symtab.empty
357 (** Definitions and functions for FOL clauses and formulas for TPTP **)
359 (** Isabelle arities **)
361 type arity_atom = name * name * name list
363 val type_class = the_single @{sort type}
367 prem_atoms : arity_atom list,
368 concl_atom : arity_atom}
370 fun add_prem_atom tvar =
371 fold (fn s => s <> type_class ? cons (`make_type_class s, `I tvar, []))
373 (* Arity of type constructor "tcon :: (arg1, ..., argN) res" *)
374 fun make_axiom_arity_clause (tcons, name, (cls, args)) =
376 val tvars = map (prefix tvar_prefix o string_of_int) (1 upto length args)
377 val tvars_srts = ListPair.zip (tvars, args)
380 prem_atoms = [] |> fold (uncurry add_prem_atom) tvars_srts,
381 concl_atom = (`make_type_class cls, `make_fixed_type_const tcons,
385 fun arity_clause _ _ (_, []) = []
386 | arity_clause seen n (tcons, ("HOL.type", _) :: ars) = (* ignore *)
387 arity_clause seen n (tcons, ars)
388 | arity_clause seen n (tcons, (ar as (class, _)) :: ars) =
389 if member (op =) seen class then
390 (* multiple arities for the same (tycon, class) pair *)
391 make_axiom_arity_clause (tcons,
392 lookup_const tcons ^ "___" ^ ascii_of class ^ "_" ^ string_of_int n,
394 arity_clause seen (n + 1) (tcons, ars)
396 make_axiom_arity_clause (tcons, lookup_const tcons ^ "___" ^
397 ascii_of class, ar) ::
398 arity_clause (class :: seen) n (tcons, ars)
400 fun multi_arity_clause [] = []
401 | multi_arity_clause ((tcons, ars) :: tc_arlists) =
402 arity_clause [] 1 (tcons, ars) @ multi_arity_clause tc_arlists
404 (* Generate all pairs (tycon, class, sorts) such that tycon belongs to class in
405 theory thy provided its arguments have the corresponding sorts. *)
406 fun type_class_pairs thy tycons classes =
408 val alg = Sign.classes_of thy
409 fun domain_sorts tycon = Sorts.mg_domain alg tycon o single
410 fun add_class tycon class =
411 cons (class, domain_sorts tycon class)
412 handle Sorts.CLASS_ERROR _ => I
413 fun try_classes tycon = (tycon, fold (add_class tycon) classes [])
414 in map try_classes tycons end
416 (*Proving one (tycon, class) membership may require proving others, so iterate.*)
417 fun iter_type_class_pairs _ _ [] = ([], [])
418 | iter_type_class_pairs thy tycons classes =
420 fun maybe_insert_class s =
421 (s <> type_class andalso not (member (op =) classes s))
423 val cpairs = type_class_pairs thy tycons classes
425 [] |> fold (fold (fold (fold maybe_insert_class) o snd) o snd) cpairs
426 val (classes', cpairs') = iter_type_class_pairs thy tycons newclasses
427 in (classes' @ classes, union (op =) cpairs' cpairs) end
429 fun make_arity_clauses thy tycons =
430 iter_type_class_pairs thy tycons ##> multi_arity_clause
433 (** Isabelle class relations **)
435 type class_rel_clause =
440 (* Generate all pairs (sub, super) such that sub is a proper subclass of super
442 fun class_pairs _ [] _ = []
443 | class_pairs thy subs supers =
445 val class_less = Sorts.class_less (Sign.classes_of thy)
446 fun add_super sub super = class_less (sub, super) ? cons (sub, super)
447 fun add_supers sub = fold (add_super sub) supers
448 in fold add_supers subs [] end
450 fun make_class_rel_clause (sub, super) =
451 {name = sub ^ "_" ^ super, subclass = `make_type_class sub,
452 superclass = `make_type_class super}
454 fun make_class_rel_clauses thy subs supers =
455 map make_class_rel_clause (class_pairs thy subs supers)
457 (* intermediate terms *)
459 IConst of name * typ * typ list |
461 IApp of iterm * iterm |
462 IAbs of (name * typ) * iterm
464 fun ityp_of (IConst (_, T, _)) = T
465 | ityp_of (IVar (_, T)) = T
466 | ityp_of (IApp (t1, _)) = snd (dest_funT (ityp_of t1))
467 | ityp_of (IAbs ((_, T), tm)) = T --> ityp_of tm
469 (*gets the head of a combinator application, along with the list of arguments*)
470 fun strip_iterm_comb u =
472 fun stripc (IApp (t, u), ts) = stripc (t, u :: ts)
474 in stripc (u, []) end
476 fun atomic_types_of T = fold_atyps (insert (op =)) T []
478 val tvar_a_str = "'a"
479 val tvar_a = TVar ((tvar_a_str, 0), HOLogic.typeS)
480 val tvar_a_name = (make_schematic_type_var (tvar_a_str, 0), tvar_a_str)
481 val itself_name = `make_fixed_type_const @{type_name itself}
482 val TYPE_name = `(make_fixed_const NONE) @{const_name TYPE}
483 val tvar_a_atype = AType (tvar_a_name, [])
484 val a_itself_atype = AType (itself_name, [tvar_a_atype])
486 fun new_skolem_const_name s num_T_args =
487 [new_skolem_const_prefix, s, string_of_int num_T_args]
490 fun robust_const_type thy s =
491 if s = app_op_name then
492 Logic.varifyT_global @{typ "('a => 'b) => 'a => 'b"}
493 else if String.isPrefix lam_lifted_prefix s then
494 Logic.varifyT_global @{typ "'a => 'b"}
496 (* Old Skolems throw a "TYPE" exception here, which will be caught. *)
497 s |> Sign.the_const_type thy
499 val robust_const_ary =
501 fun ary (Type (@{type_name fun}, [_, T])) = 1 + ary T
503 in ary oo robust_const_type end
505 (* This function only makes sense if "T" is as general as possible. *)
506 fun robust_const_typargs thy (s, T) =
507 if s = app_op_name then
508 let val (T1, T2) = T |> domain_type |> dest_funT in [T1, T2] end
509 else if String.isPrefix old_skolem_const_prefix s then
510 [] |> Term.add_tvarsT T |> rev |> map TVar
511 else if String.isPrefix lam_lifted_prefix s then
512 if String.isPrefix lam_lifted_poly_prefix s then
513 let val (T1, T2) = T |> dest_funT in [T1, T2] end
517 (s, T) |> Sign.const_typargs thy
519 (* Converts an Isabelle/HOL term (with combinators) into an intermediate term.
520 Also accumulates sort infomation. *)
521 fun iterm_from_term thy format bs (P $ Q) =
523 val (P', P_atomics_Ts) = iterm_from_term thy format bs P
524 val (Q', Q_atomics_Ts) = iterm_from_term thy format bs Q
525 in (IApp (P', Q'), union (op =) P_atomics_Ts Q_atomics_Ts) end
526 | iterm_from_term thy format _ (Const (c, T)) =
527 (IConst (`(make_fixed_const (SOME format)) c, T,
528 robust_const_typargs thy (c, T)),
530 | iterm_from_term _ _ _ (Free (s, T)) =
531 (IConst (`make_fixed_var s, T, []), atomic_types_of T)
532 | iterm_from_term _ format _ (Var (v as (s, _), T)) =
533 (if String.isPrefix Meson_Clausify.new_skolem_var_prefix s then
535 val Ts = T |> strip_type |> swap |> op ::
536 val s' = new_skolem_const_name s (length Ts)
537 in IConst (`(make_fixed_const (SOME format)) s', T, Ts) end
539 IVar ((make_schematic_var v, s), T), atomic_types_of T)
540 | iterm_from_term _ _ bs (Bound j) =
541 nth bs j |> (fn (_, (name, T)) => (IConst (name, T, []), atomic_types_of T))
542 | iterm_from_term thy format bs (Abs (s, T, t)) =
544 fun vary s = s |> AList.defined (op =) bs s ? vary o Symbol.bump_string
546 val name = `make_bound_var s
547 val (tm, atomic_Ts) = iterm_from_term thy format ((s, (name, T)) :: bs) t
548 in (IAbs ((name, T), tm), union (op =) atomic_Ts (atomic_types_of T)) end
550 datatype scope = Global | Local | Assum | Chained
551 datatype status = General | Induction | Intro | Inductive | Elim | Simp | Def
552 type stature = scope * status
554 datatype order = First_Order | Higher_Order
555 datatype polymorphism = Polymorphic | Raw_Monomorphic | Mangled_Monomorphic
556 datatype strictness = Strict | Non_Strict
557 datatype granularity = All_Vars | Positively_Naked_Vars | Ghost_Type_Arg_Vars
558 datatype type_level =
560 Noninf_Nonmono_Types of strictness * granularity |
561 Fin_Nonmono_Types of granularity |
566 Simple_Types of order * polymorphism * type_level |
567 Guards of polymorphism * type_level |
568 Tags of polymorphism * type_level
570 fun is_type_enc_higher_order (Simple_Types (Higher_Order, _, _)) = true
571 | is_type_enc_higher_order _ = false
573 fun polymorphism_of_type_enc (Simple_Types (_, poly, _)) = poly
574 | polymorphism_of_type_enc (Guards (poly, _)) = poly
575 | polymorphism_of_type_enc (Tags (poly, _)) = poly
577 fun level_of_type_enc (Simple_Types (_, _, level)) = level
578 | level_of_type_enc (Guards (_, level)) = level
579 | level_of_type_enc (Tags (_, level)) = level
581 fun granularity_of_type_level (Noninf_Nonmono_Types (_, grain)) = grain
582 | granularity_of_type_level (Fin_Nonmono_Types grain) = grain
583 | granularity_of_type_level _ = All_Vars
585 fun is_type_level_quasi_sound All_Types = true
586 | is_type_level_quasi_sound (Noninf_Nonmono_Types _) = true
587 | is_type_level_quasi_sound _ = false
588 val is_type_enc_quasi_sound = is_type_level_quasi_sound o level_of_type_enc
590 fun is_type_level_fairly_sound (Fin_Nonmono_Types _) = true
591 | is_type_level_fairly_sound level = is_type_level_quasi_sound level
592 val is_type_enc_fairly_sound = is_type_level_fairly_sound o level_of_type_enc
594 fun is_type_level_monotonicity_based (Noninf_Nonmono_Types _) = true
595 | is_type_level_monotonicity_based (Fin_Nonmono_Types _) = true
596 | is_type_level_monotonicity_based _ = false
598 (* "_query", "_bang", and "_at" are for the ASCII-challenged Metis and
600 val queries = ["?", "_query"]
601 val bangs = ["!", "_bang"]
602 val ats = ["@", "_at"]
604 fun try_unsuffixes ss s =
605 fold (fn s' => fn NONE => try (unsuffix s') s | some => some) ss NONE
607 fun try_nonmono constr suffixes fallback s =
608 case try_unsuffixes suffixes s of
610 (case try_unsuffixes suffixes s of
611 SOME s => (constr Positively_Naked_Vars, s)
613 case try_unsuffixes ats s of
614 SOME s => (constr Ghost_Type_Arg_Vars, s)
615 | NONE => (constr All_Vars, s))
618 fun type_enc_from_string strictness s =
619 (case try (unprefix "poly_") s of
620 SOME s => (SOME Polymorphic, s)
622 case try (unprefix "raw_mono_") s of
623 SOME s => (SOME Raw_Monomorphic, s)
625 case try (unprefix "mono_") s of
626 SOME s => (SOME Mangled_Monomorphic, s)
629 |> try_nonmono Fin_Nonmono_Types bangs
630 |> try_nonmono (curry Noninf_Nonmono_Types strictness) queries)
631 |> (fn (poly, (level, core)) =>
632 case (core, (poly, level)) of
633 ("native", (SOME poly, _)) =>
634 (case (poly, level) of
635 (Polymorphic, All_Types) =>
636 Simple_Types (First_Order, Polymorphic, All_Types)
637 | (Mangled_Monomorphic, _) =>
638 if granularity_of_type_level level = All_Vars then
639 Simple_Types (First_Order, Mangled_Monomorphic, level)
642 | _ => raise Same.SAME)
643 | ("native_higher", (SOME poly, _)) =>
644 (case (poly, level) of
645 (Polymorphic, All_Types) =>
646 Simple_Types (Higher_Order, Polymorphic, All_Types)
647 | (_, Noninf_Nonmono_Types _) => raise Same.SAME
648 | (Mangled_Monomorphic, _) =>
649 if granularity_of_type_level level = All_Vars then
650 Simple_Types (Higher_Order, Mangled_Monomorphic, level)
653 | _ => raise Same.SAME)
654 | ("guards", (SOME poly, _)) =>
655 if poly = Mangled_Monomorphic andalso
656 granularity_of_type_level level = Ghost_Type_Arg_Vars then
660 | ("tags", (SOME poly, _)) =>
661 if granularity_of_type_level level = Ghost_Type_Arg_Vars then
665 | ("args", (SOME poly, All_Types (* naja *))) =>
666 Guards (poly, Const_Arg_Types)
667 | ("erased", (NONE, All_Types (* naja *))) =>
668 Guards (Polymorphic, No_Types)
669 | _ => raise Same.SAME)
670 handle Same.SAME => error ("Unknown type encoding: " ^ quote s ^ ".")
672 fun adjust_type_enc (THF (TPTP_Monomorphic, _, _))
673 (Simple_Types (order, _, level)) =
674 Simple_Types (order, Mangled_Monomorphic, level)
675 | adjust_type_enc (THF _) type_enc = type_enc
676 | adjust_type_enc (TFF (TPTP_Monomorphic, _)) (Simple_Types (_, _, level)) =
677 Simple_Types (First_Order, Mangled_Monomorphic, level)
678 | adjust_type_enc (DFG DFG_Sorted) (Simple_Types (_, _, level)) =
679 Simple_Types (First_Order, Mangled_Monomorphic, level)
680 | adjust_type_enc (TFF _) (Simple_Types (_, poly, level)) =
681 Simple_Types (First_Order, poly, level)
682 | adjust_type_enc format (Simple_Types (_, poly, level)) =
683 adjust_type_enc format (Guards (poly, level))
684 | adjust_type_enc CNF_UEQ (type_enc as Guards stuff) =
685 (if is_type_enc_fairly_sound type_enc then Tags else Guards) stuff
686 | adjust_type_enc _ type_enc = type_enc
690 @{const Not} $ t1 => is_fol_term t1
691 | Const (@{const_name All}, _) $ Abs (_, _, t') => is_fol_term t'
692 | Const (@{const_name All}, _) $ t1 => is_fol_term t1
693 | Const (@{const_name Ex}, _) $ Abs (_, _, t') => is_fol_term t'
694 | Const (@{const_name Ex}, _) $ t1 => is_fol_term t1
695 | @{const HOL.conj} $ t1 $ t2 => is_fol_term t1 andalso is_fol_term t2
696 | @{const HOL.disj} $ t1 $ t2 => is_fol_term t1 andalso is_fol_term t2
697 | @{const HOL.implies} $ t1 $ t2 => is_fol_term t1 andalso is_fol_term t2
698 | Const (@{const_name HOL.eq}, Type (_, [@{typ bool}, _])) $ t1 $ t2 =>
699 is_fol_term t1 andalso is_fol_term t2
700 | _ => not (exists_subterm (fn Abs _ => true | _ => false) t)
702 fun simple_translate_lambdas do_lambdas ctxt t =
703 if is_fol_term t then
709 @{const Not} $ t1 => @{const Not} $ trans Ts t1
710 | (t0 as Const (@{const_name All}, _)) $ Abs (s, T, t') =>
711 t0 $ Abs (s, T, trans (T :: Ts) t')
712 | (t0 as Const (@{const_name All}, _)) $ t1 =>
713 trans Ts (t0 $ eta_expand Ts t1 1)
714 | (t0 as Const (@{const_name Ex}, _)) $ Abs (s, T, t') =>
715 t0 $ Abs (s, T, trans (T :: Ts) t')
716 | (t0 as Const (@{const_name Ex}, _)) $ t1 =>
717 trans Ts (t0 $ eta_expand Ts t1 1)
718 | (t0 as @{const HOL.conj}) $ t1 $ t2 =>
719 t0 $ trans Ts t1 $ trans Ts t2
720 | (t0 as @{const HOL.disj}) $ t1 $ t2 =>
721 t0 $ trans Ts t1 $ trans Ts t2
722 | (t0 as @{const HOL.implies}) $ t1 $ t2 =>
723 t0 $ trans Ts t1 $ trans Ts t2
724 | (t0 as Const (@{const_name HOL.eq}, Type (_, [@{typ bool}, _])))
726 t0 $ trans Ts t1 $ trans Ts t2
728 if not (exists_subterm (fn Abs _ => true | _ => false) t) then t
729 else t |> Envir.eta_contract |> do_lambdas ctxt Ts
730 val (t, ctxt') = Variable.import_terms true [t] ctxt |>> the_single
731 in t |> trans [] |> singleton (Variable.export_terms ctxt' ctxt) end
733 fun do_cheaply_conceal_lambdas Ts (t1 $ t2) =
734 do_cheaply_conceal_lambdas Ts t1
735 $ do_cheaply_conceal_lambdas Ts t2
736 | do_cheaply_conceal_lambdas Ts (Abs (_, T, t)) =
737 Const (lam_lifted_poly_prefix ^ serial_string (),
738 T --> fastype_of1 (T :: Ts, t))
739 | do_cheaply_conceal_lambdas _ t = t
741 fun concealed_bound_name j = atp_weak_prefix ^ string_of_int j
742 fun conceal_bounds Ts t =
743 subst_bounds (map (Free o apfst concealed_bound_name)
744 (0 upto length Ts - 1 ~~ Ts), t)
745 fun reveal_bounds Ts =
746 subst_atomic (map (fn (j, T) => (Free (concealed_bound_name j, T), Bound j))
747 (0 upto length Ts - 1 ~~ Ts))
749 fun do_introduce_combinators ctxt Ts t =
750 let val thy = Proof_Context.theory_of ctxt in
751 t |> conceal_bounds Ts
753 |> Meson_Clausify.introduce_combinators_in_cterm
754 |> prop_of |> Logic.dest_equals |> snd
757 (* A type variable of sort "{}" will make abstraction fail. *)
758 handle THM _ => t |> do_cheaply_conceal_lambdas Ts
759 val introduce_combinators = simple_translate_lambdas do_introduce_combinators
761 fun constify_lifted (t $ u) = constify_lifted t $ constify_lifted u
762 | constify_lifted (Abs (s, T, t)) = Abs (s, T, constify_lifted t)
763 | constify_lifted (Free (x as (s, _))) =
764 (if String.isPrefix lam_lifted_prefix s then Const else Free) x
765 | constify_lifted t = t
767 (* Requires bound variables not to clash with any schematic variables (as should
768 be the case right after lambda-lifting). *)
769 fun open_form unprefix (t as Const (@{const_name All}, _) $ Abs (s, T, t')) =
770 (case try unprefix s of
773 val names = Name.make_context (map fst (Term.add_var_names t' []))
774 val (s, _) = Name.variant s names
775 in open_form unprefix (subst_bound (Var ((s, 0), T), t')) end
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 |>> map (open_form (unprefix close_form_prefix))
796 ||> map (open_form I)
798 fun lift_lams ctxt = lift_lams_part_2 ctxt oo lift_lams_part_1 ctxt
800 fun intentionalize_def (Const (@{const_name All}, _) $ Abs (_, _, t)) =
802 | intentionalize_def (Const (@{const_name HOL.eq}, _) $ t $ u) =
804 fun lam T t = Abs (Name.uu, T, t)
805 val (head, args) = strip_comb t ||> rev
806 val head_T = fastype_of head
808 val arg_Ts = head_T |> binder_types |> take n |> rev
809 val u = u |> subst_atomic (args ~~ map Bound (0 upto n - 1))
810 in HOLogic.eq_const head_T $ head $ fold lam arg_Ts u end
811 | intentionalize_def t = t
813 type translated_formula =
817 iformula : (name, typ, iterm) formula,
818 atomic_types : typ list}
820 fun update_iformula f ({name, stature, kind, iformula, atomic_types}
821 : translated_formula) =
822 {name = name, stature = stature, kind = kind, iformula = f iformula,
823 atomic_types = atomic_types} : translated_formula
825 fun fact_lift f ({iformula, ...} : translated_formula) = f iformula
827 fun insert_type thy get_T x xs =
828 let val T = get_T x in
829 if exists (type_instance thy T o get_T) xs then xs
830 else x :: filter_out (type_generalization thy T o get_T) xs
833 (* The Booleans indicate whether all type arguments should be kept. *)
834 datatype type_arg_policy =
835 Explicit_Type_Args of bool (* infer_from_term_args *) |
839 fun type_arg_policy monom_constrs type_enc s =
840 let val poly = polymorphism_of_type_enc type_enc in
841 if s = type_tag_name then
842 if poly = Mangled_Monomorphic then Mangled_Type_Args
843 else Explicit_Type_Args false
844 else case type_enc of
845 Simple_Types (_, Polymorphic, _) => Explicit_Type_Args false
846 | Tags (_, All_Types) => No_Type_Args
848 let val level = level_of_type_enc type_enc in
849 if level = No_Types orelse s = @{const_name HOL.eq} orelse
850 (s = app_op_name andalso level = Const_Arg_Types) then
852 else if poly = Mangled_Monomorphic then
854 else if member (op =) monom_constrs s andalso
855 granularity_of_type_level level = Positively_Naked_Vars then
859 (level = All_Types orelse
860 granularity_of_type_level level = Ghost_Type_Arg_Vars)
864 (* Make atoms for sorted type variables. *)
865 fun generic_add_sorts_on_type (_, []) = I
866 | generic_add_sorts_on_type ((x, i), s :: ss) =
867 generic_add_sorts_on_type ((x, i), ss)
868 #> (if s = the_single @{sort HOL.type} then
871 insert (op =) (`make_type_class s, `make_fixed_type_var x)
873 insert (op =) (`make_type_class s,
874 (make_schematic_type_var (x, i), x)))
875 fun add_sorts_on_tfree (TFree (s, S)) = generic_add_sorts_on_type ((s, ~1), S)
876 | add_sorts_on_tfree _ = I
877 fun add_sorts_on_tvar (TVar z) = generic_add_sorts_on_type z
878 | add_sorts_on_tvar _ = I
880 fun type_class_formula type_enc class arg =
881 AAtom (ATerm (class, arg ::
883 Simple_Types (First_Order, Polymorphic, _) =>
884 if avoid_first_order_ghost_type_vars then [ATerm (TYPE_name, [arg])]
887 fun formulas_for_types type_enc add_sorts_on_typ Ts =
888 [] |> level_of_type_enc type_enc <> No_Types ? fold add_sorts_on_typ Ts
889 |> map (fn (class, name) =>
890 type_class_formula type_enc class (ATerm (name, [])))
892 fun mk_aconns c phis =
893 let val (phis', phi') = split_last phis in
894 fold_rev (mk_aconn c) phis' phi'
896 fun mk_ahorn [] phi = phi
897 | mk_ahorn phis psi = AConn (AImplies, [mk_aconns AAnd phis, psi])
898 fun mk_aquant _ [] phi = phi
899 | mk_aquant q xs (phi as AQuant (q', xs', phi')) =
900 if q = q' then AQuant (q, xs @ xs', phi') else AQuant (q, xs, phi)
901 | mk_aquant q xs phi = AQuant (q, xs, phi)
903 fun close_universally add_term_vars phi =
905 fun add_formula_vars bounds (AQuant (_, xs, phi)) =
906 add_formula_vars (map fst xs @ bounds) phi
907 | add_formula_vars bounds (AConn (_, phis)) =
908 fold (add_formula_vars bounds) phis
909 | add_formula_vars bounds (AAtom tm) = add_term_vars bounds tm
910 in mk_aquant AForall (add_formula_vars [] phi []) phi end
912 fun add_term_vars bounds (ATerm (name as (s, _), tms)) =
913 (if is_tptp_variable s andalso
914 not (String.isPrefix tvar_prefix s) andalso
915 not (member (op =) bounds name) then
916 insert (op =) (name, NONE)
919 #> fold (add_term_vars bounds) tms
920 | add_term_vars bounds (AAbs ((name, _), tm)) =
921 add_term_vars (name :: bounds) tm
922 fun close_formula_universally phi = close_universally add_term_vars phi
924 fun add_iterm_vars bounds (IApp (tm1, tm2)) =
925 fold (add_iterm_vars bounds) [tm1, tm2]
926 | add_iterm_vars _ (IConst _) = I
927 | add_iterm_vars bounds (IVar (name, T)) =
928 not (member (op =) bounds name) ? insert (op =) (name, SOME T)
929 | add_iterm_vars bounds (IAbs (_, tm)) = add_iterm_vars bounds tm
930 fun close_iformula_universally phi = close_universally add_iterm_vars phi
932 val fused_infinite_type_name = "ATP.fused_inf" (* shouldn't clash *)
933 val fused_infinite_type = Type (fused_infinite_type_name, [])
935 fun tvar_name (x as (s, _)) = (make_schematic_type_var x, s)
937 fun ho_term_from_typ format type_enc =
939 fun term (Type (s, Ts)) =
940 ATerm (case (is_type_enc_higher_order type_enc, s) of
941 (true, @{type_name bool}) => `I tptp_bool_type
942 | (true, @{type_name fun}) => `I tptp_fun_type
943 | _ => if s = fused_infinite_type_name andalso
944 is_format_typed format then
945 `I tptp_individual_type
947 `make_fixed_type_const s,
949 | term (TFree (s, _)) = ATerm (`make_fixed_type_var s, [])
950 | term (TVar (x, _)) = ATerm (tvar_name x, [])
953 fun ho_term_for_type_arg format type_enc T =
954 if T = dummyT then NONE else SOME (ho_term_from_typ format type_enc T)
956 (* This shouldn't clash with anything else. *)
957 val uncurried_alias_sep = "\000"
958 val mangled_type_sep = "\001"
960 val ascii_of_uncurried_alias_sep = ascii_of uncurried_alias_sep
962 fun generic_mangled_type_name f (ATerm (name, [])) = f name
963 | generic_mangled_type_name f (ATerm (name, tys)) =
964 f name ^ "(" ^ space_implode "," (map (generic_mangled_type_name f) tys)
966 | generic_mangled_type_name _ _ = raise Fail "unexpected type abstraction"
968 fun mangled_type format type_enc =
969 generic_mangled_type_name fst o ho_term_from_typ format type_enc
971 fun make_native_type s =
972 if s = tptp_bool_type orelse s = tptp_fun_type orelse
973 s = tptp_individual_type then
976 native_type_prefix ^ ascii_of s
978 fun ho_type_from_ho_term type_enc pred_sym ary =
980 fun to_mangled_atype ty =
981 AType ((make_native_type (generic_mangled_type_name fst ty),
982 generic_mangled_type_name snd ty), [])
983 fun to_poly_atype (ATerm (name, tys)) = AType (name, map to_poly_atype tys)
984 | to_poly_atype _ = raise Fail "unexpected type abstraction"
986 if polymorphism_of_type_enc type_enc = Polymorphic then to_poly_atype
987 else to_mangled_atype
988 fun to_afun f1 f2 tys = AFun (f1 (hd tys), f2 (nth tys 1))
989 fun to_fo 0 ty = if pred_sym then bool_atype else to_atype ty
990 | to_fo ary (ATerm (_, tys)) = to_afun to_atype (to_fo (ary - 1)) tys
991 | to_fo _ _ = raise Fail "unexpected type abstraction"
992 fun to_ho (ty as ATerm ((s, _), tys)) =
993 if s = tptp_fun_type then to_afun to_ho to_ho tys else to_atype ty
994 | to_ho _ = raise Fail "unexpected type abstraction"
995 in if is_type_enc_higher_order type_enc then to_ho else to_fo ary end
997 fun ho_type_from_typ format type_enc pred_sym ary =
998 ho_type_from_ho_term type_enc pred_sym ary
999 o ho_term_from_typ format type_enc
1001 fun aliased_uncurried ary (s, s') =
1002 (s ^ ascii_of_uncurried_alias_sep ^ string_of_int ary, s' ^ string_of_int ary)
1003 fun unaliased_uncurried (s, s') =
1004 case space_explode uncurried_alias_sep s of
1006 | [s1, s2] => (s1, unsuffix s2 s')
1007 | _ => raise Fail "ill-formed explicit application alias"
1009 fun raw_mangled_const_name type_name ty_args (s, s') =
1011 fun type_suffix f g =
1012 fold_rev (curry (op ^) o g o prefix mangled_type_sep o type_name f)
1014 in (s ^ type_suffix fst ascii_of, s' ^ type_suffix snd I) end
1015 fun mangled_const_name format type_enc =
1016 map_filter (ho_term_for_type_arg format type_enc)
1017 #> raw_mangled_const_name generic_mangled_type_name
1019 val parse_mangled_ident =
1020 Scan.many1 (not o member (op =) ["(", ")", ","]) >> implode
1022 fun parse_mangled_type x =
1023 (parse_mangled_ident
1024 -- Scan.optional ($$ "(" |-- Scan.optional parse_mangled_types [] --| $$ ")")
1026 and parse_mangled_types x =
1027 (parse_mangled_type ::: Scan.repeat ($$ "," |-- parse_mangled_type)) x
1029 fun unmangled_type s =
1030 s |> suffix ")" |> raw_explode
1031 |> Scan.finite Symbol.stopper
1032 (Scan.error (!! (fn _ => raise Fail ("unrecognized mangled type " ^
1033 quote s)) parse_mangled_type))
1036 fun unmangled_const_name s =
1037 (s, s) |> unaliased_uncurried |> fst |> space_explode mangled_type_sep
1038 fun unmangled_const s =
1039 let val ss = unmangled_const_name s in
1040 (hd ss, map unmangled_type (tl ss))
1043 fun introduce_proxies_in_iterm type_enc =
1045 fun tweak_ho_quant ho_quant T [IAbs _] = IConst (`I ho_quant, T, [])
1046 | tweak_ho_quant ho_quant (T as Type (_, [p_T as Type (_, [x_T, _]), _]))
1048 (* Eta-expand "!!" and "??", to work around LEO-II 1.2.8 parser
1049 limitation. This works in conjuction with special code in
1050 "ATP_Problem" that uses the syntactic sugar "!" and "?" whenever
1052 IAbs ((`I "P", p_T),
1053 IApp (IConst (`I ho_quant, T, []),
1054 IAbs ((`I "X", x_T),
1055 IApp (IConst (`I "P", p_T, []),
1056 IConst (`I "X", x_T, [])))))
1057 | tweak_ho_quant _ _ _ = raise Fail "unexpected type for quantifier"
1058 fun intro top_level args (IApp (tm1, tm2)) =
1059 IApp (intro top_level (tm2 :: args) tm1, intro false [] tm2)
1060 | intro top_level args (IConst (name as (s, _), T, T_args)) =
1061 (case proxify_const s of
1063 if top_level orelse is_type_enc_higher_order type_enc then
1064 case (top_level, s) of
1065 (_, "c_False") => IConst (`I tptp_false, T, [])
1066 | (_, "c_True") => IConst (`I tptp_true, T, [])
1067 | (false, "c_Not") => IConst (`I tptp_not, T, [])
1068 | (false, "c_conj") => IConst (`I tptp_and, T, [])
1069 | (false, "c_disj") => IConst (`I tptp_or, T, [])
1070 | (false, "c_implies") => IConst (`I tptp_implies, T, [])
1071 | (false, "c_All") => tweak_ho_quant tptp_ho_forall T args
1072 | (false, "c_Ex") => tweak_ho_quant tptp_ho_exists T args
1074 if is_tptp_equal s andalso length args = 2 then
1075 IConst (`I tptp_equal, T, [])
1077 (* Use a proxy even for partially applied THF0 equality,
1078 because the LEO-II and Satallax parsers complain about not
1079 being able to infer the type of "=". *)
1080 IConst (proxy_base |>> prefix const_prefix, T, T_args)
1081 | _ => IConst (name, T, [])
1083 IConst (proxy_base |>> prefix const_prefix, T, T_args)
1084 | NONE => if s = tptp_choice then tweak_ho_quant tptp_choice T args
1085 else IConst (name, T, T_args))
1086 | intro _ _ (IAbs (bound, tm)) = IAbs (bound, intro false [] tm)
1088 in intro true [] end
1090 fun mangle_type_args_in_const format type_enc (name as (s, _)) T_args =
1091 case unprefix_and_unascii const_prefix s of
1092 NONE => (name, T_args)
1094 case type_arg_policy [] type_enc (invert_const s'') of
1095 Mangled_Type_Args => (mangled_const_name format type_enc T_args name, [])
1096 | _ => (name, T_args)
1097 fun mangle_type_args_in_iterm format type_enc =
1098 if polymorphism_of_type_enc type_enc = Mangled_Monomorphic then
1100 fun mangle (IApp (tm1, tm2)) = IApp (mangle tm1, mangle tm2)
1101 | mangle (tm as IConst (_, _, [])) = tm
1102 | mangle (IConst (name, T, T_args)) =
1103 mangle_type_args_in_const format type_enc name T_args
1104 |> (fn (name, T_args) => IConst (name, T, T_args))
1105 | mangle (IAbs (bound, tm)) = IAbs (bound, mangle tm)
1111 fun chop_fun 0 T = ([], T)
1112 | chop_fun n (Type (@{type_name fun}, [dom_T, ran_T])) =
1113 chop_fun (n - 1) ran_T |>> cons dom_T
1114 | chop_fun _ T = ([], T)
1116 fun filter_const_type_args _ _ _ [] = []
1117 | filter_const_type_args thy s ary T_args =
1119 val U = robust_const_type thy s
1120 val arg_U_vars = fold Term.add_tvarsT (U |> chop_fun ary |> fst) []
1121 val U_args = (s, U) |> robust_const_typargs thy
1124 |> map (fn (U, T) =>
1125 if member (op =) arg_U_vars (dest_TVar U) then dummyT else T)
1127 handle TYPE _ => T_args
1129 fun filter_type_args_in_const _ _ _ _ _ [] = []
1130 | filter_type_args_in_const thy monom_constrs type_enc ary s T_args =
1131 case unprefix_and_unascii const_prefix s of
1133 if level_of_type_enc type_enc = No_Types orelse s = tptp_choice then []
1137 val s'' = invert_const s''
1138 fun filter_T_args false = T_args
1139 | filter_T_args true = filter_const_type_args thy s'' ary T_args
1141 case type_arg_policy monom_constrs type_enc s'' of
1142 Explicit_Type_Args infer_from_term_args =>
1143 filter_T_args infer_from_term_args
1144 | No_Type_Args => []
1145 | Mangled_Type_Args => raise Fail "unexpected (un)mangled symbol"
1147 fun filter_type_args_in_iterm thy monom_constrs type_enc =
1149 fun filt ary (IApp (tm1, tm2)) = IApp (filt (ary + 1) tm1, filt 0 tm2)
1150 | filt ary (IConst (name as (s, _), T, T_args)) =
1151 filter_type_args_in_const thy monom_constrs type_enc ary s T_args
1152 |> (fn T_args => IConst (name, T, T_args))
1153 | filt _ (IAbs (bound, tm)) = IAbs (bound, filt 0 tm)
1157 fun iformula_from_prop ctxt format type_enc eq_as_iff =
1159 val thy = Proof_Context.theory_of ctxt
1160 fun do_term bs t atomic_Ts =
1161 iterm_from_term thy format bs (Envir.eta_contract t)
1162 |>> (introduce_proxies_in_iterm type_enc
1163 #> mangle_type_args_in_iterm format type_enc #> AAtom)
1164 ||> union (op =) atomic_Ts
1165 fun do_quant bs q pos s T t' =
1167 val s = singleton (Name.variant_list (map fst bs)) s
1168 val universal = Option.map (q = AExists ? not) pos
1170 s |> `(case universal of
1171 SOME true => make_all_bound_var
1172 | SOME false => make_exist_bound_var
1173 | NONE => make_bound_var)
1175 do_formula ((s, (name, T)) :: bs) pos t'
1176 #>> mk_aquant q [(name, SOME T)]
1177 ##> union (op =) (atomic_types_of T)
1179 and do_conn bs c pos1 t1 pos2 t2 =
1180 do_formula bs pos1 t1 ##>> do_formula bs pos2 t2 #>> uncurry (mk_aconn c)
1181 and do_formula bs pos t =
1183 @{const Trueprop} $ t1 => do_formula bs pos t1
1184 | @{const Not} $ t1 => do_formula bs (Option.map not pos) t1 #>> mk_anot
1185 | Const (@{const_name All}, _) $ Abs (s, T, t') =>
1186 do_quant bs AForall pos s T t'
1187 | (t0 as Const (@{const_name All}, _)) $ t1 =>
1188 do_formula bs pos (t0 $ eta_expand (map (snd o snd) bs) t1 1)
1189 | Const (@{const_name Ex}, _) $ Abs (s, T, t') =>
1190 do_quant bs AExists pos s T t'
1191 | (t0 as Const (@{const_name Ex}, _)) $ t1 =>
1192 do_formula bs pos (t0 $ eta_expand (map (snd o snd) bs) t1 1)
1193 | @{const HOL.conj} $ t1 $ t2 => do_conn bs AAnd pos t1 pos t2
1194 | @{const HOL.disj} $ t1 $ t2 => do_conn bs AOr pos t1 pos t2
1195 | @{const HOL.implies} $ t1 $ t2 =>
1196 do_conn bs AImplies (Option.map not pos) t1 pos t2
1197 | Const (@{const_name HOL.eq}, Type (_, [@{typ bool}, _])) $ t1 $ t2 =>
1198 if eq_as_iff then do_conn bs AIff NONE t1 NONE t2 else do_term bs t
1200 in do_formula [] end
1202 fun presimplify_term thy t =
1203 if exists_Const (member (op =) Meson.presimplified_consts o fst) t then
1204 t |> Skip_Proof.make_thm thy
1205 |> Meson.presimplify
1210 fun is_fun_equality (@{const_name HOL.eq},
1211 Type (_, [Type (@{type_name fun}, _), _])) = true
1212 | is_fun_equality _ = false
1214 fun extensionalize_term ctxt t =
1215 if exists_Const is_fun_equality t then
1216 let val thy = Proof_Context.theory_of ctxt in
1217 t |> cterm_of thy |> Meson.extensionalize_conv ctxt
1218 |> prop_of |> Logic.dest_equals |> snd
1223 fun preprocess_abstractions_in_terms trans_lams facts =
1225 val (facts, lambda_ts) =
1226 facts |> map (snd o snd) |> trans_lams
1227 |>> map2 (fn (name, (kind, _)) => fn t => (name, (kind, t))) facts
1229 map2 (fn t => fn j =>
1230 ((lam_fact_prefix ^ Int.toString j, (Global, Def)), (Axiom, t)))
1231 lambda_ts (1 upto length lambda_ts)
1232 in (facts, lam_facts) end
1234 (* Metis's use of "resolve_tac" freezes the schematic variables. We simulate the
1235 same in Sledgehammer to prevent the discovery of unreplayable proofs. *)
1238 fun freeze (t $ u) = freeze t $ freeze u
1239 | freeze (Abs (s, T, t)) = Abs (s, T, freeze t)
1240 | freeze (Var ((s, i), T)) =
1241 Free (atp_weak_prefix ^ s ^ "_" ^ string_of_int i, T)
1243 in t |> exists_subterm is_Var t ? freeze end
1245 fun presimp_prop ctxt t =
1247 val thy = Proof_Context.theory_of ctxt
1248 val t = t |> Envir.beta_eta_contract
1249 |> transform_elim_prop
1250 |> Object_Logic.atomize_term thy
1251 val need_trueprop = (fastype_of t = @{typ bool})
1253 t |> need_trueprop ? HOLogic.mk_Trueprop
1254 |> extensionalize_term ctxt
1255 |> presimplify_term thy
1256 |> HOLogic.dest_Trueprop
1258 handle TERM _ => @{const True}
1260 fun make_formula ctxt format type_enc eq_as_iff name stature kind t =
1262 val (iformula, atomic_Ts) =
1263 iformula_from_prop ctxt format type_enc eq_as_iff
1264 (SOME (kind <> Conjecture)) t []
1265 |>> close_iformula_universally
1267 {name = name, stature = stature, kind = kind, iformula = iformula,
1268 atomic_types = atomic_Ts}
1271 fun make_fact ctxt format type_enc eq_as_iff ((name, stature), t) =
1272 case t |> make_formula ctxt format type_enc (eq_as_iff andalso format <> CNF)
1273 name stature Axiom of
1274 formula as {iformula = AAtom (IConst ((s, _), _, _)), ...} =>
1275 if s = tptp_true then NONE else SOME formula
1276 | formula => SOME formula
1278 fun s_not_prop (@{const Trueprop} $ t) = @{const Trueprop} $ s_not t
1279 | s_not_prop _ = @{prop True} (* "t" is too meta for "metis" *)
1281 | s_not_prop (@{const "==>"} $ t $ @{prop False}) = t
1282 | s_not_prop t = @{const "==>"} $ t $ @{prop False}
1285 fun make_conjecture ctxt format type_enc =
1286 map (fn ((name, stature), (kind, t)) =>
1287 t |> kind = Conjecture ? s_not
1288 |> make_formula ctxt format type_enc (format <> CNF) name stature
1291 (** Finite and infinite type inference **)
1293 fun tvar_footprint thy s ary =
1294 (case unprefix_and_unascii const_prefix s of
1296 s |> invert_const |> robust_const_type thy |> chop_fun ary |> fst
1297 |> map (fn T => Term.add_tvarsT T [] |> map fst)
1301 fun ghost_type_args thy s ary =
1302 if is_tptp_equal s then
1306 val footprint = tvar_footprint thy s ary
1307 val eq = (s = @{const_name HOL.eq})
1308 fun ghosts _ [] = []
1309 | ghosts seen ((i, tvars) :: args) =
1310 ghosts (union (op =) seen tvars) args
1311 |> (eq orelse exists (fn tvar => not (member (op =) seen tvar)) tvars)
1314 if forall null footprint then
1317 0 upto length footprint - 1 ~~ footprint
1318 |> sort (rev_order o list_ord Term_Ord.indexname_ord o pairself snd)
1322 type monotonicity_info =
1323 {maybe_finite_Ts : typ list,
1324 surely_finite_Ts : typ list,
1325 maybe_infinite_Ts : typ list,
1326 surely_infinite_Ts : typ list,
1327 maybe_nonmono_Ts : typ list}
1329 (* These types witness that the type classes they belong to allow infinite
1330 models and hence that any types with these type classes is monotonic. *)
1331 val known_infinite_types =
1332 [@{typ nat}, HOLogic.intT, HOLogic.realT, @{typ "nat => bool"}]
1334 fun is_type_kind_of_surely_infinite ctxt strictness cached_Ts T =
1335 strictness <> Strict andalso is_type_surely_infinite ctxt true cached_Ts T
1337 (* Finite types such as "unit", "bool", "bool * bool", and "bool => bool" are
1338 dangerous because their "exhaust" properties can easily lead to unsound ATP
1339 proofs. On the other hand, all HOL infinite types can be given the same
1340 models in first-order logic (via Löwenheim-Skolem). *)
1342 fun should_encode_type _ (_ : monotonicity_info) All_Types _ = true
1343 | should_encode_type ctxt {maybe_finite_Ts, surely_infinite_Ts,
1344 maybe_nonmono_Ts, ...}
1345 (Noninf_Nonmono_Types (strictness, grain)) T =
1346 let val thy = Proof_Context.theory_of ctxt in
1347 grain = Ghost_Type_Arg_Vars orelse
1348 (exists (type_intersect thy T) maybe_nonmono_Ts andalso
1349 not (exists (type_instance thy T) surely_infinite_Ts orelse
1350 (not (member (type_equiv thy) maybe_finite_Ts T) andalso
1351 is_type_kind_of_surely_infinite ctxt strictness surely_infinite_Ts
1354 | should_encode_type ctxt {surely_finite_Ts, maybe_infinite_Ts,
1355 maybe_nonmono_Ts, ...}
1356 (Fin_Nonmono_Types grain) T =
1357 let val thy = Proof_Context.theory_of ctxt in
1358 grain = Ghost_Type_Arg_Vars orelse
1359 (exists (type_intersect thy T) maybe_nonmono_Ts andalso
1360 (exists (type_generalization thy T) surely_finite_Ts orelse
1361 (not (member (type_equiv thy) maybe_infinite_Ts T) andalso
1362 is_type_surely_finite ctxt T)))
1364 | should_encode_type _ _ _ _ = false
1366 fun should_guard_type ctxt mono (Guards (_, level)) should_guard_var T =
1367 should_guard_var () andalso should_encode_type ctxt mono level T
1368 | should_guard_type _ _ _ _ _ = false
1370 fun is_maybe_universal_var (IConst ((s, _), _, _)) =
1371 String.isPrefix bound_var_prefix s orelse
1372 String.isPrefix all_bound_var_prefix s
1373 | is_maybe_universal_var (IVar _) = true
1374 | is_maybe_universal_var _ = false
1377 Top_Level of bool option |
1378 Eq_Arg of bool option |
1381 fun should_tag_with_type _ _ _ (Top_Level _) _ _ = false
1382 | should_tag_with_type ctxt mono (Tags (_, level)) site u T =
1383 if granularity_of_type_level level = All_Vars then
1384 should_encode_type ctxt mono level T
1386 (case (site, is_maybe_universal_var u) of
1387 (Eq_Arg _, true) => should_encode_type ctxt mono level T
1389 | should_tag_with_type _ _ _ _ _ _ = false
1391 fun fused_type ctxt mono level =
1393 val should_encode = should_encode_type ctxt mono level
1394 fun fuse 0 T = if should_encode T then T else fused_infinite_type
1395 | fuse ary (Type (@{type_name fun}, [T1, T2])) =
1396 fuse 0 T1 --> fuse (ary - 1) T2
1397 | fuse _ _ = raise Fail "expected function type"
1400 (** predicators and application operators **)
1403 {pred_sym : bool, min_ary : int, max_ary : int, types : typ list,
1406 fun default_sym_tab_entries type_enc =
1407 (make_fixed_const NONE @{const_name undefined},
1408 {pred_sym = false, min_ary = 0, max_ary = 0, types = [],
1409 in_conj = false}) ::
1410 ([tptp_false, tptp_true]
1411 |> map (rpair {pred_sym = true, min_ary = 0, max_ary = 0, types = [],
1412 in_conj = false})) @
1413 ([tptp_equal, tptp_old_equal]
1414 |> map (rpair {pred_sym = true, min_ary = 2, max_ary = 2, types = [],
1416 |> not (is_type_enc_higher_order type_enc)
1417 ? cons (prefixed_predicator_name,
1418 {pred_sym = true, min_ary = 1, max_ary = 1, types = [],
1421 datatype app_op_level =
1424 Sufficient_App_Op_And_Predicator |
1425 Full_App_Op_And_Predicator
1427 fun sym_table_for_facts ctxt type_enc app_op_level conjs facts =
1429 val thy = Proof_Context.theory_of ctxt
1430 fun consider_var_ary const_T var_T max_ary =
1433 if ary = max_ary orelse type_instance thy var_T T orelse
1434 type_instance thy T var_T then
1437 iter (ary + 1) (range_type T)
1438 in iter 0 const_T end
1439 fun add_universal_var T (accum as ((bool_vars, fun_var_Ts), sym_tab)) =
1440 if (app_op_level = Sufficient_App_Op andalso can dest_funT T) orelse
1441 (app_op_level = Sufficient_App_Op_And_Predicator andalso
1442 (can dest_funT T orelse T = @{typ bool})) then
1446 (app_op_level = Sufficient_App_Op_And_Predicator andalso
1447 body_type T = @{typ bool})
1448 fun repair_min_ary {pred_sym, min_ary, max_ary, types, in_conj} =
1449 {pred_sym = pred_sym andalso not bool_vars',
1450 min_ary = fold (fn T' => consider_var_ary T' T) types min_ary,
1451 max_ary = max_ary, types = types, in_conj = in_conj}
1453 fun_var_Ts |> can dest_funT T ? insert_type thy I T
1455 if bool_vars' = bool_vars andalso
1456 pointer_eq (fun_var_Ts', fun_var_Ts) then
1459 ((bool_vars', fun_var_Ts'), Symtab.map (K repair_min_ary) sym_tab)
1463 fun add_iterm_syms conj_fact top_level tm
1464 (accum as ((bool_vars, fun_var_Ts), sym_tab)) =
1465 let val (head, args) = strip_iterm_comb tm in
1467 IConst ((s, _), T, _) =>
1468 if String.isPrefix bound_var_prefix s orelse
1469 String.isPrefix all_bound_var_prefix s then
1470 add_universal_var T accum
1471 else if String.isPrefix exist_bound_var_prefix s then
1474 let val ary = length args in
1475 ((bool_vars, fun_var_Ts),
1476 case Symtab.lookup sym_tab s of
1477 SOME {pred_sym, min_ary, max_ary, types, in_conj} =>
1480 pred_sym andalso top_level andalso not bool_vars
1481 val types' = types |> insert_type thy I T
1482 val in_conj = in_conj orelse conj_fact
1484 if (app_op_level = Sufficient_App_Op orelse
1485 app_op_level = Sufficient_App_Op_And_Predicator)
1486 andalso not (pointer_eq (types', types)) then
1487 fold (consider_var_ary T) fun_var_Ts min_ary
1491 Symtab.update (s, {pred_sym = pred_sym,
1492 min_ary = Int.min (ary, min_ary),
1493 max_ary = Int.max (ary, max_ary),
1494 types = types', in_conj = in_conj})
1499 val pred_sym = top_level andalso not bool_vars
1501 case unprefix_and_unascii const_prefix s of
1503 (if String.isSubstring uncurried_alias_sep s then
1505 else case try (robust_const_ary thy
1507 o unmangled_const_name) s of
1508 SOME ary0 => Int.min (ary0, ary)
1512 case app_op_level of
1514 | Full_App_Op_And_Predicator => 0
1515 | _ => fold (consider_var_ary T) fun_var_Ts ary
1517 Symtab.update_new (s,
1518 {pred_sym = pred_sym, min_ary = min_ary,
1519 max_ary = ary, types = [T], in_conj = conj_fact})
1523 | IVar (_, T) => add_universal_var T accum
1524 | IAbs ((_, T), tm) =>
1525 accum |> add_universal_var T |> add_iterm_syms conj_fact false tm
1527 |> fold (add_iterm_syms conj_fact false) args
1529 fun add_fact_syms conj_fact =
1530 K (add_iterm_syms conj_fact true) |> formula_fold NONE |> fact_lift
1532 ((false, []), Symtab.empty)
1533 |> fold (add_fact_syms true) conjs
1534 |> fold (add_fact_syms false) facts
1536 |> fold Symtab.update (default_sym_tab_entries type_enc)
1539 fun min_ary_of sym_tab s =
1540 case Symtab.lookup sym_tab s of
1541 SOME ({min_ary, ...} : sym_info) => min_ary
1543 case unprefix_and_unascii const_prefix s of
1545 let val s = s |> unmangled_const_name |> hd |> invert_const in
1546 if s = predicator_name then 1
1547 else if s = app_op_name then 2
1548 else if s = type_guard_name then 1
1553 (* True if the constant ever appears outside of the top-level position in
1554 literals, or if it appears with different arities (e.g., because of different
1555 type instantiations). If false, the constant always receives all of its
1556 arguments and is used as a predicate. *)
1557 fun is_pred_sym sym_tab s =
1558 case Symtab.lookup sym_tab s of
1559 SOME ({pred_sym, min_ary, max_ary, ...} : sym_info) =>
1560 pred_sym andalso min_ary = max_ary
1563 val app_op = `(make_fixed_const NONE) app_op_name
1564 val predicator_combconst =
1565 IConst (`(make_fixed_const NONE) predicator_name, @{typ "bool => bool"}, [])
1567 fun list_app head args = fold (curry (IApp o swap)) args head
1568 fun predicator tm = IApp (predicator_combconst, tm)
1570 fun mk_app_op format type_enc head arg =
1572 val head_T = ityp_of head
1573 val (arg_T, res_T) = dest_funT head_T
1575 IConst (app_op, head_T --> head_T, [arg_T, res_T])
1576 |> mangle_type_args_in_iterm format type_enc
1577 in list_app app [head, arg] end
1579 fun firstorderize_fact thy monom_constrs format type_enc sym_tab
1582 fun do_app arg head = mk_app_op format type_enc head arg
1583 fun list_app_ops head args = fold do_app args head
1584 fun introduce_app_ops tm =
1585 let val (head, args) = tm |> strip_iterm_comb ||> map introduce_app_ops in
1587 IConst (name as (s, _), T, T_args) =>
1588 if uncurried_aliases andalso String.isPrefix const_prefix s then
1590 val ary = length args
1592 name |> ary > min_ary_of sym_tab s ? aliased_uncurried ary
1593 in list_app (IConst (name, T, T_args)) args end
1595 args |> chop (min_ary_of sym_tab s)
1596 |>> list_app head |-> list_app_ops
1597 | _ => list_app_ops head args
1599 fun introduce_predicators tm =
1600 case strip_iterm_comb tm of
1601 (IConst ((s, _), _, _), _) =>
1602 if is_pred_sym sym_tab s then tm else predicator tm
1603 | _ => predicator tm
1605 not (is_type_enc_higher_order type_enc)
1606 ? (introduce_app_ops #> introduce_predicators)
1607 #> filter_type_args_in_iterm thy monom_constrs type_enc
1608 in update_iformula (formula_map do_iterm) end
1610 (** Helper facts **)
1612 val not_ffalse = @{lemma "~ fFalse" by (unfold fFalse_def) fast}
1613 val ftrue = @{lemma "fTrue" by (unfold fTrue_def) fast}
1615 (* The Boolean indicates that a fairly sound type encoding is needed. *)
1617 [(("COMBI", false), @{thms Meson.COMBI_def}),
1618 (("COMBK", false), @{thms Meson.COMBK_def}),
1619 (("COMBB", false), @{thms Meson.COMBB_def}),
1620 (("COMBC", false), @{thms Meson.COMBC_def}),
1621 (("COMBS", false), @{thms Meson.COMBS_def}),
1622 ((predicator_name, false), [not_ffalse, ftrue]),
1623 (("fFalse", false), [not_ffalse]),
1624 (("fFalse", true), @{thms True_or_False}),
1625 (("fTrue", false), [ftrue]),
1626 (("fTrue", true), @{thms True_or_False}),
1628 @{thms fNot_def [THEN Meson.iff_to_disjD, THEN conjunct1]
1629 fNot_def [THEN Meson.iff_to_disjD, THEN conjunct2]}),
1631 @{lemma "~ P | ~ Q | fconj P Q" "~ fconj P Q | P" "~ fconj P Q | Q"
1632 by (unfold fconj_def) fast+}),
1634 @{lemma "~ P | fdisj P Q" "~ Q | fdisj P Q" "~ fdisj P Q | P | Q"
1635 by (unfold fdisj_def) fast+}),
1636 (("fimplies", false),
1637 @{lemma "P | fimplies P Q" "~ Q | fimplies P Q" "~ fimplies P Q | ~ P | Q"
1638 by (unfold fimplies_def) fast+}),
1640 (* This is a lie: Higher-order equality doesn't need a sound type encoding.
1641 However, this is done so for backward compatibility: Including the
1642 equality helpers by default in Metis breaks a few existing proofs. *)
1643 @{thms fequal_def [THEN Meson.iff_to_disjD, THEN conjunct1]
1644 fequal_def [THEN Meson.iff_to_disjD, THEN conjunct2]}),
1645 (* Partial characterization of "fAll" and "fEx". A complete characterization
1646 would require the axiom of choice for replay with Metis. *)
1647 (("fAll", false), [@{lemma "~ fAll P | P x" by (auto simp: fAll_def)}]),
1648 (("fEx", false), [@{lemma "~ P x | fEx P" by (auto simp: fEx_def)}]),
1649 (("If", true), @{thms if_True if_False True_or_False})]
1650 |> map (apsnd (map zero_var_indexes))
1652 fun atype_of_type_vars (Simple_Types (_, Polymorphic, _)) = SOME atype_of_types
1653 | atype_of_type_vars _ = NONE
1655 fun bound_tvars type_enc sorts Ts =
1656 (sorts ? mk_ahorn (formulas_for_types type_enc add_sorts_on_tvar Ts))
1657 #> mk_aquant AForall
1658 (map_filter (fn TVar (x as (s, _), _) =>
1659 SOME ((make_schematic_type_var x, s),
1660 atype_of_type_vars type_enc)
1663 fun eq_formula type_enc atomic_Ts bounds pred_sym tm1 tm2 =
1664 (if pred_sym then AConn (AIff, [AAtom tm1, AAtom tm2])
1665 else AAtom (ATerm (`I tptp_equal, [tm1, tm2])))
1666 |> mk_aquant AForall bounds
1667 |> close_formula_universally
1668 |> bound_tvars type_enc true atomic_Ts
1670 val helper_rank = default_rank
1671 val min_rank = 9 * helper_rank div 10
1672 val max_rank = 4 * min_rank
1674 fun rank_of_fact_num n j = min_rank + (max_rank - min_rank) * j div n
1676 val type_tag = `(make_fixed_const NONE) type_tag_name
1678 fun should_specialize_helper type_enc t =
1679 polymorphism_of_type_enc type_enc <> Polymorphic andalso
1680 level_of_type_enc type_enc <> No_Types andalso
1681 not (null (Term.hidden_polymorphism t))
1683 fun helper_facts_for_sym ctxt format type_enc (s, {types, ...} : sym_info) =
1684 case unprefix_and_unascii const_prefix s of
1687 val thy = Proof_Context.theory_of ctxt
1688 val unmangled_s = mangled_s |> unmangled_const_name |> hd
1689 fun dub needs_fairly_sound j k =
1690 unmangled_s ^ "_" ^ string_of_int j ^ "_" ^ string_of_int k ^
1691 (if mangled_s = unmangled_s then "" else "_" ^ ascii_of mangled_s) ^
1692 (if needs_fairly_sound then typed_helper_suffix
1693 else untyped_helper_suffix)
1694 fun dub_and_inst needs_fairly_sound (th, j) =
1695 let val t = prop_of th in
1696 if should_specialize_helper type_enc t then
1697 map (fn T => specialize_type thy (invert_const unmangled_s, T) t)
1703 |> map (fn (k, t) => ((dub needs_fairly_sound j k, (Global, Def)), t))
1704 val make_facts = map_filter (make_fact ctxt format type_enc false)
1705 val fairly_sound = is_type_enc_fairly_sound type_enc
1708 |> maps (fn ((helper_s, needs_fairly_sound), ths) =>
1709 if helper_s <> unmangled_s orelse
1710 (needs_fairly_sound andalso not fairly_sound) then
1713 ths ~~ (1 upto length ths)
1714 |> maps (dub_and_inst needs_fairly_sound)
1718 fun helper_facts_for_sym_table ctxt format type_enc sym_tab =
1719 Symtab.fold_rev (append o helper_facts_for_sym ctxt format type_enc) sym_tab
1722 (***************************************************************)
1723 (* Type Classes Present in the Axiom or Conjecture Clauses *)
1724 (***************************************************************)
1726 fun set_insert (x, s) = Symtab.update (x, ()) s
1728 fun add_classes (sorts, cset) = List.foldl set_insert cset (flat sorts)
1730 (* Remove this trivial type class (FIXME: similar code elsewhere) *)
1731 fun delete_type cset = Symtab.delete_safe (the_single @{sort HOL.type}) cset
1733 fun classes_of_terms get_Ts =
1734 map (map snd o get_Ts)
1735 #> List.foldl add_classes Symtab.empty
1736 #> delete_type #> Symtab.keys
1738 val tfree_classes_of_terms = classes_of_terms Misc_Legacy.term_tfrees
1739 val tvar_classes_of_terms = classes_of_terms Misc_Legacy.term_tvars
1741 fun fold_type_constrs f (Type (s, Ts)) x =
1742 fold (fold_type_constrs f) Ts (f (s, x))
1743 | fold_type_constrs _ _ x = x
1745 (* Type constructors used to instantiate overloaded constants are the only ones
1747 fun add_type_constrs_in_term thy =
1749 fun add (Const (@{const_name Meson.skolem}, _) $ _) = I
1750 | add (t $ u) = add t #> add u
1752 x |> robust_const_typargs thy |> fold (fold_type_constrs set_insert)
1753 | add (Abs (_, _, u)) = add u
1757 fun type_constrs_of_terms thy ts =
1758 Symtab.keys (fold (add_type_constrs_in_term thy) ts Symtab.empty)
1760 fun extract_lambda_def (Const (@{const_name HOL.eq}, _) $ t $ u) =
1761 let val (head, args) = strip_comb t in
1762 (head |> dest_Const |> fst,
1763 fold_rev (fn t as Var ((s, _), T) =>
1764 (fn u => Abs (s, T, abstract_over (t, u)))
1765 | _ => raise Fail "expected Var") args u)
1767 | extract_lambda_def _ = raise Fail "malformed lifted lambda"
1769 fun trans_lams_from_string ctxt type_enc lam_trans =
1770 if lam_trans = no_lamsN then
1772 else if lam_trans = hide_lamsN then
1773 lift_lams ctxt type_enc ##> K []
1774 else if lam_trans = liftingN orelse lam_trans = lam_liftingN then
1775 lift_lams ctxt type_enc
1776 else if lam_trans = combsN then
1777 map (introduce_combinators ctxt) #> rpair []
1778 else if lam_trans = combs_and_liftingN then
1779 lift_lams_part_1 ctxt type_enc
1780 ##> maps (fn t => [t, introduce_combinators ctxt (intentionalize_def t)])
1781 #> lift_lams_part_2 ctxt
1782 else if lam_trans = combs_or_liftingN then
1783 lift_lams_part_1 ctxt type_enc
1784 ##> map (fn t => case head_of (strip_qnt_body @{const_name All} t) of
1785 @{term "op =::bool => bool => bool"} => t
1786 | _ => introduce_combinators ctxt (intentionalize_def t))
1787 #> lift_lams_part_2 ctxt
1788 else if lam_trans = keep_lamsN then
1789 map (Envir.eta_contract) #> rpair []
1791 error ("Unknown lambda translation scheme: " ^ quote lam_trans ^ ".")
1793 fun translate_formulas ctxt format prem_kind type_enc lam_trans presimp hyp_ts
1796 val thy = Proof_Context.theory_of ctxt
1797 val trans_lams = trans_lams_from_string ctxt type_enc lam_trans
1798 val fact_ts = facts |> map snd
1799 (* Remove existing facts from the conjecture, as this can dramatically
1800 boost an ATP's performance (for some reason). *)
1803 |> map (fn t => if member (op aconv) fact_ts t then @{prop True} else t)
1804 val facts = facts |> map (apsnd (pair Axiom))
1806 map (pair prem_kind) hyp_ts @ [(Conjecture, s_not_prop concl_t)]
1807 |> map (apsnd freeze_term)
1808 |> map2 (pair o rpair (Local, General) o string_of_int)
1809 (0 upto length hyp_ts)
1810 val ((conjs, facts), lam_facts) =
1812 |> presimp ? pairself (map (apsnd (apsnd (presimp_prop ctxt))))
1813 |> (if lam_trans = no_lamsN then
1817 #> preprocess_abstractions_in_terms trans_lams
1818 #>> chop (length conjs))
1819 val conjs = conjs |> make_conjecture ctxt format type_enc
1820 val (fact_names, facts) =
1822 |> map_filter (fn (name, (_, t)) =>
1823 make_fact ctxt format type_enc true (name, t)
1824 |> Option.map (pair name))
1826 val lifted = lam_facts |> map (extract_lambda_def o snd o snd)
1828 lam_facts |> map_filter (make_fact ctxt format type_enc true o apsnd snd)
1829 val all_ts = concl_t :: hyp_ts @ fact_ts
1830 val subs = tfree_classes_of_terms all_ts
1831 val supers = tvar_classes_of_terms all_ts
1832 val tycons = type_constrs_of_terms thy all_ts
1833 val (supers, arity_clauses) =
1834 if level_of_type_enc type_enc = No_Types then ([], [])
1835 else make_arity_clauses thy tycons supers
1836 val class_rel_clauses = make_class_rel_clauses thy subs supers
1838 (fact_names |> map single, union (op =) subs supers, conjs,
1839 facts @ lam_facts, class_rel_clauses, arity_clauses, lifted)
1842 val type_guard = `(make_fixed_const NONE) type_guard_name
1844 fun type_guard_iterm format type_enc T tm =
1845 IApp (IConst (type_guard, T --> @{typ bool}, [T])
1846 |> mangle_type_args_in_iterm format type_enc, tm)
1848 fun is_var_positively_naked_in_term _ (SOME false) _ accum = accum
1849 | is_var_positively_naked_in_term name _ (ATerm ((s, _), tms)) accum =
1850 accum orelse (is_tptp_equal s andalso member (op =) tms (ATerm (name, [])))
1851 | is_var_positively_naked_in_term _ _ _ _ = true
1853 fun is_var_ghost_type_arg_in_term thy polym_constrs name pos tm accum =
1854 is_var_positively_naked_in_term name pos tm accum orelse
1856 val var = ATerm (name, [])
1857 fun is_nasty_in_term (ATerm (_, [])) = false
1858 | is_nasty_in_term (ATerm ((s, _), tms)) =
1860 val ary = length tms
1861 val polym_constr = member (op =) polym_constrs s
1862 val ghosts = ghost_type_args thy s ary
1864 exists (fn (j, tm) =>
1865 if polym_constr then
1866 member (op =) ghosts j andalso
1867 (tm = var orelse is_nasty_in_term tm)
1869 tm = var andalso member (op =) ghosts j)
1870 (0 upto ary - 1 ~~ tms)
1871 orelse (not polym_constr andalso exists is_nasty_in_term tms)
1873 | is_nasty_in_term _ = true
1874 in is_nasty_in_term tm end
1876 fun should_guard_var_in_formula thy polym_constrs level pos phi (SOME true)
1878 (case granularity_of_type_level level of
1880 | Positively_Naked_Vars =>
1881 formula_fold pos (is_var_positively_naked_in_term name) phi false
1882 | Ghost_Type_Arg_Vars =>
1883 formula_fold pos (is_var_ghost_type_arg_in_term thy polym_constrs name) phi
1885 | should_guard_var_in_formula _ _ _ _ _ _ _ = true
1887 fun always_guard_var_in_formula _ _ _ _ _ _ _ = true
1889 fun should_generate_tag_bound_decl _ _ _ (SOME true) _ = false
1890 | should_generate_tag_bound_decl ctxt mono (Tags (_, level)) _ T =
1891 granularity_of_type_level level <> All_Vars andalso
1892 should_encode_type ctxt mono level T
1893 | should_generate_tag_bound_decl _ _ _ _ _ = false
1895 fun mk_aterm format type_enc name T_args args =
1896 ATerm (name, map_filter (ho_term_for_type_arg format type_enc) T_args @ args)
1898 fun do_bound_type ctxt format mono type_enc =
1900 Simple_Types (_, _, level) =>
1901 fused_type ctxt mono level 0
1902 #> ho_type_from_typ format type_enc false 0 #> SOME
1905 fun tag_with_type ctxt format mono type_enc pos T tm =
1906 IConst (type_tag, T --> T, [T])
1907 |> mangle_type_args_in_iterm format type_enc
1908 |> ho_term_from_iterm ctxt format 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 format 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
1937 map (term arg_site) args |> mk_aterm format type_enc name T_args
1940 map (term Elsewhere) args |> mk_aterm format type_enc name []
1941 | IAbs ((name, T), tm) =>
1942 if is_type_enc_higher_order type_enc then
1943 AAbs ((name, ho_type_from_typ format type_enc true 0 T),
1946 raise Fail "unexpected lambda-abstraction"
1947 | IApp _ => raise Fail "impossible \"IApp\""
1950 if should_tag_with_type ctxt mono type_enc site u T then
1951 tag_with_type ctxt format mono type_enc pos T t
1955 in term (Top_Level pos) o beta_red [] end
1956 and formula_from_iformula ctxt polym_constrs format mono type_enc
1959 val thy = Proof_Context.theory_of ctxt
1960 val level = level_of_type_enc type_enc
1961 val do_term = ho_term_from_iterm ctxt format mono type_enc
1962 fun do_out_of_bound_type pos phi universal (name, T) =
1963 if should_guard_type ctxt mono type_enc
1964 (fn () => should_guard_var thy polym_constrs level pos phi
1965 universal name) T then
1967 |> type_guard_iterm format type_enc T
1968 |> do_term pos |> AAtom |> SOME
1969 else if should_generate_tag_bound_decl ctxt mono type_enc universal T then
1971 val var = ATerm (name, [])
1972 val tagged_var = tag_with_type ctxt format mono type_enc pos T var
1973 in SOME (AAtom (ATerm (`I tptp_equal, [tagged_var, var]))) end
1976 fun do_formula pos (AQuant (q, xs, phi)) =
1978 val phi = phi |> do_formula pos
1979 val universal = Option.map (q = AExists ? not) pos
1980 val do_bound_type = do_bound_type ctxt format mono type_enc
1982 AQuant (q, xs |> map (apsnd (fn NONE => NONE
1983 | SOME T => do_bound_type T)),
1984 (if q = AForall then mk_ahorn else fold_rev (mk_aconn AAnd))
1986 (fn (_, NONE) => NONE
1988 do_out_of_bound_type pos phi universal (s, T))
1992 | do_formula pos (AConn conn) = aconn_map pos do_formula conn
1993 | do_formula pos (AAtom tm) = AAtom (do_term pos tm)
1996 (* Each fact is given a unique fact number to avoid name clashes (e.g., because
1997 of monomorphization). The TPTP explicitly forbids name clashes, and some of
1998 the remote provers might care. *)
1999 fun formula_line_for_fact ctxt polym_constrs format prefix encode freshen pos
2000 mono type_enc rank (j, {name, stature, kind, iformula, atomic_types}) =
2001 (prefix ^ (if freshen then string_of_int j ^ "_" else "") ^ encode name, kind,
2003 |> formula_from_iformula ctxt polym_constrs format mono type_enc
2004 should_guard_var_in_formula (if pos then SOME true else NONE)
2005 |> close_formula_universally
2006 |> bound_tvars type_enc true atomic_types,
2008 let val rank = rank j in
2010 Intro => isabelle_info introN rank
2011 | Inductive => isabelle_info inductiveN rank
2012 | Elim => isabelle_info elimN rank
2013 | Simp => isabelle_info simpN rank
2014 | Def => isabelle_info defN rank
2015 | _ => isabelle_info "" rank
2019 fun formula_line_for_class_rel_clause type_enc
2020 ({name, subclass, superclass, ...} : class_rel_clause) =
2021 let val ty_arg = ATerm (tvar_a_name, []) in
2022 Formula (class_rel_clause_prefix ^ ascii_of name, Axiom,
2024 [type_class_formula type_enc subclass ty_arg,
2025 type_class_formula type_enc superclass ty_arg])
2026 |> mk_aquant AForall
2027 [(tvar_a_name, atype_of_type_vars type_enc)],
2028 NONE, isabelle_info inductiveN helper_rank)
2031 fun formula_from_arity_atom type_enc (class, t, args) =
2032 ATerm (t, map (fn arg => ATerm (arg, [])) args)
2033 |> type_class_formula type_enc class
2035 fun formula_line_for_arity_clause type_enc
2036 ({name, prem_atoms, concl_atom} : arity_clause) =
2037 Formula (arity_clause_prefix ^ name, Axiom,
2038 mk_ahorn (map (formula_from_arity_atom type_enc) prem_atoms)
2039 (formula_from_arity_atom type_enc concl_atom)
2040 |> mk_aquant AForall
2041 (map (rpair (atype_of_type_vars type_enc)) (#3 concl_atom)),
2042 NONE, isabelle_info inductiveN helper_rank)
2044 fun formula_line_for_conjecture ctxt polym_constrs format mono type_enc
2045 ({name, kind, iformula, atomic_types, ...} : translated_formula) =
2046 Formula (conjecture_prefix ^ name, kind,
2048 |> formula_from_iformula ctxt polym_constrs format mono type_enc
2049 should_guard_var_in_formula (SOME false)
2050 |> close_formula_universally
2051 |> bound_tvars type_enc true atomic_types, NONE, [])
2053 fun type_enc_needs_free_types (Simple_Types (_, Polymorphic, _)) = true
2054 | type_enc_needs_free_types (Simple_Types _) = false
2055 | type_enc_needs_free_types _ = true
2057 fun formula_line_for_free_type j phi =
2058 Formula (tfree_clause_prefix ^ string_of_int j, Hypothesis, phi, NONE, [])
2059 fun formula_lines_for_free_types type_enc (facts : translated_formula list) =
2060 if type_enc_needs_free_types type_enc then
2063 fold (union (op =)) (map #atomic_types facts) []
2064 |> formulas_for_types type_enc add_sorts_on_tfree
2065 in map2 formula_line_for_free_type (0 upto length phis - 1) phis end
2069 (** Symbol declarations **)
2071 fun decl_line_for_class order s =
2072 let val name as (s, _) = `make_type_class s in
2073 Decl (sym_decl_prefix ^ s, name,
2074 if order = First_Order then
2075 ATyAbs ([tvar_a_name],
2076 if avoid_first_order_ghost_type_vars then
2077 AFun (a_itself_atype, bool_atype)
2081 AFun (atype_of_types, bool_atype))
2084 fun decl_lines_for_classes type_enc classes =
2086 Simple_Types (order, Polymorphic, _) =>
2087 map (decl_line_for_class order) classes
2090 fun sym_decl_table_for_facts thy format type_enc sym_tab
2091 (conjs, facts, extra_tms) =
2093 fun add_iterm_syms tm =
2094 let val (head, args) = strip_iterm_comb tm in
2096 IConst ((s, s'), T, T_args) =>
2098 val (pred_sym, in_conj) =
2099 case Symtab.lookup sym_tab s of
2100 SOME ({pred_sym, in_conj, ...} : sym_info) =>
2102 | NONE => (false, false)
2105 Guards _ => not pred_sym
2106 | _ => true) andalso
2107 is_tptp_user_symbol s
2110 Symtab.map_default (s, [])
2111 (insert_type thy #3 (s', T_args, T, pred_sym, length args,
2116 | IAbs (_, tm) => add_iterm_syms tm
2118 #> fold add_iterm_syms args
2120 val add_fact_syms = K add_iterm_syms |> formula_fold NONE |> fact_lift
2121 fun add_formula_var_types (AQuant (_, xs, phi)) =
2122 fold (fn (_, SOME T) => insert_type thy I T | _ => I) xs
2123 #> add_formula_var_types phi
2124 | add_formula_var_types (AConn (_, phis)) =
2125 fold add_formula_var_types phis
2126 | add_formula_var_types _ = I
2128 if polymorphism_of_type_enc type_enc = Polymorphic then [tvar_a]
2129 else fold (fact_lift add_formula_var_types) (conjs @ facts) []
2130 fun add_undefined_const T =
2133 `(make_fixed_const NONE) @{const_name undefined}
2134 |> (case type_arg_policy [] type_enc @{const_name undefined} of
2135 Mangled_Type_Args => mangled_const_name format type_enc [T]
2138 Symtab.map_default (s, [])
2139 (insert_type thy #3 (s', [T], T, false, 0, false))
2141 fun add_TYPE_const () =
2142 let val (s, s') = TYPE_name in
2143 Symtab.map_default (s, [])
2145 (s', [tvar_a], @{typ "'a itself"}, false, 0, false))
2149 |> is_type_enc_fairly_sound type_enc
2150 ? (fold (fold add_fact_syms) [conjs, facts]
2151 #> fold add_iterm_syms extra_tms
2152 #> (case type_enc of
2153 Simple_Types (First_Order, Polymorphic, _) =>
2154 if avoid_first_order_ghost_type_vars then add_TYPE_const ()
2156 | Simple_Types _ => I
2157 | _ => fold add_undefined_const (var_types ())))
2160 (* We add "bool" in case the helper "True_or_False" is included later. *)
2161 fun default_mono level =
2162 {maybe_finite_Ts = [@{typ bool}],
2163 surely_finite_Ts = [@{typ bool}],
2164 maybe_infinite_Ts = known_infinite_types,
2165 surely_infinite_Ts =
2167 Noninf_Nonmono_Types (Strict, _) => []
2168 | _ => known_infinite_types,
2169 maybe_nonmono_Ts = [@{typ bool}]}
2171 (* This inference is described in section 2.3 of Claessen et al.'s "Sorting it
2172 out with monotonicity" paper presented at CADE 2011. *)
2173 fun add_iterm_mononotonicity_info _ _ (SOME false) _ mono = mono
2174 | add_iterm_mononotonicity_info ctxt level _
2175 (IApp (IApp (IConst ((s, _), Type (_, [T, _]), _), tm1), tm2))
2176 (mono as {maybe_finite_Ts, surely_finite_Ts, maybe_infinite_Ts,
2177 surely_infinite_Ts, maybe_nonmono_Ts}) =
2178 let val thy = Proof_Context.theory_of ctxt in
2179 if is_tptp_equal s andalso exists is_maybe_universal_var [tm1, tm2] then
2181 Noninf_Nonmono_Types (strictness, _) =>
2182 if exists (type_instance thy T) surely_infinite_Ts orelse
2183 member (type_equiv thy) maybe_finite_Ts T then
2185 else if is_type_kind_of_surely_infinite ctxt strictness
2186 surely_infinite_Ts T then
2187 {maybe_finite_Ts = maybe_finite_Ts,
2188 surely_finite_Ts = surely_finite_Ts,
2189 maybe_infinite_Ts = maybe_infinite_Ts,
2190 surely_infinite_Ts = surely_infinite_Ts |> insert_type thy I T,
2191 maybe_nonmono_Ts = maybe_nonmono_Ts}
2193 {maybe_finite_Ts = maybe_finite_Ts |> insert (type_equiv thy) T,
2194 surely_finite_Ts = surely_finite_Ts,
2195 maybe_infinite_Ts = maybe_infinite_Ts,
2196 surely_infinite_Ts = surely_infinite_Ts,
2197 maybe_nonmono_Ts = maybe_nonmono_Ts |> insert_type thy I T}
2198 | Fin_Nonmono_Types _ =>
2199 if exists (type_instance thy T) surely_finite_Ts orelse
2200 member (type_equiv thy) maybe_infinite_Ts T then
2202 else if is_type_surely_finite ctxt T then
2203 {maybe_finite_Ts = maybe_finite_Ts,
2204 surely_finite_Ts = surely_finite_Ts |> insert_type thy I T,
2205 maybe_infinite_Ts = maybe_infinite_Ts,
2206 surely_infinite_Ts = surely_infinite_Ts,
2207 maybe_nonmono_Ts = maybe_nonmono_Ts |> insert_type thy I T}
2209 {maybe_finite_Ts = maybe_finite_Ts,
2210 surely_finite_Ts = surely_finite_Ts,
2211 maybe_infinite_Ts = maybe_infinite_Ts |> insert (type_equiv thy) T,
2212 surely_infinite_Ts = surely_infinite_Ts,
2213 maybe_nonmono_Ts = maybe_nonmono_Ts}
2218 | add_iterm_mononotonicity_info _ _ _ _ mono = mono
2219 fun add_fact_mononotonicity_info ctxt level
2220 ({kind, iformula, ...} : translated_formula) =
2221 formula_fold (SOME (kind <> Conjecture))
2222 (add_iterm_mononotonicity_info ctxt level) iformula
2223 fun mononotonicity_info_for_facts ctxt type_enc facts =
2224 let val level = level_of_type_enc type_enc in
2226 |> is_type_level_monotonicity_based level
2227 ? fold (add_fact_mononotonicity_info ctxt level) facts
2230 fun add_iformula_monotonic_types ctxt mono type_enc =
2232 val thy = Proof_Context.theory_of ctxt
2233 val level = level_of_type_enc type_enc
2234 val should_encode = should_encode_type ctxt mono level
2235 fun add_type T = not (should_encode T) ? insert_type thy I T
2236 fun add_args (IApp (tm1, tm2)) = add_args tm1 #> add_term tm2
2238 and add_term tm = add_type (ityp_of tm) #> add_args tm
2239 in formula_fold NONE (K add_term) end
2240 fun add_fact_monotonic_types ctxt mono type_enc =
2241 add_iformula_monotonic_types ctxt mono type_enc |> fact_lift
2242 fun monotonic_types_for_facts ctxt mono type_enc facts =
2243 let val level = level_of_type_enc type_enc in
2244 [] |> (polymorphism_of_type_enc type_enc = Polymorphic andalso
2245 is_type_level_monotonicity_based level andalso
2246 granularity_of_type_level level <> Ghost_Type_Arg_Vars)
2247 ? fold (add_fact_monotonic_types ctxt mono type_enc) facts
2250 fun formula_line_for_guards_mono_type ctxt format mono type_enc T =
2251 Formula (guards_sym_formula_prefix ^
2252 ascii_of (mangled_type format type_enc T),
2254 IConst (`make_bound_var "X", T, [])
2255 |> type_guard_iterm format type_enc T
2257 |> formula_from_iformula ctxt [] format mono type_enc
2258 always_guard_var_in_formula (SOME true)
2259 |> close_formula_universally
2260 |> bound_tvars type_enc true (atomic_types_of T),
2261 NONE, isabelle_info inductiveN helper_rank)
2263 fun formula_line_for_tags_mono_type ctxt format mono type_enc T =
2264 let val x_var = ATerm (`make_bound_var "X", []) in
2265 Formula (tags_sym_formula_prefix ^
2266 ascii_of (mangled_type format type_enc T),
2268 eq_formula type_enc (atomic_types_of T) [] false
2269 (tag_with_type ctxt format mono type_enc NONE T x_var) x_var,
2270 NONE, isabelle_info defN helper_rank)
2273 fun problem_lines_for_mono_types ctxt format mono type_enc Ts =
2275 Simple_Types _ => []
2277 map (formula_line_for_guards_mono_type ctxt format mono type_enc) Ts
2278 | Tags _ => map (formula_line_for_tags_mono_type ctxt format mono type_enc) Ts
2280 fun decl_line_for_sym ctxt format mono type_enc s
2281 (s', T_args, T, pred_sym, ary, _) =
2283 val thy = Proof_Context.theory_of ctxt
2287 else case unprefix_and_unascii const_prefix s of
2290 val s' = s' |> invert_const
2291 val T = s' |> robust_const_type thy
2292 in (T, robust_const_typargs thy (s', T)) end
2293 | NONE => raise Fail "unexpected type arguments"
2295 Decl (sym_decl_prefix ^ s, (s, s'),
2296 T |> fused_type ctxt mono (level_of_type_enc type_enc) ary
2297 |> ho_type_from_typ format type_enc pred_sym ary
2298 |> not (null T_args)
2299 ? curry ATyAbs (map (tvar_name o fst o dest_TVar) T_args))
2302 fun honor_conj_sym_kind in_conj conj_sym_kind =
2303 if in_conj then (conj_sym_kind, conj_sym_kind = Conjecture ? mk_anot)
2306 fun formula_line_for_guards_sym_decl ctxt format conj_sym_kind mono type_enc n s
2307 j (s', T_args, T, _, ary, in_conj) =
2309 val thy = Proof_Context.theory_of ctxt
2310 val (kind, maybe_negate) = honor_conj_sym_kind in_conj conj_sym_kind
2311 val (arg_Ts, res_T) = chop_fun ary T
2312 val bound_names = 1 upto ary |> map (`I o make_bound_var o string_of_int)
2314 bound_names ~~ arg_Ts |> map (fn (name, T) => IConst (name, T, []))
2316 if exists (curry (op =) dummyT) T_args then
2317 case level_of_type_enc type_enc of
2318 All_Types => map SOME arg_Ts
2320 if granularity_of_type_level level = Ghost_Type_Arg_Vars then
2321 let val ghosts = ghost_type_args thy s ary in
2322 map2 (fn j => if member (op =) ghosts j then SOME else K NONE)
2323 (0 upto ary - 1) arg_Ts
2330 Formula (guards_sym_formula_prefix ^ s ^
2331 (if n > 1 then "_" ^ string_of_int j else ""), kind,
2332 IConst ((s, s'), T, T_args)
2333 |> fold (curry (IApp o swap)) bounds
2334 |> type_guard_iterm format type_enc res_T
2335 |> AAtom |> mk_aquant AForall (bound_names ~~ bound_Ts)
2336 |> formula_from_iformula ctxt [] format mono type_enc
2337 always_guard_var_in_formula (SOME true)
2338 |> close_formula_universally
2339 |> bound_tvars type_enc (n > 1) (atomic_types_of T)
2341 NONE, isabelle_info inductiveN helper_rank)
2344 fun formula_lines_for_tags_sym_decl ctxt format conj_sym_kind mono type_enc n s
2345 (j, (s', T_args, T, pred_sym, ary, in_conj)) =
2347 val thy = Proof_Context.theory_of ctxt
2348 val level = level_of_type_enc type_enc
2349 val grain = granularity_of_type_level level
2351 tags_sym_formula_prefix ^ s ^
2352 (if n > 1 then "_" ^ string_of_int j else "")
2353 val (kind, maybe_negate) = honor_conj_sym_kind in_conj conj_sym_kind
2354 val (arg_Ts, res_T) = chop_fun ary T
2355 val bound_names = 1 upto ary |> map (`I o make_bound_var o string_of_int)
2356 val bounds = bound_names |> map (fn name => ATerm (name, []))
2357 val cst = mk_aterm format type_enc (s, s') T_args
2358 val eq = maybe_negate oo eq_formula type_enc (atomic_types_of T) [] pred_sym
2359 val should_encode = should_encode_type ctxt mono level
2360 val tag_with = tag_with_type ctxt format mono type_enc NONE
2361 val add_formula_for_res =
2362 if should_encode res_T then
2365 if grain = Ghost_Type_Arg_Vars then
2366 let val ghosts = ghost_type_args thy s ary in
2367 map2 (fn (j, arg_T) => member (op =) ghosts j ? tag_with arg_T)
2368 (0 upto ary - 1 ~~ arg_Ts) bounds
2373 cons (Formula (ident_base ^ "_res", kind,
2374 eq (tag_with res_T (cst bounds)) (cst tagged_bounds),
2375 NONE, isabelle_info defN helper_rank))
2379 in [] |> not pred_sym ? add_formula_for_res end
2381 fun result_type_of_decl (_, _, T, _, ary, _) = chop_fun ary T |> snd
2383 fun rationalize_decls thy (decls as decl :: (decls' as _ :: _)) =
2385 val T = result_type_of_decl decl
2386 |> map_type_tvar (fn (z, _) => TVar (z, HOLogic.typeS))
2388 if forall (type_generalization thy T o result_type_of_decl) decls' then
2393 | rationalize_decls _ decls = decls
2395 fun problem_lines_for_sym_decls ctxt format conj_sym_kind mono type_enc
2398 Simple_Types _ => [decl_line_for_sym ctxt format mono type_enc s (hd decls)]
2399 | Guards (_, level) =>
2401 val thy = Proof_Context.theory_of ctxt
2402 val decls = decls |> rationalize_decls thy
2403 val n = length decls
2405 decls |> filter (should_encode_type ctxt mono level
2406 o result_type_of_decl)
2408 (0 upto length decls - 1, decls)
2409 |-> map2 (formula_line_for_guards_sym_decl ctxt format conj_sym_kind mono
2412 | Tags (_, level) =>
2413 if granularity_of_type_level level = All_Vars then
2416 let val n = length decls in
2417 (0 upto n - 1 ~~ decls)
2418 |> maps (formula_lines_for_tags_sym_decl ctxt format conj_sym_kind mono
2422 fun problem_lines_for_sym_decl_table ctxt format conj_sym_kind mono type_enc
2423 mono_Ts sym_decl_tab =
2425 val syms = sym_decl_tab |> Symtab.dest |> sort_wrt fst
2427 problem_lines_for_mono_types ctxt format mono type_enc mono_Ts
2429 fold_rev (append o problem_lines_for_sym_decls ctxt format conj_sym_kind
2432 in mono_lines @ decl_lines end
2434 fun pair_append (xs1, xs2) (ys1, ys2) = (xs1 @ ys1, xs2 @ ys2)
2436 fun do_uncurried_alias_lines_for_sym ctxt monom_constrs format conj_sym_kind
2437 mono type_enc sym_tab0 sym_tab base_s0 types in_conj =
2441 val thy = Proof_Context.theory_of ctxt
2442 val (kind, maybe_negate) = honor_conj_sym_kind in_conj conj_sym_kind
2443 val base_name = base_s0 |> `(make_fixed_const (SOME format))
2444 val T = case types of [T] => T | _ => robust_const_type thy base_s0
2445 val T_args = robust_const_typargs thy (base_s0, T)
2446 val (base_name as (base_s, _), T_args) =
2447 mangle_type_args_in_const format type_enc base_name T_args
2448 val base_ary = min_ary_of sym_tab0 base_s
2449 fun do_const name = IConst (name, T, T_args)
2450 val filter_ty_args =
2451 filter_type_args_in_iterm thy monom_constrs type_enc
2453 ho_term_from_iterm ctxt format mono type_enc (SOME true)
2454 val name1 as (s1, _) =
2455 base_name |> ary - 1 > base_ary ? aliased_uncurried (ary - 1)
2456 val name2 as (s2, _) = base_name |> aliased_uncurried ary
2457 val (arg_Ts, _) = chop_fun ary T
2459 1 upto ary |> map (`I o make_bound_var o string_of_int)
2460 val bounds = bound_names ~~ arg_Ts
2461 val (first_bounds, last_bound) =
2462 bounds |> map (fn (name, T) => IConst (name, T, [])) |> split_last
2464 mk_app_op format type_enc (list_app (do_const name1) first_bounds)
2468 list_app (do_const name2) (first_bounds @ [last_bound])
2470 val do_bound_type = do_bound_type ctxt format mono type_enc
2472 eq_formula type_enc (atomic_types_of T)
2473 (map (apsnd do_bound_type) bounds) false
2474 (ho_term_of tm1) (ho_term_of tm2)
2477 [Formula (uncurried_alias_eq_prefix ^ s2, kind, eq |> maybe_negate,
2478 NONE, isabelle_info defN helper_rank)])
2479 |> (if ary - 1 = base_ary orelse Symtab.defined sym_tab s1 then I
2480 else pair_append (do_alias (ary - 1)))
2483 fun uncurried_alias_lines_for_sym ctxt monom_constrs format conj_sym_kind mono
2484 type_enc sym_tab0 sym_tab
2485 (s, {min_ary, types, in_conj, ...} : sym_info) =
2486 case unprefix_and_unascii const_prefix s of
2488 if String.isSubstring uncurried_alias_sep mangled_s then
2490 val base_s0 = mangled_s |> unmangled_const_name |> hd |> invert_const
2492 do_uncurried_alias_lines_for_sym ctxt monom_constrs format conj_sym_kind
2493 mono type_enc sym_tab0 sym_tab base_s0 types in_conj min_ary
2498 fun uncurried_alias_lines_for_sym_table ctxt monom_constrs format conj_sym_kind
2499 mono type_enc uncurried_aliases sym_tab0 sym_tab =
2501 |> uncurried_aliases
2504 o uncurried_alias_lines_for_sym ctxt monom_constrs format
2505 conj_sym_kind mono type_enc sym_tab0 sym_tab) sym_tab
2507 val implicit_declsN = "Should-be-implicit typings"
2508 val explicit_declsN = "Explicit typings"
2509 val uncurried_alias_eqsN = "Uncurried aliases"
2510 val factsN = "Relevant facts"
2511 val class_relsN = "Class relationships"
2512 val aritiesN = "Arities"
2513 val helpersN = "Helper facts"
2514 val conjsN = "Conjectures"
2515 val free_typesN = "Type variables"
2517 (* TFF allows implicit declarations of types, function symbols, and predicate
2518 symbols (with "$i" as the type of individuals), but some provers (e.g.,
2519 SNARK) require explicit declarations. The situation is similar for THF. *)
2521 fun default_type type_enc pred_sym s =
2526 if String.isPrefix type_const_prefix s orelse
2527 String.isPrefix tfree_prefix s then
2531 | _ => individual_atype
2532 fun typ 0 = if pred_sym then bool_atype else ind
2533 | typ ary = AFun (ind, typ (ary - 1))
2536 fun nary_type_constr_type n =
2537 funpow n (curry AFun atype_of_types) atype_of_types
2539 fun undeclared_syms_in_problem type_enc problem =
2541 fun do_sym (name as (s, _)) ty =
2542 if is_tptp_user_symbol s then
2543 Symtab.default (s, (name, ty))
2546 fun do_type (AType (name, tys)) =
2547 do_sym name (fn () => nary_type_constr_type (length tys))
2549 | do_type (AFun (ty1, ty2)) = do_type ty1 #> do_type ty2
2550 | do_type (ATyAbs (_, ty)) = do_type ty
2551 fun do_term pred_sym (ATerm (name as (s, _), tms)) =
2552 do_sym name (fn _ => default_type type_enc pred_sym s (length tms))
2553 #> fold (do_term false) tms
2554 | do_term _ (AAbs ((_, ty), tm)) = do_type ty #> do_term false tm
2555 fun do_formula (AQuant (_, xs, phi)) =
2556 fold do_type (map_filter snd xs) #> do_formula phi
2557 | do_formula (AConn (_, phis)) = fold do_formula phis
2558 | do_formula (AAtom tm) = do_term true tm
2559 fun do_problem_line (Decl (_, _, ty)) = do_type ty
2560 | do_problem_line (Formula (_, _, phi, _, _)) = do_formula phi
2563 |> fold (fn (s, _) => Symtab.default (s, (("", ""), K tvar_a_atype)))
2564 (declared_syms_in_problem problem)
2565 |> fold (fold do_problem_line o snd) problem
2568 fun declare_undeclared_syms_in_atp_problem type_enc problem =
2571 Symtab.fold (fn (_, (("", ""), _)) => I (* already declared *)
2573 cons (Decl (type_decl_prefix ^ s, sym, ty ())))
2574 (undeclared_syms_in_problem type_enc problem) []
2575 in (implicit_declsN, decls) :: problem end
2577 fun exists_subdtype P =
2579 fun ex U = P U orelse
2580 (case U of Datatype.DtType (_, Us) => exists ex Us | _ => false)
2583 fun is_poly_constr (_, Us) =
2584 exists (exists_subdtype (fn Datatype.DtTFree _ => true | _ => false)) Us
2586 fun all_constrs_of_polymorphic_datatypes thy =
2590 #> (fn cs => exists is_poly_constr cs ? append cs))
2591 (Datatype.get_all thy) []
2592 |> List.partition is_poly_constr
2593 |> pairself (map fst)
2595 val app_op_and_predicator_threshold = 50
2597 fun prepare_atp_problem ctxt format conj_sym_kind prem_kind type_enc exporter
2598 lam_trans uncurried_aliases readable_names preproc
2599 hyp_ts concl_t facts =
2601 val thy = Proof_Context.theory_of ctxt
2602 val type_enc = type_enc |> adjust_type_enc format
2603 (* Forcing explicit applications is expensive for polymorphic encodings,
2604 because it takes only one existential variable ranging over "'a => 'b" to
2605 ruin everything. Hence we do it only if there are few facts (which is
2606 normally the case for "metis" and the minimizer). *)
2608 if length facts > app_op_and_predicator_threshold then
2609 if polymorphism_of_type_enc type_enc = Polymorphic then
2614 Sufficient_App_Op_And_Predicator
2616 if lam_trans = keep_lamsN andalso
2617 not (is_type_enc_higher_order type_enc) then
2618 error ("Lambda translation scheme incompatible with first-order \
2622 val (fact_names, classes, conjs, facts, class_rel_clauses, arity_clauses,
2624 translate_formulas ctxt format prem_kind type_enc lam_trans preproc hyp_ts
2626 val sym_tab0 = sym_table_for_facts ctxt type_enc app_op_level conjs facts
2627 val mono = conjs @ facts |> mononotonicity_info_for_facts ctxt type_enc
2628 val (polym_constrs, monom_constrs) =
2629 all_constrs_of_polymorphic_datatypes thy
2630 |>> map (make_fixed_const (SOME format))
2631 fun firstorderize in_helper =
2632 firstorderize_fact thy monom_constrs format type_enc sym_tab0
2633 (uncurried_aliases andalso not in_helper)
2634 val (conjs, facts) = (conjs, facts) |> pairself (map (firstorderize false))
2635 val sym_tab = sym_table_for_facts ctxt type_enc Min_App_Op conjs facts
2637 sym_tab |> helper_facts_for_sym_table ctxt format type_enc
2638 |> map (firstorderize true)
2640 helpers @ conjs @ facts |> monotonic_types_for_facts ctxt mono type_enc
2641 val class_decl_lines = decl_lines_for_classes type_enc classes
2642 val (uncurried_alias_eq_tms, uncurried_alias_eq_lines) =
2643 uncurried_alias_lines_for_sym_table ctxt monom_constrs format
2644 conj_sym_kind mono type_enc uncurried_aliases sym_tab0 sym_tab
2645 val sym_decl_lines =
2646 (conjs, helpers @ facts, uncurried_alias_eq_tms)
2647 |> sym_decl_table_for_facts thy format type_enc sym_tab
2648 |> problem_lines_for_sym_decl_table ctxt format conj_sym_kind mono
2650 val num_facts = length facts
2652 map (formula_line_for_fact ctxt polym_constrs format fact_prefix
2653 ascii_of (not exporter) (not exporter) mono type_enc
2654 (rank_of_fact_num num_facts))
2655 (0 upto num_facts - 1 ~~ facts)
2657 0 upto length helpers - 1 ~~ helpers
2658 |> map (formula_line_for_fact ctxt polym_constrs format helper_prefix I
2659 false true mono type_enc (K default_rank))
2660 (* Reordering these might confuse the proof reconstruction code or the SPASS
2663 [(explicit_declsN, class_decl_lines @ sym_decl_lines),
2664 (uncurried_alias_eqsN, uncurried_alias_eq_lines),
2665 (factsN, fact_lines),
2667 map (formula_line_for_class_rel_clause type_enc) class_rel_clauses),
2668 (aritiesN, map (formula_line_for_arity_clause type_enc) arity_clauses),
2669 (helpersN, helper_lines),
2670 (free_typesN, formula_lines_for_free_types type_enc (facts @ conjs)),
2672 map (formula_line_for_conjecture ctxt polym_constrs format mono
2677 CNF => ensure_cnf_problem
2678 | CNF_UEQ => filter_cnf_ueq_problem
2680 | TFF (_, TPTP_Implicit) => I
2681 | THF (_, TPTP_Implicit, _) => I
2682 | _ => declare_undeclared_syms_in_atp_problem type_enc)
2683 val (problem, pool) = problem |> nice_atp_problem readable_names format
2684 fun add_sym_ary (s, {min_ary, ...} : sym_info) =
2685 min_ary > 0 ? Symtab.insert (op =) (s, min_ary)
2688 case pool of SOME the_pool => snd the_pool | NONE => Symtab.empty,
2689 fact_names |> Vector.fromList,
2691 Symtab.empty |> Symtab.fold add_sym_ary sym_tab)
2695 val conj_weight = 0.0
2696 val hyp_weight = 0.1
2697 val fact_min_weight = 0.2
2698 val fact_max_weight = 1.0
2699 val type_info_default_weight = 0.8
2701 (* Weights are from 0.0 (most important) to 1.0 (least important). *)
2702 fun atp_problem_selection_weights problem =
2704 fun add_term_weights weight (ATerm (s, tms)) =
2705 is_tptp_user_symbol s ? Symtab.default (s, weight)
2706 #> fold (add_term_weights weight) tms
2707 | add_term_weights weight (AAbs (_, tm)) = add_term_weights weight tm
2708 fun add_line_weights weight (Formula (_, _, phi, _, _)) =
2709 formula_fold NONE (K (add_term_weights weight)) phi
2710 | add_line_weights _ _ = I
2711 fun add_conjectures_weights [] = I
2712 | add_conjectures_weights conjs =
2713 let val (hyps, conj) = split_last conjs in
2714 add_line_weights conj_weight conj
2715 #> fold (add_line_weights hyp_weight) hyps
2717 fun add_facts_weights facts =
2719 val num_facts = length facts
2721 fact_min_weight + (fact_max_weight - fact_min_weight) * Real.fromInt j
2722 / Real.fromInt num_facts
2724 map weight_of (0 upto num_facts - 1) ~~ facts
2725 |> fold (uncurry add_line_weights)
2727 val get = these o AList.lookup (op =) problem
2730 |> add_conjectures_weights (get free_typesN @ get conjsN)
2731 |> add_facts_weights (get factsN)
2732 |> fold (fold (add_line_weights type_info_default_weight) o get)
2733 [explicit_declsN, class_relsN, aritiesN]
2735 |> sort (prod_ord Real.compare string_ord o pairself swap)
2738 (* Ugly hack: may make innocent victims (collateral damage) *)
2739 fun may_be_app s args = String.isPrefix app_op_name s andalso length args = 2
2740 fun may_be_predicator s =
2741 member (op =) [predicator_name, prefixed_predicator_name] s
2743 fun strip_predicator (tm as ATerm (s, [tm'])) =
2744 if may_be_predicator s then tm' else tm
2745 | strip_predicator tm = tm
2747 fun make_head_roll (ATerm (s, tms)) =
2748 if may_be_app s tms then make_head_roll (hd tms) ||> append (tl tms)
2750 | make_head_roll _ = ("", [])
2752 fun strip_up_to_predicator (AQuant (_, _, phi)) = strip_up_to_predicator phi
2753 | strip_up_to_predicator (AConn (_, phis)) = maps strip_up_to_predicator phis
2754 | strip_up_to_predicator (AAtom tm) = [strip_predicator tm]
2756 fun strip_ahorn_etc (AQuant (_, _, phi)) = strip_ahorn_etc phi
2757 | strip_ahorn_etc (AConn (AImplies, [phi1, phi2])) =
2758 strip_ahorn_etc phi2 |>> append (strip_up_to_predicator phi1)
2759 | strip_ahorn_etc phi = ([], hd (strip_up_to_predicator phi))
2761 fun strip_iff_etc (AQuant (_, _, phi)) = strip_iff_etc phi
2762 | strip_iff_etc (AConn (AIff, [phi1, phi2])) =
2763 pairself strip_up_to_predicator (phi1, phi2)
2764 | strip_iff_etc _ = ([], [])
2766 val max_term_order_weight = 2147483647
2768 fun atp_problem_term_order_info problem =
2771 Graph.default_node (s, ())
2772 #> Graph.default_node (s', ())
2773 #> Graph.add_edge_acyclic (s, s')
2774 fun add_term_deps head (ATerm (s, args)) =
2775 if is_tptp_user_symbol head then
2776 (if is_tptp_user_symbol s then perhaps (try (add_edge s head)) else I)
2777 #> fold (add_term_deps head) args
2780 | add_term_deps head (AAbs (_, tm)) = add_term_deps head tm
2781 fun add_intro_deps pred (Formula (_, role, phi, _, info)) =
2782 if pred (role, info) then
2783 let val (hyps, concl) = strip_ahorn_etc phi in
2784 case make_head_roll concl of
2785 (head, args as _ :: _) => fold (add_term_deps head) (hyps @ args)
2790 | add_intro_deps _ _ = I
2791 fun add_atom_eq_deps (SOME true) (ATerm (s, [lhs as _, rhs])) =
2792 if is_tptp_equal s then
2793 case make_head_roll lhs of
2794 (head, args as _ :: _) => fold (add_term_deps head) (rhs :: args)
2798 | add_atom_eq_deps _ _ = I
2799 fun add_eq_deps pred (Formula (_, role, phi, _, info)) =
2800 if pred (role, info) then
2801 case strip_iff_etc phi of
2803 (case make_head_roll lhs of
2804 (head, args as _ :: _) => fold (add_term_deps head) (rhs @ args)
2806 | _ => formula_fold (SOME (role <> Conjecture)) add_atom_eq_deps phi
2809 | add_eq_deps _ _ = I
2810 fun has_status status (_, info) =
2811 extract_isabelle_status info = SOME status
2812 fun is_conj (role, _) = (role = Conjecture orelse role = Hypothesis)
2815 |> fold (fold (add_eq_deps (has_status defN)) o snd) problem
2816 |> fold (fold (add_eq_deps (has_status simpN orf is_conj)) o snd) problem
2817 |> fold (fold (add_intro_deps (has_status inductiveN)) o snd) problem
2818 |> fold (fold (add_intro_deps (has_status introN)) o snd) problem
2819 fun next_weight w = if w + w <= max_term_order_weight then w + w else w + 1
2820 fun add_weights _ [] = I
2821 | add_weights weight syms =
2822 fold (AList.update (op =) o rpair weight) syms
2823 #> add_weights (next_weight weight)
2824 (fold (union (op =) o Graph.immediate_succs graph) syms [])
2826 (* Sorting is not just for aesthetics: It specifies the precedence order
2827 for the term ordering (KBO or LPO), from smaller to larger values. *)
2828 [] |> add_weights 1 (Graph.minimals graph) |> sort (int_ord o pairself snd)