src/HOL/Tools/induct_method.ML
changeset 7512 930e5947562d
parent 7017 e4e64a0b0b6b
child 8154 dab09e1ad594
equal deleted inserted replaced
7511:85cf7fa5b138 7512:930e5947562d
    14 struct
    14 struct
    15 
    15 
    16 
    16 
    17 (* type induct_kind *)
    17 (* type induct_kind *)
    18 
    18 
    19 datatype induct_kind = Type | Set | Function;
    19 datatype induct_kind = Type | Set | Function | Rule;
    20 
    20 
    21 val typeN = "type";
    21 val kind_name =
    22 val setN = "set";
    22   Args.$$$ "type" >> K Type ||
    23 val functionN = "function";
    23   Args.$$$ "set" >> K Set ||
       
    24   Args.$$$ "function" >> K Function ||
       
    25   Args.$$$ "rule" >> K Rule;
    24 
    26 
    25 val kind =
    27 val kind = kind_name --| Args.$$$ ":";
    26   (Args.$$$ typeN >> K Type || Args.$$$ setN >> K Set || Args.$$$ functionN >> K Function)
       
    27     --| Args.$$$ ":";
       
    28 
    28 
    29 
    29 
    30 (* induct_rule *)
    30 (* induct_rule *)
    31 
    31 
    32 fun kind_rule Type = (#induction oo DatatypePackage.datatype_info_err, Sign.intern_tycon)
    32 fun kind_rule Type = (#induction oo DatatypePackage.datatype_info_err, Sign.intern_tycon)
    33   | kind_rule Set = ((#induct o #2) oo InductivePackage.get_inductive, Sign.intern_const)
    33   | kind_rule Set = ((#induct o #2) oo InductivePackage.get_inductive, Sign.intern_const)
    34   | kind_rule Function = (#induct oo RecdefPackage.get_recdef, Sign.intern_const);
    34   | kind_rule Function = (#induct oo RecdefPackage.get_recdef, Sign.intern_const)
       
    35   | kind_rule Rule = (PureThy.get_thm, K I);
    35 
    36 
    36 fun induct_rule thy kind name =
    37 fun induct_rule thy kind name =
    37   let val (ind_rule, intern) = kind_rule kind
    38   let val (ind_rule, intern) = kind_rule kind
    38   in ind_rule thy (intern (Theory.sign_of thy) name) end;
    39   in ind_rule thy (intern (Theory.sign_of thy) name) end;
    39 
    40 
    46       (case opt_kind_name of Some kind_name => kind_name | None =>
    47       (case opt_kind_name of Some kind_name => kind_name | None =>
    47         (case try (#1 o Term.dest_Type o Term.type_of o #2 o hd) insts of
    48         (case try (#1 o Term.dest_Type o Term.type_of o #2 o hd) insts of
    48           Some name => (Type, name)
    49           Some name => (Type, name)
    49         | None => error "Unable to figure out induction rule"));
    50         | None => error "Unable to figure out induction rule"));
    50     val rule = Drule.incr_indexes_wrt [] [] [] [state] (induct_rule thy kind name);
    51     val rule = Drule.incr_indexes_wrt [] [] [] [state] (induct_rule thy kind name);
    51 
       
    52 
    52 
    53     val cert = Thm.cterm_of (Sign.merge (pairself Thm.sign_of_thm (state, rule)));
    53     val cert = Thm.cterm_of (Sign.merge (pairself Thm.sign_of_thm (state, rule)));
    54 
    54 
    55     fun prep_inst ((P $ x), (Some Q, y)) = [(cert P, cert Q), (cert x, cert y)]
    55     fun prep_inst ((P $ x), (Some Q, y)) = [(cert P, cert Q), (cert x, cert y)]
    56       | prep_inst ((_ $ x), (None, y)) = [(cert x, cert y)]
    56       | prep_inst ((_ $ x), (None, y)) = [(cert x, cert y)]
    73 fun induct ctxt =
    73 fun induct ctxt =
    74   Args.and_list inst -- Scan.option (Scan.lift (kind -- Args.name))
    74   Args.and_list inst -- Scan.option (Scan.lift (kind -- Args.name))
    75   >> (fn (is, k) => Method.METHOD (FIRSTGOAL o induct_tac (ProofContext.theory_of ctxt) is k));
    75   >> (fn (is, k) => Method.METHOD (FIRSTGOAL o induct_tac (ProofContext.theory_of ctxt) is k));
    76 
    76 
    77 fun induct_meth src ctxt = #2 (Method.syntax (induct ctxt) ctxt src);
    77 fun induct_meth src ctxt = #2 (Method.syntax (induct ctxt) ctxt src);
    78 val induct_method = ("induct", induct_meth, "induction on types / sets / functions");
    78 val induct_method = ("induct", induct_meth, "induction on types, sets, functions etc.");
    79 
    79 
    80 
    80 
    81 (* theory setup *)
    81 (* theory setup *)
    82 
    82 
    83 val setup = [Method.add_methods [induct_method]];
    83 val setup = [Method.add_methods [induct_method]];