| author | haftmann | 
| Mon, 06 Jun 2016 21:28:46 +0200 | |
| changeset 63240 | f82c0b803bda | 
| parent 63120 | 629a4c5e953e | 
| child 67149 | e61557884799 | 
| permissions | -rw-r--r-- | 
| 28308 | 1  | 
(* Title: Tools/induct_tacs.ML  | 
| 
27326
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
2  | 
Author: Makarius  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
3  | 
|
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
4  | 
Unstructured induction and cases analysis.  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
5  | 
*)  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
6  | 
|
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
7  | 
signature INDUCT_TACS =  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
8  | 
sig  | 
| 59802 | 9  | 
val case_tac: Proof.context -> string -> (binding * string option * mixfix) list ->  | 
| 59826 | 10  | 
thm option -> int -> tactic  | 
11  | 
val induct_tac: Proof.context -> string option list list ->  | 
|
12  | 
thm list option -> int -> tactic  | 
|
| 
27326
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
13  | 
end  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
14  | 
|
| 45133 | 15  | 
structure Induct_Tacs: INDUCT_TACS =  | 
| 
27326
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
16  | 
struct  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
17  | 
|
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
18  | 
(* case analysis *)  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
19  | 
|
| 46836 | 20  | 
fun check_type ctxt (t, pos) =  | 
| 
27326
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
21  | 
let  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
22  | 
val u = singleton (Variable.polymorphic ctxt) t;  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
23  | 
val U = Term.fastype_of u;  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
24  | 
val _ = Term.is_TVar U andalso  | 
| 
55715
 
bc04f1ab3c3a
tuned messages -- prefer quote before Position.here, which might be just \<here>;
 
wenzelm 
parents: 
55111 
diff
changeset
 | 
25  | 
      error ("Cannot determine type of " ^
 | 
| 
 
bc04f1ab3c3a
tuned messages -- prefer quote before Position.here, which might be just \<here>;
 
wenzelm 
parents: 
55111 
diff
changeset
 | 
26  | 
quote (Syntax.string_of_term ctxt u) ^ Position.here pos);  | 
| 
27326
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
27  | 
in (u, U) end;  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
28  | 
|
| 59829 | 29  | 
fun case_tac ctxt s fixes opt_rule = SUBGOAL (fn (goal, i) =>  | 
| 
27326
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
30  | 
let  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
31  | 
val rule =  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
32  | 
(case opt_rule of  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
33  | 
SOME rule => rule  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
34  | 
| NONE =>  | 
| 59802 | 35  | 
let  | 
| 
59827
 
04e569577c18
proper Rule_Insts.read_term, e.g. to enable case_tac using "_";
 
wenzelm 
parents: 
59826 
diff
changeset
 | 
36  | 
val (t, ctxt') = ctxt  | 
| 59829 | 37  | 
|> Rule_Insts.goal_context goal |> #2  | 
| 
59827
 
04e569577c18
proper Rule_Insts.read_term, e.g. to enable case_tac using "_";
 
wenzelm 
parents: 
59826 
diff
changeset
 | 
38  | 
|> Context_Position.set_visible false  | 
| 
 
04e569577c18
proper Rule_Insts.read_term, e.g. to enable case_tac using "_";
 
wenzelm 
parents: 
59826 
diff
changeset
 | 
39  | 
|> Rule_Insts.read_term s;  | 
| 
 
04e569577c18
proper Rule_Insts.read_term, e.g. to enable case_tac using "_";
 
wenzelm 
parents: 
59826 
diff
changeset
 | 
40  | 
val pos = Syntax.read_input_pos s;  | 
| 59802 | 41  | 
in  | 
| 
59827
 
04e569577c18
proper Rule_Insts.read_term, e.g. to enable case_tac using "_";
 
wenzelm 
parents: 
59826 
diff
changeset
 | 
42  | 
(case Induct.find_casesT ctxt' (#2 (check_type ctxt' (t, pos))) of  | 
| 59802 | 43  | 
rule :: _ => rule  | 
44  | 
            | [] => @{thm case_split})
 | 
|
45  | 
end);  | 
|
| 
27326
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
46  | 
val _ = Method.trace ctxt [rule];  | 
| 59829 | 47  | 
in  | 
48  | 
(case Induct.vars_of (Thm.term_of (Thm.cprem_of rule 1)) handle THM _ => [] of  | 
|
49  | 
Var (xi, _) :: _ => Rule_Insts.res_inst_tac ctxt [((xi, Position.none), s)] fixes rule i  | 
|
50  | 
| _ => no_tac)  | 
|
51  | 
end);  | 
|
| 
27326
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
52  | 
|
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
53  | 
|
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
54  | 
(* induction *)  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
55  | 
|
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
56  | 
local  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
57  | 
|
| 59755 | 58  | 
fun prep_var (Var (xi, _), SOME x) = SOME ((xi, Position.none), x)  | 
| 
27326
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
59  | 
| prep_var _ = NONE;  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
60  | 
|
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
61  | 
fun prep_inst (concl, xs) =  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
62  | 
let val vs = Induct.vars_of concl  | 
| 33957 | 63  | 
in map_filter prep_var (drop (length vs - length xs) vs ~~ xs) end;  | 
| 
27326
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
64  | 
|
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
65  | 
in  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
66  | 
|
| 59830 | 67  | 
fun induct_tac ctxt varss opt_rules i st =  | 
| 
27326
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
68  | 
let  | 
| 59830 | 69  | 
val goal = Thm.cprem_of st i;  | 
70  | 
val (_, goal_ctxt) = Rule_Insts.goal_context (Thm.term_of goal) ctxt  | 
|
| 
60695
 
757549b4bbe6
Variable.focus etc.: optional bindings provided by user;
 
wenzelm 
parents: 
59830 
diff
changeset
 | 
71  | 
and ((_, goal'), _) = Variable.focus_cterm NONE goal ctxt;  | 
| 59830 | 72  | 
val (prems, concl) = Logic.strip_horn (Thm.term_of goal');  | 
| 
27326
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
73  | 
|
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
74  | 
fun induct_var name =  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
75  | 
let  | 
| 59830 | 76  | 
val t = Syntax.read_term goal_ctxt name;  | 
| 59795 | 77  | 
val pos = Syntax.read_input_pos name;  | 
| 
27326
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
78  | 
val (x, _) = Term.dest_Free t handle TERM _ =>  | 
| 46836 | 79  | 
          error ("Induction argument not a variable: " ^
 | 
| 59830 | 80  | 
quote (Syntax.string_of_term goal_ctxt t) ^ Position.here pos);  | 
| 
27326
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
81  | 
val eq_x = fn Free (y, _) => x = y | _ => false;  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
82  | 
val _ =  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
83  | 
if Term.exists_subterm eq_x concl then ()  | 
| 46836 | 84  | 
else  | 
85  | 
            error ("No such variable in subgoal: " ^
 | 
|
| 59830 | 86  | 
quote (Syntax.string_of_term goal_ctxt t) ^ Position.here pos);  | 
| 
27326
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
87  | 
val _ =  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
88  | 
if (exists o Term.exists_subterm) eq_x prems then  | 
| 46836 | 89  | 
            warning ("Induction variable occurs also among premises: " ^
 | 
| 59830 | 90  | 
quote (Syntax.string_of_term goal_ctxt t) ^ Position.here pos)  | 
| 
27326
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
91  | 
else ();  | 
| 59830 | 92  | 
in #1 (check_type goal_ctxt (t, pos)) end;  | 
| 
27326
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
93  | 
|
| 59830 | 94  | 
val argss = (map o map o Option.map) induct_var varss;  | 
| 
27326
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
95  | 
val rule =  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
96  | 
(case opt_rules of  | 
| 33368 | 97  | 
SOME rules => #2 (Rule_Cases.strict_mutual_rule ctxt rules)  | 
| 
27326
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
98  | 
| NONE =>  | 
| 33368 | 99  | 
(case map_filter (Rule_Cases.mutual_rule ctxt) (Induct.get_inductT ctxt argss) of  | 
| 
27326
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
100  | 
(_, rule) :: _ => rule  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
101  | 
          | [] => raise THM ("No induction rules", 0, [])));
 | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
102  | 
|
| 
54742
 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 
wenzelm 
parents: 
48992 
diff
changeset
 | 
103  | 
val rule' = rule |> Conv.fconv_rule (Conv.concl_conv ~1 (Object_Logic.atomize ctxt));  | 
| 
27326
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
104  | 
val _ = Method.trace ctxt [rule'];  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
105  | 
|
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
106  | 
val concls = Logic.dest_conjunctions (Thm.concl_of rule);  | 
| 
40722
 
441260986b63
make two copies (!) of Library.UnequalLengths coincide with ListPair.UnequalLengths;
 
wenzelm 
parents: 
36960 
diff
changeset
 | 
107  | 
val insts = maps prep_inst (concls ~~ varss) handle ListPair.UnequalLengths =>  | 
| 
27326
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
108  | 
error "Induction rule has different numbers of variables";  | 
| 59780 | 109  | 
in Rule_Insts.res_inst_tac ctxt insts [] rule' i st end  | 
| 
27326
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
110  | 
handle THM _ => Seq.empty;  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
111  | 
|
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
112  | 
end;  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
113  | 
|
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
114  | 
|
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
115  | 
(* method syntax *)  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
116  | 
|
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
117  | 
local  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
118  | 
|
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
119  | 
val rule_spec = Scan.lift (Args.$$$ "rule" -- Args.$$$ ":");  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
120  | 
val opt_rule = Scan.option (rule_spec |-- Attrib.thm);  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
121  | 
val opt_rules = Scan.option (rule_spec |-- Attrib.thms);  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
122  | 
|
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
123  | 
val varss =  | 
| 55111 | 124  | 
Parse.and_list'  | 
| 
63120
 
629a4c5e953e
embedded content may be delimited via cartouches;
 
wenzelm 
parents: 
60695 
diff
changeset
 | 
125  | 
(Scan.repeat (Scan.unless rule_spec (Scan.lift (Args.maybe Args.embedded_inner_syntax))));  | 
| 
27326
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
126  | 
|
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
127  | 
in  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
128  | 
|
| 58826 | 129  | 
val _ =  | 
130  | 
Theory.setup  | 
|
131  | 
   (Method.setup @{binding case_tac}
 | 
|
| 
63120
 
629a4c5e953e
embedded content may be delimited via cartouches;
 
wenzelm 
parents: 
60695 
diff
changeset
 | 
132  | 
(Args.goal_spec -- Scan.lift (Args.embedded_inner_syntax -- Parse.for_fixes) -- opt_rule >>  | 
| 59826 | 133  | 
(fn ((quant, (s, xs)), r) => fn ctxt => SIMPLE_METHOD'' quant (case_tac ctxt s xs r)))  | 
| 58826 | 134  | 
"unstructured case analysis on types" #>  | 
135  | 
    Method.setup @{binding induct_tac}
 | 
|
136  | 
(Args.goal_spec -- varss -- opt_rules >>  | 
|
| 59826 | 137  | 
(fn ((quant, vs), rs) => fn ctxt => SIMPLE_METHOD'' quant (induct_tac ctxt vs rs)))  | 
| 58826 | 138  | 
"unstructured induction on types");  | 
| 
27326
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
139  | 
|
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
140  | 
end;  | 
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
141  | 
|
| 
 
d3beec370964
moved src/HOL/Tools/induct_tacs.ML to src/Tools/induct_tacs.ML;
 
wenzelm 
parents:  
diff
changeset
 | 
142  | 
end;  |