make sure chained facts appear in Isar proofs generated by Sledgehammer -- otherwise the proof won't work
authorblanchet
Fri, 28 May 2010 13:49:21 +0200
changeset 37171 fc1e20373e6a
parent 37170 38ba15040455
child 37172 365f2296ae5b
make sure chained facts appear in Isar proofs generated by Sledgehammer -- otherwise the proof won't work
src/HOL/Tools/ATP_Manager/atp_systems.ML
src/HOL/Tools/Sledgehammer/sledgehammer_fact_filter.ML
src/HOL/Tools/Sledgehammer/sledgehammer_fact_preprocessor.ML
src/HOL/Tools/Sledgehammer/sledgehammer_isar.ML
src/HOL/Tools/Sledgehammer/sledgehammer_proof_reconstruct.ML
--- a/src/HOL/Tools/ATP_Manager/atp_systems.ML	Thu May 27 17:22:16 2010 +0200
+++ b/src/HOL/Tools/ATP_Manager/atp_systems.ML	Fri May 28 13:49:21 2010 +0200
@@ -121,9 +121,8 @@
          : problem) =
   let
     (* get clauses and prepare them for writing *)
-    val (ctxt, (chain_ths, th)) = goal;
+    val (ctxt, (chained_ths, th)) = goal;
     val thy = ProofContext.theory_of ctxt;
-    val chain_ths = map (Thm.put_name_hint chained_hint) chain_ths;
     val goal_clss = #1 (neg_conjecture_clauses ctxt th subgoal)
     val goal_cls = List.concat goal_clss
     val the_filtered_clauses =
@@ -135,7 +134,7 @@
         NONE => the_filtered_clauses
       | SOME axcls => axcls);
     val (internal_thm_names, clauses) =
-      prepare goal_cls chain_ths the_axiom_clauses the_filtered_clauses thy;
+      prepare goal_cls chained_ths the_axiom_clauses the_filtered_clauses thy;
 
     (* path to unique problem file *)
     val the_dest_dir = if overlord then getenv "ISABELLE_HOME_USER"
--- a/src/HOL/Tools/Sledgehammer/sledgehammer_fact_filter.ML	Thu May 27 17:22:16 2010 +0200
+++ b/src/HOL/Tools/Sledgehammer/sledgehammer_fact_filter.ML	Fri May 28 13:49:21 2010 +0200
@@ -352,7 +352,7 @@
 fun subtract_cls ax_clauses =
   filter_out (Termtab.defined (mk_clause_table ax_clauses) o prop_of)
 
-fun all_valid_thms respect_no_atp ctxt chain_ths =
+fun all_valid_thms respect_no_atp ctxt chained_ths =
   let
     val global_facts = PureThy.facts_of (ProofContext.theory_of ctxt);
     val local_facts = ProofContext.facts_of ctxt;
@@ -372,12 +372,13 @@
           val ths = filter_out bad_for_atp ths0;
         in
           if Facts.is_concealed facts name orelse
-             forall (member Thm.eq_thm chain_ths) ths orelse
              (respect_no_atp andalso is_package_def name) then
             I
           else case find_first check_thms [name1, name2, name] of
             NONE => I
-          | SOME a => cons (a, ths)
+          | SOME name' =>
+            cons (name' |> forall (member Thm.eq_thm chained_ths) ths
+                           ? prefix chained_prefix, ths)
         end);
   in valid_facts global_facts @ valid_facts local_facts end;
 
@@ -397,10 +398,10 @@
 
 (* The single-name theorems go after the multiple-name ones, so that single
    names are preferred when both are available. *)
-fun name_thm_pairs respect_no_atp ctxt chain_ths =
+fun name_thm_pairs respect_no_atp ctxt chained_ths =
   let
     val (mults, singles) =
-      List.partition is_multi (all_valid_thms respect_no_atp ctxt chain_ths)
+      List.partition is_multi (all_valid_thms respect_no_atp ctxt chained_ths)
     val ps = [] |> fold add_single_names singles
                 |> fold add_multi_names mults
   in ps |> respect_no_atp ? filter_out (No_ATPs.member ctxt o snd) end;
@@ -409,11 +410,11 @@
       (warning ("No name for theorem " ^ Display.string_of_thm_without_context th); false)
   | check_named _ = true;
 
-fun get_all_lemmas respect_no_atp ctxt chain_ths =
+fun get_all_lemmas respect_no_atp ctxt chained_ths =
   let val included_thms =
         tap (fn ths => trace_msg
                      (fn () => ("Including all " ^ Int.toString (length ths) ^ " theorems")))
-            (name_thm_pairs respect_no_atp ctxt chain_ths)
+            (name_thm_pairs respect_no_atp ctxt chained_ths)
   in
     filter check_named included_thms
   end;
@@ -510,14 +511,14 @@
 fun get_relevant_facts respect_no_atp relevance_threshold relevance_convergence
                        defs_relevant max_new theory_relevant
                        (relevance_override as {add, only, ...})
-                       (ctxt, (chain_ths, _)) goal_cls =
+                       (ctxt, (chained_ths, _)) goal_cls =
   if (only andalso null add) orelse relevance_threshold > 1.0 then
     []
   else
     let
       val thy = ProofContext.theory_of ctxt
       val is_FO = is_first_order thy goal_cls
-      val included_cls = get_all_lemmas respect_no_atp ctxt chain_ths
+      val included_cls = get_all_lemmas respect_no_atp ctxt chained_ths
         |> cnf_rules_pairs thy |> make_unique
         |> restrict_to_logic thy is_FO
         |> remove_unwanted_clauses
@@ -529,14 +530,8 @@
 
 (* prepare for passing to writer,
    create additional clauses based on the information from extra_cls *)
-fun prepare_clauses dfg goal_cls chain_ths axcls extra_cls thy =
+fun prepare_clauses dfg goal_cls chained_ths axcls extra_cls thy =
   let
-    (* add chain thms *)
-    val chain_cls =
-      cnf_rules_pairs thy (filter check_named
-                                  (map (`Thm.get_name_hint) chain_ths))
-    val axcls = chain_cls @ axcls
-    val extra_cls = chain_cls @ extra_cls
     val is_FO = is_first_order thy goal_cls
     val ccls = subtract_cls extra_cls goal_cls
     val _ = app (fn th => trace_msg (fn _ => Display.string_of_thm_global thy th)) ccls
--- a/src/HOL/Tools/Sledgehammer/sledgehammer_fact_preprocessor.ML	Thu May 27 17:22:16 2010 +0200
+++ b/src/HOL/Tools/Sledgehammer/sledgehammer_fact_preprocessor.ML	Fri May 28 13:49:21 2010 +0200
@@ -7,6 +7,7 @@
 
 signature SLEDGEHAMMER_FACT_PREPROCESSOR =
 sig
+  val chained_prefix: string
   val trace: bool Unsynchronized.ref
   val trace_msg: (unit -> string) -> unit
   val skolem_prefix: string
@@ -31,6 +32,9 @@
 
 open Sledgehammer_FOL_Clause
 
+(* Used to label theorems chained into the goal. *)
+val chained_prefix = "Sledgehammer.chained_"
+
 val trace = Unsynchronized.ref false;
 fun trace_msg msg = if !trace then tracing (msg ()) else ();
 
--- a/src/HOL/Tools/Sledgehammer/sledgehammer_isar.ML	Thu May 27 17:22:16 2010 +0200
+++ b/src/HOL/Tools/Sledgehammer/sledgehammer_isar.ML	Fri May 28 13:49:21 2010 +0200
@@ -233,13 +233,19 @@
                                          state) atps
       in () end
 
-fun minimize override_params i fact_refs state =
+fun minimize override_params i frefs state =
   let
     val thy = Proof.theory_of state
     val ctxt = Proof.context_of state
-    val theorems_from_refs =
-      map o pairf Facts.string_of_ref o ProofContext.get_fact
-    val name_thms_pairs = theorems_from_refs ctxt fact_refs
+    val chained_ths = #facts (Proof.goal state)
+    fun theorems_from_ref ctxt fref =
+      let
+        val ths = ProofContext.get_fact ctxt fref
+        val name = Facts.string_of_ref fref
+                   |> forall (member Thm.eq_thm chained_ths) ths
+                      ? prefix chained_prefix
+      in (name, ths) end
+    val name_thms_pairs = map (theorems_from_ref ctxt) frefs
   in
     case subgoal_count state of
       0 => priority "No subgoal!"
@@ -267,11 +273,11 @@
 fun string_for_raw_param (key, values) =
   key ^ (case space_implode " " values of "" => "" | value => " = " ^ value)
 
-fun minimize_command override_params i atp_name facts =
+fun minimize_command override_params i atp_name fact_names =
   sledgehammerN ^ " " ^ minimizeN ^ " [atp = " ^ atp_name ^
   (override_params |> filter is_raw_param_relevant_for_minimize
                    |> implode o map (prefix ", " o string_for_raw_param)) ^
-  "] (" ^ space_implode " " facts ^ ")" ^
+  "] (" ^ space_implode " " fact_names ^ ")" ^
   (if i = 1 then "" else " " ^ string_of_int i)
 
 fun hammer_away override_params subcommand opt_i relevance_override state =
--- a/src/HOL/Tools/Sledgehammer/sledgehammer_proof_reconstruct.ML	Thu May 27 17:22:16 2010 +0200
+++ b/src/HOL/Tools/Sledgehammer/sledgehammer_proof_reconstruct.ML	Fri May 28 13:49:21 2010 +0200
@@ -10,7 +10,6 @@
   type minimize_command = string list -> string
   type name_pool = Sledgehammer_FOL_Clause.name_pool
 
-  val chained_hint: string
   val invert_const: string -> string
   val invert_type_const: string -> string
   val num_type_args: theory -> string -> int
@@ -582,9 +581,6 @@
       | extract_num _ = NONE
   in atp_proof |> split_lines |> map_filter (extract_num o tokens_of) end
   
-(* Used to label theorems chained into the goal. *)
-val chained_hint = "sledgehammer_chained"
-
 fun apply_command _ 1 = "by "
   | apply_command 1 _ = "apply "
   | apply_command i _ = "prefer " ^ string_of_int i ^ " apply "
@@ -602,16 +598,24 @@
       "To minimize the number of lemmas, try this command: " ^
       Markup.markup Markup.sendback command ^ ".\n"
 
+val unprefix_chained = perhaps (try (unprefix chained_prefix))
+
 fun metis_proof_text (minimize_command, atp_proof, thm_names, goal, i) =
   let
-    val lemmas =
+    val raw_lemmas =
       atp_proof |> extract_clause_numbers_in_atp_proof
                 |> filter (is_axiom_clause_number thm_names)
                 |> map (fn i => Vector.sub (thm_names, i - 1))
-                |> filter_out (fn s => s = "??.unknown" orelse s = chained_hint)
-                |> sort_distinct string_ord
+    val (chained_lemmas, other_lemmas) =
+      raw_lemmas |> List.partition (String.isPrefix chained_prefix)
+                 |>> map (unprefix chained_prefix)
+                 |> pairself (sort_distinct string_ord)
+    val lemmas = other_lemmas @ chained_lemmas
     val n = Logic.count_prems (prop_of goal)
-  in (metis_line i n lemmas ^ minimize_line minimize_command lemmas, lemmas) end
+  in
+    (metis_line i n other_lemmas ^ minimize_line minimize_command lemmas,
+     lemmas)
+  end
 
 (** Isar proof construction and manipulation **)
 
@@ -929,7 +933,7 @@
     fun do_facts (ls, ss) =
       let
         val ls = ls |> sort_distinct (prod_ord string_ord int_ord)
-        val ss = ss |> sort_distinct string_ord
+        val ss = ss |> map unprefix_chained |> sort_distinct string_ord
       in metis_command 1 1 (map string_for_label ls @ ss) end
     and do_step ind (Fix xs) =
         do_indent ind ^ "fix " ^ space_implode " and " (map do_free xs) ^ "\n"