src/HOL/Tools/Meson/meson.ML
changeset 43964 9338aa218f09
parent 43821 048619bb1dc3
child 45567 8e3891309a8e
equal deleted inserted replaced
43963:78c723cc3d99 43964:9338aa218f09
    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!*)
   735     end;
   740     end;
   736 
   741 
   737 fun iter_deepen_prolog_tac horns =
   742 fun iter_deepen_prolog_tac horns =
   738     ITER_DEEPEN iter_deepen_limit (has_fewer_prems 1) (prolog_step_tac' horns);
   743     ITER_DEEPEN iter_deepen_limit (has_fewer_prems 1) (prolog_step_tac' horns);
   739 
   744 
   740 fun iter_deepen_meson_tac ctxt ths = ctxt |> MESON all_tac make_clauses
   745 fun iter_deepen_meson_tac ctxt ths = ctxt |> MESON all_tac (make_clauses ctxt)
   741   (fn cls =>
   746   (fn cls =>
   742     (case (gocls (cls @ ths)) of
   747     (case (gocls (cls @ ths)) of
   743       [] => no_tac  (*no goal clauses*)
   748       [] => no_tac  (*no goal clauses*)
   744     | goes =>
   749     | goes =>
   745         let
   750         let