sane version of distinct_subgoals_tac, based on composition with Drule.distinct_prems_rl;
authorwenzelm
Wed, 15 Feb 2006 21:35:06 +0100
changeset 19056 6ac9dfe98e54
parent 19055 4f408867f9d4
child 19057 9201b2bb36c2
sane version of distinct_subgoals_tac, based on composition with Drule.distinct_prems_rl;
src/Pure/tactic.ML
--- a/src/Pure/tactic.ML	Wed Feb 15 21:35:06 2006 +0100
+++ b/src/Pure/tactic.ML	Wed Feb 15 21:35:06 2006 +0100
@@ -199,25 +199,30 @@
 (*Smash all flex-flex disagreement pairs in the proof state.*)
 val flexflex_tac = PRIMSEQ flexflex_rule;
 
-
-(*Remove duplicate subgoals.  By Mark Staples*)
-local
-fun cterm_aconv (a,b) = term_of a aconv term_of b;
-in
+(*Remove duplicate subgoals.*)
 fun distinct_subgoals_tac state =
-    let val (frozth,thawfn) = freeze_thaw state
-        val froz_prems = cprems_of frozth
-        val assumed = implies_elim_list frozth (map assume froz_prems)
-        val implied = implies_intr_list (gen_distinct cterm_aconv froz_prems)
-                                        assumed;
-    in  (*Applying Thm.varifyT to the result of thawfn would (re-)generalize
-          all type variables that appear in the subgoals. Unfortunately, it
-          would also break the function AxClass.intro_classes_tac, even in the
-          trivial case where the type class has no axioms.*)
-        Seq.single (thawfn implied)
-    end
-end;
+  let
+    val perm_tac = PRIMITIVE oo Thm.permute_prems;
 
+    fun distinct_tac (i, k) =
+      perm_tac 0 (i - 1) THEN
+      perm_tac 1 (k - 1) THEN
+      DETERM (PRIMSEQ (fn st =>
+        Thm.compose_no_flatten false (st, 0) 1
+          (Drule.incr_indexes st Drule.distinct_prems_rl))) THEN
+      perm_tac 1 (1 - k) THEN
+      perm_tac 0 (1 - i);
+
+    fun distinct_subgoal_tac i st =
+      (case Library.drop (i - 1, Thm.prems_of st) of
+        [] => no_tac st
+      | A :: Bs =>
+          st |> EVERY (fold (fn (B, k) =>
+            if A aconv B then cons (distinct_tac (i, k)) else I) (Bs ~~ (1 upto length Bs)) []));
+
+    val goals = Thm.prems_of state;
+    val dups = distinct (eq_fst (op aconv)) (goals ~~ (1 upto length goals));
+  in EVERY (rev (map (distinct_subgoal_tac o snd) dups)) state end;
 
 (*Determine print names of goal parameters (reversed)*)
 fun innermost_params i st =
@@ -567,7 +572,7 @@
   Returns longest lhs first to avoid folding its subexpressions.*)
 fun sort_lhs_depths defs =
   let val keylist = AList.make (term_depth o lhs_of_thm) defs
-      val keys = gen_distinct (op =) (sort (rev_order o int_ord) (map #2 keylist))
+      val keys = sort_distinct (rev_order o int_ord) (map #2 keylist)
   in map (AList.find (op =) keylist) keys end;
 
 val rev_defs = sort_lhs_depths o map symmetric;