use definitional CNF for the goal if at least one of the premisses would lead to too many clauses in Meson
authorblanchet
Thu, 09 Sep 2010 20:11:52 +0200
changeset 39269 c2795d8a2461
parent 39268 a56f931fffff
child 39270 d67e8537eae5
use definitional CNF for the goal if at least one of the premisses would lead to too many clauses in Meson
src/HOL/Tools/Sledgehammer/metis_tactics.ML
src/HOL/Tools/meson.ML
--- a/src/HOL/Tools/Sledgehammer/metis_tactics.ML	Thu Sep 09 20:09:43 2010 +0200
+++ b/src/HOL/Tools/Sledgehammer/metis_tactics.ML	Thu Sep 09 20:11:52 2010 +0200
@@ -816,6 +816,13 @@
   #> map Clausifier.introduce_combinators_in_theorem
   #> Meson.finish_cnf
 
+fun preskolem_tac ctxt st0 =
+  (if exists (Meson.has_too_many_clauses ctxt)
+             (Logic.prems_of_goal (prop_of st0) 1) then
+     cnf.cnfx_rewrite_tac ctxt 1
+   else
+     all_tac) st0
+
 val type_has_top_sort =
   exists_subtype (fn TFree (_, []) => true | TVar (_, []) => true | _ => false)
 
@@ -828,7 +835,7 @@
     if exists_type type_has_top_sort (prop_of st0) then
       (warning ("Metis: Proof state contains the universal sort {}"); Seq.empty)
     else
-      Meson.MESON (K all_tac) (maps neg_clausify)
+      Meson.MESON (preskolem_tac ctxt) (maps neg_clausify)
                   (fn cls => resolve_tac (FOL_SOLVE mode ctxt cls ths) 1)
                   ctxt i st0
   end
--- a/src/HOL/Tools/meson.ML	Thu Sep 09 20:09:43 2010 +0200
+++ b/src/HOL/Tools/meson.ML	Thu Sep 09 20:11:52 2010 +0200
@@ -11,7 +11,8 @@
   val term_pair_of: indexname * (typ * 'a) -> term * 'a
   val flexflex_first_order: thm -> thm
   val size_of_subgoals: thm -> int
-  val too_many_clauses: Proof.context option -> term -> bool
+  val estimated_num_clauses: Proof.context -> int -> term -> int
+  val has_too_many_clauses: Proof.context -> term -> bool
   val make_cnf: thm list -> thm -> Proof.context -> thm list * Proof.context
   val finish_cnf: thm list -> thm list
   val presimplify: thm -> thm
@@ -26,8 +27,8 @@
   val gocls: thm list -> thm list
   val skolemize_prems_tac: Proof.context -> thm list -> int -> tactic
   val MESON:
-    (int -> tactic) -> (thm list -> thm list) -> (thm list -> tactic)
-    -> Proof.context -> int -> tactic
+    tactic -> (thm list -> thm list) -> (thm list -> tactic) -> Proof.context
+    -> int -> tactic
   val best_meson_tac: (thm -> int) -> Proof.context -> int -> tactic
   val safe_best_meson_tac: Proof.context -> int -> tactic
   val depth_meson_tac: Proof.context -> int -> tactic
@@ -262,13 +263,10 @@
 
 (*** The basic CNF transformation ***)
 
-fun too_many_clauses ctxto t = 
+fun estimated_num_clauses ctxt bound t =
  let
-  val max_cl = case ctxto of SOME ctxt => Config.get ctxt max_clauses
-                           | NONE => max_clauses_default
-  
-  fun sum x y = if x < max_cl andalso y < max_cl then x+y else max_cl;
-  fun prod x y = if x < max_cl andalso y < max_cl then x*y else max_cl;
+  fun sum x y = if x < bound andalso y < bound then x+y else bound
+  fun prod x y = if x < bound andalso y < bound then x*y else bound
   
   (*Estimate the number of clauses in order to detect infeasible theorems*)
   fun signed_nclauses b (Const(@{const_name Trueprop},_) $ t) = signed_nclauses b t
@@ -292,9 +290,12 @@
     | signed_nclauses b (Const(@{const_name Ex}, _) $ Abs (_,_,t)) = signed_nclauses b t
     | signed_nclauses b (Const(@{const_name All},_) $ Abs (_,_,t)) = signed_nclauses b t
     | signed_nclauses _ _ = 1; (* literal *)
- in 
-  signed_nclauses true t >= max_cl
- end;
+ in signed_nclauses true t end
+
+fun has_too_many_clauses ctxt t =
+  let val max_cl = Config.get ctxt max_clauses in
+    estimated_num_clauses ctxt (max_cl + 1) t > max_cl
+  end
 
 (*Replaces universally quantified variables by FREE variables -- because
   assumptions may not contain scheme variables.  Later, generalize using Variable.export. *)
@@ -355,8 +356,8 @@
               in  Seq.list_of (tac (th RS disj_forward)) @ ths  end
           | _ => nodups ctxt th :: ths  (*no work to do*)
       and cnf_nil th = cnf_aux (th,[])
-      val cls = 
-            if too_many_clauses (SOME ctxt) (concl_of th)
+      val cls =
+            if has_too_many_clauses ctxt (concl_of th)
             then (trace_msg (fn () => "cnf is ignoring: " ^ Display.string_of_thm ctxt th); ths)
             else cnf_aux (th,ths)
   in  (cls, !ctxtr)  end;
@@ -605,9 +606,9 @@
   SELECT_GOAL
     (EVERY [Object_Logic.atomize_prems_tac 1,
             rtac ccontr 1,
+            preskolem_tac,
             Subgoal.FOCUS (fn {context = ctxt', prems = negs, ...} =>
-                      EVERY1 [preskolem_tac,
-                              skolemize_prems_tac ctxt negs,
+                      EVERY1 [skolemize_prems_tac ctxt negs,
                               Subgoal.FOCUS (cltac o mkcl o #prems) ctxt']) ctxt 1]) i st
   handle THM _ => no_tac st;    (*probably from make_meta_clause, not first-order*)
 
@@ -616,7 +617,7 @@
 
 (*ths is a list of additional clauses (HOL disjunctions) to use.*)
 fun best_meson_tac sizef =
-  MESON (K all_tac) make_clauses
+  MESON all_tac make_clauses
     (fn cls =>
          THEN_BEST_FIRST (resolve_tac (gocls cls) 1)
                          (has_fewer_prems 1, sizef)
@@ -630,7 +631,7 @@
 (** Depth-first search version **)
 
 val depth_meson_tac =
-  MESON (K all_tac) make_clauses
+  MESON all_tac make_clauses
     (fn cls => EVERY [resolve_tac (gocls cls) 1, depth_prolog_tac (make_horns cls)]);
 
 
@@ -650,7 +651,7 @@
 fun iter_deepen_prolog_tac horns =
     ITER_DEEPEN iter_deepen_limit (has_fewer_prems 1) (prolog_step_tac' horns);
 
-fun iter_deepen_meson_tac ctxt ths = ctxt |> MESON (K all_tac) make_clauses
+fun iter_deepen_meson_tac ctxt ths = ctxt |> MESON all_tac make_clauses
   (fn cls =>
     (case (gocls (cls @ ths)) of
       [] => no_tac  (*no goal clauses*)