114 |
114 |
115 (* Type variables are given the basic sort "HOL.type". Some will later be |
115 (* Type variables are given the basic sort "HOL.type". Some will later be |
116 constrained by information from type literals, or by type inference. *) |
116 constrained by information from type literals, or by type inference. *) |
117 fun typ_of_atp ctxt (u as ATerm ((a, _), us)) = |
117 fun typ_of_atp ctxt (u as ATerm ((a, _), us)) = |
118 let val Ts = map (typ_of_atp ctxt) us in |
118 let val Ts = map (typ_of_atp ctxt) us in |
119 case unprefix_and_unascii type_const_prefix a of |
119 (case unprefix_and_unascii type_const_prefix a of |
120 SOME b => Type (invert_const b, Ts) |
120 SOME b => Type (invert_const b, Ts) |
121 | NONE => |
121 | NONE => |
122 if not (null us) then |
122 if not (null us) then |
123 raise ATP_TERM [u] (* only "tconst"s have type arguments *) |
123 raise ATP_TERM [u] (* only "tconst"s have type arguments *) |
124 else case unprefix_and_unascii tfree_prefix a of |
124 else |
125 SOME b => make_tfree ctxt b |
125 (case unprefix_and_unascii tfree_prefix a of |
126 | NONE => |
126 SOME b => make_tfree ctxt b |
127 (* Could be an Isabelle variable or a variable from the ATP, say "X1" |
127 | NONE => |
128 or "_5018". Sometimes variables from the ATP are indistinguishable |
128 (* The term could be an Isabelle variable or a variable from the ATP, say "X1" or "_5018". |
129 from Isabelle variables, which forces us to use a type parameter in |
129 Sometimes variables from the ATP are indistinguishable from Isabelle variables, which |
130 all cases. *) |
130 forces us to use a type parameter in all cases. *) |
131 (a |> perhaps (unprefix_and_unascii tvar_prefix), HOLogic.typeS) |
131 (a |> perhaps (unprefix_and_unascii tvar_prefix), HOLogic.typeS) |
132 |> Type_Infer.param 0 |
132 |> Type_Infer.param 0)) |
133 end |
133 end |
134 |
134 |
135 (* Type class literal applied to a type. Returns triple of polarity, class, |
135 (* Type class literal applied to a type. Returns triple of polarity, class, type. *) |
136 type. *) |
|
137 fun type_constraint_of_term ctxt (u as ATerm ((a, _), us)) = |
136 fun type_constraint_of_term ctxt (u as ATerm ((a, _), us)) = |
138 case (unprefix_and_unascii class_prefix a, map (typ_of_atp ctxt) us) of |
137 (case (unprefix_and_unascii class_prefix a, map (typ_of_atp ctxt) us) of |
139 (SOME b, [T]) => (b, T) |
138 (SOME b, [T]) => (b, T) |
140 | _ => raise ATP_TERM [u] |
139 | _ => raise ATP_TERM [u]) |
141 |
140 |
142 (* Accumulate type constraints in a formula: negative type literals. *) |
141 (* Accumulate type constraints in a formula: negative type literals. *) |
143 fun add_var (key, z) = Vartab.map_default (key, []) (cons z) |
142 fun add_var (key, z) = Vartab.map_default (key, []) (cons z) |
144 fun add_type_constraint false (cl, TFree (a ,_)) = add_var ((a, ~1), cl) |
143 fun add_type_constraint false (cl, TFree (a ,_)) = add_var ((a, ~1), cl) |
145 | add_type_constraint false (cl, TVar (ix, _)) = add_var (ix, cl) |
144 | add_type_constraint false (cl, TVar (ix, _)) = add_var (ix, cl) |
148 fun repair_var_name s = |
147 fun repair_var_name s = |
149 let |
148 let |
150 fun subscript_name s n = s ^ nat_subscript n |
149 fun subscript_name s n = s ^ nat_subscript n |
151 val s = s |> String.map Char.toLower |
150 val s = s |> String.map Char.toLower |
152 in |
151 in |
153 case space_explode "_" s of |
152 (case space_explode "_" s of |
154 [_] => (case take_suffix Char.isDigit (String.explode s) of |
153 [_] => |
155 (cs1 as _ :: _, cs2 as _ :: _) => |
154 (case take_suffix Char.isDigit (String.explode s) of |
156 subscript_name (String.implode cs1) |
155 (cs1 as _ :: _, cs2 as _ :: _) => |
157 (the (Int.fromString (String.implode cs2))) |
156 subscript_name (String.implode cs1) (the (Int.fromString (String.implode cs2))) |
158 | (_, _) => s) |
157 | (_, _) => s) |
159 | [s1, s2] => (case Int.fromString s2 of |
158 | [s1, s2] => (case Int.fromString s2 of SOME n => subscript_name s1 n | NONE => s) |
160 SOME n => subscript_name s1 n |
159 | _ => s) |
161 | NONE => s) |
|
162 | _ => s |
|
163 end |
160 end |
164 |
161 |
165 (* The number of type arguments of a constant, zero if it's monomorphic. For |
162 (* The number of type arguments of a constant, zero if it's monomorphic. For (instances of) Skolem |
166 (instances of) Skolem pseudoconstants, this information is encoded in the |
163 pseudoconstants, this information is encoded in the constant name. *) |
167 constant name. *) |
|
168 fun robust_const_num_type_args thy s = |
164 fun robust_const_num_type_args thy s = |
169 if String.isPrefix skolem_const_prefix s then |
165 if String.isPrefix skolem_const_prefix s then |
170 s |> Long_Name.explode |> List.last |> Int.fromString |> the |
166 s |> Long_Name.explode |> List.last |> Int.fromString |> the |
171 else if String.isPrefix lam_lifted_prefix s then |
167 else if String.isPrefix lam_lifted_prefix s then |
172 if String.isPrefix lam_lifted_poly_prefix s then 2 else 0 |
168 if String.isPrefix lam_lifted_poly_prefix s then 2 else 0 |
180 | loose_aconv (t, t') = t aconv t' |
176 | loose_aconv (t, t') = t aconv t' |
181 |
177 |
182 val spass_skolem_prefix = "sk" (* "skc" or "skf" *) |
178 val spass_skolem_prefix = "sk" (* "skc" or "skf" *) |
183 val vampire_skolem_prefix = "sK" |
179 val vampire_skolem_prefix = "sK" |
184 |
180 |
185 (* First-order translation. No types are known for variables. "HOLogic.typeT" |
181 (* First-order translation. No types are known for variables. "HOLogic.typeT" should allow them to |
186 should allow them to be inferred. *) |
182 be inferred. *) |
187 fun term_of_atp ctxt textual sym_tab = |
183 fun term_of_atp ctxt textual sym_tab = |
188 let |
184 let |
189 val thy = Proof_Context.theory_of ctxt |
185 val thy = Proof_Context.theory_of ctxt |
190 (* For Metis, we use 1 rather than 0 because variable references in clauses |
186 (* For Metis, we use 1 rather than 0 because variable references in clauses may otherwise |
191 may otherwise conflict with variable constraints in the goal. At least, |
187 conflict with variable constraints in the goal. At least, type inference often fails |
192 type inference often fails otherwise. See also "axiom_inference" in |
188 otherwise. See also "axiom_inference" in "Metis_Reconstruct". *) |
193 "Metis_Reconstruct". *) |
|
194 val var_index = if textual then 0 else 1 |
189 val var_index = if textual then 0 else 1 |
195 fun do_term extra_ts opt_T u = |
190 fun do_term extra_ts opt_T u = |
196 case u of |
191 (case u of |
197 ATerm ((s, _), us) => |
192 ATerm ((s, _), us) => |
198 if s = "" |
193 if s = "" |
199 then error "Isar proof reconstruction failed because the ATP proof \ |
194 then error "Isar proof reconstruction failed because the ATP proof \ |
200 \contains unparsable material." |
195 \contains unparsable material." |
201 else if String.isPrefix native_type_prefix s then |
196 else if String.isPrefix native_type_prefix s then |
206 loose_aconv (hd ts, List.last ts) then |
201 loose_aconv (hd ts, List.last ts) then |
207 @{const True} |
202 @{const True} |
208 else |
203 else |
209 list_comb (Const (@{const_name HOL.eq}, HOLogic.typeT), ts) |
204 list_comb (Const (@{const_name HOL.eq}, HOLogic.typeT), ts) |
210 end |
205 end |
211 else case unprefix_and_unascii const_prefix s of |
206 else |
212 SOME s' => |
207 (case unprefix_and_unascii const_prefix s of |
213 let |
208 SOME s' => |
214 val ((s', s''), mangled_us) = |
209 let |
215 s' |> unmangled_const |>> `invert_const |
210 val ((s', s''), mangled_us) = |
216 in |
211 s' |> unmangled_const |>> `invert_const |
217 if s' = type_tag_name then |
212 in |
218 case mangled_us @ us of |
213 if s' = type_tag_name then |
219 [typ_u, term_u] => |
214 (case mangled_us @ us of |
220 do_term extra_ts (SOME (typ_of_atp ctxt typ_u)) term_u |
215 [typ_u, term_u] => do_term extra_ts (SOME (typ_of_atp ctxt typ_u)) term_u |
221 | _ => raise ATP_TERM us |
216 | _ => raise ATP_TERM us) |
222 else if s' = predicator_name then |
217 else if s' = predicator_name then |
223 do_term [] (SOME @{typ bool}) (hd us) |
218 do_term [] (SOME @{typ bool}) (hd us) |
224 else if s' = app_op_name then |
219 else if s' = app_op_name then |
225 let val extra_t = do_term [] NONE (List.last us) in |
220 let val extra_t = do_term [] NONE (List.last us) in |
226 do_term (extra_t :: extra_ts) |
221 do_term (extra_t :: extra_ts) |
227 (case opt_T of |
222 (case opt_T of |
228 SOME T => SOME (slack_fastype_of extra_t --> T) |
223 SOME T => SOME (slack_fastype_of extra_t --> T) |
229 | NONE => NONE) |
224 | NONE => NONE) |
230 (nth us (length us - 2)) |
225 (nth us (length us - 2)) |
231 end |
226 end |
232 else if s' = type_guard_name then |
227 else if s' = type_guard_name then |
233 @{const True} (* ignore type predicates *) |
228 @{const True} (* ignore type predicates *) |
234 else |
229 else |
235 let |
230 let |
236 val new_skolem = String.isPrefix new_skolem_const_prefix s'' |
231 val new_skolem = String.isPrefix new_skolem_const_prefix s'' |
237 val num_ty_args = |
232 val num_ty_args = |
238 length us - the_default 0 (Symtab.lookup sym_tab s) |
233 length us - the_default 0 (Symtab.lookup sym_tab s) |
239 val (type_us, term_us) = |
234 val (type_us, term_us) = |
240 chop num_ty_args us |>> append mangled_us |
235 chop num_ty_args us |>> append mangled_us |
241 val term_ts = map (do_term [] NONE) term_us |
236 val term_ts = map (do_term [] NONE) term_us |
242 val T = |
237 val T = |
243 (if not (null type_us) andalso |
238 (if not (null type_us) andalso |
244 robust_const_num_type_args thy s' = length type_us then |
239 robust_const_num_type_args thy s' = length type_us then |
245 let val Ts = type_us |> map (typ_of_atp ctxt) in |
240 let val Ts = type_us |> map (typ_of_atp ctxt) in |
246 if new_skolem then |
241 if new_skolem then |
247 SOME (Type_Infer.paramify_vars (tl Ts ---> hd Ts)) |
242 SOME (Type_Infer.paramify_vars (tl Ts ---> hd Ts)) |
248 else if textual then |
243 else if textual then |
249 try (Sign.const_instance thy) (s', Ts) |
244 try (Sign.const_instance thy) (s', Ts) |
250 else |
245 else |
251 NONE |
246 NONE |
252 end |
247 end |
253 else |
248 else |
254 NONE) |
249 NONE) |
255 |> (fn SOME T => T |
250 |> (fn SOME T => T |
256 | NONE => map slack_fastype_of term_ts ---> |
251 | NONE => |
257 (case opt_T of |
252 map slack_fastype_of term_ts ---> the_default HOLogic.typeT opt_T) |
258 SOME T => T |
253 val t = |
259 | NONE => HOLogic.typeT)) |
254 if new_skolem then Var ((new_skolem_var_name_of_const s'', var_index), T) |
260 val t = |
255 else Const (unproxify_const s', T) |
261 if new_skolem then |
256 in list_comb (t, term_ts @ extra_ts) end |
262 Var ((new_skolem_var_name_of_const s'', var_index), T) |
257 end |
263 else |
258 | NONE => (* a free or schematic variable *) |
264 Const (unproxify_const s', T) |
259 let |
265 in list_comb (t, term_ts @ extra_ts) end |
260 (* This assumes that distinct names are mapped to distinct names by |
266 end |
261 "Variable.variant_frees". This does not hold in general but |
267 | NONE => (* a free or schematic variable *) |
262 should hold for ATP-generated Skolem function names, since these |
268 let |
263 end with a digit and "variant_frees" appends letters. *) |
269 (* This assumes that distinct names are mapped to distinct names by |
264 fun fresh_up s = |
270 "Variable.variant_frees". This does not hold in general but |
265 [(s, ())] |> Variable.variant_frees ctxt [] |> hd |> fst |
271 should hold for ATP-generated Skolem function names, since these |
266 val term_ts = |
272 end with a digit and "variant_frees" appends letters. *) |
267 map (do_term [] NONE) us |
273 fun fresh_up s = |
268 (* SPASS (3.8ds) and Vampire (2.6) pass arguments to Skolem functions in reverse |
274 [(s, ())] |> Variable.variant_frees ctxt [] |> hd |> fst |
269 order, which is incompatible with the new Metis skolemizer. *) |
275 val term_ts = |
270 |> exists (fn pre => String.isPrefix pre s) |
276 map (do_term [] NONE) us |
271 [spass_skolem_prefix, vampire_skolem_prefix] ? rev |
277 (* SPASS (3.8ds) and Vampire (2.6) pass arguments to Skolem functions in reverse |
272 val ts = term_ts @ extra_ts |
278 order, which is incompatible with the new Metis skolemizer. *) |
273 val T = |
279 |> exists (fn pre => String.isPrefix pre s) |
274 (case opt_T of |
280 [spass_skolem_prefix, vampire_skolem_prefix] ? rev |
275 SOME T => map slack_fastype_of term_ts ---> T |
281 val ts = term_ts @ extra_ts |
276 | NONE => map slack_fastype_of ts ---> HOLogic.typeT) |
282 val T = |
277 val t = |
283 case opt_T of |
278 (case unprefix_and_unascii fixed_var_prefix s of |
284 SOME T => map slack_fastype_of term_ts ---> T |
279 SOME s => Free (s, T) |
285 | NONE => map slack_fastype_of ts ---> HOLogic.typeT |
|
286 val t = |
|
287 case unprefix_and_unascii fixed_var_prefix s of |
|
288 SOME s => Free (s, T) |
|
289 | NONE => |
|
290 case unprefix_and_unascii schematic_var_prefix s of |
|
291 SOME s => Var ((s, var_index), T) |
|
292 | NONE => |
280 | NONE => |
293 if textual andalso not (is_tptp_variable s) then |
281 (case unprefix_and_unascii schematic_var_prefix s of |
294 Free (s |> textual ? (repair_var_name #> fresh_up), T) |
282 SOME s => Var ((s, var_index), T) |
295 else |
283 | NONE => |
296 Var ((s |> textual ? repair_var_name, var_index), T) |
284 if textual andalso not (is_tptp_variable s) then |
297 in list_comb (t, ts) end |
285 Free (s |> textual ? (repair_var_name #> fresh_up), T) |
|
286 else |
|
287 Var ((s |> textual ? repair_var_name, var_index), T))) |
|
288 in list_comb (t, ts) end)) |
298 in do_term [] end |
289 in do_term [] end |
299 |
290 |
300 fun term_of_atom ctxt textual sym_tab pos (u as ATerm ((s, _), _)) = |
291 fun term_of_atom ctxt textual sym_tab pos (u as ATerm ((s, _), _)) = |
301 if String.isPrefix class_prefix s then |
292 if String.isPrefix class_prefix s then |
302 add_type_constraint pos (type_constraint_of_term ctxt u) |
293 add_type_constraint pos (type_constraint_of_term ctxt u) |
323 fun quantify_over_var quant_of var_s t = |
314 fun quantify_over_var quant_of var_s t = |
324 let |
315 let |
325 val vars = [] |> Term.add_vars t |> filter (fn ((s, _), _) => s = var_s) |
316 val vars = [] |> Term.add_vars t |> filter (fn ((s, _), _) => s = var_s) |
326 val normTs = vars |> AList.group (op =) |> map (apsnd hd) |
317 val normTs = vars |> AList.group (op =) |> map (apsnd hd) |
327 fun norm_var_types (Var (x, T)) = |
318 fun norm_var_types (Var (x, T)) = |
328 Var (x, case AList.lookup (op =) normTs x of |
319 Var (x, (case AList.lookup (op =) normTs x of NONE => T | SOME T' => T')) |
329 NONE => T |
|
330 | SOME T' => T') |
|
331 | norm_var_types t = t |
320 | norm_var_types t = t |
332 in t |> map_aterms norm_var_types |> fold_rev quant_of (map Var normTs) end |
321 in t |> map_aterms norm_var_types |> fold_rev quant_of (map Var normTs) end |
333 |
322 |
334 (* Interpret an ATP formula as a HOL term, extracting sort constraints as they |
323 (* Interpret an ATP formula as a HOL term, extracting sort constraints as they |
335 appear in the formula. *) |
324 appear in the formula. *) |
336 fun prop_of_atp ctxt textual sym_tab phi = |
325 fun prop_of_atp ctxt textual sym_tab phi = |
337 let |
326 let |
338 fun do_formula pos phi = |
327 fun do_formula pos phi = |
339 case phi of |
328 (case phi of |
340 AQuant (_, [], phi) => do_formula pos phi |
329 AQuant (_, [], phi) => do_formula pos phi |
341 | AQuant (q, (s, _) :: xs, phi') => |
330 | AQuant (q, (s, _) :: xs, phi') => |
342 do_formula pos (AQuant (q, xs, phi')) |
331 do_formula pos (AQuant (q, xs, phi')) |
343 (* FIXME: TFF *) |
332 (* FIXME: TFF *) |
344 #>> quantify_over_var (case q of AForall => forall_of | AExists => exists_of) |
333 #>> quantify_over_var (case q of AForall => forall_of | AExists => exists_of) |
352 | AOr => s_disj |
341 | AOr => s_disj |
353 | AImplies => s_imp |
342 | AImplies => s_imp |
354 | AIff => s_iff |
343 | AIff => s_iff |
355 | ANot => raise Fail "impossible connective") |
344 | ANot => raise Fail "impossible connective") |
356 | AAtom tm => term_of_atom ctxt textual sym_tab pos tm |
345 | AAtom tm => term_of_atom ctxt textual sym_tab pos tm |
357 | _ => raise ATP_FORMULA [phi] |
346 | _ => raise ATP_FORMULA [phi]) |
358 in repair_tvar_sorts (do_formula true phi Vartab.empty) end |
347 in |
|
348 repair_tvar_sorts (do_formula true phi Vartab.empty) |
|
349 end |
359 |
350 |
360 fun find_first_in_list_vector vec key = |
351 fun find_first_in_list_vector vec key = |
361 Vector.foldl (fn (ps, NONE) => AList.lookup (op =) ps key |
352 Vector.foldl (fn (ps, NONE) => AList.lookup (op =) ps key |
362 | (_, value) => value) NONE vec |
353 | (_, value) => value) NONE vec |
363 |
354 |
364 val unprefix_fact_number = space_implode "_" o tl o space_explode "_" |
355 val unprefix_fact_number = space_implode "_" o tl o space_explode "_" |
365 |
356 |
366 fun resolve_one_named_fact fact_names s = |
357 fun resolve_one_named_fact fact_names s = |
367 case try (unprefix fact_prefix) s of |
358 (case try (unprefix fact_prefix) s of |
368 SOME s' => |
359 SOME s' => |
369 let val s' = s' |> unprefix_fact_number |> unascii_of in |
360 let val s' = s' |> unprefix_fact_number |> unascii_of in |
370 s' |> find_first_in_list_vector fact_names |> Option.map (pair s') |
361 s' |> find_first_in_list_vector fact_names |> Option.map (pair s') |
371 end |
362 end |
372 | NONE => NONE |
363 | NONE => NONE) |
373 |
364 |
374 fun resolve_fact fact_names = map_filter (resolve_one_named_fact fact_names) |
365 fun resolve_fact fact_names = map_filter (resolve_one_named_fact fact_names) |
375 |
366 |
376 fun resolve_one_named_conjecture s = |
367 fun resolve_one_named_conjecture s = |
377 case try (unprefix conjecture_prefix) s of |
368 (case try (unprefix conjecture_prefix) s of |
378 SOME s' => Int.fromString s' |
369 SOME s' => Int.fromString s' |
379 | NONE => NONE |
370 | NONE => NONE) |
380 |
371 |
381 val resolve_conjecture = map_filter resolve_one_named_conjecture |
372 val resolve_conjecture = map_filter resolve_one_named_conjecture |
382 |
373 |
383 fun is_axiom_used_in_proof pred = |
374 fun is_axiom_used_in_proof pred = |
384 exists (fn ((_, ss), _, _, _, []) => exists pred ss | _ => false) |
375 exists (fn ((_, ss), _, _, _, []) => exists pred ss | _ => false) |
404 |
395 |
405 fun add_fact ctxt fact_names ((_, ss), _, _, rule, deps) = |
396 fun add_fact ctxt fact_names ((_, ss), _, _, rule, deps) = |
406 (if rule = leo2_extcnf_equal_neg_rule then |
397 (if rule = leo2_extcnf_equal_neg_rule then |
407 insert (op =) (ext_name ctxt, (Global, General)) |
398 insert (op =) (ext_name ctxt, (Global, General)) |
408 else if rule = leo2_unfold_def_rule then |
399 else if rule = leo2_unfold_def_rule then |
409 (* LEO 1.3.3 does not record definitions properly, leading to missing |
400 (* LEO 1.3.3 does not record definitions properly, leading to missing dependencies in the TSTP |
410 dependencies in the TSTP proof. Remove the next line once this is |
401 proof. Remove the next line once this is fixed. *) |
411 fixed. *) |
|
412 add_non_rec_defs fact_names |
402 add_non_rec_defs fact_names |
413 else if rule = agsyhol_core_rule orelse rule = satallax_core_rule then |
403 else if rule = agsyhol_core_rule orelse rule = satallax_core_rule then |
414 (fn [] => |
404 (fn [] => |
415 (* agsyHOL and Satallax don't include definitions in their |
405 (* agsyHOL and Satallax don't include definitions in their unsatisfiable cores, so we |
416 unsatisfiable cores, so we assume the worst and include them all |
406 assume the worst and include them all here. *) |
417 here. *) |
|
418 [(ext_name ctxt, (Global, General))] |> add_non_rec_defs fact_names |
407 [(ext_name ctxt, (Global, General))] |> add_non_rec_defs fact_names |
419 | facts => facts) |
408 | facts => facts) |
420 else |
409 else |
421 I) |
410 I) |
422 #> (if null deps then union (op =) (resolve_fact fact_names ss) else I) |
411 #> (if null deps then union (op =) (resolve_fact fact_names ss) else I) |
443 String.isSubstring ascii_of_lam_fact_prefix s |
432 String.isSubstring ascii_of_lam_fact_prefix s |
444 |
433 |
445 val is_combinator_def = String.isPrefix (helper_prefix ^ combinator_prefix) |
434 val is_combinator_def = String.isPrefix (helper_prefix ^ combinator_prefix) |
446 |
435 |
447 fun lam_trans_of_atp_proof atp_proof default = |
436 fun lam_trans_of_atp_proof atp_proof default = |
448 case (is_axiom_used_in_proof is_combinator_def atp_proof, |
437 (case (is_axiom_used_in_proof is_combinator_def atp_proof, |
449 is_axiom_used_in_proof is_lam_lifted atp_proof) of |
438 is_axiom_used_in_proof is_lam_lifted atp_proof) of |
450 (false, false) => default |
439 (false, false) => default |
451 | (false, true) => liftingN |
440 | (false, true) => liftingN |
452 (* | (true, true) => combs_and_liftingN -- not supported by "metis" *) |
441 (* | (true, true) => combs_and_liftingN -- not supported by "metis" *) |
453 | (true, _) => combsN |
442 | (true, _) => combsN) |
454 |
443 |
455 val is_typed_helper_name = |
444 val is_typed_helper_name = |
456 String.isPrefix helper_prefix andf String.isSuffix typed_helper_suffix |
445 String.isPrefix helper_prefix andf String.isSuffix typed_helper_suffix |
457 |
446 |
458 fun is_typed_helper_used_in_atp_proof atp_proof = |
447 fun is_typed_helper_used_in_atp_proof atp_proof = |