| author | wenzelm | 
| Fri, 01 Nov 2024 17:13:42 +0100 | |
| changeset 81302 | 07e1e978b093 | 
| parent 80727 | 49067bf1cf92 | 
| child 81519 | cdc43c0fdbfc | 
| permissions | -rw-r--r-- | 
| 31723 
f5cafe803b55
discontinued ancient tradition to suffix certain ML module names with "_package"
 haftmann parents: 
31177diff
changeset | 1 | (* Title: HOL/Tools/inductive.ML | 
| 5094 | 2 | Author: Lawrence C Paulson, Cambridge University Computer Laboratory | 
| 21367 
7a0cc1bb4dcc
inductive: canonical specification syntax (flattened result only);
 wenzelm parents: 
21350diff
changeset | 3 | Author: Stefan Berghofer and Markus Wenzel, TU Muenchen | 
| 5094 | 4 | |
| 6424 | 5 | (Co)Inductive Definition module for HOL. | 
| 5094 | 6 | |
| 7 | Features: | |
| 6424 | 8 | * least or greatest fixedpoints | 
| 9 | * mutually recursive definitions | |
| 10 | * definitions involving arbitrary monotone operators | |
| 11 | * automatically proves introduction and elimination rules | |
| 5094 | 12 | |
| 13 | Introduction rules have the form | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 14 | [| M Pj ti, ..., Q x, ... |] ==> Pk t | 
| 5094 | 15 | where M is some monotone operator (usually the identity) | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 16 | Q x is any side condition on the free variables | 
| 5094 | 17 | ti, t are any terms | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 18 | Pj, Pk are two of the predicates being defined in mutual recursion | 
| 5094 | 19 | *) | 
| 20 | ||
| 69709 | 21 | signature INDUCTIVE = | 
| 5094 | 22 | sig | 
| 69709 | 23 | type result = | 
| 33458 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 24 |     {preds: term list, elims: thm list, raw_induct: thm,
 | 
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 25 | induct: thm, inducts: thm list, intrs: thm list, eqs: thm list} | 
| 69709 | 26 | val transform_result: morphism -> result -> result | 
| 27 |   type info = {names: string list, coind: bool} * result
 | |
| 28 | val the_inductive: Proof.context -> term -> info | |
| 29 | val the_inductive_global: Proof.context -> string -> info | |
| 59917 
9830c944670f
more uniform "verbose" option to print name space;
 wenzelm parents: 
59880diff
changeset | 30 | val print_inductives: bool -> Proof.context -> unit | 
| 45651 | 31 | val get_monos: Proof.context -> thm list | 
| 18728 | 32 | val mono_add: attribute | 
| 33 | val mono_del: attribute | |
| 53994 | 34 | val mk_cases_tac: Proof.context -> tactic | 
| 21367 
7a0cc1bb4dcc
inductive: canonical specification syntax (flattened result only);
 wenzelm parents: 
21350diff
changeset | 35 | val mk_cases: Proof.context -> term -> thm | 
| 10910 
058775a575db
export inductive_forall_name, inductive_forall_def, rulify;
 wenzelm parents: 
10804diff
changeset | 36 | val inductive_forall_def: thm | 
| 51717 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51658diff
changeset | 37 | val rulify: Proof.context -> thm -> thm | 
| 79732 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 38 | val inductive_cases: (Attrib.binding * term list) list -> bool -> local_theory -> | 
| 53995 | 39 | (string * thm list) list * local_theory | 
| 79732 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 40 | val inductive_cases_cmd: (Attrib.binding * string list) list -> bool -> local_theory -> | 
| 53995 | 41 | (string * thm list) list * local_theory | 
| 59845 | 42 | val ind_cases_rules: Proof.context -> | 
| 43 | string list -> (binding * string option * mixfix) list -> thm list | |
| 79732 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 44 | val inductive_simps: (Attrib.binding * term list) list -> bool -> local_theory -> | 
| 53995 | 45 | (string * thm list) list * local_theory | 
| 79732 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 46 | val inductive_simps_cmd: (Attrib.binding * string list) list -> bool -> local_theory -> | 
| 53995 | 47 | (string * thm list) list * local_theory | 
| 69709 | 48 | type flags = | 
| 33669 | 49 |     {quiet_mode: bool, verbose: bool, alt_name: binding, coind: bool,
 | 
| 49170 
03bee3a6a1b7
discontinued obsolete fork_mono to loosen some brakes -- NB: TTY interaction has Goal.future_proofs disabled due to missing Future.worker_task;
 wenzelm parents: 
47876diff
changeset | 50 | no_elim: bool, no_ind: bool, skip_mono: bool} | 
| 69709 | 51 | val add_inductive: | 
| 52 | flags -> ((binding * typ) * mixfix) list -> | |
| 28084 
a05ca48ef263
type Attrib.binding abbreviates Name.binding without attributes;
 wenzelm parents: 
28083diff
changeset | 53 | (string * typ) list -> (Attrib.binding * term) list -> thm list -> local_theory -> | 
| 69709 | 54 | result * local_theory | 
| 55 | val add_inductive_cmd: bool -> bool -> | |
| 29581 | 56 | (binding * string option * mixfix) list -> | 
| 57 | (binding * string option * mixfix) list -> | |
| 63064 
2f18172214c8
support 'assumes' in specifications, e.g. 'definition', 'inductive';
 wenzelm parents: 
63019diff
changeset | 58 | Specification.multi_specs_cmd -> | 
| 58011 
bc6bced136e5
tuned signature -- moved type src to Token, without aliases;
 wenzelm parents: 
56334diff
changeset | 59 | (Facts.ref * Token.src list) list -> | 
| 69709 | 60 | local_theory -> result * local_theory | 
| 22789 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 61 | val arities_of: thm -> (string * int) list | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 62 | val params_of: thm -> term list | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 63 | val partition_rules: thm -> thm list -> (string * thm list) list | 
| 25822 | 64 | val partition_rules': thm -> (thm * 'a) list -> (string * (thm * 'a) list) list | 
| 22789 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 65 | val unpartition_rules: thm list -> (string * 'a list) list -> 'a list | 
| 60362 | 66 | val infer_intro_vars: theory -> thm -> int -> thm list -> term list list | 
| 62093 | 67 | val inductive_internals: bool Config.T | 
| 59532 | 68 | val select_disj_tac: Proof.context -> int -> int -> int -> tactic | 
| 33458 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 69 | type add_ind_def = | 
| 69709 | 70 | flags -> | 
| 33458 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 71 | term list -> (Attrib.binding * term) list -> thm list -> | 
| 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 72 | term list -> (binding * mixfix) list -> | 
| 69709 | 73 | local_theory -> result * local_theory | 
| 71214 
5727bcc3c47c
proper spec_rule name via naming/binding/Morphism.binding;
 wenzelm parents: 
71179diff
changeset | 74 | val declare_rules: binding -> bool -> bool -> binding -> string list -> term list -> | 
| 58011 
bc6bced136e5
tuned signature -- moved type src to Token, without aliases;
 wenzelm parents: 
56334diff
changeset | 75 | thm list -> binding list -> Token.src list list -> (thm * string list * int) list -> | 
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 76 | thm list -> thm -> local_theory -> thm list * thm list * thm list * thm * thm list * local_theory | 
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 77 | val add_ind_def: add_ind_def | 
| 69709 | 78 | val gen_add_inductive: add_ind_def -> flags -> | 
| 29581 | 79 | ((binding * typ) * mixfix) list -> (string * typ) list -> (Attrib.binding * term) list -> | 
| 69709 | 80 | thm list -> local_theory -> result * local_theory | 
| 81 | val gen_add_inductive_cmd: add_ind_def -> bool -> bool -> | |
| 29581 | 82 | (binding * string option * mixfix) list -> | 
| 83 | (binding * string option * mixfix) list -> | |
| 63064 
2f18172214c8
support 'assumes' in specifications, e.g. 'definition', 'inductive';
 wenzelm parents: 
63019diff
changeset | 84 | Specification.multi_specs_cmd -> (Facts.ref * Token.src list) list -> | 
| 69709 | 85 | local_theory -> result * local_theory | 
| 49324 
4f28543ae7fa
removed obsolete argument "int" and thus made SML/NJ happy (cf. 03bee3a6a1b7);
 wenzelm parents: 
49170diff
changeset | 86 | val gen_ind_decl: add_ind_def -> bool -> (local_theory -> local_theory) parser | 
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 87 | end; | 
| 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 88 | |
| 31723 
f5cafe803b55
discontinued ancient tradition to suffix certain ML module names with "_package"
 haftmann parents: 
31177diff
changeset | 89 | structure Inductive: INDUCTIVE = | 
| 5094 | 90 | struct | 
| 91 | ||
| 10729 | 92 | (** theory context references **) | 
| 93 | ||
| 59940 
087d81f5213e
local setup of induction tools, with restricted access to auxiliary consts;
 wenzelm parents: 
59936diff
changeset | 94 | val inductive_forall_def = @{thm HOL.induct_forall_def};
 | 
| 
087d81f5213e
local setup of induction tools, with restricted access to auxiliary consts;
 wenzelm parents: 
59936diff
changeset | 95 | val inductive_conj_def = @{thm HOL.induct_conj_def};
 | 
| 32602 | 96 | val inductive_conj = @{thms induct_conj};
 | 
| 97 | val inductive_atomize = @{thms induct_atomize};
 | |
| 98 | val inductive_rulify = @{thms induct_rulify};
 | |
| 99 | val inductive_rulify_fallback = @{thms induct_rulify_fallback};
 | |
| 10729 | 100 | |
| 45649 | 101 | val simp_thms1 = | 
| 102 | map mk_meta_eq | |
| 67091 | 103 |     @{lemma "(\<not> True) = False" "(\<not> False) = True"
 | 
| 104 | "(True \<longrightarrow> P) = P" "(False \<longrightarrow> P) = True" | |
| 105 | "(P \<and> True) = P" "(True \<and> P) = P" | |
| 45649 | 106 | by (fact simp_thms)+}; | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 107 | |
| 45649 | 108 | val simp_thms2 = | 
| 109 |   map mk_meta_eq [@{thm inf_fun_def}, @{thm inf_bool_def}] @ simp_thms1;
 | |
| 32652 | 110 | |
| 45649 | 111 | val simp_thms3 = | 
| 63863 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 112 |   @{thms le_rel_bool_arg_iff if_False if_True conj_ac
 | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 113 | le_fun_def le_bool_def sup_fun_def sup_bool_def simp_thms | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 114 | if_bool_eq_disj all_simps ex_simps imp_conjL}; | 
| 10729 | 115 | |
| 116 | ||
| 45647 | 117 | |
| 10735 | 118 | (** misc utilities **) | 
| 6424 | 119 | |
| 67149 | 120 | val inductive_internals = Attrib.setup_config_bool \<^binding>\<open>inductive_internals\<close> (K false); | 
| 61681 
ca53150406c9
option "inductive_defs" controls exposure of def and mono facts;
 wenzelm parents: 
61308diff
changeset | 121 | |
| 26477 
ecf06644f6cb
eliminated quiete_mode ref (turned into proper argument);
 wenzelm parents: 
26336diff
changeset | 122 | fun message quiet_mode s = if quiet_mode then () else writeln s; | 
| 52059 | 123 | |
| 124 | fun clean_message ctxt quiet_mode s = | |
| 125 | if Config.get ctxt quick_and_dirty then () else message quiet_mode s; | |
| 5662 | 126 | |
| 6424 | 127 | fun coind_prefix true = "co" | 
| 128 | | coind_prefix false = ""; | |
| 129 | ||
| 45651 | 130 | fun log (b: int) m n = if m >= n then 0 else 1 + log b (b * m) n; | 
| 6424 | 131 | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 132 | fun make_bool_args f g [] i = [] | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 133 | | make_bool_args f g (x :: xs) i = | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 134 | (if i mod 2 = 0 then f x else g x) :: make_bool_args f g xs (i div 2); | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 135 | |
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 136 | fun make_bool_args' xs = | 
| 80727 | 137 | make_bool_args (K \<^Const>\<open>False\<close>) (K \<^Const>\<open>True\<close>) xs; | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 138 | |
| 33957 | 139 | fun arg_types_of k c = drop k (binder_types (fastype_of c)); | 
| 33077 
3c9cf88ec841
arg_types_of auxiliary function; using multiset operations
 haftmann parents: 
33056diff
changeset | 140 | |
| 40316 
665862241968
replaced ancient sys_error by raise Fail, assuming that the latter is not handled specifically by the environment;
 wenzelm parents: 
39248diff
changeset | 141 | fun find_arg T x [] = raise Fail "find_arg" | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 142 | | find_arg T x ((p as (_, (SOME _, _))) :: ps) = | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 143 | apsnd (cons p) (find_arg T x ps) | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 144 | | find_arg T x ((p as (U, (NONE, y))) :: ps) = | 
| 23577 | 145 | if (T: typ) = U then (y, (U, (SOME x, y)) :: ps) | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 146 | else apsnd (cons p) (find_arg T x ps); | 
| 7020 
75ff179df7b7
Exported function unify_consts (workaround to avoid inconsistently
 berghofe parents: 
6851diff
changeset | 147 | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 148 | fun make_args Ts xs = | 
| 80727 | 149 | map (fn (T, (NONE, ())) => \<^Const>\<open>undefined T\<close> | (_, (SOME t, ())) => t) | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 150 | (fold (fn (t, T) => snd o find_arg T t) xs (map (rpair (NONE, ())) Ts)); | 
| 7020 
75ff179df7b7
Exported function unify_consts (workaround to avoid inconsistently
 berghofe parents: 
6851diff
changeset | 151 | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 152 | fun make_args' Ts xs Us = | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 153 | fst (fold_map (fn T => find_arg T ()) Us (Ts ~~ map (pair NONE) xs)); | 
| 7020 
75ff179df7b7
Exported function unify_consts (workaround to avoid inconsistently
 berghofe parents: 
6851diff
changeset | 154 | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 155 | fun dest_predicate cs params t = | 
| 5094 | 156 | let | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 157 | val k = length params; | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 158 | val (c, ts) = strip_comb t; | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 159 | val (xs, ys) = chop k ts; | 
| 31986 | 160 | val i = find_index (fn c' => c' = c) cs; | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 161 | in | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 162 | if xs = params andalso i >= 0 then | 
| 33077 
3c9cf88ec841
arg_types_of auxiliary function; using multiset operations
 haftmann parents: 
33056diff
changeset | 163 | SOME (c, i, ys, chop (length ys) (arg_types_of k c)) | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 164 | else NONE | 
| 5094 | 165 | end; | 
| 166 | ||
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 167 | fun mk_names a 0 = [] | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 168 | | mk_names a 1 = [a] | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 169 | | mk_names a n = map (fn i => a ^ string_of_int i) (1 upto n); | 
| 10988 
e0016a009c17
Splitting of arguments of product types in induction rules is now less
 berghofe parents: 
10910diff
changeset | 170 | |
| 59532 | 171 | fun select_disj_tac ctxt = | 
| 172 | let | |
| 173 | fun tacs 1 1 = [] | |
| 174 |       | tacs _ 1 = [resolve_tac ctxt @{thms disjI1}]
 | |
| 175 |       | tacs n i = resolve_tac ctxt @{thms disjI2} :: tacs (n - 1) (i - 1);
 | |
| 176 | in fn n => fn i => EVERY' (tacs n i) end; | |
| 45647 | 177 | |
| 6424 | 178 | |
| 179 | ||
| 45651 | 180 | (** context data **) | 
| 181 | ||
| 69709 | 182 | type result = | 
| 45651 | 183 |   {preds: term list, elims: thm list, raw_induct: thm,
 | 
| 184 | induct: thm, inducts: thm list, intrs: thm list, eqs: thm list}; | |
| 185 | ||
| 186 | fun transform_result phi {preds, elims, raw_induct: thm, induct, inducts, intrs, eqs} =
 | |
| 187 | let | |
| 188 | val term = Morphism.term phi; | |
| 189 | val thm = Morphism.thm phi; | |
| 190 | val fact = Morphism.fact phi; | |
| 191 | in | |
| 192 |    {preds = map term preds, elims = fact elims, raw_induct = thm raw_induct,
 | |
| 193 | induct = thm induct, inducts = fact inducts, intrs = fact intrs, eqs = fact eqs} | |
| 194 | end; | |
| 195 | ||
| 69709 | 196 | type info = {names: string list, coind: bool} * result;
 | 
| 45651 | 197 | |
| 65411 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 198 | val empty_infos = | 
| 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 199 | Item_Net.init (op = o apply2 (#names o fst)) (#preds o snd) | 
| 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 200 | |
| 45651 | 201 | val empty_equations = | 
| 45652 
18214436e1d3
permissive update for improved "tool compliance";
 wenzelm parents: 
45651diff
changeset | 202 | Item_Net.init Thm.eq_thm_prop | 
| 
18214436e1d3
permissive update for improved "tool compliance";
 wenzelm parents: 
45651diff
changeset | 203 | (single o fst o HOLogic.dest_eq o HOLogic.dest_Trueprop o Thm.prop_of); | 
| 45651 | 204 | |
| 205 | datatype data = Data of | |
| 69709 | 206 |  {infos: info Item_Net.T,
 | 
| 45651 | 207 | monos: thm list, | 
| 208 | equations: thm Item_Net.T}; | |
| 209 | ||
| 210 | fun make_data (infos, monos, equations) = | |
| 211 |   Data {infos = infos, monos = monos, equations = equations};
 | |
| 212 | ||
| 213 | structure Data = Generic_Data | |
| 214 | ( | |
| 215 | type T = data; | |
| 65411 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 216 | val empty = make_data (empty_infos, [], empty_equations); | 
| 45651 | 217 |   fun merge (Data {infos = infos1, monos = monos1, equations = equations1},
 | 
| 218 |       Data {infos = infos2, monos = monos2, equations = equations2}) =
 | |
| 65411 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 219 | make_data (Item_Net.merge (infos1, infos2), | 
| 45651 | 220 | Thm.merge_thms (monos1, monos2), | 
| 221 | Item_Net.merge (equations1, equations2)); | |
| 222 | ); | |
| 223 | ||
| 224 | fun map_data f = | |
| 225 |   Data.map (fn Data {infos, monos, equations} => make_data (f (infos, monos, equations)));
 | |
| 226 | ||
| 227 | fun rep_data ctxt = Data.get (Context.Proof ctxt) |> (fn Data rep => rep); | |
| 228 | ||
| 59917 
9830c944670f
more uniform "verbose" option to print name space;
 wenzelm parents: 
59880diff
changeset | 229 | fun print_inductives verbose ctxt = | 
| 45651 | 230 | let | 
| 231 |     val {infos, monos, ...} = rep_data ctxt;
 | |
| 232 | val space = Consts.space_of (Proof_Context.consts_of ctxt); | |
| 65411 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 233 | val consts = | 
| 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 234 | Item_Net.content infos | 
| 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 235 |       |> maps (fn ({names, ...}, result) => map (rpair result) names)
 | 
| 45651 | 236 | in | 
| 50301 | 237 | [Pretty.block | 
| 238 | (Pretty.breaks | |
| 239 | (Pretty.str "(co)inductives:" :: | |
| 59917 
9830c944670f
more uniform "verbose" option to print name space;
 wenzelm parents: 
59880diff
changeset | 240 | map (Pretty.mark_str o #1) | 
| 65411 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 241 | (Name_Space.markup_entries verbose ctxt space consts))), | 
| 61268 | 242 | Pretty.big_list "monotonicity rules:" (map (Thm.pretty_thm_item ctxt) monos)] | 
| 56334 
6b3739fee456
some shortcuts for chunks, which sometimes avoid bulky string output;
 wenzelm parents: 
56249diff
changeset | 243 | end |> Pretty.writeln_chunks; | 
| 45651 | 244 | |
| 245 | ||
| 246 | (* inductive info *) | |
| 247 | ||
| 65411 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 248 | fun the_inductive ctxt term = | 
| 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 249 | Item_Net.retrieve (#infos (rep_data ctxt)) term | 
| 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 250 | |> the_single | 
| 67664 | 251 | |> apsnd (transform_result (Morphism.transfer_morphism' ctxt)) | 
| 45651 | 252 | |
| 65411 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 253 | fun the_inductive_global ctxt name = | 
| 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 254 | #infos (rep_data ctxt) | 
| 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 255 | |> Item_Net.content | 
| 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 256 |   |> filter (fn ({names, ...}, _) => member op = names name)
 | 
| 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 257 | |> the_single | 
| 67664 | 258 | |> apsnd (transform_result (Morphism.transfer_morphism' ctxt)) | 
| 65411 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 259 | |
| 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 260 | fun put_inductives info = | 
| 45651 | 261 | map_data (fn (infos, monos, equations) => | 
| 67637 | 262 | (Item_Net.update (apsnd (transform_result Morphism.trim_context_morphism) info) infos, | 
| 263 | monos, equations)); | |
| 45651 | 264 | |
| 265 | ||
| 266 | (* monotonicity rules *) | |
| 267 | ||
| 67637 | 268 | fun get_monos ctxt = | 
| 269 | #monos (rep_data ctxt) | |
| 67649 | 270 | |> map (Thm.transfer' ctxt); | 
| 45651 | 271 | |
| 272 | fun mk_mono ctxt thm = | |
| 273 | let | |
| 274 |     fun eq_to_mono thm' = thm' RS (thm' RS @{thm eq_to_mono});
 | |
| 275 |     fun dest_less_concl thm = dest_less_concl (thm RS @{thm le_funD})
 | |
| 276 |       handle THM _ => thm RS @{thm le_boolD}
 | |
| 277 | in | |
| 59582 | 278 | (case Thm.concl_of thm of | 
| 80727 | 279 | \<^Const_>\<open>Pure.eq _ for _ _\<close> => eq_to_mono (HOLogic.mk_obj_eq thm) | 
| 280 | | _ $ \<^Const_>\<open>HOL.eq _ for _ _\<close> => eq_to_mono thm | |
| 281 | | _ $ \<^Const_>\<open>less_eq _ for _ _\<close> => | |
| 45651 | 282 | dest_less_concl (Seq.hd (REPEAT (FIRSTGOAL | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 283 |         (resolve_tac ctxt [@{thm le_funI}, @{thm le_boolI'}])) thm))
 | 
| 45651 | 284 | | _ => thm) | 
| 61268 | 285 |   end handle THM _ => error ("Bad monotonicity theorem:\n" ^ Thm.string_of_thm ctxt thm);
 | 
| 45651 | 286 | |
| 287 | val mono_add = | |
| 288 | Thm.declaration_attribute (fn thm => fn context => | |
| 289 | map_data (fn (infos, monos, equations) => | |
| 67637 | 290 | (infos, Thm.add_thm (Thm.trim_context (mk_mono (Context.proof_of context) thm)) monos, | 
| 291 | equations)) context); | |
| 45651 | 292 | |
| 293 | val mono_del = | |
| 294 | Thm.declaration_attribute (fn thm => fn context => | |
| 295 | map_data (fn (infos, monos, equations) => | |
| 296 | (infos, Thm.del_thm (mk_mono (Context.proof_of context) thm) monos, equations)) context); | |
| 297 | ||
| 58815 | 298 | val _ = | 
| 299 | Theory.setup | |
| 67149 | 300 | (Attrib.setup \<^binding>\<open>mono\<close> (Attrib.add_del mono_add mono_del) | 
| 58815 | 301 | "declaration of monotonicity rule"); | 
| 302 | ||
| 45651 | 303 | |
| 304 | (* equations *) | |
| 305 | ||
| 67637 | 306 | fun retrieve_equations ctxt = | 
| 307 | Item_Net.retrieve (#equations (rep_data ctxt)) | |
| 67649 | 308 | #> map (Thm.transfer' ctxt); | 
| 45651 | 309 | |
| 45652 
18214436e1d3
permissive update for improved "tool compliance";
 wenzelm parents: 
45651diff
changeset | 310 | val equation_add_permissive = | 
| 45651 | 311 | Thm.declaration_attribute (fn thm => | 
| 45652 
18214436e1d3
permissive update for improved "tool compliance";
 wenzelm parents: 
45651diff
changeset | 312 | map_data (fn (infos, monos, equations) => | 
| 67637 | 313 | (infos, monos, perhaps (try (Item_Net.update (Thm.trim_context thm))) equations))); | 
| 45651 | 314 | |
| 315 | ||
| 316 | ||
| 10729 | 317 | (** process rules **) | 
| 318 | ||
| 319 | local | |
| 5094 | 320 | |
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 321 | fun err_in_rule ctxt name t msg = | 
| 42381 
309ec68442c6
added Binding.print convenience, which includes quote already;
 wenzelm parents: 
42364diff
changeset | 322 | error (cat_lines ["Ill-formed introduction rule " ^ Binding.print name, | 
| 24920 | 323 | Syntax.string_of_term ctxt t, msg]); | 
| 10729 | 324 | |
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 325 | fun err_in_prem ctxt name t p msg = | 
| 24920 | 326 | error (cat_lines ["Ill-formed premise", Syntax.string_of_term ctxt p, | 
| 42381 
309ec68442c6
added Binding.print convenience, which includes quote already;
 wenzelm parents: 
42364diff
changeset | 327 | "in introduction rule " ^ Binding.print name, Syntax.string_of_term ctxt t, msg]); | 
| 5094 | 328 | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 329 | val bad_concl = "Conclusion of introduction rule must be an inductive predicate"; | 
| 10729 | 330 | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 331 | val bad_ind_occ = "Inductive predicate occurs in argument of inductive predicate"; | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 332 | |
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 333 | val bad_app = "Inductive predicate must be applied to parameter(s) "; | 
| 11358 
416ea5c009f5
now checks for leading meta-quantifiers and complains, instead of
 paulson parents: 
11036diff
changeset | 334 | |
| 41228 
e1fce873b814
renamed structure MetaSimplifier to raw_Simplifer, to emphasize its meaning;
 wenzelm parents: 
41075diff
changeset | 335 | fun atomize_term thy = Raw_Simplifier.rewrite_term thy inductive_atomize []; | 
| 10729 | 336 | |
| 337 | in | |
| 5094 | 338 | |
| 28083 
103d9282a946
explicit type Name.binding for higher-specification elements;
 wenzelm parents: 
27882diff
changeset | 339 | fun check_rule ctxt cs params ((binding, att), rule) = | 
| 10729 | 340 | let | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 341 | val params' = Term.variant_frees rule (Logic.strip_params rule); | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 342 | val frees = rev (map Free params'); | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 343 | val concl = subst_bounds (frees, Logic.strip_assums_concl rule); | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 344 | val prems = map (curry subst_bounds frees) (Logic.strip_assums_hyp rule); | 
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 345 | val rule' = Logic.list_implies (prems, concl); | 
| 42361 | 346 | val aprems = map (atomize_term (Proof_Context.theory_of ctxt)) prems; | 
| 46215 
0da9433f959e
discontinued old-style Term.list_all_free in favour of plain Logic.all;
 wenzelm parents: 
45740diff
changeset | 347 | val arule = fold_rev (Logic.all o Free) params' (Logic.list_implies (aprems, concl)); | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 348 | |
| 45647 | 349 | fun check_ind err t = | 
| 350 | (case dest_predicate cs params t of | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 351 | NONE => err (bad_app ^ | 
| 24920 | 352 | commas (map (Syntax.string_of_term ctxt) params)) | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 353 | | SOME (_, _, ys, _) => | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 354 | if exists (fn c => exists (fn t => Logic.occs (c, t)) ys) cs | 
| 45647 | 355 | then err bad_ind_occ else ()); | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 356 | |
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 357 | fun check_prem' prem t = | 
| 36692 
54b64d4ad524
farewell to old-style mem infixes -- type inference in situations with mem_int and mem_string should provide enough information to resolve the type of (op =)
 haftmann parents: 
36642diff
changeset | 358 | if member (op =) cs (head_of t) then | 
| 42381 
309ec68442c6
added Binding.print convenience, which includes quote already;
 wenzelm parents: 
42364diff
changeset | 359 | check_ind (err_in_prem ctxt binding rule prem) t | 
| 45647 | 360 | else | 
| 361 | (case t of | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 362 | Abs (_, _, t) => check_prem' prem t | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 363 | | t $ u => (check_prem' prem t; check_prem' prem u) | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 364 | | _ => ()); | 
| 5094 | 365 | |
| 10729 | 366 | fun check_prem (prem, aprem) = | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 367 | if can HOLogic.dest_Trueprop aprem then check_prem' prem prem | 
| 42381 
309ec68442c6
added Binding.print convenience, which includes quote already;
 wenzelm parents: 
42364diff
changeset | 368 | else err_in_prem ctxt binding rule prem "Non-atomic premise"; | 
| 45647 | 369 | |
| 370 | val _ = | |
| 371 | (case concl of | |
| 80727 | 372 | \<^Const_>\<open>Trueprop for t\<close> => | 
| 45647 | 373 | if member (op =) cs (head_of t) then | 
| 42381 
309ec68442c6
added Binding.print convenience, which includes quote already;
 wenzelm parents: 
42364diff
changeset | 374 | (check_ind (err_in_rule ctxt binding rule') t; | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 375 | List.app check_prem (prems ~~ aprems)) | 
| 45647 | 376 | else err_in_rule ctxt binding rule' bad_concl | 
| 377 | | _ => err_in_rule ctxt binding rule' bad_concl); | |
| 378 | in | |
| 28083 
103d9282a946
explicit type Name.binding for higher-specification elements;
 wenzelm parents: 
27882diff
changeset | 379 | ((binding, att), arule) | 
| 10729 | 380 | end; | 
| 5094 | 381 | |
| 51717 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51658diff
changeset | 382 | fun rulify ctxt = | 
| 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51658diff
changeset | 383 | hol_simplify ctxt inductive_conj | 
| 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51658diff
changeset | 384 | #> hol_simplify ctxt inductive_rulify | 
| 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51658diff
changeset | 385 | #> hol_simplify ctxt inductive_rulify_fallback | 
| 54883 
dd04a8b654fc
proper context for norm_hhf and derived operations;
 wenzelm parents: 
54742diff
changeset | 386 | #> Simplifier.norm_hhf ctxt; | 
| 10729 | 387 | |
| 388 | end; | |
| 389 | ||
| 5094 | 390 | |
| 6424 | 391 | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 392 | (** proofs for (co)inductive predicates **) | 
| 6424 | 393 | |
| 26534 | 394 | (* prove monotonicity *) | 
| 5094 | 395 | |
| 49170 
03bee3a6a1b7
discontinued obsolete fork_mono to loosen some brakes -- NB: TTY interaction has Goal.future_proofs disabled due to missing Future.worker_task;
 wenzelm parents: 
47876diff
changeset | 396 | fun prove_mono quiet_mode skip_mono predT fp_fun monos ctxt = | 
| 52059 | 397 | (message (quiet_mode orelse skip_mono andalso Config.get ctxt quick_and_dirty) | 
| 26534 | 398 | " Proving monotonicity ..."; | 
| 51551 | 399 | (if skip_mono then Goal.prove_sorry else Goal.prove_future) ctxt | 
| 36642 | 400 | [] [] | 
| 17985 | 401 | (HOLogic.mk_Trueprop | 
| 76054 
a4b47c684445
moved mono and strict_mono to Fun and redefined them as abbreviations
 desharna parents: 
74561diff
changeset | 402 | (\<^Const>\<open>monotone_on predT predT for | 
| 
a4b47c684445
moved mono and strict_mono to Fun and redefined them as abbreviations
 desharna parents: 
74561diff
changeset | 403 | \<^Const>\<open>top \<^Type>\<open>set predT\<close>\<close> \<^Const>\<open>less_eq predT\<close> \<^Const>\<open>less_eq predT\<close> fp_fun\<close>)) | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 404 |     (fn _ => EVERY [resolve_tac ctxt @{thms monoI} 1,
 | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 405 |       REPEAT (resolve_tac ctxt [@{thm le_funI}, @{thm le_boolI'}] 1),
 | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 406 | REPEAT (FIRST | 
| 58963 
26bf09b95dda
proper context for assume_tac (atac remains as fall-back without context);
 wenzelm parents: 
58936diff
changeset | 407 | [assume_tac ctxt 1, | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 408 | resolve_tac ctxt (map (mk_mono ctxt) monos @ get_monos ctxt) 1, | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 409 |          eresolve_tac ctxt @{thms le_funE} 1,
 | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 410 |          dresolve_tac ctxt @{thms le_boolD} 1])]));
 | 
| 5094 | 411 | |
| 6424 | 412 | |
| 10735 | 413 | (* prove introduction rules *) | 
| 5094 | 414 | |
| 36642 | 415 | fun prove_intrs quiet_mode coind mono fp_def k intr_ts rec_preds_defs ctxt ctxt' = | 
| 5094 | 416 | let | 
| 52059 | 417 | val _ = clean_message ctxt quiet_mode " Proving the introduction rules ..."; | 
| 5094 | 418 | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 419 | val unfold = funpow k (fn th => th RS fun_cong) | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 420 | (mono RS (fp_def RS | 
| 32652 | 421 |         (if coind then @{thm def_gfp_unfold} else @{thm def_lfp_unfold})));
 | 
| 5094 | 422 | |
| 67091 | 423 |     val rules = [refl, TrueI, @{lemma "\<not> False" by (rule notI)}, exI, conjI];
 | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 424 | |
| 36642 | 425 | val intrs = map_index (fn (i, intr) => | 
| 51551 | 426 | Goal.prove_sorry ctxt [] [] intr (fn _ => EVERY | 
| 54742 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
53995diff
changeset | 427 | [rewrite_goals_tac ctxt rec_preds_defs, | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 428 | resolve_tac ctxt [unfold RS iffD2] 1, | 
| 59532 | 429 | select_disj_tac ctxt (length intr_ts) (i + 1) 1, | 
| 17985 | 430 | (*Not ares_tac, since refl must be tried before any equality assumptions; | 
| 431 | backtracking may occur if the premises have extra variables!*) | |
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 432 | DEPTH_SOLVE_1 (resolve_tac ctxt rules 1 APPEND assume_tac ctxt 1)]) | 
| 42361 | 433 | |> singleton (Proof_Context.export ctxt ctxt')) intr_ts | 
| 5094 | 434 | |
| 435 | in (intrs, unfold) end; | |
| 436 | ||
| 6424 | 437 | |
| 10735 | 438 | (* prove elimination rules *) | 
| 5094 | 439 | |
| 36642 | 440 | fun prove_elims quiet_mode cs params intr_ts intr_names unfold rec_preds_defs ctxt ctxt''' = | 
| 5094 | 441 | let | 
| 52059 | 442 | val _ = clean_message ctxt quiet_mode " Proving the elimination rules ..."; | 
| 5094 | 443 | |
| 36642 | 444 | val ([pname], ctxt') = Variable.variant_fixes ["P"] ctxt; | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 445 | val P = HOLogic.mk_Trueprop (Free (pname, HOLogic.boolT)); | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 446 | |
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 447 | fun dest_intr r = | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 448 | (the (dest_predicate cs params (HOLogic.dest_Trueprop (Logic.strip_assums_concl r))), | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 449 | Logic.strip_assums_hyp r, Logic.strip_params r); | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 450 | |
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 451 | val intrs = map dest_intr intr_ts ~~ intr_names; | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 452 | |
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 453 | val rules1 = [disjE, exE, FalseE]; | 
| 67091 | 454 |     val rules2 = [conjE, FalseE, @{lemma "\<not> True \<Longrightarrow> R" by (rule notE [OF _ TrueI])}];
 | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 455 | |
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 456 | fun prove_elim c = | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 457 | let | 
| 33077 
3c9cf88ec841
arg_types_of auxiliary function; using multiset operations
 haftmann parents: 
33056diff
changeset | 458 | val Ts = arg_types_of (length params) c; | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 459 | val (anames, ctxt'') = Variable.variant_fixes (mk_names "a" (length Ts)) ctxt'; | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 460 | val frees = map Free (anames ~~ Ts); | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 461 | |
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 462 | fun mk_elim_prem ((_, _, us, _), ts, params') = | 
| 46218 
ecf6375e2abb
renamed Term.list_all to Logic.list_all, in accordance to HOLogic.list_all;
 wenzelm parents: 
46215diff
changeset | 463 | Logic.list_all (params', | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 464 | Logic.list_implies (map (HOLogic.mk_Trueprop o HOLogic.mk_eq) | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 465 | (frees ~~ us) @ ts, P)); | 
| 33317 | 466 | val c_intrs = filter (equal c o #1 o #1 o #1) intrs; | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 467 | val prems = HOLogic.mk_Trueprop (list_comb (c, params @ frees)) :: | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 468 | map mk_elim_prem (map #1 c_intrs) | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 469 | in | 
| 51551 | 470 | (Goal.prove_sorry ctxt'' [] prems P | 
| 54742 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
53995diff
changeset | 471 |           (fn {context = ctxt4, prems} => EVERY
 | 
| 46708 
b138dee7bed3
prefer cut_tac, where it is clear that the special variants cut_rules_tac or cut_facts_tac are not required;
 wenzelm parents: 
46219diff
changeset | 472 | [cut_tac (hd prems) 1, | 
| 54742 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
53995diff
changeset | 473 | rewrite_goals_tac ctxt4 rec_preds_defs, | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 474 | dresolve_tac ctxt4 [unfold RS iffD1] 1, | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 475 | REPEAT (FIRSTGOAL (eresolve_tac ctxt4 rules1)), | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 476 | REPEAT (FIRSTGOAL (eresolve_tac ctxt4 rules2)), | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 477 | EVERY (map (fn prem => | 
| 59499 | 478 | DEPTH_SOLVE_1 (assume_tac ctxt4 1 ORELSE | 
| 479 | resolve_tac ctxt [rewrite_rule ctxt4 rec_preds_defs prem, conjI] 1)) | |
| 54742 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
53995diff
changeset | 480 | (tl prems))]) | 
| 42361 | 481 | |> singleton (Proof_Context.export ctxt'' ctxt'''), | 
| 34986 
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
 berghofe parents: 
33966diff
changeset | 482 | map #2 c_intrs, length Ts) | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 483 | end | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 484 | |
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 485 | in map prove_elim cs end; | 
| 5094 | 486 | |
| 45647 | 487 | |
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 488 | (* prove simplification equations *) | 
| 6424 | 489 | |
| 45647 | 490 | fun prove_eqs quiet_mode cs params intr_ts intrs | 
| 491 | (elims: (thm * bstring list * int) list) ctxt ctxt'' = (* FIXME ctxt'' ?? *) | |
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 492 | let | 
| 52059 | 493 | val _ = clean_message ctxt quiet_mode " Proving the simplification rules ..."; | 
| 45647 | 494 | |
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 495 | fun dest_intr r = | 
| 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 496 | (the (dest_predicate cs params (HOLogic.dest_Trueprop (Logic.strip_assums_concl r))), | 
| 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 497 | Logic.strip_assums_hyp r, Logic.strip_params r); | 
| 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 498 | val intr_ts' = map dest_intr intr_ts; | 
| 45647 | 499 | |
| 37901 | 500 | fun prove_eq c (elim: thm * 'a * 'b) = | 
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 501 | let | 
| 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 502 | val Ts = arg_types_of (length params) c; | 
| 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 503 | val (anames, ctxt') = Variable.variant_fixes (mk_names "a" (length Ts)) ctxt; | 
| 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 504 | val frees = map Free (anames ~~ Ts); | 
| 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 505 | val c_intrs = filter (equal c o #1 o #1 o #1) (intr_ts' ~~ intrs); | 
| 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 506 | fun mk_intr_conj (((_, _, us, _), ts, params'), _) = | 
| 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 507 | let | 
| 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 508 | fun list_ex ([], t) = t | 
| 45647 | 509 | | list_ex ((a, T) :: vars, t) = | 
| 510 | HOLogic.exists_const T $ Abs (a, T, list_ex (vars, t)); | |
| 47876 
0521ee2e504d
tweaked Inductive.prove_eqs to allow degenerate definition like "inductive TRUE where TRUE";
 wenzelm parents: 
46961diff
changeset | 511 | val conjs = map2 (curry HOLogic.mk_eq) frees us @ map HOLogic.dest_Trueprop ts; | 
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 512 | in | 
| 80727 | 513 | list_ex (params', if null conjs then \<^Const>\<open>True\<close> else foldr1 HOLogic.mk_conj conjs) | 
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 514 | end; | 
| 45647 | 515 | val lhs = list_comb (c, params @ frees); | 
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 516 | val rhs = | 
| 80727 | 517 | if null c_intrs then \<^Const>\<open>False\<close> | 
| 45647 | 518 | else foldr1 HOLogic.mk_disj (map mk_intr_conj c_intrs); | 
| 519 | val eq = HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, rhs)); | |
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 520 |         fun prove_intr1 (i, _) = Subgoal.FOCUS_PREMS (fn {context = ctxt'', params, prems, ...} =>
 | 
| 59532 | 521 | select_disj_tac ctxt'' (length c_intrs) (i + 1) 1 THEN | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 522 |             EVERY (replicate (length params) (resolve_tac ctxt'' @{thms exI} 1)) THEN
 | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 523 |             (if null prems then resolve_tac ctxt'' @{thms TrueI} 1
 | 
| 47876 
0521ee2e504d
tweaked Inductive.prove_eqs to allow degenerate definition like "inductive TRUE where TRUE";
 wenzelm parents: 
46961diff
changeset | 524 | else | 
| 
0521ee2e504d
tweaked Inductive.prove_eqs to allow degenerate definition like "inductive TRUE where TRUE";
 wenzelm parents: 
46961diff
changeset | 525 | let | 
| 
0521ee2e504d
tweaked Inductive.prove_eqs to allow degenerate definition like "inductive TRUE where TRUE";
 wenzelm parents: 
46961diff
changeset | 526 | val (prems', last_prem) = split_last prems; | 
| 
0521ee2e504d
tweaked Inductive.prove_eqs to allow degenerate definition like "inductive TRUE where TRUE";
 wenzelm parents: 
46961diff
changeset | 527 | in | 
| 58839 | 528 | EVERY (map (fn prem => | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 529 |                   (resolve_tac ctxt'' @{thms conjI} 1 THEN resolve_tac ctxt'' [prem] 1)) prems')
 | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 530 | THEN resolve_tac ctxt'' [last_prem] 1 | 
| 47876 
0521ee2e504d
tweaked Inductive.prove_eqs to allow degenerate definition like "inductive TRUE where TRUE";
 wenzelm parents: 
46961diff
changeset | 531 | end)) ctxt' 1; | 
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 532 | fun prove_intr2 (((_, _, us, _), ts, params'), intr) = | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 533 |           EVERY (replicate (length params') (eresolve_tac ctxt' @{thms exE} 1)) THEN
 | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 534 | (if null ts andalso null us then resolve_tac ctxt' [intr] 1 | 
| 47876 
0521ee2e504d
tweaked Inductive.prove_eqs to allow degenerate definition like "inductive TRUE where TRUE";
 wenzelm parents: 
46961diff
changeset | 535 | else | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 536 |             EVERY (replicate (length ts + length us - 1) (eresolve_tac ctxt' @{thms conjE} 1)) THEN
 | 
| 59059 | 537 |             Subgoal.FOCUS_PREMS (fn {context = ctxt'', prems, ...} =>
 | 
| 47876 
0521ee2e504d
tweaked Inductive.prove_eqs to allow degenerate definition like "inductive TRUE where TRUE";
 wenzelm parents: 
46961diff
changeset | 538 | let | 
| 
0521ee2e504d
tweaked Inductive.prove_eqs to allow degenerate definition like "inductive TRUE where TRUE";
 wenzelm parents: 
46961diff
changeset | 539 | val (eqs, prems') = chop (length us) prems; | 
| 
0521ee2e504d
tweaked Inductive.prove_eqs to allow degenerate definition like "inductive TRUE where TRUE";
 wenzelm parents: 
46961diff
changeset | 540 |                 val rew_thms = map (fn th => th RS @{thm eq_reflection}) eqs;
 | 
| 
0521ee2e504d
tweaked Inductive.prove_eqs to allow degenerate definition like "inductive TRUE where TRUE";
 wenzelm parents: 
46961diff
changeset | 541 | in | 
| 54742 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
53995diff
changeset | 542 | rewrite_goal_tac ctxt'' rew_thms 1 THEN | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 543 | resolve_tac ctxt'' [intr] 1 THEN | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 544 | EVERY (map (fn p => resolve_tac ctxt'' [p] 1) prems') | 
| 47876 
0521ee2e504d
tweaked Inductive.prove_eqs to allow degenerate definition like "inductive TRUE where TRUE";
 wenzelm parents: 
46961diff
changeset | 545 | end) ctxt' 1); | 
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 546 | in | 
| 51551 | 547 | Goal.prove_sorry ctxt' [] [] eq (fn _ => | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 548 |           resolve_tac ctxt' @{thms iffI} 1 THEN
 | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 549 | eresolve_tac ctxt' [#1 elim] 1 THEN | 
| 45647 | 550 | EVERY (map_index prove_intr1 c_intrs) THEN | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 551 |           (if null c_intrs then eresolve_tac ctxt' @{thms FalseE} 1
 | 
| 45647 | 552 | else | 
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 553 | let val (c_intrs', last_c_intr) = split_last c_intrs in | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 554 |               EVERY (map (fn ci => eresolve_tac ctxt' @{thms disjE} 1 THEN prove_intr2 ci) c_intrs')
 | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 555 | THEN prove_intr2 last_c_intr | 
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 556 | end)) | 
| 51717 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51658diff
changeset | 557 | |> rulify ctxt' | 
| 42361 | 558 | |> singleton (Proof_Context.export ctxt' ctxt'') | 
| 45647 | 559 | end; | 
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 560 | in | 
| 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 561 | map2 prove_eq cs elims | 
| 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 562 | end; | 
| 45647 | 563 | |
| 564 | ||
| 10735 | 565 | (* derivation of simplified elimination rules *) | 
| 5094 | 566 | |
| 11682 
d9063229b4a1
simp_case_tac is back again from induct_method.ML;
 wenzelm parents: 
11628diff
changeset | 567 | local | 
| 
d9063229b4a1
simp_case_tac is back again from induct_method.ML;
 wenzelm parents: 
11628diff
changeset | 568 | |
| 
d9063229b4a1
simp_case_tac is back again from induct_method.ML;
 wenzelm parents: 
11628diff
changeset | 569 | (*delete needless equality assumptions*) | 
| 69593 | 570 | val refl_thin = Goal.prove_global \<^theory>\<open>HOL\<close> [] [] \<^prop>\<open>\<And>P. a = a \<Longrightarrow> P \<Longrightarrow> P\<close> | 
| 58963 
26bf09b95dda
proper context for assume_tac (atac remains as fall-back without context);
 wenzelm parents: 
58936diff
changeset | 571 |   (fn {context = ctxt, ...} => assume_tac ctxt 1);
 | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 572 | val elim_rls = [asm_rl, FalseE, refl_thin, conjE, exE]; | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 573 | fun elim_tac ctxt = REPEAT o eresolve_tac ctxt elim_rls; | 
| 11682 
d9063229b4a1
simp_case_tac is back again from induct_method.ML;
 wenzelm parents: 
11628diff
changeset | 574 | |
| 51717 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51658diff
changeset | 575 | fun simp_case_tac ctxt i = | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 576 | EVERY' [elim_tac ctxt, | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 577 | asm_full_simp_tac ctxt, | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 578 | elim_tac ctxt, | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 579 | REPEAT o bound_hyp_subst_tac ctxt] i; | 
| 21367 
7a0cc1bb4dcc
inductive: canonical specification syntax (flattened result only);
 wenzelm parents: 
21350diff
changeset | 580 | |
| 11682 
d9063229b4a1
simp_case_tac is back again from induct_method.ML;
 wenzelm parents: 
11628diff
changeset | 581 | in | 
| 9598 | 582 | |
| 54742 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
53995diff
changeset | 583 | fun mk_cases_tac ctxt = ALLGOALS (simp_case_tac ctxt) THEN prune_params_tac ctxt; | 
| 53994 | 584 | |
| 21367 
7a0cc1bb4dcc
inductive: canonical specification syntax (flattened result only);
 wenzelm parents: 
21350diff
changeset | 585 | fun mk_cases ctxt prop = | 
| 7107 | 586 | let | 
| 21526 
1e6bd5ed7abc
added morh_result, the_inductive, add_inductive_global;
 wenzelm parents: 
21508diff
changeset | 587 | fun err msg = | 
| 
1e6bd5ed7abc
added morh_result, the_inductive, add_inductive_global;
 wenzelm parents: 
21508diff
changeset | 588 | error (Pretty.string_of (Pretty.block | 
| 24920 | 589 | [Pretty.str msg, Pretty.fbrk, Syntax.pretty_term ctxt prop])); | 
| 21526 
1e6bd5ed7abc
added morh_result, the_inductive, add_inductive_global;
 wenzelm parents: 
21508diff
changeset | 590 | |
| 24861 
cc669ca5f382
tuned Induct interface: prefer pred'' over set'';
 wenzelm parents: 
24830diff
changeset | 591 | val elims = Induct.find_casesP ctxt prop; | 
| 21367 
7a0cc1bb4dcc
inductive: canonical specification syntax (flattened result only);
 wenzelm parents: 
21350diff
changeset | 592 | |
| 59642 | 593 | val cprop = Thm.cterm_of ctxt prop; | 
| 21367 
7a0cc1bb4dcc
inductive: canonical specification syntax (flattened result only);
 wenzelm parents: 
21350diff
changeset | 594 | fun mk_elim rl = | 
| 53994 | 595 | Thm.implies_intr cprop | 
| 596 | (Tactic.rule_by_tactic ctxt (mk_cases_tac ctxt) (Thm.assume cprop RS rl)) | |
| 70318 
9eff9e2dc177
proper Proof_Context.export_morphism corresponding to Proof_Context.augment (see 7f568724d67e);
 wenzelm parents: 
70308diff
changeset | 597 | |> singleton (Proof_Context.export (Proof_Context.augment prop ctxt) ctxt); | 
| 7107 | 598 | in | 
| 599 | (case get_first (try mk_elim) elims of | |
| 15531 | 600 | SOME r => r | 
| 21526 
1e6bd5ed7abc
added morh_result, the_inductive, add_inductive_global;
 wenzelm parents: 
21508diff
changeset | 601 | | NONE => err "Proposition not an inductive predicate:") | 
| 7107 | 602 | end; | 
| 603 | ||
| 11682 
d9063229b4a1
simp_case_tac is back again from induct_method.ML;
 wenzelm parents: 
11628diff
changeset | 604 | end; | 
| 
d9063229b4a1
simp_case_tac is back again from induct_method.ML;
 wenzelm parents: 
11628diff
changeset | 605 | |
| 45647 | 606 | |
| 21367 
7a0cc1bb4dcc
inductive: canonical specification syntax (flattened result only);
 wenzelm parents: 
21350diff
changeset | 607 | (* inductive_cases *) | 
| 7107 | 608 | |
| 79732 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 609 | fun gen_inductive_cases prep_att prep_prop args int lthy = | 
| 9598 | 610 | let | 
| 46915 | 611 | val thmss = | 
| 612 | map snd args | |
| 58993 
302104d8366b
prefer independent parallel map where user input is processed -- avoid non-deterministic feedback in error situations;
 wenzelm parents: 
58963diff
changeset | 613 | |> burrow (grouped 10 Par_List.map_independent (mk_cases lthy o prep_prop lthy)); | 
| 46915 | 614 | val facts = | 
| 55997 
9dc5ce83202c
modernized Attrib.check_name/check_src similar to methods (see also a989bdaf8121);
 wenzelm parents: 
55111diff
changeset | 615 | map2 (fn ((a, atts), _) => fn thms => ((a, map (prep_att lthy) atts), [(thms, [])])) | 
| 46915 | 616 | args thmss; | 
| 79732 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 617 | val (res, lthy') = lthy |> Local_Theory.notes facts | 
| 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 618 | val _ = | 
| 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 619 | Proof_Display.print_results | 
| 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 620 |         {interactive = int, pos = Position.thread_data (), proof_state = false}
 | 
| 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 621 | lthy' ((Thm.theoremK, ""), res); | 
| 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 622 | in (res, lthy') end; | 
| 5094 | 623 | |
| 69709 | 624 | val inductive_cases = gen_inductive_cases (K I) Syntax.check_prop; | 
| 625 | val inductive_cases_cmd = gen_inductive_cases Attrib.check_src Syntax.read_prop; | |
| 7107 | 626 | |
| 59845 | 627 | |
| 628 | (* ind_cases *) | |
| 629 | ||
| 630 | fun ind_cases_rules ctxt raw_props raw_fixes = | |
| 631 | let | |
| 63180 | 632 | val (props, ctxt') = Specification.read_props raw_props raw_fixes ctxt; | 
| 59845 | 633 | val rules = Proof_Context.export ctxt' ctxt (map (mk_cases ctxt') props); | 
| 634 | in rules end; | |
| 635 | ||
| 58815 | 636 | val _ = | 
| 637 | Theory.setup | |
| 67149 | 638 | (Method.setup \<^binding>\<open>ind_cases\<close> | 
| 59845 | 639 | (Scan.lift (Scan.repeat1 Parse.prop -- Parse.for_fixes) >> | 
| 640 | (fn (props, fixes) => fn ctxt => | |
| 641 | Method.erule ctxt 0 (ind_cases_rules ctxt props fixes))) | |
| 642 | "case analysis for inductive definitions, based on simplified elimination rule"); | |
| 9598 | 643 | |
| 45647 | 644 | |
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 645 | (* derivation of simplified equation *) | 
| 9598 | 646 | |
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 647 | fun mk_simp_eq ctxt prop = | 
| 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 648 | let | 
| 45647 | 649 | val thy = Proof_Context.theory_of ctxt; | 
| 70308 | 650 | val ctxt' = Proof_Context.augment prop ctxt; | 
| 45647 | 651 | val lhs_of = fst o HOLogic.dest_eq o HOLogic.dest_Trueprop o Thm.prop_of; | 
| 652 | val substs = | |
| 67637 | 653 | retrieve_equations ctxt (HOLogic.dest_Trueprop prop) | 
| 38665 
e92223c886f8
introducing simplification equations for inductive sets; added data structure for storing equations; rewriting retrieval of simplification equation for inductive predicates and sets
 bulwahn parents: 
38388diff
changeset | 654 | |> map_filter | 
| 
e92223c886f8
introducing simplification equations for inductive sets; added data structure for storing equations; rewriting retrieval of simplification equation for inductive predicates and sets
 bulwahn parents: 
38388diff
changeset | 655 | (fn eq => SOME (Pattern.match thy (lhs_of eq, HOLogic.dest_Trueprop prop) | 
| 
e92223c886f8
introducing simplification equations for inductive sets; added data structure for storing equations; rewriting retrieval of simplification equation for inductive predicates and sets
 bulwahn parents: 
38388diff
changeset | 656 | (Vartab.empty, Vartab.empty), eq) | 
| 45647 | 657 | handle Pattern.MATCH => NONE); | 
| 658 | val (subst, eq) = | |
| 659 | (case substs of | |
| 38665 
e92223c886f8
introducing simplification equations for inductive sets; added data structure for storing equations; rewriting retrieval of simplification equation for inductive predicates and sets
 bulwahn parents: 
38388diff
changeset | 660 | [s] => s | 
| 
e92223c886f8
introducing simplification equations for inductive sets; added data structure for storing equations; rewriting retrieval of simplification equation for inductive predicates and sets
 bulwahn parents: 
38388diff
changeset | 661 | | _ => error | 
| 45647 | 662 |         ("equations matching pattern " ^ Syntax.string_of_term ctxt prop ^ " is not unique"));
 | 
| 663 | val inst = | |
| 60784 | 664 | map (fn v => (fst v, Thm.cterm_of ctxt' (Envir.subst_term subst (Var v)))) | 
| 45647 | 665 | (Term.add_vars (lhs_of eq) []); | 
| 666 | in | |
| 60784 | 667 | infer_instantiate ctxt' inst eq | 
| 668 | |> Conv.fconv_rule (Conv.arg_conv (Conv.arg_conv (Simplifier.full_rewrite ctxt'))) | |
| 70318 
9eff9e2dc177
proper Proof_Context.export_morphism corresponding to Proof_Context.augment (see 7f568724d67e);
 wenzelm parents: 
70308diff
changeset | 669 | |> singleton (Proof_Context.export ctxt' ctxt) | 
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 670 | end | 
| 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 671 | |
| 45647 | 672 | |
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 673 | (* inductive simps *) | 
| 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 674 | |
| 79732 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 675 | fun gen_inductive_simps prep_att prep_prop args int lthy = | 
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 676 | let | 
| 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 677 | val facts = args |> map (fn ((a, atts), props) => | 
| 55997 
9dc5ce83202c
modernized Attrib.check_name/check_src similar to methods (see also a989bdaf8121);
 wenzelm parents: 
55111diff
changeset | 678 | ((a, map (prep_att lthy) atts), | 
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 679 | map (Thm.no_attributes o single o mk_simp_eq lthy o prep_prop lthy) props)); | 
| 79732 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 680 | val (res, lthy') = lthy |> Local_Theory.notes facts | 
| 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 681 | val _ = | 
| 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 682 | Proof_Display.print_results | 
| 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 683 |         {interactive = int, pos = Position.thread_data (), proof_state = false}
 | 
| 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 684 | lthy' ((Thm.theoremK, ""), res) | 
| 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 685 | in (res, lthy') end; | 
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 686 | |
| 69709 | 687 | val inductive_simps = gen_inductive_simps (K I) Syntax.check_prop; | 
| 688 | val inductive_simps_cmd = gen_inductive_simps Attrib.check_src Syntax.read_prop; | |
| 40902 | 689 | |
| 45647 | 690 | |
| 10735 | 691 | (* prove induction rule *) | 
| 5094 | 692 | |
| 26477 
ecf06644f6cb
eliminated quiete_mode ref (turned into proper argument);
 wenzelm parents: 
26336diff
changeset | 693 | fun prove_indrule quiet_mode cs argTs bs xs rec_const params intr_ts mono | 
| 45647 | 694 | fp_def rec_preds_defs ctxt ctxt''' = (* FIXME ctxt''' ?? *) | 
| 5094 | 695 | let | 
| 52059 | 696 | val _ = clean_message ctxt quiet_mode " Proving the induction rule ..."; | 
| 5094 | 697 | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 698 | (* predicates for induction rule *) | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 699 | |
| 36642 | 700 | val (pnames, ctxt') = Variable.variant_fixes (mk_names "P" (length cs)) ctxt; | 
| 45647 | 701 | val preds = | 
| 702 | map2 (curry Free) pnames | |
| 703 | (map (fn c => arg_types_of (length params) c ---> HOLogic.boolT) cs); | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 704 | |
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 705 | (* transform an introduction rule into a premise for induction rule *) | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 706 | |
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 707 | fun mk_ind_prem r = | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 708 | let | 
| 33669 | 709 | fun subst s = | 
| 710 | (case dest_predicate cs params s of | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 711 | SOME (_, i, ys, (_, Ts)) => | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 712 | let | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 713 | val k = length Ts; | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 714 | val bs = map Bound (k - 1 downto 0); | 
| 42364 | 715 | val P = list_comb (nth preds i, map (incr_boundvars k) ys @ bs); | 
| 46219 
426ed18eba43
discontinued old-style Term.list_abs in favour of plain Term.abs;
 wenzelm parents: 
46218diff
changeset | 716 | val Q = | 
| 
426ed18eba43
discontinued old-style Term.list_abs in favour of plain Term.abs;
 wenzelm parents: 
46218diff
changeset | 717 | fold_rev Term.abs (mk_names "x" k ~~ Ts) | 
| 67149 | 718 | (HOLogic.mk_binop \<^const_name>\<open>HOL.induct_conj\<close> | 
| 46219 
426ed18eba43
discontinued old-style Term.list_abs in favour of plain Term.abs;
 wenzelm parents: 
46218diff
changeset | 719 | (list_comb (incr_boundvars k s, bs), P)); | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 720 | in (Q, case Ts of [] => SOME (s, P) | _ => NONE) end | 
| 33669 | 721 | | NONE => | 
| 722 | (case s of | |
| 45647 | 723 | t $ u => (fst (subst t) $ fst (subst u), NONE) | 
| 724 | | Abs (a, T, t) => (Abs (a, T, fst (subst t)), NONE) | |
| 33669 | 725 | | _ => (s, NONE))); | 
| 7293 | 726 | |
| 33338 | 727 | fun mk_prem s prems = | 
| 728 | (case subst s of | |
| 729 | (_, SOME (t, u)) => t :: u :: prems | |
| 730 | | (t, _) => t :: prems); | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 731 | |
| 45647 | 732 | val SOME (_, i, ys, _) = | 
| 733 | dest_predicate cs params (HOLogic.dest_Trueprop (Logic.strip_assums_concl r)); | |
| 42364 | 734 | in | 
| 46215 
0da9433f959e
discontinued old-style Term.list_all_free in favour of plain Logic.all;
 wenzelm parents: 
45740diff
changeset | 735 | fold_rev (Logic.all o Free) (Logic.strip_params r) | 
| 
0da9433f959e
discontinued old-style Term.list_all_free in favour of plain Logic.all;
 wenzelm parents: 
45740diff
changeset | 736 | (Logic.list_implies (map HOLogic.mk_Trueprop (fold_rev mk_prem | 
| 42364 | 737 | (map HOLogic.dest_Trueprop (Logic.strip_assums_hyp r)) []), | 
| 738 | HOLogic.mk_Trueprop (list_comb (nth preds i, ys)))) | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 739 | end; | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 740 | |
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 741 | val ind_prems = map mk_ind_prem intr_ts; | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 742 | |
| 21526 
1e6bd5ed7abc
added morh_result, the_inductive, add_inductive_global;
 wenzelm parents: 
21508diff
changeset | 743 | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 744 | (* make conclusions for induction rules *) | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 745 | |
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 746 | val Tss = map (binder_types o fastype_of) preds; | 
| 45647 | 747 | val (xnames, ctxt'') = Variable.variant_fixes (mk_names "x" (length (flat Tss))) ctxt'; | 
| 748 | val mutual_ind_concl = | |
| 749 | HOLogic.mk_Trueprop (foldr1 HOLogic.mk_conj | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 750 | (map (fn (((xnames, Ts), c), P) => | 
| 45647 | 751 | let val frees = map Free (xnames ~~ Ts) | 
| 752 | in HOLogic.mk_imp (list_comb (c, params @ frees), list_comb (P, frees)) end) | |
| 753 | (unflat Tss xnames ~~ Tss ~~ cs ~~ preds))); | |
| 5094 | 754 | |
| 13626 
282fbabec862
Fixed bug involving inductive definitions having equalities in the premises,
 paulson parents: 
13197diff
changeset | 755 | |
| 5094 | 756 | (* make predicate for instantiation of abstract induction rule *) | 
| 757 | ||
| 45647 | 758 | val ind_pred = | 
| 759 | fold_rev lambda (bs @ xs) (foldr1 HOLogic.mk_conj | |
| 760 | (map_index (fn (i, P) => fold_rev (curry HOLogic.mk_imp) | |
| 761 | (make_bool_args HOLogic.mk_not I bs i) | |
| 762 | (list_comb (P, make_args' argTs xs (binder_types (fastype_of P))))) preds)); | |
| 5094 | 763 | |
| 45647 | 764 | val ind_concl = | 
| 765 | HOLogic.mk_Trueprop | |
| 67149 | 766 | (HOLogic.mk_binrel \<^const_name>\<open>Orderings.less_eq\<close> (rec_const, ind_pred)); | 
| 5094 | 767 | |
| 45647 | 768 |     val raw_fp_induct = mono RS (fp_def RS @{thm def_lfp_induct});
 | 
| 13626 
282fbabec862
Fixed bug involving inductive definitions having equalities in the premises,
 paulson parents: 
13197diff
changeset | 769 | |
| 51551 | 770 | val induct = Goal.prove_sorry ctxt'' [] ind_prems ind_concl | 
| 54742 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
53995diff
changeset | 771 |       (fn {context = ctxt3, prems} => EVERY
 | 
| 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
53995diff
changeset | 772 | [rewrite_goals_tac ctxt3 [inductive_conj_def], | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 773 | DETERM (resolve_tac ctxt3 [raw_fp_induct] 1), | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 774 |          REPEAT (resolve_tac ctxt3 [@{thm le_funI}, @{thm le_boolI}] 1),
 | 
| 54742 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
53995diff
changeset | 775 | rewrite_goals_tac ctxt3 simp_thms2, | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 776 | (*This disjE separates out the introduction rules*) | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 777 | REPEAT (FIRSTGOAL (eresolve_tac ctxt3 [disjE, exE, FalseE])), | 
| 5094 | 778 | (*Now break down the individual cases. No disjE here in case | 
| 779 | some premise involves disjunction.*) | |
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 780 | REPEAT (FIRSTGOAL (eresolve_tac ctxt3 [conjE] ORELSE' bound_hyp_subst_tac ctxt3)), | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 781 | REPEAT (FIRSTGOAL | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 782 | (resolve_tac ctxt3 [conjI, impI] ORELSE' | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 783 | (eresolve_tac ctxt3 [notE] THEN' assume_tac ctxt3))), | 
| 59499 | 784 | EVERY (map (fn prem => | 
| 785 | DEPTH_SOLVE_1 (assume_tac ctxt3 1 ORELSE | |
| 786 | resolve_tac ctxt3 | |
| 787 | [rewrite_rule ctxt3 (inductive_conj_def :: rec_preds_defs @ simp_thms2) prem, | |
| 788 | conjI, refl] 1)) prems)]); | |
| 5094 | 789 | |
| 51551 | 790 | val lemma = Goal.prove_sorry ctxt'' [] [] | 
| 54742 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
53995diff
changeset | 791 |       (Logic.mk_implies (ind_concl, mutual_ind_concl)) (fn {context = ctxt3, ...} => EVERY
 | 
| 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
53995diff
changeset | 792 | [rewrite_goals_tac ctxt3 rec_preds_defs, | 
| 5094 | 793 | REPEAT (EVERY | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 794 | [REPEAT (resolve_tac ctxt3 [conjI, impI] 1), | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 795 |             REPEAT (eresolve_tac ctxt3 [@{thm le_funE}, @{thm le_boolE}] 1),
 | 
| 58963 
26bf09b95dda
proper context for assume_tac (atac remains as fall-back without context);
 wenzelm parents: 
58936diff
changeset | 796 | assume_tac ctxt3 1, | 
| 54742 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
53995diff
changeset | 797 | rewrite_goals_tac ctxt3 simp_thms1, | 
| 58963 
26bf09b95dda
proper context for assume_tac (atac remains as fall-back without context);
 wenzelm parents: 
58936diff
changeset | 798 | assume_tac ctxt3 1])]); | 
| 5094 | 799 | |
| 42361 | 800 | in singleton (Proof_Context.export ctxt'' ctxt''') (induct RS lemma) end; | 
| 5094 | 801 | |
| 63863 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 802 | (* prove coinduction rule *) | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 803 | |
| 80727 | 804 | fun mk_If p t f = let val T = fastype_of t in \<^Const>\<open>If T\<close> $ p $ t $ f end; | 
| 63863 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 805 | |
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 806 | fun prove_coindrule quiet_mode preds cs argTs bs xs params intr_ts mono | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 807 | fp_def rec_preds_defs ctxt ctxt''' = (* FIXME ctxt''' ?? *) | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 808 | let | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 809 | val _ = clean_message ctxt quiet_mode " Proving the coinduction rule ..."; | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 810 | val n = length cs; | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 811 | val (ns, xss) = map_split (fn pred => | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 812 | make_args' argTs xs (arg_types_of (length params) pred) |> `length) preds; | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 813 | val xTss = map (map fastype_of) xss; | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 814 | val (Rs_names, names_ctxt) = Variable.variant_fixes (mk_names "X" n) ctxt; | 
| 80727 | 815 | val Rs = map2 (fn name => fn Ts => Free (name, Ts ---> \<^Type>\<open>bool\<close>)) Rs_names xTss; | 
| 63863 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 816 | val Rs_applied = map2 (curry list_comb) Rs xss; | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 817 | val preds_applied = map2 (curry list_comb) (map (fn p => list_comb (p, params)) preds) xss; | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 818 | val abstract_list = fold_rev (absfree o dest_Free); | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 819 | val bss = map (make_bool_args | 
| 80727 | 820 | (fn b => HOLogic.mk_eq (b, \<^Const>\<open>False\<close>)) | 
| 821 | (fn b => HOLogic.mk_eq (b, \<^Const>\<open>True\<close>)) bs) (0 upto n - 1); | |
| 63863 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 822 | val eq_undefinedss = map (fn ys => map (fn x => | 
| 80727 | 823 | let val T = fastype_of x | 
| 824 | in \<^Const>\<open>HOL.eq T for x \<^Const>\<open>undefined T\<close>\<close> end) | |
| 63863 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 825 | (subtract (op =) ys xs)) xss; | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 826 | val R = | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 827 |       @{fold 3} (fn bs => fn eqs => fn R => fn t => if null bs andalso null eqs then R else
 | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 828 | mk_If (Library.foldr1 HOLogic.mk_conj (bs @ eqs)) R t) | 
| 80727 | 829 | bss eq_undefinedss Rs_applied \<^Const>\<open>False\<close> | 
| 63863 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 830 | |> abstract_list (bs @ xs); | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 831 | |
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 832 | fun subst t = | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 833 | (case dest_predicate cs params t of | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 834 | SOME (_, i, ts, (_, Us)) => | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 835 | let | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 836 | val l = length Us; | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 837 | val bs = map Bound (l - 1 downto 0); | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 838 | val args = map (incr_boundvars l) ts @ bs | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 839 | in | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 840 | HOLogic.mk_disj (list_comb (nth Rs i, args), | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 841 | list_comb (nth preds i, params @ args)) | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 842 | |> fold_rev absdummy Us | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 843 | end | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 844 | | NONE => | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 845 | (case t of | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 846 | t1 $ t2 => subst t1 $ subst t2 | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 847 | | Abs (x, T, u) => Abs (x, T, subst u) | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 848 | | _ => t)); | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 849 | |
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 850 | fun mk_coind_prem r = | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 851 | let | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 852 | val SOME (_, i, ts, (Ts, _)) = | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 853 | dest_predicate cs params (HOLogic.dest_Trueprop (Logic.strip_assums_concl r)); | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 854 | val ps = | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 855 | map HOLogic.mk_eq (make_args' argTs xs Ts ~~ ts) @ | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 856 | map (subst o HOLogic.dest_Trueprop) (Logic.strip_assums_hyp r); | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 857 | in | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 858 | (i, fold_rev (fn (x, T) => fn P => HOLogic.exists_const T $ Abs (x, T, P)) | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 859 | (Logic.strip_params r) | 
| 80727 | 860 | (if null ps then \<^Const>\<open>True\<close> else foldr1 HOLogic.mk_conj ps)) | 
| 63863 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 861 | end; | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 862 | |
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 863 | fun mk_prem i Ps = Logic.mk_implies | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 864 |         ((nth Rs_applied i, Library.foldr1 HOLogic.mk_disj Ps) |> @{apply 2} HOLogic.mk_Trueprop)
 | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 865 | |> fold_rev Logic.all (nth xss i); | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 866 | |
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 867 | val prems = map mk_coind_prem intr_ts |> AList.group (op =) |> sort (int_ord o apply2 fst) | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 868 | |> map (uncurry mk_prem); | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 869 | |
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 870 |     val concl = @{map 3} (fn xs =>
 | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 871 | Ctr_Sugar_Util.list_all_free xs oo curry HOLogic.mk_imp) xss Rs_applied preds_applied | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 872 | |> Library.foldr1 HOLogic.mk_conj |> HOLogic.mk_Trueprop; | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 873 | |
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 874 | |
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 875 | val pred_defs_sym = if null rec_preds_defs then [] else map2 (fn n => fn thm => | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 876 |         funpow n (fn thm => thm RS @{thm meta_fun_cong}) thm RS @{thm Pure.symmetric})
 | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 877 | ns rec_preds_defs; | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 878 | val simps = simp_thms3 @ pred_defs_sym; | 
| 80701 | 879 | val simproc = Simplifier.the_simproc ctxt "HOL.defined_All"; | 
| 880 | val simplify = | |
| 881 | asm_full_simplify (Ctr_Sugar_Util.ss_only simps ctxt |> Simplifier.add_proc simproc); | |
| 63863 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 882 |     val coind = (mono RS (fp_def RS @{thm def_coinduct}))
 | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 883 | |> infer_instantiate' ctxt [SOME (Thm.cterm_of ctxt R)] | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 884 | |> simplify; | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 885 | fun idx_of t = find_index (fn R => | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 886 | R = the_single (subtract (op =) (preds @ params) (map Free (Term.add_frees t [])))) Rs; | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 887 | val coind_concls = HOLogic.dest_Trueprop (Thm.concl_of coind) |> HOLogic.dest_conj | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 888 |       |> map (fn t => (idx_of t, t)) |> sort (int_ord o @{apply 2} fst) |> map snd;
 | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 889 | val reorder_bound_goals = map_filter (fn (t, u) => if t aconv u then NONE else | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 890 | SOME (HOLogic.mk_Trueprop (HOLogic.mk_eq (t, u)))) | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 891 | ((HOLogic.dest_Trueprop concl |> HOLogic.dest_conj) ~~ coind_concls); | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 892 | val reorder_bound_thms = map (fn goal => Goal.prove_sorry ctxt [] [] goal | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 893 |       (fn {context = ctxt, prems = _} =>
 | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 894 | HEADGOAL (EVERY' [resolve_tac ctxt [iffI], | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 895 | REPEAT_DETERM o resolve_tac ctxt [allI, impI], | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 896 | REPEAT_DETERM o dresolve_tac ctxt [spec], eresolve_tac ctxt [mp], assume_tac ctxt, | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 897 | REPEAT_DETERM o resolve_tac ctxt [allI, impI], | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 898 | REPEAT_DETERM o dresolve_tac ctxt [spec], eresolve_tac ctxt [mp], assume_tac ctxt]))) | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 899 | reorder_bound_goals; | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 900 |     val coinduction = Goal.prove_sorry ctxt [] prems concl (fn {context = ctxt, prems = CIH} =>
 | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 901 | HEADGOAL (full_simp_tac | 
| 80701 | 902 | (Ctr_Sugar_Util.ss_only (simps @ reorder_bound_thms) ctxt | 
| 903 | |> Simplifier.add_proc simproc) THEN' | |
| 63863 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 904 | resolve_tac ctxt [coind]) THEN | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 905 | ALLGOALS (REPEAT_ALL_NEW (REPEAT_DETERM o resolve_tac ctxt [allI, impI, conjI] THEN' | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 906 | REPEAT_DETERM o eresolve_tac ctxt [exE, conjE] THEN' | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 907 | dresolve_tac ctxt (map simplify CIH) THEN' | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 908 | REPEAT_DETERM o (assume_tac ctxt ORELSE' | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 909 | eresolve_tac ctxt [conjE] ORELSE' dresolve_tac ctxt [spec, mp])))) | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 910 | in | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 911 | coinduction | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 912 | |> length cs = 1 ? (Object_Logic.rulify ctxt #> rotate_prems ~1) | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 913 | |> singleton (Proof_Context.export names_ctxt ctxt''') | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 914 | end | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 915 | |
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 916 | |
| 6424 | 917 | |
| 918 | ||
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 919 | (** specification of (co)inductive predicates **) | 
| 10729 | 920 | |
| 49170 
03bee3a6a1b7
discontinued obsolete fork_mono to loosen some brakes -- NB: TTY interaction has Goal.future_proofs disabled due to missing Future.worker_task;
 wenzelm parents: 
47876diff
changeset | 921 | fun mk_ind_def quiet_mode skip_mono alt_name coind cs intr_ts monos params cnames_syn lthy = | 
| 33458 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 922 | let | 
| 33077 
3c9cf88ec841
arg_types_of auxiliary function; using multiset operations
 haftmann parents: 
33056diff
changeset | 923 | val argTs = fold (combine (op =) o arg_types_of (length params)) cs []; | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 924 | val k = log 2 1 (length cs); | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 925 | val predT = replicate k HOLogic.boolT ---> argTs ---> HOLogic.boolT; | 
| 80727 | 926 | val fp_const = if coind then \<^Const>\<open>gfp predT\<close> else \<^Const>\<open>lfp predT\<close>; | 
| 927 | ||
| 45647 | 928 | val p :: xs = | 
| 929 | map Free (Variable.variant_frees lthy intr_ts | |
| 930 |         (("p", predT) :: (mk_names "x" (length argTs) ~~ argTs)));
 | |
| 931 | val bs = | |
| 932 | map Free (Variable.variant_frees lthy (p :: xs @ intr_ts) | |
| 933 | (map (rpair HOLogic.boolT) (mk_names "b" k))); | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 934 | |
| 33458 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 935 | fun subst t = | 
| 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 936 | (case dest_predicate cs params t of | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 937 | SOME (_, i, ts, (Ts, Us)) => | 
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 938 | let | 
| 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 939 | val l = length Us; | 
| 33669 | 940 | val zs = map Bound (l - 1 downto 0); | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 941 | in | 
| 46219 
426ed18eba43
discontinued old-style Term.list_abs in favour of plain Term.abs;
 wenzelm parents: 
46218diff
changeset | 942 | fold_rev (Term.abs o pair "z") Us | 
| 
426ed18eba43
discontinued old-style Term.list_abs in favour of plain Term.abs;
 wenzelm parents: 
46218diff
changeset | 943 | (list_comb (p, | 
| 
426ed18eba43
discontinued old-style Term.list_abs in favour of plain Term.abs;
 wenzelm parents: 
46218diff
changeset | 944 | make_bool_args' bs i @ make_args argTs | 
| 
426ed18eba43
discontinued old-style Term.list_abs in favour of plain Term.abs;
 wenzelm parents: 
46218diff
changeset | 945 | ((map (incr_boundvars l) ts ~~ Ts) @ (zs ~~ Us)))) | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 946 | end | 
| 33669 | 947 | | NONE => | 
| 948 | (case t of | |
| 949 | t1 $ t2 => subst t1 $ subst t2 | |
| 950 | | Abs (x, T, u) => Abs (x, T, subst u) | |
| 951 | | _ => t)); | |
| 5149 | 952 | |
| 5094 | 953 | (* transform an introduction rule into a conjunction *) | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 954 | (* [| p_i t; ... |] ==> p_j u *) | 
| 5094 | 955 | (* is transformed into *) | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 956 | (* b_j & x_j = u & p b_j t & ... *) | 
| 5094 | 957 | |
| 958 | fun transform_rule r = | |
| 959 | let | |
| 45647 | 960 | val SOME (_, i, ts, (Ts, _)) = | 
| 961 | dest_predicate cs params (HOLogic.dest_Trueprop (Logic.strip_assums_concl r)); | |
| 962 | val ps = | |
| 963 | make_bool_args HOLogic.mk_not I bs i @ | |
| 21048 
e57e91f72831
Restructured and repaired code dealing with case names
 berghofe parents: 
21024diff
changeset | 964 | map HOLogic.mk_eq (make_args' argTs xs Ts ~~ ts) @ | 
| 45647 | 965 | map (subst o HOLogic.dest_Trueprop) (Logic.strip_assums_hyp r); | 
| 33338 | 966 | in | 
| 967 | fold_rev (fn (x, T) => fn P => HOLogic.exists_const T $ Abs (x, T, P)) | |
| 968 | (Logic.strip_params r) | |
| 80727 | 969 | (if null ps then \<^Const>\<open>True\<close> else foldr1 HOLogic.mk_conj ps) | 
| 45647 | 970 | end; | 
| 5094 | 971 | |
| 972 | (* make a disjunction of all introduction rules *) | |
| 973 | ||
| 45647 | 974 | val fp_fun = | 
| 975 | fold_rev lambda (p :: bs @ xs) | |
| 80727 | 976 | (if null intr_ts then \<^Const>\<open>False\<close> | 
| 45647 | 977 | else foldr1 HOLogic.mk_disj (map transform_rule intr_ts)); | 
| 5094 | 978 | |
| 61308 | 979 | (* add definition of recursive predicates to theory *) | 
| 5094 | 980 | |
| 61948 | 981 | val is_auxiliary = length cs > 1; | 
| 982 | ||
| 61681 
ca53150406c9
option "inductive_defs" controls exposure of def and mono facts;
 wenzelm parents: 
61308diff
changeset | 983 | val rec_binding = | 
| 63006 | 984 | if Binding.is_empty alt_name then Binding.conglomerate (map #1 cnames_syn) else alt_name; | 
| 61681 
ca53150406c9
option "inductive_defs" controls exposure of def and mono facts;
 wenzelm parents: 
61308diff
changeset | 985 | val rec_name = Binding.name_of rec_binding; | 
| 5094 | 986 | |
| 62093 | 987 | val internals = Config.get lthy inductive_internals; | 
| 61681 
ca53150406c9
option "inductive_defs" controls exposure of def and mono facts;
 wenzelm parents: 
61308diff
changeset | 988 | |
| 33458 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 989 | val ((rec_const, (_, fp_def)), lthy') = lthy | 
| 59880 
30687c3f2b10
clarified role of naming for background theory: transform_binding (e.g. for "concealed" flag) uses naming of hypothetical context;
 wenzelm parents: 
59859diff
changeset | 990 | |> is_auxiliary ? Proof_Context.concealed | 
| 33766 
c679f05600cd
adapted Local_Theory.define -- eliminated odd thm kind;
 wenzelm parents: 
33726diff
changeset | 991 | |> Local_Theory.define | 
| 61951 | 992 | ((rec_binding, case cnames_syn of [(_, mx)] => mx | _ => NoSyn), | 
| 62093 | 993 |          ((Thm.make_def_binding internals rec_binding, @{attributes [nitpick_unfold]}),
 | 
| 80727 | 994 | fold_rev lambda params (fp_const $ fp_fun))) | 
| 59880 
30687c3f2b10
clarified role of naming for background theory: transform_binding (e.g. for "concealed" flag) uses naming of hypothetical context;
 wenzelm parents: 
59859diff
changeset | 995 | ||> Proof_Context.restore_naming lthy; | 
| 45647 | 996 | val fp_def' = | 
| 51717 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51658diff
changeset | 997 | Simplifier.rewrite (put_simpset HOL_basic_ss lthy' addsimps [fp_def]) | 
| 59621 
291934bac95e
Thm.cterm_of and Thm.ctyp_of operate on local context;
 wenzelm parents: 
59582diff
changeset | 998 | (Thm.cterm_of lthy' (list_comb (rec_const, params))); | 
| 33278 | 999 | val specs = | 
| 61681 
ca53150406c9
option "inductive_defs" controls exposure of def and mono facts;
 wenzelm parents: 
61308diff
changeset | 1000 | if is_auxiliary then | 
| 61951 | 1001 | map_index (fn (i, ((b, mx), c)) => | 
| 33278 | 1002 | let | 
| 1003 | val Ts = arg_types_of (length params) c; | |
| 45647 | 1004 | val xs = | 
| 61063 | 1005 | map Free (Variable.variant_frees lthy' intr_ts (mk_names "x" (length Ts) ~~ Ts)); | 
| 33278 | 1006 | in | 
| 61951 | 1007 | ((b, mx), | 
| 62093 | 1008 | ((Thm.make_def_binding internals b, []), fold_rev lambda (params @ xs) | 
| 61951 | 1009 | (list_comb (rec_const, params @ make_bool_args' bs i @ | 
| 1010 | make_args argTs (xs ~~ Ts))))) | |
| 61681 
ca53150406c9
option "inductive_defs" controls exposure of def and mono facts;
 wenzelm parents: 
61308diff
changeset | 1011 | end) (cnames_syn ~~ cs) | 
| 
ca53150406c9
option "inductive_defs" controls exposure of def and mono facts;
 wenzelm parents: 
61308diff
changeset | 1012 | else []; | 
| 33458 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 1013 | val (consts_defs, lthy'') = lthy' | 
| 39248 
4a3747517552
only conceal primitive definition theorems, not predicate names
 haftmann parents: 
38864diff
changeset | 1014 | |> fold_map Local_Theory.define specs; | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 1015 | val preds = (case cs of [_] => [rec_const] | _ => map #1 consts_defs); | 
| 5094 | 1016 | |
| 61063 | 1017 | val (_, ctxt'') = Variable.add_fixes (map (fst o dest_Free) params) lthy''; | 
| 1018 | val mono = prove_mono quiet_mode skip_mono predT fp_fun monos ctxt''; | |
| 1019 | val (_, lthy''') = lthy'' | |
| 61681 
ca53150406c9
option "inductive_defs" controls exposure of def and mono facts;
 wenzelm parents: 
61308diff
changeset | 1020 | |> Local_Theory.note | 
| 62093 | 1021 | ((if internals | 
| 61681 
ca53150406c9
option "inductive_defs" controls exposure of def and mono facts;
 wenzelm parents: 
61308diff
changeset | 1022 | then Binding.qualify true rec_name (Binding.name "mono") | 
| 
ca53150406c9
option "inductive_defs" controls exposure of def and mono facts;
 wenzelm parents: 
61308diff
changeset | 1023 | else Binding.empty, []), | 
| 
ca53150406c9
option "inductive_defs" controls exposure of def and mono facts;
 wenzelm parents: 
61308diff
changeset | 1024 | Proof_Context.export ctxt'' lthy'' [mono]); | 
| 61063 | 1025 | in | 
| 1026 | (lthy''', Proof_Context.transfer (Proof_Context.theory_of lthy''') ctxt'', | |
| 61681 
ca53150406c9
option "inductive_defs" controls exposure of def and mono facts;
 wenzelm parents: 
61308diff
changeset | 1027 | rec_binding, mono, fp_def', map (#2 o #2) consts_defs, | 
| 61063 | 1028 | list_comb (rec_const, params), preds, argTs, bs, xs) | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 1029 | end; | 
| 5094 | 1030 | |
| 71179 | 1031 | fun declare_rules rec_binding coind no_ind spec_name cnames | 
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 1032 | preds intrs intr_bindings intr_atts elims eqs raw_induct lthy = | 
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 1033 | let | 
| 30223 
24d975352879
renamed Binding.name_pos to Binding.make, renamed Binding.base_name to Binding.name_of, renamed Binding.map_base to Binding.map_name, added mandatory flag to Binding.qualify;
 wenzelm parents: 
30218diff
changeset | 1034 | val rec_name = Binding.name_of rec_binding; | 
| 32773 | 1035 | fun rec_qualified qualified = Binding.qualify qualified rec_name; | 
| 30223 
24d975352879
renamed Binding.name_pos to Binding.make, renamed Binding.base_name to Binding.name_of, renamed Binding.map_base to Binding.map_name, added mandatory flag to Binding.qualify;
 wenzelm parents: 
30218diff
changeset | 1036 | val intr_names = map Binding.name_of intr_bindings; | 
| 61308 | 1037 | val ind_case_names = | 
| 1038 | if forall (equal "") intr_names then [] | |
| 63019 | 1039 | else [Attrib.case_names intr_names]; | 
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 1040 | val induct = | 
| 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 1041 | if coind then | 
| 50771 
2852f997bfb5
prefer negative "consumes", relative to the total number of prems, which is stable under more morphisms, notably those from nested context with assumes (cf. existing treatment of 'obtains');
 wenzelm parents: 
50302diff
changeset | 1042 | (raw_induct, | 
| 63019 | 1043 | [Attrib.case_names [rec_name], | 
| 1044 | Attrib.case_conclusion (rec_name, intr_names), | |
| 1045 | Attrib.consumes (1 - Thm.nprems_of raw_induct), | |
| 78095 | 1046 | Attrib.internal \<^here> (K (Induct.coinduct_pred (hd cnames)))]) | 
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 1047 | else if no_ind orelse length cnames > 1 then | 
| 63019 | 1048 | (raw_induct, ind_case_names @ [Attrib.consumes (~ (Thm.nprems_of raw_induct))]) | 
| 50771 
2852f997bfb5
prefer negative "consumes", relative to the total number of prems, which is stable under more morphisms, notably those from nested context with assumes (cf. existing treatment of 'obtains');
 wenzelm parents: 
50302diff
changeset | 1049 | else | 
| 
2852f997bfb5
prefer negative "consumes", relative to the total number of prems, which is stable under more morphisms, notably those from nested context with assumes (cf. existing treatment of 'obtains');
 wenzelm parents: 
50302diff
changeset | 1050 | (raw_induct RSN (2, rev_mp), | 
| 63019 | 1051 | ind_case_names @ [Attrib.consumes (~ (Thm.nprems_of raw_induct))]); | 
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 1052 | |
| 33458 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 1053 | val (intrs', lthy1) = | 
| 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 1054 | lthy |> | 
| 71179 | 1055 | Spec_Rules.add spec_name | 
| 1056 | (if coind then Spec_Rules.Co_Inductive else Spec_Rules.Inductive) preds intrs |> | |
| 33671 | 1057 | Local_Theory.notes | 
| 33278 | 1058 | (map (rec_qualified false) intr_bindings ~~ intr_atts ~~ | 
| 63019 | 1059 |           map (fn th => [([th], @{attributes [Pure.intro?]})]) intrs) |>>
 | 
| 24744 
dcb8cf5fc99c
- add_inductive_i now takes typ instead of typ option as argument
 berghofe parents: 
24721diff
changeset | 1060 | map (hd o snd); | 
| 33458 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 1061 | val (((_, elims'), (_, [induct'])), lthy2) = | 
| 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 1062 | lthy1 |> | 
| 33671 | 1063 | Local_Theory.note ((rec_qualified true (Binding.name "intros"), []), intrs') ||>> | 
| 34986 
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
 berghofe parents: 
33966diff
changeset | 1064 | fold_map (fn (name, (elim, cases, k)) => | 
| 33671 | 1065 | Local_Theory.note | 
| 33458 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 1066 | ((Binding.qualify true (Long_Name.base_name name) (Binding.name "cases"), | 
| 63019 | 1067 | ((if forall (equal "") cases then [] else [Attrib.case_names cases]) @ | 
| 1068 | [Attrib.consumes (1 - Thm.nprems_of elim), Attrib.constraints k, | |
| 78095 | 1069 |                Attrib.internal \<^here> (K (Induct.cases_pred name))] @ @{attributes [Pure.elim?]})),
 | 
| 63019 | 1070 | [elim]) #> | 
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 1071 | apfst (hd o snd)) (if null elims then [] else cnames ~~ elims) ||>> | 
| 33671 | 1072 | Local_Theory.note | 
| 61308 | 1073 | ((rec_qualified true (Binding.name (coind_prefix coind ^ "induct")), #2 induct), | 
| 1074 | [rulify lthy1 (#1 induct)]); | |
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 1075 | |
| 45647 | 1076 | val (eqs', lthy3) = lthy2 |> | 
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 1077 | fold_map (fn (name, eq) => Local_Theory.note | 
| 38665 
e92223c886f8
introducing simplification equations for inductive sets; added data structure for storing equations; rewriting retrieval of simplification equation for inductive predicates and sets
 bulwahn parents: 
38388diff
changeset | 1078 | ((Binding.qualify true (Long_Name.base_name name) (Binding.name "simps"), | 
| 78095 | 1079 | [Attrib.internal \<^here> (K equation_add_permissive)]), [eq]) | 
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 1080 | #> apfst (hd o snd)) | 
| 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 1081 | (if null eqs then [] else (cnames ~~ eqs)) | 
| 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 1082 | val (inducts, lthy4) = | 
| 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 1083 | if no_ind orelse coind then ([], lthy3) | 
| 33458 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 1084 | else | 
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 1085 | let val inducts = cnames ~~ Project_Rule.projects lthy3 (1 upto length cnames) induct' in | 
| 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 1086 | lthy3 |> | 
| 33671 | 1087 | Local_Theory.notes [((rec_qualified true (Binding.name "inducts"), []), | 
| 33458 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 1088 | inducts |> map (fn (name, th) => ([th], | 
| 61308 | 1089 | ind_case_names @ | 
| 63019 | 1090 | [Attrib.consumes (1 - Thm.nprems_of th), | 
| 78095 | 1091 | Attrib.internal \<^here> (K (Induct.induct_pred name))])))] |>> snd o hd | 
| 33458 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 1092 | end; | 
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 1093 | in (intrs', elims', eqs', induct', inducts, lthy4) end; | 
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 1094 | |
| 69709 | 1095 | type flags = | 
| 33669 | 1096 |   {quiet_mode: bool, verbose: bool, alt_name: binding, coind: bool,
 | 
| 49170 
03bee3a6a1b7
discontinued obsolete fork_mono to loosen some brakes -- NB: TTY interaction has Goal.future_proofs disabled due to missing Future.worker_task;
 wenzelm parents: 
47876diff
changeset | 1097 | no_elim: bool, no_ind: bool, skip_mono: bool}; | 
| 26534 | 1098 | |
| 1099 | type add_ind_def = | |
| 69709 | 1100 | flags -> | 
| 28084 
a05ca48ef263
type Attrib.binding abbreviates Name.binding without attributes;
 wenzelm parents: 
28083diff
changeset | 1101 | term list -> (Attrib.binding * term) list -> thm list -> | 
| 29581 | 1102 | term list -> (binding * mixfix) list -> | 
| 69709 | 1103 | local_theory -> result * local_theory; | 
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 1104 | |
| 49170 
03bee3a6a1b7
discontinued obsolete fork_mono to loosen some brakes -- NB: TTY interaction has Goal.future_proofs disabled due to missing Future.worker_task;
 wenzelm parents: 
47876diff
changeset | 1105 | fun add_ind_def {quiet_mode, verbose, alt_name, coind, no_elim, no_ind, skip_mono}
 | 
| 33458 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 1106 | cs intros monos params cnames_syn lthy = | 
| 9072 
a4896cf23638
Now also proves monotonicity when in quick_and_dirty mode.
 berghofe parents: 
8720diff
changeset | 1107 | let | 
| 25288 | 1108 | val _ = null cnames_syn andalso error "No inductive predicates given"; | 
| 30223 
24d975352879
renamed Binding.name_pos to Binding.make, renamed Binding.base_name to Binding.name_of, renamed Binding.map_base to Binding.map_name, added mandatory flag to Binding.qualify;
 wenzelm parents: 
30218diff
changeset | 1109 | val names = map (Binding.name_of o fst) cnames_syn; | 
| 26477 
ecf06644f6cb
eliminated quiete_mode ref (turned into proper argument);
 wenzelm parents: 
26336diff
changeset | 1110 | val _ = message (quiet_mode andalso not verbose) | 
| 28083 
103d9282a946
explicit type Name.binding for higher-specification elements;
 wenzelm parents: 
27882diff
changeset | 1111 |       ("Proofs for " ^ coind_prefix coind ^ "inductive predicate(s) " ^ commas_quote names);
 | 
| 9072 
a4896cf23638
Now also proves monotonicity when in quick_and_dirty mode.
 berghofe parents: 
8720diff
changeset | 1112 | |
| 71214 
5727bcc3c47c
proper spec_rule name via naming/binding/Morphism.binding;
 wenzelm parents: 
71179diff
changeset | 1113 | val spec_name = Binding.conglomerate (map #1 cnames_syn); | 
| 33671 | 1114 | val cnames = map (Local_Theory.full_name lthy o #1) cnames_syn; (* FIXME *) | 
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 1115 | val ((intr_names, intr_atts), intr_ts) = | 
| 33458 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 1116 | apfst split_list (split_list (map (check_rule lthy cs params) intros)); | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 1117 | |
| 61681 
ca53150406c9
option "inductive_defs" controls exposure of def and mono facts;
 wenzelm parents: 
61308diff
changeset | 1118 | val (lthy1, lthy2, rec_binding, mono, fp_def, rec_preds_defs, rec_const, preds, | 
| 49170 
03bee3a6a1b7
discontinued obsolete fork_mono to loosen some brakes -- NB: TTY interaction has Goal.future_proofs disabled due to missing Future.worker_task;
 wenzelm parents: 
47876diff
changeset | 1119 | argTs, bs, xs) = mk_ind_def quiet_mode skip_mono alt_name coind cs intr_ts | 
| 33458 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 1120 | monos params cnames_syn lthy; | 
| 9072 
a4896cf23638
Now also proves monotonicity when in quick_and_dirty mode.
 berghofe parents: 
8720diff
changeset | 1121 | |
| 26477 
ecf06644f6cb
eliminated quiete_mode ref (turned into proper argument);
 wenzelm parents: 
26336diff
changeset | 1122 | val (intrs, unfold) = prove_intrs quiet_mode coind mono fp_def (length bs + length xs) | 
| 36642 | 1123 | intr_ts rec_preds_defs lthy2 lthy1; | 
| 33459 | 1124 | val elims = | 
| 1125 | if no_elim then [] | |
| 1126 | else | |
| 1127 | prove_elims quiet_mode cs params intr_ts (map Binding.name_of intr_names) | |
| 36642 | 1128 | unfold rec_preds_defs lthy2 lthy1; | 
| 22605 
41b092e7d89a
- Removed occurrences of ProofContext.export in add_ind_def that
 berghofe parents: 
22460diff
changeset | 1129 | val raw_induct = zero_var_indexes | 
| 33459 | 1130 | (if no_ind then Drule.asm_rl | 
| 1131 | else if coind then | |
| 63863 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 1132 | prove_coindrule quiet_mode preds cs argTs bs xs params intr_ts mono fp_def | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 1133 | rec_preds_defs lthy2 lthy1 | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 1134 | else | 
| 26477 
ecf06644f6cb
eliminated quiete_mode ref (turned into proper argument);
 wenzelm parents: 
26336diff
changeset | 1135 | prove_indrule quiet_mode cs argTs bs xs rec_const params intr_ts mono fp_def | 
| 36642 | 1136 | rec_preds_defs lthy2 lthy1); | 
| 63863 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 1137 | |
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 1138 | val eqs = | 
| 45647 | 1139 | if no_elim then [] else prove_eqs quiet_mode cs params intr_ts intrs elims lthy2 lthy1; | 
| 5094 | 1140 | |
| 51717 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51658diff
changeset | 1141 | val elims' = map (fn (th, ns, i) => (rulify lthy1 th, ns, i)) elims; | 
| 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51658diff
changeset | 1142 | val intrs' = map (rulify lthy1) intrs; | 
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 1143 | |
| 45647 | 1144 | val (intrs'', elims'', eqs', induct, inducts, lthy3) = | 
| 61681 
ca53150406c9
option "inductive_defs" controls exposure of def and mono facts;
 wenzelm parents: 
61308diff
changeset | 1145 | declare_rules rec_binding coind no_ind | 
| 71179 | 1146 | spec_name cnames preds intrs' intr_names intr_atts elims' eqs raw_induct lthy1; | 
| 21048 
e57e91f72831
Restructured and repaired code dealing with case names
 berghofe parents: 
21024diff
changeset | 1147 | |
| 
e57e91f72831
Restructured and repaired code dealing with case names
 berghofe parents: 
21024diff
changeset | 1148 | val result = | 
| 
e57e91f72831
Restructured and repaired code dealing with case names
 berghofe parents: 
21024diff
changeset | 1149 |       {preds = preds,
 | 
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 1150 | intrs = intrs'', | 
| 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 1151 | elims = elims'', | 
| 51717 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51658diff
changeset | 1152 | raw_induct = rulify lthy3 raw_induct, | 
| 35646 | 1153 | induct = induct, | 
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 1154 | inducts = inducts, | 
| 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 1155 | eqs = eqs'}; | 
| 21367 
7a0cc1bb4dcc
inductive: canonical specification syntax (flattened result only);
 wenzelm parents: 
21350diff
changeset | 1156 | |
| 36642 | 1157 | val lthy4 = lthy3 | 
| 78095 | 1158 |       |> Local_Theory.declaration {syntax = false, pervasive = false, pos = \<^here>} (fn phi =>
 | 
| 45290 | 1159 | let val result' = transform_result phi result; | 
| 65411 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 1160 |         in put_inductives ({names = cnames, coind = coind}, result') end);
 | 
| 36642 | 1161 | in (result, lthy4) end; | 
| 5094 | 1162 | |
| 6424 | 1163 | |
| 10735 | 1164 | (* external interfaces *) | 
| 5094 | 1165 | |
| 69709 | 1166 | fun gen_add_inductive mk_def | 
| 59059 | 1167 | flags cnames_syn pnames spec monos lthy = | 
| 5094 | 1168 | let | 
| 21766 
3eb48154388e
Abbreviations can now be specified simultaneously
 berghofe parents: 
21658diff
changeset | 1169 | |
| 25029 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1170 | (* abbrevs *) | 
| 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1171 | |
| 30223 
24d975352879
renamed Binding.name_pos to Binding.make, renamed Binding.base_name to Binding.name_of, renamed Binding.map_base to Binding.map_name, added mandatory flag to Binding.qualify;
 wenzelm parents: 
30218diff
changeset | 1172 | val (_, ctxt1) = Variable.add_fixes (map (Binding.name_of o fst o fst) cnames_syn) lthy; | 
| 21766 
3eb48154388e
Abbreviations can now be specified simultaneously
 berghofe parents: 
21658diff
changeset | 1173 | |
| 25029 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1174 | fun get_abbrev ((name, atts), t) = | 
| 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1175 | if can (Logic.strip_assums_concl #> Logic.dest_equals) t then | 
| 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1176 | let | 
| 29006 | 1177 | val _ = Binding.is_empty name andalso null atts orelse | 
| 25029 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1178 | error "Abbreviations may not have names or attributes"; | 
| 63395 | 1179 | val ((x, T), rhs) = Local_Defs.abs_def (snd (Local_Defs.cert_def ctxt1 (K []) t)); | 
| 28083 
103d9282a946
explicit type Name.binding for higher-specification elements;
 wenzelm parents: 
27882diff
changeset | 1180 | val var = | 
| 30223 
24d975352879
renamed Binding.name_pos to Binding.make, renamed Binding.base_name to Binding.name_of, renamed Binding.map_base to Binding.map_name, added mandatory flag to Binding.qualify;
 wenzelm parents: 
30218diff
changeset | 1181 | (case find_first (fn ((c, _), _) => Binding.name_of c = x) cnames_syn of | 
| 25029 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1182 |               NONE => error ("Undeclared head of abbreviation " ^ quote x)
 | 
| 28083 
103d9282a946
explicit type Name.binding for higher-specification elements;
 wenzelm parents: 
27882diff
changeset | 1183 | | SOME ((b, T'), mx) => | 
| 25029 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1184 |                 if T <> T' then error ("Bad type specification for abbreviation " ^ quote x)
 | 
| 28083 
103d9282a946
explicit type Name.binding for higher-specification elements;
 wenzelm parents: 
27882diff
changeset | 1185 | else (b, mx)); | 
| 
103d9282a946
explicit type Name.binding for higher-specification elements;
 wenzelm parents: 
27882diff
changeset | 1186 | in SOME (var, rhs) end | 
| 25029 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1187 | else NONE; | 
| 21766 
3eb48154388e
Abbreviations can now be specified simultaneously
 berghofe parents: 
21658diff
changeset | 1188 | |
| 25029 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1189 | val abbrevs = map_filter get_abbrev spec; | 
| 30223 
24d975352879
renamed Binding.name_pos to Binding.make, renamed Binding.base_name to Binding.name_of, renamed Binding.map_base to Binding.map_name, added mandatory flag to Binding.qualify;
 wenzelm parents: 
30218diff
changeset | 1190 | val bs = map (Binding.name_of o fst o fst) abbrevs; | 
| 25029 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1191 | |
| 21766 
3eb48154388e
Abbreviations can now be specified simultaneously
 berghofe parents: 
21658diff
changeset | 1192 | |
| 25029 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1193 | (* predicates *) | 
| 21766 
3eb48154388e
Abbreviations can now be specified simultaneously
 berghofe parents: 
21658diff
changeset | 1194 | |
| 25029 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1195 | val pre_intros = filter_out (is_some o get_abbrev) spec; | 
| 30223 
24d975352879
renamed Binding.name_pos to Binding.make, renamed Binding.base_name to Binding.name_of, renamed Binding.map_base to Binding.map_name, added mandatory flag to Binding.qualify;
 wenzelm parents: 
30218diff
changeset | 1196 | val cnames_syn' = filter_out (member (op =) bs o Binding.name_of o fst o fst) cnames_syn; | 
| 
24d975352879
renamed Binding.name_pos to Binding.make, renamed Binding.base_name to Binding.name_of, renamed Binding.map_base to Binding.map_name, added mandatory flag to Binding.qualify;
 wenzelm parents: 
30218diff
changeset | 1197 | val cs = map (Free o apfst Binding.name_of o fst) cnames_syn'; | 
| 25029 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1198 | val ps = map Free pnames; | 
| 5094 | 1199 | |
| 30223 
24d975352879
renamed Binding.name_pos to Binding.make, renamed Binding.base_name to Binding.name_of, renamed Binding.map_base to Binding.map_name, added mandatory flag to Binding.qualify;
 wenzelm parents: 
30218diff
changeset | 1200 | val (_, ctxt2) = lthy |> Variable.add_fixes (map (Binding.name_of o fst o fst) cnames_syn'); | 
| 35624 | 1201 | val ctxt3 = ctxt2 |> fold (snd oo Local_Defs.fixed_abbrev) abbrevs; | 
| 42361 | 1202 | val expand = Assumption.export_term ctxt3 lthy #> Proof_Context.cert_term lthy; | 
| 25029 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1203 | |
| 46215 
0da9433f959e
discontinued old-style Term.list_all_free in favour of plain Logic.all;
 wenzelm parents: 
45740diff
changeset | 1204 | fun close_rule r = | 
| 
0da9433f959e
discontinued old-style Term.list_all_free in favour of plain Logic.all;
 wenzelm parents: 
45740diff
changeset | 1205 | fold (Logic.all o Free) (fold_aterms | 
| 
0da9433f959e
discontinued old-style Term.list_all_free in favour of plain Logic.all;
 wenzelm parents: 
45740diff
changeset | 1206 | (fn t as Free (v as (s, _)) => | 
| 
0da9433f959e
discontinued old-style Term.list_all_free in favour of plain Logic.all;
 wenzelm parents: 
45740diff
changeset | 1207 | if Variable.is_fixed ctxt1 s orelse | 
| 
0da9433f959e
discontinued old-style Term.list_all_free in favour of plain Logic.all;
 wenzelm parents: 
45740diff
changeset | 1208 | member (op =) ps t then I else insert (op =) v | 
| 
0da9433f959e
discontinued old-style Term.list_all_free in favour of plain Logic.all;
 wenzelm parents: 
45740diff
changeset | 1209 | | _ => I) r []) r; | 
| 5094 | 1210 | |
| 26736 
e6091328718f
added explicit check phase after reading of specification
 haftmann parents: 
26534diff
changeset | 1211 | val intros = map (apsnd (Syntax.check_term lthy #> close_rule #> expand)) pre_intros; | 
| 25029 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1212 | val preds = map (fn ((c, _), mx) => (c, mx)) cnames_syn'; | 
| 21048 
e57e91f72831
Restructured and repaired code dealing with case names
 berghofe parents: 
21024diff
changeset | 1213 | in | 
| 25029 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1214 | lthy | 
| 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1215 | |> mk_def flags cs intros monos ps preds | 
| 33671 | 1216 | ||> fold (snd oo Local_Theory.abbrev Syntax.mode_default) abbrevs | 
| 21048 
e57e91f72831
Restructured and repaired code dealing with case names
 berghofe parents: 
21024diff
changeset | 1217 | end; | 
| 5094 | 1218 | |
| 69709 | 1219 | fun gen_add_inductive_cmd mk_def verbose coind cnames_syn pnames_syn intro_srcs raw_monos lthy = | 
| 5094 | 1220 | let | 
| 30486 
9cdc7ce0e389
simplified preparation and outer parsing of specification;
 wenzelm parents: 
30435diff
changeset | 1221 | val ((vars, intrs), _) = lthy | 
| 42361 | 1222 | |> Proof_Context.set_mode Proof_Context.mode_abbrev | 
| 63064 
2f18172214c8
support 'assumes' in specifications, e.g. 'definition', 'inductive';
 wenzelm parents: 
63019diff
changeset | 1223 | |> Specification.read_multi_specs (cnames_syn @ pnames_syn) intro_srcs; | 
| 24721 | 1224 | val (cs, ps) = chop (length cnames_syn) vars; | 
| 1225 | val monos = Attrib.eval_thms lthy raw_monos; | |
| 49170 
03bee3a6a1b7
discontinued obsolete fork_mono to loosen some brakes -- NB: TTY interaction has Goal.future_proofs disabled due to missing Future.worker_task;
 wenzelm parents: 
47876diff
changeset | 1226 | val flags = | 
| 
03bee3a6a1b7
discontinued obsolete fork_mono to loosen some brakes -- NB: TTY interaction has Goal.future_proofs disabled due to missing Future.worker_task;
 wenzelm parents: 
47876diff
changeset | 1227 |      {quiet_mode = false, verbose = verbose, alt_name = Binding.empty,
 | 
| 
03bee3a6a1b7
discontinued obsolete fork_mono to loosen some brakes -- NB: TTY interaction has Goal.future_proofs disabled due to missing Future.worker_task;
 wenzelm parents: 
47876diff
changeset | 1228 | coind = coind, no_elim = false, no_ind = false, skip_mono = false}; | 
| 26128 | 1229 | in | 
| 1230 | lthy | |
| 69709 | 1231 | |> gen_add_inductive mk_def flags cs (map (apfst Binding.name_of o fst) ps) intrs monos | 
| 26128 | 1232 | end; | 
| 5094 | 1233 | |
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 1234 | val add_inductive = gen_add_inductive add_ind_def; | 
| 69709 | 1235 | val add_inductive_cmd = gen_add_inductive_cmd add_ind_def; | 
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 1236 | |
| 6424 | 1237 | |
| 22789 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1238 | (* read off arities of inductive predicates from raw induction rule *) | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1239 | fun arities_of induct = | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1240 | map (fn (_ $ t $ u) => | 
| 80636 
4041e7c8059d
tuned: more explicit dest_Const_name and dest_Const_type;
 wenzelm parents: 
79732diff
changeset | 1241 | (dest_Const_name (head_of t), length (snd (strip_comb u)))) | 
| 59582 | 1242 | (HOLogic.dest_conj (HOLogic.dest_Trueprop (Thm.concl_of induct))); | 
| 22789 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1243 | |
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1244 | (* read off parameters of inductive predicate from raw induction rule *) | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1245 | fun params_of induct = | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1246 | let | 
| 59582 | 1247 | val (_ $ t $ u :: _) = HOLogic.dest_conj (HOLogic.dest_Trueprop (Thm.concl_of induct)); | 
| 22789 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1248 | val (_, ts) = strip_comb t; | 
| 45647 | 1249 | val (_, us) = strip_comb u; | 
| 22789 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1250 | in | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1251 | List.take (ts, length ts - length us) | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1252 | end; | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1253 | |
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1254 | val pname_of_intr = | 
| 80636 
4041e7c8059d
tuned: more explicit dest_Const_name and dest_Const_type;
 wenzelm parents: 
79732diff
changeset | 1255 | Thm.concl_of #> HOLogic.dest_Trueprop #> head_of #> dest_Const_name; | 
| 22789 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1256 | |
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1257 | (* partition introduction rules according to predicate name *) | 
| 25822 | 1258 | fun gen_partition_rules f induct intros = | 
| 1259 | fold_rev (fn r => AList.map_entry op = (pname_of_intr (f r)) (cons r)) intros | |
| 22789 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1260 | (map (rpair [] o fst) (arities_of induct)); | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1261 | |
| 25822 | 1262 | val partition_rules = gen_partition_rules I; | 
| 1263 | fun partition_rules' induct = gen_partition_rules fst induct; | |
| 1264 | ||
| 22789 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1265 | fun unpartition_rules intros xs = | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1266 | fold_map (fn r => AList.map_entry_yield op = (pname_of_intr r) | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1267 | (fn x :: xs => (x, xs)) #>> the) intros xs |> fst; | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1268 | |
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1269 | (* infer order of variables in intro rules from order of quantifiers in elim rule *) | 
| 60362 | 1270 | fun infer_intro_vars thy elim arity intros = | 
| 22789 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1271 | let | 
| 59582 | 1272 | val _ :: cases = Thm.prems_of elim; | 
| 1273 | val used = map (fst o fst) (Term.add_vars (Thm.prop_of elim) []); | |
| 22789 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1274 | fun mtch (t, u) = | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1275 | let | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1276 | val params = Logic.strip_params t; | 
| 45647 | 1277 | val vars = | 
| 1278 | map (Var o apfst (rpair 0)) | |
| 1279 | (Name.variant_list used (map fst params) ~~ map snd params); | |
| 1280 | val ts = | |
| 1281 | map (curry subst_bounds (rev vars)) | |
| 1282 | (List.drop (Logic.strip_assums_hyp t, arity)); | |
| 22789 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1283 | val us = Logic.strip_imp_prems u; | 
| 45647 | 1284 | val tab = | 
| 1285 | fold (Pattern.first_order_match thy) (ts ~~ us) (Vartab.empty, Vartab.empty); | |
| 22789 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1286 | in | 
| 32035 | 1287 | map (Envir.subst_term tab) vars | 
| 22789 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1288 | end | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1289 | in | 
| 59582 | 1290 | map (mtch o apsnd Thm.prop_of) (cases ~~ intros) | 
| 22789 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1291 | end; | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1292 | |
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1293 | |
| 25978 | 1294 | |
| 58815 | 1295 | (** outer syntax **) | 
| 6424 | 1296 | |
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 1297 | fun gen_ind_decl mk_def coind = | 
| 63285 | 1298 | Parse.vars -- Parse.for_fixes -- | 
| 63064 
2f18172214c8
support 'assumes' in specifications, e.g. 'definition', 'inductive';
 wenzelm parents: 
63019diff
changeset | 1299 | Scan.optional Parse_Spec.where_multi_specs [] -- | 
| 67149 | 1300 | Scan.optional (\<^keyword>\<open>monos\<close> |-- Parse.!!! Parse.thms1) [] | 
| 26988 
742e26213212
more uniform treatment of OuterSyntax.local_theory commands;
 wenzelm parents: 
26928diff
changeset | 1301 | >> (fn (((preds, params), specs), monos) => | 
| 69709 | 1302 | (snd o gen_add_inductive_cmd mk_def true coind preds params specs monos)); | 
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 1303 | |
| 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 1304 | val ind_decl = gen_ind_decl add_ind_def; | 
| 6424 | 1305 | |
| 33458 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 1306 | val _ = | 
| 67149 | 1307 | Outer_Syntax.local_theory \<^command_keyword>\<open>inductive\<close> "define inductive predicates" | 
| 33458 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 1308 | (ind_decl false); | 
| 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 1309 | |
| 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 1310 | val _ = | 
| 67149 | 1311 | Outer_Syntax.local_theory \<^command_keyword>\<open>coinductive\<close> "define coinductive predicates" | 
| 33458 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 1312 | (ind_decl true); | 
| 6723 | 1313 | |
| 24867 | 1314 | val _ = | 
| 79732 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 1315 | Outer_Syntax.local_theory' \<^command_keyword>\<open>inductive_cases\<close> | 
| 50214 | 1316 | "create simplified instances of elimination rules" | 
| 79732 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 1317 | (Parse.and_list1 Parse_Spec.simple_specs >> (#2 ooo inductive_cases_cmd)); | 
| 7107 | 1318 | |
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 1319 | val _ = | 
| 79732 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 1320 | Outer_Syntax.local_theory' \<^command_keyword>\<open>inductive_simps\<close> | 
| 46961 
5c6955f487e5
outer syntax command definitions based on formal command_spec derived from theory header declarations;
 wenzelm parents: 
46949diff
changeset | 1321 | "create simplification rules for inductive predicates" | 
| 79732 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 1322 | (Parse.and_list1 Parse_Spec.simple_specs >> (#2 ooo inductive_simps_cmd)); | 
| 37734 
489ac1ecb9f1
added the new command inductive_cases to derive simplification equations for inductive predicates; added binding simps for general simplification equation
 bulwahn parents: 
37264diff
changeset | 1323 | |
| 50302 | 1324 | val _ = | 
| 67149 | 1325 | Outer_Syntax.command \<^command_keyword>\<open>print_inductives\<close> | 
| 50302 | 1326 | "print (co)inductive definitions and monotonicity rules" | 
| 60097 
d20ca79d50e4
discontinued pointless warnings: commands are only defined inside a theory context;
 wenzelm parents: 
59940diff
changeset | 1327 | (Parse.opt_bang >> (fn b => Toplevel.keep (print_inductives b o Toplevel.context_of))); | 
| 50302 | 1328 | |
| 5094 | 1329 | end; |