12 val unfold_set_consts : bool Config.T |
12 val unfold_set_consts : bool Config.T |
13 val max_clauses : int Config.T |
13 val max_clauses : int Config.T |
14 val term_pair_of: indexname * (typ * 'a) -> term * 'a |
14 val term_pair_of: indexname * (typ * 'a) -> term * 'a |
15 val size_of_subgoals: thm -> int |
15 val size_of_subgoals: thm -> int |
16 val has_too_many_clauses: Proof.context -> term -> bool |
16 val has_too_many_clauses: Proof.context -> term -> bool |
17 val make_cnf: thm list -> thm -> Proof.context -> thm list * Proof.context |
17 val make_cnf: |
|
18 thm list -> thm -> Proof.context |
|
19 -> Proof.context -> thm list * Proof.context |
18 val finish_cnf: thm list -> thm list |
20 val finish_cnf: thm list -> thm list |
19 val unfold_set_const_simps : Proof.context -> thm list |
21 val unfold_set_const_simps : Proof.context -> thm list |
20 val presimplified_consts : Proof.context -> string list |
22 val presimplified_consts : Proof.context -> string list |
21 val presimplify: Proof.context -> thm -> thm |
23 val presimplify: Proof.context -> thm -> thm |
22 val make_nnf: Proof.context -> thm -> thm |
24 val make_nnf: Proof.context -> thm -> thm |
24 val skolemize_with_choice_theorems : Proof.context -> thm list -> thm -> thm |
26 val skolemize_with_choice_theorems : Proof.context -> thm list -> thm -> thm |
25 val skolemize : Proof.context -> thm -> thm |
27 val skolemize : Proof.context -> thm -> thm |
26 val extensionalize_conv : Proof.context -> conv |
28 val extensionalize_conv : Proof.context -> conv |
27 val extensionalize_theorem : Proof.context -> thm -> thm |
29 val extensionalize_theorem : Proof.context -> thm -> thm |
28 val is_fol_term: theory -> term -> bool |
30 val is_fol_term: theory -> term -> bool |
29 val make_clauses_unsorted: thm list -> thm list |
31 val make_clauses_unsorted: Proof.context -> thm list -> thm list |
30 val make_clauses: thm list -> thm list |
32 val make_clauses: Proof.context -> thm list -> thm list |
31 val make_horns: thm list -> thm list |
33 val make_horns: thm list -> thm list |
32 val best_prolog_tac: (thm -> int) -> thm list -> tactic |
34 val best_prolog_tac: (thm -> int) -> thm list -> tactic |
33 val depth_prolog_tac: thm list -> tactic |
35 val depth_prolog_tac: thm list -> tactic |
34 val gocls: thm list -> thm list |
36 val gocls: thm list -> thm list |
35 val skolemize_prems_tac : Proof.context -> thm list -> int -> tactic |
37 val skolemize_prems_tac : Proof.context -> thm list -> int -> tactic |
364 in tryall rls end |
366 in tryall rls end |
365 |
367 |
366 (* Conjunctive normal form, adding clauses from th in front of ths (for foldr). |
368 (* Conjunctive normal form, adding clauses from th in front of ths (for foldr). |
367 Strips universal quantifiers and breaks up conjunctions. |
369 Strips universal quantifiers and breaks up conjunctions. |
368 Eliminates existential quantifiers using Skolemization theorems. *) |
370 Eliminates existential quantifiers using Skolemization theorems. *) |
369 fun cnf old_skolem_ths ctxt (th, ths) = |
371 fun cnf old_skolem_ths ctxt ctxt0 (th, ths) = |
370 let val ctxtr = Unsynchronized.ref ctxt (* FIXME ??? *) |
372 let val ctxt0r = Unsynchronized.ref ctxt0 (* FIXME ??? *) |
371 fun cnf_aux (th,ths) = |
373 fun cnf_aux (th,ths) = |
372 if not (can HOLogic.dest_Trueprop (prop_of th)) then ths (*meta-level: ignore*) |
374 if not (can HOLogic.dest_Trueprop (prop_of th)) then ths (*meta-level: ignore*) |
373 else if not (has_conns [@{const_name All}, @{const_name Ex}, @{const_name HOL.conj}] (prop_of th)) |
375 else if not (has_conns [@{const_name All}, @{const_name Ex}, @{const_name HOL.conj}] (prop_of th)) |
374 then nodups ctxt th :: ths (*no work to do, terminate*) |
376 then nodups ctxt0 th :: ths (*no work to do, terminate*) |
375 else case head_of (HOLogic.dest_Trueprop (concl_of th)) of |
377 else case head_of (HOLogic.dest_Trueprop (concl_of th)) of |
376 Const (@{const_name HOL.conj}, _) => (*conjunction*) |
378 Const (@{const_name HOL.conj}, _) => (*conjunction*) |
377 cnf_aux (th RS conjunct1, cnf_aux (th RS conjunct2, ths)) |
379 cnf_aux (th RS conjunct1, cnf_aux (th RS conjunct2, ths)) |
378 | Const (@{const_name All}, _) => (*universal quantifier*) |
380 | Const (@{const_name All}, _) => (*universal quantifier*) |
379 let val (th',ctxt') = freeze_spec th (!ctxtr) |
381 let val (th',ctxt0') = freeze_spec th (!ctxt0r) |
380 in ctxtr := ctxt'; cnf_aux (th', ths) end |
382 in ctxt0r := ctxt0'; cnf_aux (th', ths) end |
381 | Const (@{const_name Ex}, _) => |
383 | Const (@{const_name Ex}, _) => |
382 (*existential quantifier: Insert Skolem functions*) |
384 (*existential quantifier: Insert Skolem functions*) |
383 cnf_aux (apply_skolem_theorem (th, old_skolem_ths), ths) |
385 cnf_aux (apply_skolem_theorem (th, old_skolem_ths), ths) |
384 | Const (@{const_name HOL.disj}, _) => |
386 | Const (@{const_name HOL.disj}, _) => |
385 (*Disjunction of P, Q: Create new goal of proving ?P | ?Q and solve it using |
387 (*Disjunction of P, Q: Create new goal of proving ?P | ?Q and solve it using |
386 all combinations of converting P, Q to CNF.*) |
388 all combinations of converting P, Q to CNF.*) |
387 let val tac = |
389 let val tac = |
388 Misc_Legacy.METAHYPS (resop cnf_nil) 1 THEN |
390 Misc_Legacy.METAHYPS (resop cnf_nil) 1 THEN |
389 (fn st' => st' |> Misc_Legacy.METAHYPS (resop cnf_nil) 1) |
391 (fn st' => st' |> Misc_Legacy.METAHYPS (resop cnf_nil) 1) |
390 in Seq.list_of (tac (th RS disj_forward)) @ ths end |
392 in Seq.list_of (tac (th RS disj_forward)) @ ths end |
391 | _ => nodups ctxt th :: ths (*no work to do*) |
393 | _ => nodups ctxt0 th :: ths (*no work to do*) |
392 and cnf_nil th = cnf_aux (th,[]) |
394 and cnf_nil th = cnf_aux (th,[]) |
393 val cls = |
395 val cls = |
394 if has_too_many_clauses ctxt (concl_of th) |
396 if has_too_many_clauses ctxt (concl_of th) then |
395 then (trace_msg ctxt (fn () => "cnf is ignoring: " ^ Display.string_of_thm ctxt th); ths) |
397 (trace_msg ctxt (fn () => |
396 else cnf_aux (th,ths) |
398 "cnf is ignoring: " ^ Display.string_of_thm ctxt0 th); ths) |
397 in (cls, !ctxtr) end; |
399 else |
398 |
400 cnf_aux (th, ths) |
399 fun make_cnf old_skolem_ths th ctxt = cnf old_skolem_ths ctxt (th, []) |
401 in (cls, !ctxt0r) end |
|
402 fun make_cnf old_skolem_ths th ctxt ctxt0 = |
|
403 cnf old_skolem_ths ctxt ctxt0 (th, []) |
400 |
404 |
401 (*Generalization, removal of redundant equalities, removal of tautologies.*) |
405 (*Generalization, removal of redundant equalities, removal of tautologies.*) |
402 fun finish_cnf ths = filter (not o is_taut) (map refl_clause ths); |
406 fun finish_cnf ths = filter (not o is_taut) (map refl_clause ths); |
403 |
407 |
404 |
408 |
655 trace_msg ctxt (fn () => |
659 trace_msg ctxt (fn () => |
656 "Failed to skolemize " ^ |
660 "Failed to skolemize " ^ |
657 Display.string_of_thm ctxt th) |
661 Display.string_of_thm ctxt th) |
658 | _ => ())) |
662 | _ => ())) |
659 |
663 |
660 fun add_clauses th cls = |
664 fun add_clauses ctxt th cls = |
661 let val ctxt0 = Variable.global_thm_context th |
665 let val ctxt0 = Variable.global_thm_context th |
662 val (cnfs, ctxt) = make_cnf [] th ctxt0 |
666 val (cnfs, ctxt) = make_cnf [] th ctxt ctxt0 |
663 in Variable.export ctxt ctxt0 cnfs @ cls end; |
667 in Variable.export ctxt ctxt0 cnfs @ cls end; |
664 |
668 |
665 (*Make clauses from a list of theorems, previously Skolemized and put into nnf. |
669 (*Make clauses from a list of theorems, previously Skolemized and put into nnf. |
666 The resulting clauses are HOL disjunctions.*) |
670 The resulting clauses are HOL disjunctions.*) |
667 fun make_clauses_unsorted ths = fold_rev add_clauses ths []; |
671 fun make_clauses_unsorted ctxt ths = fold_rev (add_clauses ctxt) ths []; |
668 val make_clauses = sort_clauses o make_clauses_unsorted; |
672 val make_clauses = sort_clauses oo make_clauses_unsorted; |
669 |
673 |
670 (*Convert a list of clauses (disjunctions) to Horn clauses (contrapositives)*) |
674 (*Convert a list of clauses (disjunctions) to Horn clauses (contrapositives)*) |
671 fun make_horns ths = |
675 fun make_horns ths = |
672 name_thms "Horn#" |
676 name_thms "Horn#" |
673 (distinct Thm.eq_thm_prop (fold_rev (add_contras clause_rules) ths [])); |
677 (distinct Thm.eq_thm_prop (fold_rev (add_contras clause_rules) ths [])); |
701 |
705 |
702 |
706 |
703 (** Best-first search versions **) |
707 (** Best-first search versions **) |
704 |
708 |
705 (*ths is a list of additional clauses (HOL disjunctions) to use.*) |
709 (*ths is a list of additional clauses (HOL disjunctions) to use.*) |
706 fun best_meson_tac sizef = |
710 fun best_meson_tac sizef ctxt = |
707 MESON all_tac make_clauses |
711 MESON all_tac (make_clauses ctxt) |
708 (fn cls => |
712 (fn cls => |
709 THEN_BEST_FIRST (resolve_tac (gocls cls) 1) |
713 THEN_BEST_FIRST (resolve_tac (gocls cls) 1) |
710 (has_fewer_prems 1, sizef) |
714 (has_fewer_prems 1, sizef) |
711 (prolog_step_tac (make_horns cls) 1)); |
715 (prolog_step_tac (make_horns cls) 1)) |
|
716 ctxt |
712 |
717 |
713 (*First, breaks the goal into independent units*) |
718 (*First, breaks the goal into independent units*) |
714 fun safe_best_meson_tac ctxt = |
719 fun safe_best_meson_tac ctxt = |
715 SELECT_GOAL (TRY (safe_tac ctxt) THEN TRYALL (best_meson_tac size_of_subgoals ctxt)); |
720 SELECT_GOAL (TRY (safe_tac ctxt) THEN TRYALL (best_meson_tac size_of_subgoals ctxt)); |
716 |
721 |
717 (** Depth-first search version **) |
722 (** Depth-first search version **) |
718 |
723 |
719 val depth_meson_tac = |
724 fun depth_meson_tac ctxt = |
720 MESON all_tac make_clauses |
725 MESON all_tac (make_clauses ctxt) |
721 (fn cls => EVERY [resolve_tac (gocls cls) 1, depth_prolog_tac (make_horns cls)]); |
726 (fn cls => EVERY [resolve_tac (gocls cls) 1, depth_prolog_tac (make_horns cls)]) |
722 |
727 ctxt |
723 |
728 |
724 (** Iterative deepening version **) |
729 (** Iterative deepening version **) |
725 |
730 |
726 (*This version does only one inference per call; |
731 (*This version does only one inference per call; |
727 having only one eq_assume_tac speeds it up!*) |
732 having only one eq_assume_tac speeds it up!*) |