116 (case strip_combterm_comb tm of |
117 (case strip_combterm_comb tm of |
117 (CombConst(("equal", _), _, _), tms) => |
118 (CombConst(("equal", _), _, _), tms) => |
118 metis_lit pol "=" (map hol_term_to_fol_FT tms) |
119 metis_lit pol "=" (map hol_term_to_fol_FT tms) |
119 | _ => metis_lit pol "{}" [hol_term_to_fol_FT tm]) (*hBOOL*); |
120 | _ => metis_lit pol "{}" [hol_term_to_fol_FT tm]) (*hBOOL*); |
120 |
121 |
121 fun literals_of_hol_thm thy mode t = |
122 fun literals_of_hol_term thy mode t = |
122 let val (lits, types_sorts) = literals_of_term thy t |
123 let val (lits, types_sorts) = literals_of_term thy t |
123 in (map (hol_literal_to_fol mode) lits, types_sorts) end; |
124 in (map (hol_literal_to_fol mode) lits, types_sorts) end; |
124 |
125 |
125 (*Sign should be "true" for conjecture type constraints, "false" for type lits in clauses.*) |
126 (*Sign should be "true" for conjecture type constraints, "false" for type lits in clauses.*) |
126 fun metis_of_type_literals pos (TyLitVar (s, (s', _))) = |
127 fun metis_of_type_literals pos (TyLitVar (s, (s', _))) = |
132 | default_sort ctxt (TFree (x, s)) = (s = the_default [] (Variable.def_sort ctxt (x, ~1))); |
133 | default_sort ctxt (TFree (x, s)) = (s = the_default [] (Variable.def_sort ctxt (x, ~1))); |
133 |
134 |
134 fun metis_of_tfree tf = |
135 fun metis_of_tfree tf = |
135 Metis.Thm.axiom (Metis.LiteralSet.singleton (metis_of_type_literals true tf)); |
136 Metis.Thm.axiom (Metis.LiteralSet.singleton (metis_of_type_literals true tf)); |
136 |
137 |
137 fun hol_thm_to_fol is_conjecture ctxt mode th = |
138 fun hol_thm_to_fol is_conjecture ctxt mode j skolem_somes th = |
138 let val thy = ProofContext.theory_of ctxt |
139 let |
139 val (mlits, types_sorts) = |
140 val thy = ProofContext.theory_of ctxt |
140 (literals_of_hol_thm thy mode o HOLogic.dest_Trueprop o prop_of) th |
141 val (skolem_somes, (mlits, types_sorts)) = |
|
142 th |> prop_of |> kill_skolem_Eps j skolem_somes |
|
143 ||> (HOLogic.dest_Trueprop #> literals_of_hol_term thy mode) |
141 in |
144 in |
142 if is_conjecture then |
145 if is_conjecture then |
143 (Metis.Thm.axiom (Metis.LiteralSet.fromList mlits), |
146 (Metis.Thm.axiom (Metis.LiteralSet.fromList mlits), |
144 type_literals_for_types types_sorts) |
147 type_literals_for_types types_sorts, skolem_somes) |
145 else |
148 else |
146 let val tylits = filter_out (default_sort ctxt) types_sorts |
149 let val tylits = filter_out (default_sort ctxt) types_sorts |
147 |> type_literals_for_types |
150 |> type_literals_for_types |
148 val mtylits = if Config.get ctxt type_lits |
151 val mtylits = if Config.get ctxt type_lits |
149 then map (metis_of_type_literals false) tylits else [] |
152 then map (metis_of_type_literals false) tylits else [] |
150 in |
153 in |
151 (Metis.Thm.axiom (Metis.LiteralSet.fromList(mtylits @ mlits)), []) |
154 (Metis.Thm.axiom (Metis.LiteralSet.fromList(mtylits @ mlits)), [], |
|
155 skolem_somes) |
152 end |
156 end |
153 end; |
157 end; |
154 |
158 |
155 (* ARITY CLAUSE *) |
159 (* ARITY CLAUSE *) |
156 |
160 |
229 | NONE => |
233 | NONE => |
230 case strip_prefix tfree_prefix x of |
234 case strip_prefix tfree_prefix x of |
231 SOME tf => mk_tfree ctxt tf |
235 SOME tf => mk_tfree ctxt tf |
232 | NONE => error ("fol_type_to_isa: " ^ x)); |
236 | NONE => error ("fol_type_to_isa: " ^ x)); |
233 |
237 |
|
238 fun reintroduce_skolem_Eps thy skolem_somes = |
|
239 let |
|
240 fun aux Ts args t = |
|
241 case t of |
|
242 t1 $ t2 => aux Ts (aux Ts [] t2 :: args) t1 |
|
243 | Abs (s, T, t') => list_comb (Abs (s, T, aux (T :: Ts) [] t'), args) |
|
244 | Const (s, T) => |
|
245 if String.isPrefix skolem_Eps_pseudo_theory s then |
|
246 let |
|
247 val (T', args', def') = AList.lookup (op =) skolem_somes s |> the |
|
248 in |
|
249 def' |> subst_free (args' ~~ args) |
|
250 |> map_types Type_Infer.paramify_vars |
|
251 end |
|
252 else |
|
253 list_comb (t, args) |
|
254 | t => list_comb (t, args) |
|
255 in aux [] [] end |
|
256 |
234 (*Maps metis terms to isabelle terms*) |
257 (*Maps metis terms to isabelle terms*) |
235 fun fol_term_to_hol_RAW ctxt fol_tm = |
258 fun hol_term_from_fol_PT ctxt fol_tm = |
236 let val thy = ProofContext.theory_of ctxt |
259 let val thy = ProofContext.theory_of ctxt |
237 val _ = trace_msg (fn () => "fol_term_to_hol: " ^ Metis.Term.toString fol_tm) |
260 val _ = trace_msg (fn () => "hol_term_from_fol_PT: " ^ |
|
261 Metis.Term.toString fol_tm) |
238 fun tm_to_tt (Metis.Term.Var v) = |
262 fun tm_to_tt (Metis.Term.Var v) = |
239 (case strip_prefix tvar_prefix v of |
263 (case strip_prefix tvar_prefix v of |
240 SOME w => Type (make_tvar w) |
264 SOME w => Type (make_tvar w) |
241 | NONE => |
265 | NONE => |
242 case strip_prefix schematic_var_prefix v of |
266 case strip_prefix schematic_var_prefix v of |
283 case strip_prefix fixed_var_prefix a of |
307 case strip_prefix fixed_var_prefix a of |
284 SOME b => |
308 SOME b => |
285 let val opr = Term.Free(b, HOLogic.typeT) |
309 let val opr = Term.Free(b, HOLogic.typeT) |
286 in apply_list opr (length ts) (map tm_to_tt ts) end |
310 in apply_list opr (length ts) (map tm_to_tt ts) end |
287 | NONE => error ("unexpected metis function: " ^ a) |
311 | NONE => error ("unexpected metis function: " ^ a) |
288 in case tm_to_tt fol_tm of Term t => t | _ => error "fol_tm_to_tt: Term expected" end; |
312 in |
|
313 case tm_to_tt fol_tm of |
|
314 Term t => t |
|
315 | _ => error "fol_tm_to_tt: Term expected" |
|
316 end |
289 |
317 |
290 (*Maps fully-typed metis terms to isabelle terms*) |
318 (*Maps fully-typed metis terms to isabelle terms*) |
291 fun fol_term_to_hol_FT ctxt fol_tm = |
319 fun hol_term_from_fol_FT ctxt fol_tm = |
292 let val _ = trace_msg (fn () => "fol_term_to_hol_FT: " ^ Metis.Term.toString fol_tm) |
320 let val _ = trace_msg (fn () => "hol_term_from_fol_FT: " ^ |
|
321 Metis.Term.toString fol_tm) |
293 fun cvt (Metis.Term.Fn ("ti", [Metis.Term.Var v, _])) = |
322 fun cvt (Metis.Term.Fn ("ti", [Metis.Term.Var v, _])) = |
294 (case strip_prefix schematic_var_prefix v of |
323 (case strip_prefix schematic_var_prefix v of |
295 SOME w => mk_var(w, dummyT) |
324 SOME w => mk_var(w, dummyT) |
296 | NONE => mk_var(v, dummyT)) |
325 | NONE => mk_var(v, dummyT)) |
297 | cvt (Metis.Term.Fn ("ti", [Metis.Term.Fn ("=",[]), _])) = |
326 | cvt (Metis.Term.Fn ("ti", [Metis.Term.Fn ("=",[]), _])) = |
300 (case strip_prefix const_prefix x of |
329 (case strip_prefix const_prefix x of |
301 SOME c => Const (invert_const c, dummyT) |
330 SOME c => Const (invert_const c, dummyT) |
302 | NONE => (*Not a constant. Is it a fixed variable??*) |
331 | NONE => (*Not a constant. Is it a fixed variable??*) |
303 case strip_prefix fixed_var_prefix x of |
332 case strip_prefix fixed_var_prefix x of |
304 SOME v => Free (v, fol_type_to_isa ctxt ty) |
333 SOME v => Free (v, fol_type_to_isa ctxt ty) |
305 | NONE => error ("fol_term_to_hol_FT bad constant: " ^ x)) |
334 | NONE => error ("hol_term_from_fol_FT bad constant: " ^ x)) |
306 | cvt (Metis.Term.Fn ("ti", [Metis.Term.Fn (".",[tm1,tm2]), _])) = |
335 | cvt (Metis.Term.Fn ("ti", [Metis.Term.Fn (".",[tm1,tm2]), _])) = |
307 cvt tm1 $ cvt tm2 |
336 cvt tm1 $ cvt tm2 |
308 | cvt (Metis.Term.Fn (".",[tm1,tm2])) = (*untyped application*) |
337 | cvt (Metis.Term.Fn (".",[tm1,tm2])) = (*untyped application*) |
309 cvt tm1 $ cvt tm2 |
338 cvt tm1 $ cvt tm2 |
310 | cvt (Metis.Term.Fn ("{}", [arg])) = cvt arg (*hBOOL*) |
339 | cvt (Metis.Term.Fn ("{}", [arg])) = cvt arg (*hBOOL*) |
314 (case strip_prefix const_prefix x of |
343 (case strip_prefix const_prefix x of |
315 SOME c => Const (invert_const c, dummyT) |
344 SOME c => Const (invert_const c, dummyT) |
316 | NONE => (*Not a constant. Is it a fixed variable??*) |
345 | NONE => (*Not a constant. Is it a fixed variable??*) |
317 case strip_prefix fixed_var_prefix x of |
346 case strip_prefix fixed_var_prefix x of |
318 SOME v => Free (v, dummyT) |
347 SOME v => Free (v, dummyT) |
319 | NONE => (trace_msg (fn () => "fol_term_to_hol_FT bad const: " ^ x); |
348 | NONE => (trace_msg (fn () => "hol_term_from_fol_FT bad const: " ^ x); |
320 fol_term_to_hol_RAW ctxt t)) |
349 hol_term_from_fol_PT ctxt t)) |
321 | cvt t = (trace_msg (fn () => "fol_term_to_hol_FT bad term: " ^ Metis.Term.toString t); |
350 | cvt t = (trace_msg (fn () => "hol_term_from_fol_FT bad term: " ^ Metis.Term.toString t); |
322 fol_term_to_hol_RAW ctxt t) |
351 hol_term_from_fol_PT ctxt t) |
323 in cvt fol_tm end; |
352 in fol_tm |> cvt end |
324 |
353 |
325 fun fol_term_to_hol ctxt FO = fol_term_to_hol_RAW ctxt |
354 fun hol_term_from_fol FT = hol_term_from_fol_FT |
326 | fol_term_to_hol ctxt HO = fol_term_to_hol_RAW ctxt |
355 | hol_term_from_fol _ = hol_term_from_fol_PT |
327 | fol_term_to_hol ctxt FT = fol_term_to_hol_FT ctxt; |
356 |
328 |
357 fun hol_terms_from_fol ctxt mode skolem_somes fol_tms = |
329 fun fol_terms_to_hol ctxt mode fol_tms = |
358 let val thy = ProofContext.theory_of ctxt |
330 let val ts = map (fol_term_to_hol ctxt mode) fol_tms |
359 val ts = map (hol_term_from_fol mode ctxt) fol_tms |
331 val _ = trace_msg (fn () => " calling type inference:") |
360 val _ = trace_msg (fn () => " calling type inference:") |
332 val _ = app (fn t => trace_msg (fn () => Syntax.string_of_term ctxt t)) ts |
361 val _ = app (fn t => trace_msg (fn () => Syntax.string_of_term ctxt t)) ts |
333 val ts' = infer_types ctxt ts; |
362 val ts' = |
|
363 ts |> map (reintroduce_skolem_Eps thy skolem_somes) |> infer_types ctxt |
334 val _ = app (fn t => trace_msg |
364 val _ = app (fn t => trace_msg |
335 (fn () => " final term: " ^ Syntax.string_of_term ctxt t ^ |
365 (fn () => " final term: " ^ Syntax.string_of_term ctxt t ^ |
336 " of type " ^ Syntax.string_of_typ ctxt (type_of t))) |
366 " of type " ^ Syntax.string_of_typ ctxt (type_of t))) |
337 ts' |
367 ts' |
338 in ts' end; |
368 in ts' end; |
369 (* INFERENCE RULE: AXIOM *) |
399 (* INFERENCE RULE: AXIOM *) |
370 fun axiom_inf thpairs th = Thm.incr_indexes 1 (lookth thpairs th); |
400 fun axiom_inf thpairs th = Thm.incr_indexes 1 (lookth thpairs th); |
371 (*This causes variables to have an index of 1 by default. SEE ALSO mk_var above.*) |
401 (*This causes variables to have an index of 1 by default. SEE ALSO mk_var above.*) |
372 |
402 |
373 (* INFERENCE RULE: ASSUME *) |
403 (* INFERENCE RULE: ASSUME *) |
374 fun assume_inf ctxt mode atm = |
404 fun assume_inf ctxt mode skolem_somes atm = |
375 inst_excluded_middle |
405 inst_excluded_middle |
376 (ProofContext.theory_of ctxt) |
406 (ProofContext.theory_of ctxt) |
377 (singleton (fol_terms_to_hol ctxt mode) (Metis.Term.Fn atm)); |
407 (singleton (hol_terms_from_fol ctxt mode skolem_somes) (Metis.Term.Fn atm)) |
378 |
408 |
379 (* INFERENCE RULE: INSTANTIATE (Subst). Type instantiations are ignored. Trying to reconstruct |
409 (* INFERENCE RULE: INSTANTIATE (Subst). Type instantiations are ignored. Trying to reconstruct |
380 them admits new possibilities of errors, e.g. concerning sorts. Instead we try to arrange |
410 them admits new possibilities of errors, e.g. concerning sorts. Instead we try to arrange |
381 that new TVars are distinct and that types can be inferred from terms.*) |
411 that new TVars are distinct and that types can be inferred from terms.*) |
382 fun inst_inf ctxt mode thpairs fsubst th = |
412 fun inst_inf ctxt mode skolem_somes thpairs fsubst th = |
383 let val thy = ProofContext.theory_of ctxt |
413 let val thy = ProofContext.theory_of ctxt |
384 val i_th = lookth thpairs th |
414 val i_th = lookth thpairs th |
385 val i_th_vars = Term.add_vars (prop_of i_th) [] |
415 val i_th_vars = Term.add_vars (prop_of i_th) [] |
386 fun find_var x = the (List.find (fn ((a,_),_) => a=x) i_th_vars) |
416 fun find_var x = the (List.find (fn ((a,_),_) => a=x) i_th_vars) |
387 fun subst_translation (x,y) = |
417 fun subst_translation (x,y) = |
388 let val v = find_var x |
418 let val v = find_var x |
389 val t = fol_term_to_hol ctxt mode y (*we call infer_types below*) |
419 (* We call "reintroduce_skolem_Eps" and "infer_types" below. *) |
|
420 val t = hol_term_from_fol mode ctxt y |
390 in SOME (cterm_of thy (Var v), t) end |
421 in SOME (cterm_of thy (Var v), t) end |
391 handle Option => |
422 handle Option => |
392 (trace_msg (fn() => "List.find failed for the variable " ^ x ^ |
423 (trace_msg (fn() => "List.find failed for the variable " ^ x ^ |
393 " in " ^ Display.string_of_thm ctxt i_th); |
424 " in " ^ Display.string_of_thm ctxt i_th); |
394 NONE) |
425 NONE) |
399 SOME _ => NONE (*type instantiations are forbidden!*) |
430 SOME _ => NONE (*type instantiations are forbidden!*) |
400 | NONE => SOME (a,t) (*internal Metis var?*) |
431 | NONE => SOME (a,t) (*internal Metis var?*) |
401 val _ = trace_msg (fn () => " isa th: " ^ Display.string_of_thm ctxt i_th) |
432 val _ = trace_msg (fn () => " isa th: " ^ Display.string_of_thm ctxt i_th) |
402 val substs = map_filter remove_typeinst (Metis.Subst.toList fsubst) |
433 val substs = map_filter remove_typeinst (Metis.Subst.toList fsubst) |
403 val (vars,rawtms) = ListPair.unzip (map_filter subst_translation substs) |
434 val (vars,rawtms) = ListPair.unzip (map_filter subst_translation substs) |
404 val tms = infer_types ctxt rawtms; |
435 val tms = rawtms |> map (reintroduce_skolem_Eps thy skolem_somes) |
|
436 |> infer_types ctxt |
405 val ctm_of = cterm_incr_types thy (1 + Thm.maxidx_of i_th) |
437 val ctm_of = cterm_incr_types thy (1 + Thm.maxidx_of i_th) |
406 val substs' = ListPair.zip (vars, map ctm_of tms) |
438 val substs' = ListPair.zip (vars, map ctm_of tms) |
407 val _ = trace_msg (fn () => |
439 val _ = trace_msg (fn () => |
408 cat_lines ("subst_translations:" :: |
440 cat_lines ("subst_translations:" :: |
409 (substs' |> map (fn (x, y) => |
441 (substs' |> map (fn (x, y) => |
410 Syntax.string_of_term ctxt (term_of x) ^ " |-> " ^ |
442 Syntax.string_of_term ctxt (term_of x) ^ " |-> " ^ |
411 Syntax.string_of_term ctxt (term_of y))))); |
443 Syntax.string_of_term ctxt (term_of y))))); |
412 in cterm_instantiate substs' i_th end |
444 in cterm_instantiate substs' i_th end |
413 handle THM (msg, _, _) => error ("metis error (inst_inf):\n" ^ msg) |
445 handle THM (msg, _, _) => error ("metis error (inst_inf):\n" ^ msg) |
414 | ERROR msg => error ("metis error (inst_inf):\n" ^ msg ^ |
446 | ERROR msg => error ("metis error (inst_inf):\n" ^ msg ^ |
415 "\n(Perhaps you want to try \"metisFT\".)") |
447 "\n(Perhaps you want to try \"metisFT\" if you \ |
|
448 \haven't done so already.)") |
416 |
449 |
417 (* INFERENCE RULE: RESOLVE *) |
450 (* INFERENCE RULE: RESOLVE *) |
418 |
451 |
419 (*Like RSN, but we rename apart only the type variables. Vars here typically have an index |
452 (*Like RSN, but we rename apart only the type variables. Vars here typically have an index |
420 of 1, and the use of RSN would increase this typically to 3. Instantiations of those Vars |
453 of 1, and the use of RSN would increase this typically to 3. Instantiations of those Vars |
426 case distinct Thm.eq_thm ths of |
459 case distinct Thm.eq_thm ths of |
427 [th] => th |
460 [th] => th |
428 | _ => raise THM ("resolve_inc_tyvars: unique result expected", i, [tha,thb]) |
461 | _ => raise THM ("resolve_inc_tyvars: unique result expected", i, [tha,thb]) |
429 end; |
462 end; |
430 |
463 |
431 fun resolve_inf ctxt mode thpairs atm th1 th2 = |
464 fun resolve_inf ctxt mode skolem_somes thpairs atm th1 th2 = |
432 let |
465 let |
433 val i_th1 = lookth thpairs th1 and i_th2 = lookth thpairs th2 |
466 val i_th1 = lookth thpairs th1 and i_th2 = lookth thpairs th2 |
434 val _ = trace_msg (fn () => " isa th1 (pos): " ^ Display.string_of_thm ctxt i_th1) |
467 val _ = trace_msg (fn () => " isa th1 (pos): " ^ Display.string_of_thm ctxt i_th1) |
435 val _ = trace_msg (fn () => " isa th2 (neg): " ^ Display.string_of_thm ctxt i_th2) |
468 val _ = trace_msg (fn () => " isa th2 (neg): " ^ Display.string_of_thm ctxt i_th2) |
436 in |
469 in |
437 if is_TrueI i_th1 then i_th2 (*Trivial cases where one operand is type info*) |
470 if is_TrueI i_th1 then i_th2 (*Trivial cases where one operand is type info*) |
438 else if is_TrueI i_th2 then i_th1 |
471 else if is_TrueI i_th2 then i_th1 |
439 else |
472 else |
440 let |
473 let |
441 val i_atm = singleton (fol_terms_to_hol ctxt mode) (Metis.Term.Fn atm) |
474 val i_atm = singleton (hol_terms_from_fol ctxt mode skolem_somes) |
|
475 (Metis.Term.Fn atm) |
442 val _ = trace_msg (fn () => " atom: " ^ Syntax.string_of_term ctxt i_atm) |
476 val _ = trace_msg (fn () => " atom: " ^ Syntax.string_of_term ctxt i_atm) |
443 val prems_th1 = prems_of i_th1 |
477 val prems_th1 = prems_of i_th1 |
444 val prems_th2 = prems_of i_th2 |
478 val prems_th2 = prems_of i_th2 |
445 val index_th1 = get_index (mk_not i_atm) prems_th1 |
479 val index_th1 = get_index (mk_not i_atm) prems_th1 |
446 handle Empty => error "Failed to find literal in th1" |
480 handle Empty => error "Failed to find literal in th1" |
453 |
487 |
454 (* INFERENCE RULE: REFL *) |
488 (* INFERENCE RULE: REFL *) |
455 val refl_x = cterm_of @{theory} (Var (hd (Term.add_vars (prop_of REFL_THM) []))); |
489 val refl_x = cterm_of @{theory} (Var (hd (Term.add_vars (prop_of REFL_THM) []))); |
456 val refl_idx = 1 + Thm.maxidx_of REFL_THM; |
490 val refl_idx = 1 + Thm.maxidx_of REFL_THM; |
457 |
491 |
458 fun refl_inf ctxt mode t = |
492 fun refl_inf ctxt mode skolem_somes t = |
459 let val thy = ProofContext.theory_of ctxt |
493 let val thy = ProofContext.theory_of ctxt |
460 val i_t = singleton (fol_terms_to_hol ctxt mode) t |
494 val i_t = singleton (hol_terms_from_fol ctxt mode skolem_somes) t |
461 val _ = trace_msg (fn () => " term: " ^ Syntax.string_of_term ctxt i_t) |
495 val _ = trace_msg (fn () => " term: " ^ Syntax.string_of_term ctxt i_t) |
462 val c_t = cterm_incr_types thy refl_idx i_t |
496 val c_t = cterm_incr_types thy refl_idx i_t |
463 in cterm_instantiate [(refl_x, c_t)] REFL_THM end; |
497 in cterm_instantiate [(refl_x, c_t)] REFL_THM end; |
464 |
498 |
465 fun get_ty_arg_size _ (Const (@{const_name "op ="}, _)) = 0 (*equality has no type arguments*) |
499 fun get_ty_arg_size _ (Const (@{const_name "op ="}, _)) = 0 (*equality has no type arguments*) |
466 | get_ty_arg_size thy (Const (c, _)) = (num_type_args thy c handle TYPE _ => 0) |
500 | get_ty_arg_size thy (Const (c, _)) = (num_type_args thy c handle TYPE _ => 0) |
467 | get_ty_arg_size _ _ = 0; |
501 | get_ty_arg_size _ _ = 0; |
468 |
502 |
469 (* INFERENCE RULE: EQUALITY *) |
503 (* INFERENCE RULE: EQUALITY *) |
470 fun equality_inf ctxt mode (pos, atm) fp fr = |
504 fun equality_inf ctxt mode skolem_somes (pos, atm) fp fr = |
471 let val thy = ProofContext.theory_of ctxt |
505 let val thy = ProofContext.theory_of ctxt |
472 val m_tm = Metis.Term.Fn atm |
506 val m_tm = Metis.Term.Fn atm |
473 val [i_atm,i_tm] = fol_terms_to_hol ctxt mode [m_tm, fr] |
507 val [i_atm,i_tm] = hol_terms_from_fol ctxt mode skolem_somes [m_tm, fr] |
474 val _ = trace_msg (fn () => "sign of the literal: " ^ Bool.toString pos) |
508 val _ = trace_msg (fn () => "sign of the literal: " ^ Bool.toString pos) |
475 fun replace_item_list lx 0 (_::ls) = lx::ls |
509 fun replace_item_list lx 0 (_::ls) = lx::ls |
476 | replace_item_list lx i (l::ls) = l :: replace_item_list lx (i-1) ls |
510 | replace_item_list lx i (l::ls) = l :: replace_item_list lx (i-1) ls |
477 fun path_finder_FO tm [] = (tm, Term.Bound 0) |
511 fun path_finder_FO tm [] = (tm, Term.Bound 0) |
478 | path_finder_FO tm (p::ps) = |
512 | path_finder_FO tm (p::ps) = |
537 (ListPair.zip (OldTerm.term_vars (prop_of subst'), [tm_abs, tm_subst, i_tm])) |
571 (ListPair.zip (OldTerm.term_vars (prop_of subst'), [tm_abs, tm_subst, i_tm])) |
538 in cterm_instantiate eq_terms subst' end; |
572 in cterm_instantiate eq_terms subst' end; |
539 |
573 |
540 val factor = Seq.hd o distinct_subgoals_tac; |
574 val factor = Seq.hd o distinct_subgoals_tac; |
541 |
575 |
542 fun step _ _ thpairs (fol_th, Metis.Proof.Axiom _) = factor (axiom_inf thpairs fol_th) |
576 fun step ctxt mode skolem_somes thpairs p = |
543 | step ctxt mode _ (_, Metis.Proof.Assume f_atm) = assume_inf ctxt mode f_atm |
577 case p of |
544 | step ctxt mode thpairs (_, Metis.Proof.Subst (f_subst, f_th1)) = |
578 (fol_th, Metis.Proof.Axiom _) => factor (axiom_inf thpairs fol_th) |
545 factor (inst_inf ctxt mode thpairs f_subst f_th1) |
579 | (_, Metis.Proof.Assume f_atm) => assume_inf ctxt mode skolem_somes f_atm |
546 | step ctxt mode thpairs (_, Metis.Proof.Resolve(f_atm, f_th1, f_th2)) = |
580 | (_, Metis.Proof.Subst (f_subst, f_th1)) => |
547 factor (resolve_inf ctxt mode thpairs f_atm f_th1 f_th2) |
581 factor (inst_inf ctxt mode skolem_somes thpairs f_subst f_th1) |
548 | step ctxt mode _ (_, Metis.Proof.Refl f_tm) = refl_inf ctxt mode f_tm |
582 | (_, Metis.Proof.Resolve(f_atm, f_th1, f_th2)) => |
549 | step ctxt mode _ (_, Metis.Proof.Equality (f_lit, f_p, f_r)) = |
583 factor (resolve_inf ctxt mode skolem_somes thpairs f_atm f_th1 f_th2) |
550 equality_inf ctxt mode f_lit f_p f_r; |
584 | (_, Metis.Proof.Refl f_tm) => refl_inf ctxt mode skolem_somes f_tm |
|
585 | (_, Metis.Proof.Equality (f_lit, f_p, f_r)) => |
|
586 equality_inf ctxt mode skolem_somes f_lit f_p f_r |
551 |
587 |
552 fun real_literal (_, (c, _)) = not (String.isPrefix class_prefix c); |
588 fun real_literal (_, (c, _)) = not (String.isPrefix class_prefix c); |
553 |
589 |
554 fun translate _ _ thpairs [] = thpairs |
590 (* TODO: use "fold" instead *) |
555 | translate mode ctxt thpairs ((fol_th, inf) :: infpairs) = |
591 fun translate _ _ _ thpairs [] = thpairs |
|
592 | translate ctxt mode skolem_somes thpairs ((fol_th, inf) :: infpairs) = |
556 let val _ = trace_msg (fn () => "=============================================") |
593 let val _ = trace_msg (fn () => "=============================================") |
557 val _ = trace_msg (fn () => "METIS THM: " ^ Metis.Thm.toString fol_th) |
594 val _ = trace_msg (fn () => "METIS THM: " ^ Metis.Thm.toString fol_th) |
558 val _ = trace_msg (fn () => "INFERENCE: " ^ Metis.Proof.inferenceToString inf) |
595 val _ = trace_msg (fn () => "INFERENCE: " ^ Metis.Proof.inferenceToString inf) |
559 val th = Meson.flexflex_first_order (step ctxt mode thpairs (fol_th, inf)) |
596 val th = Meson.flexflex_first_order (step ctxt mode skolem_somes |
|
597 thpairs (fol_th, inf)) |
560 val _ = trace_msg (fn () => "ISABELLE THM: " ^ Display.string_of_thm ctxt th) |
598 val _ = trace_msg (fn () => "ISABELLE THM: " ^ Display.string_of_thm ctxt th) |
561 val _ = trace_msg (fn () => "=============================================") |
599 val _ = trace_msg (fn () => "=============================================") |
562 val n_metis_lits = |
600 val n_metis_lits = |
563 length (filter real_literal (Metis.LiteralSet.toList (Metis.Thm.clause fol_th))) |
601 length (filter real_literal (Metis.LiteralSet.toList (Metis.Thm.clause fol_th))) |
564 in |
602 in |
565 if nprems_of th = n_metis_lits then () |
603 if nprems_of th = n_metis_lits then () |
566 else error "Metis: proof reconstruction has gone wrong"; |
604 else error "Metis: proof reconstruction has gone wrong"; |
567 translate mode ctxt ((fol_th, th) :: thpairs) infpairs |
605 translate ctxt mode skolem_somes ((fol_th, th) :: thpairs) infpairs |
568 end; |
606 end; |
569 |
607 |
570 (*Determining which axiom clauses are actually used*) |
608 (*Determining which axiom clauses are actually used*) |
571 fun used_axioms axioms (th, Metis.Proof.Axiom _) = SOME (lookth axioms th) |
609 fun used_axioms axioms (th, Metis.Proof.Axiom _) = SOME (lookth axioms th) |
572 | used_axioms _ _ = NONE; |
610 | used_axioms _ _ = NONE; |
608 |> type_literals_for_types |
647 |> type_literals_for_types |
609 end; |
648 end; |
610 |
649 |
611 (*transform isabelle type / arity clause to metis clause *) |
650 (*transform isabelle type / arity clause to metis clause *) |
612 fun add_type_thm [] lmap = lmap |
651 fun add_type_thm [] lmap = lmap |
613 | add_type_thm ((ith, mth) :: cls) {axioms, tfrees} = |
652 | add_type_thm ((ith, mth) :: cls) {axioms, tfrees, skolem_somes} = |
614 add_type_thm cls {axioms = (mth, ith) :: axioms, |
653 add_type_thm cls {axioms = (mth, ith) :: axioms, tfrees = tfrees, |
615 tfrees = tfrees} |
654 skolem_somes = skolem_somes} |
616 |
655 |
617 (*Insert non-logical axioms corresponding to all accumulated TFrees*) |
656 (*Insert non-logical axioms corresponding to all accumulated TFrees*) |
618 fun add_tfrees {axioms, tfrees} : logic_map = |
657 fun add_tfrees {axioms, tfrees, skolem_somes} : logic_map = |
619 {axioms = (map (fn tf => (metis_of_tfree tf, TrueI)) (distinct op= tfrees)) @ axioms, |
658 {axioms = map (rpair TrueI o metis_of_tfree) (distinct (op =) tfrees) @ |
620 tfrees = tfrees}; |
659 axioms, |
|
660 tfrees = tfrees, skolem_somes = skolem_somes} |
621 |
661 |
622 fun string_of_mode FO = "FO" |
662 fun string_of_mode FO = "FO" |
623 | string_of_mode HO = "HO" |
663 | string_of_mode HO = "HO" |
624 | string_of_mode FT = "FT" |
664 | string_of_mode FT = "FT" |
625 |
665 |
626 (* Function to generate metis clauses, including comb and type clauses *) |
666 (* Function to generate metis clauses, including comb and type clauses *) |
627 fun build_map mode0 ctxt cls ths = |
667 fun build_map mode0 ctxt cls ths = |
628 let val thy = ProofContext.theory_of ctxt |
668 let val thy = ProofContext.theory_of ctxt |
629 (*The modes FO and FT are sticky. HO can be downgraded to FO.*) |
669 (*The modes FO and FT are sticky. HO can be downgraded to FO.*) |
630 fun set_mode FO = FO |
670 fun set_mode FO = FO |
631 | set_mode HO = if forall (Meson.is_fol_term thy o prop_of) (cls@ths) then FO else HO |
671 | set_mode HO = |
|
672 if forall (is_quasi_fol_term thy o prop_of) (cls @ ths) then FO |
|
673 else HO |
632 | set_mode FT = FT |
674 | set_mode FT = FT |
633 val mode = set_mode mode0 |
675 val mode = set_mode mode0 |
634 (*transform isabelle clause to metis clause *) |
676 (*transform isabelle clause to metis clause *) |
635 fun add_thm is_conjecture ith {axioms, tfrees} : logic_map = |
677 fun add_thm is_conjecture ith {axioms, tfrees, skolem_somes} : logic_map = |
636 let val (mth, tfree_lits) = hol_thm_to_fol is_conjecture ctxt mode ith |
678 let |
|
679 val (mth, tfree_lits, skolem_somes) = |
|
680 hol_thm_to_fol is_conjecture ctxt mode (length axioms) skolem_somes |
|
681 ith |
637 in |
682 in |
638 {axioms = (mth, Meson.make_meta_clause ith) :: axioms, |
683 {axioms = (mth, Meson.make_meta_clause ith) :: axioms, |
639 tfrees = union (op =) tfree_lits tfrees} |
684 tfrees = union (op =) tfree_lits tfrees, |
|
685 skolem_somes = skolem_somes} |
640 end; |
686 end; |
641 val lmap0 = fold (add_thm true) cls {axioms = [], tfrees = init_tfrees ctxt} |
687 val lmap = {axioms = [], tfrees = init_tfrees ctxt, skolem_somes = []} |
642 val lmap = fold (add_thm false) ths (add_tfrees lmap0) |
688 |> fold (add_thm true) cls |
|
689 |> add_tfrees |
|
690 |> fold (add_thm false) ths |
643 val clause_lists = map (Metis.Thm.clause o #1) (#axioms lmap) |
691 val clause_lists = map (Metis.Thm.clause o #1) (#axioms lmap) |
644 fun used c = exists (Metis.LiteralSet.exists (const_in_metis c o #2)) clause_lists |
692 fun used c = exists (Metis.LiteralSet.exists (const_in_metis c o #2)) clause_lists |
645 (*Now check for the existence of certain combinators*) |
693 (*Now check for the existence of certain combinators*) |
646 val thI = if used "c_COMBI" then [cnf_th @{theory} @{thm COMBI_def}] else [] |
694 val thI = if used "c_COMBI" then [cnf_th @{theory} @{thm COMBI_def}] else [] |
647 val thK = if used "c_COMBK" then [cnf_th @{theory} @{thm COMBK_def}] else [] |
695 val thK = if used "c_COMBK" then [cnf_th @{theory} @{thm COMBK_def}] else [] |
648 val thB = if used "c_COMBB" then [cnf_th @{theory} @{thm COMBB_def}] else [] |
696 val thB = if used "c_COMBB" then [cnf_th @{theory} @{thm COMBB_def}] else [] |
649 val thC = if used "c_COMBC" then [cnf_th @{theory} @{thm COMBC_def}] else [] |
697 val thC = if used "c_COMBC" then [cnf_th @{theory} @{thm COMBC_def}] else [] |
650 val thS = if used "c_COMBS" then [cnf_th @{theory} @{thm COMBS_def}] else [] |
698 val thS = if used "c_COMBS" then [cnf_th @{theory} @{thm COMBS_def}] else [] |
651 val thEQ = if used "c_fequal" then [cnf_th @{theory} @{thm fequal_imp_equal}, cnf_th @{theory} @{thm equal_imp_fequal}] else [] |
699 val thEQ = if used "c_fequal" then [cnf_th @{theory} @{thm fequal_imp_equal}, cnf_th @{theory} @{thm equal_imp_fequal}] else [] |
652 val lmap' = if mode=FO then lmap |
700 val lmap = |
653 else fold (add_thm false) (thEQ @ thS @ thC @ thB @ thK @ thI) lmap |
701 lmap |> mode <> FO |
|
702 ? fold (add_thm false) (thEQ @ thS @ thC @ thB @ thK @ thI) |
654 in |
703 in |
655 (mode, add_type_thm (type_ext thy (map prop_of (cls @ ths))) lmap') |
704 (mode, add_type_thm (type_ext thy (map prop_of (cls @ ths))) lmap) |
656 end; |
705 end; |
657 |
706 |
658 fun refute cls = |
707 fun refute cls = |
659 Metis.Resolution.loop (Metis.Resolution.new Metis.Resolution.default cls); |
708 Metis.Resolution.loop (Metis.Resolution.new Metis.Resolution.default cls); |
660 |
709 |
662 |
711 |
663 fun common_thm ths1 ths2 = exists (member Thm.eq_thm ths1) (map Meson.make_meta_clause ths2); |
712 fun common_thm ths1 ths2 = exists (member Thm.eq_thm ths1) (map Meson.make_meta_clause ths2); |
664 |
713 |
665 exception METIS of string; |
714 exception METIS of string; |
666 |
715 |
667 (* Main function to start metis prove and reconstruction *) |
716 (* Main function to start metis proof and reconstruction *) |
668 fun FOL_SOLVE mode ctxt cls ths0 = |
717 fun FOL_SOLVE mode ctxt cls ths0 = |
669 let val thy = ProofContext.theory_of ctxt |
718 let val thy = ProofContext.theory_of ctxt |
670 val th_cls_pairs = |
719 val th_cls_pairs = |
671 map (fn th => (Thm.get_name_hint th, cnf_axiom thy th)) ths0 |
720 map (fn th => (Thm.get_name_hint th, cnf_axiom thy th)) ths0 |
672 val ths = maps #2 th_cls_pairs |
721 val ths = maps #2 th_cls_pairs |
673 val _ = trace_msg (fn () => "FOL_SOLVE: CONJECTURE CLAUSES") |
722 val _ = trace_msg (fn () => "FOL_SOLVE: CONJECTURE CLAUSES") |
674 val _ = app (fn th => trace_msg (fn () => Display.string_of_thm ctxt th)) cls |
723 val _ = app (fn th => trace_msg (fn () => Display.string_of_thm ctxt th)) cls |
675 val _ = trace_msg (fn () => "THEOREM CLAUSES") |
724 val _ = trace_msg (fn () => "THEOREM CLAUSES") |
676 val _ = app (fn th => trace_msg (fn () => Display.string_of_thm ctxt th)) ths |
725 val _ = app (fn th => trace_msg (fn () => Display.string_of_thm ctxt th)) ths |
677 val (mode, {axioms,tfrees}) = build_map mode ctxt cls ths |
726 val (mode, {axioms, tfrees, skolem_somes}) = build_map mode ctxt cls ths |
678 val _ = if null tfrees then () |
727 val _ = if null tfrees then () |
679 else (trace_msg (fn () => "TFREE CLAUSES"); |
728 else (trace_msg (fn () => "TFREE CLAUSES"); |
680 app (fn tf => trace_msg (fn _ => tptp_of_type_literal true tf NONE |> fst)) tfrees) |
729 app (fn tf => trace_msg (fn _ => tptp_of_type_literal true tf NONE |> fst)) tfrees) |
681 val _ = trace_msg (fn () => "CLAUSES GIVEN TO METIS") |
730 val _ = trace_msg (fn () => "CLAUSES GIVEN TO METIS") |
682 val thms = map #1 axioms |
731 val thms = map #1 axioms |
692 let val _ = trace_msg (fn () => "METIS RECONSTRUCTION START: " ^ |
741 let val _ = trace_msg (fn () => "METIS RECONSTRUCTION START: " ^ |
693 Metis.Thm.toString mth) |
742 Metis.Thm.toString mth) |
694 val ctxt' = fold Variable.declare_constraints (map prop_of cls) ctxt |
743 val ctxt' = fold Variable.declare_constraints (map prop_of cls) ctxt |
695 (*add constraints arising from converting goal to clause form*) |
744 (*add constraints arising from converting goal to clause form*) |
696 val proof = Metis.Proof.proof mth |
745 val proof = Metis.Proof.proof mth |
697 val result = translate mode ctxt' axioms proof |
746 val result = translate ctxt' mode skolem_somes axioms proof |
698 and used = map_filter (used_axioms axioms) proof |
747 and used = map_filter (used_axioms axioms) proof |
699 val _ = trace_msg (fn () => "METIS COMPLETED...clauses actually used:") |
748 val _ = trace_msg (fn () => "METIS COMPLETED...clauses actually used:") |
700 val _ = app (fn th => trace_msg (fn () => Display.string_of_thm ctxt th)) used |
749 val _ = app (fn th => trace_msg (fn () => Display.string_of_thm ctxt th)) used |
701 val unused = th_cls_pairs |> map_filter (fn (name, cls) => |
750 val unused = th_cls_pairs |> map_filter (fn (name, cls) => |
702 if common_thm used cls then NONE else SOME name) |
751 if common_thm used cls then NONE else SOME name) |