src/HOL/Tools/datatype_package.ML
changeset 8689 a2e82eed6454
parent 8686 5893f2952e4f
child 8697 88dafea5955c
--- a/src/HOL/Tools/datatype_package.ML	Wed Apr 12 18:53:09 2000 +0200
+++ b/src/HOL/Tools/datatype_package.ML	Wed Apr 12 18:53:20 2000 +0200
@@ -167,26 +167,39 @@
              else ();
             tacf i));
 
+
 (* generic induction tactic for datatypes *)
 
-fun gen_induct_tac (vars, opt_rule) i state =
+local
+
+fun prep_var (Var (ixn, _), Some x) = Some (implode (tl (explode (Syntax.string_of_vname ixn))), x)
+  | prep_var _ = None;
+
+fun prep_inst (concl, xs) =	(*exception LIST*)
+  let val vs = InductMethod.vars_of concl
+  in mapfilter prep_var (Library.drop (length vs - length xs, vs) ~~ xs) end;
+
+in
+
+fun gen_induct_tac (varss, opt_rule) i state =
   let
-    val (_, _, Bi, _) = dest_state (state, i);
-    val {sign, ...} = rep_thm state;
+    val (_, _, Bi, _) = Thm.dest_state (state, i);
+    val {sign, ...} = Thm.rep_thm state;
     val (rule, rule_name) =
       (case opt_rule of
         Some r => (r, "Induction rule")
       | None =>
-          let val tn = find_tname (hd vars) Bi
+          let val tn = find_tname (hd (mapfilter I (flat varss))) Bi
           in (#induction (datatype_info_sg_err sign tn), "Induction rule for type " ^ tn) end);
-    val ind_vnames = map (fn (_ $ Var (ixn, _)) =>
-      implode (tl (explode (Syntax.string_of_vname ixn))))
-        (HOLogic.dest_conj (HOLogic.dest_Trueprop (Thm.concl_of rule)));
-    val insts = (ind_vnames ~~ vars) handle LIST _ =>
-      error (rule_name ^ " has different number of variables");
-  in occs_in_prems (Tactic.res_inst_tac insts rule) vars i state end;
 
-fun induct_tac s = gen_induct_tac (Syntax.read_idents s, None);
+    val concls = HOLogic.dest_conj (HOLogic.dest_Trueprop (Thm.concl_of rule));
+    val insts = flat (map2 prep_inst (concls, varss)) handle LIST _ =>
+      error (rule_name ^ " has different numbers of variables");
+  in occs_in_prems (Tactic.res_inst_tac insts rule) (map #2 insts) i state end;
+
+fun induct_tac s = gen_induct_tac (map (Library.single o Some) (Syntax.read_idents s), None);
+
+end;
 
 
 (* generic case tactic for datatypes *)
@@ -213,19 +226,21 @@
 
 local
 
-val rule_spec = Args.$$$ "rule" -- Args.$$$ ":";
-val opt_rule = Scan.option (Scan.lift rule_spec |-- Attrib.local_thm);
+val rule_spec = Scan.lift (Args.$$$ "rule" -- Args.$$$ ":");
+val opt_rule = Scan.option (rule_spec |-- Attrib.local_thm);
+
+val varss = Args.and_list (Scan.repeat (Scan.unless rule_spec (Scan.lift Args.name_dummy)));
 
 fun tactic_syntax args tac =
-  #2 oo Method.syntax (Args.goal_spec HEADGOAL -- (Scan.lift args -- opt_rule) >>
+  #2 oo Method.syntax (Args.goal_spec HEADGOAL -- (args -- opt_rule) >>
     (fn (quant, x) => Method.METHOD (fn facts => quant (Method.insert_tac facts THEN' tac x))));
 
 in
 
 val tactic_emulations =
- [("induct_tac", tactic_syntax (Scan.repeat1 (Scan.unless rule_spec Args.name)) gen_induct_tac,
+ [("induct_tac", tactic_syntax varss gen_induct_tac,
     "induct_tac emulation (dynamic instantiation!)"),
-  ("case_tac", tactic_syntax Args.name gen_case_tac,
+  ("case_tac", tactic_syntax (Scan.lift Args.name) gen_case_tac,
     "case_tac emulation (dynamic instantiation!)")];
 
 end;