| author | wenzelm | 
| Fri, 14 Mar 2025 23:03:58 +0100 | |
| changeset 82276 | d22e9c5b5dc6 | 
| parent 81810 | 6cd42e67c0a8 | 
| child 82317 | 231b6d8231c6 | 
| 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 = | 
| 81810 
6cd42e67c0a8
store the {l,g}fp-definition and the monotonicity theorem for inductive predicates (by Jan van Brügge)
 traytel parents: 
81525diff
changeset | 24 |     {preds: term list, elims: thm list, raw_induct: thm, def: thm, mono: 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 = | 
| 81810 
6cd42e67c0a8
store the {l,g}fp-definition and the monotonicity theorem for inductive predicates (by Jan van Brügge)
 traytel parents: 
81525diff
changeset | 183 |   {preds: term list, elims: thm list, raw_induct: thm, def: thm, mono: thm,
 | 
| 45651 | 184 | induct: thm, inducts: thm list, intrs: thm list, eqs: thm list}; | 
| 185 | ||
| 81810 
6cd42e67c0a8
store the {l,g}fp-definition and the monotonicity theorem for inductive predicates (by Jan van Brügge)
 traytel parents: 
81525diff
changeset | 186 | fun transform_result phi {preds, elims, raw_induct: thm, induct, inducts, intrs, eqs, def, mono} =
 | 
| 45651 | 187 | let | 
| 188 | val term = Morphism.term phi; | |
| 189 | val thm = Morphism.thm phi; | |
| 190 | val fact = Morphism.fact phi; | |
| 191 | in | |
| 81810 
6cd42e67c0a8
store the {l,g}fp-definition and the monotonicity theorem for inductive predicates (by Jan van Brügge)
 traytel parents: 
81525diff
changeset | 192 |    {preds = map term preds, elims = fact elims, raw_induct = thm raw_induct, def = thm def,
 | 
| 
6cd42e67c0a8
store the {l,g}fp-definition and the monotonicity theorem for inductive predicates (by Jan van Brügge)
 traytel parents: 
81525diff
changeset | 193 | induct = thm induct, inducts = fact inducts, intrs = fact intrs, eqs = fact eqs, | 
| 
6cd42e67c0a8
store the {l,g}fp-definition and the monotonicity theorem for inductive predicates (by Jan van Brügge)
 traytel parents: 
81525diff
changeset | 194 | mono = thm mono} | 
| 45651 | 195 | end; | 
| 196 | ||
| 69709 | 197 | type info = {names: string list, coind: bool} * result;
 | 
| 45651 | 198 | |
| 65411 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 199 | val empty_infos = | 
| 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 200 | 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 | 201 | |
| 45651 | 202 | val empty_equations = | 
| 45652 
18214436e1d3
permissive update for improved "tool compliance";
 wenzelm parents: 
45651diff
changeset | 203 | Item_Net.init Thm.eq_thm_prop | 
| 
18214436e1d3
permissive update for improved "tool compliance";
 wenzelm parents: 
45651diff
changeset | 204 | (single o fst o HOLogic.dest_eq o HOLogic.dest_Trueprop o Thm.prop_of); | 
| 45651 | 205 | |
| 206 | datatype data = Data of | |
| 69709 | 207 |  {infos: info Item_Net.T,
 | 
| 45651 | 208 | monos: thm list, | 
| 209 | equations: thm Item_Net.T}; | |
| 210 | ||
| 211 | fun make_data (infos, monos, equations) = | |
| 212 |   Data {infos = infos, monos = monos, equations = equations};
 | |
| 213 | ||
| 214 | structure Data = Generic_Data | |
| 215 | ( | |
| 216 | type T = data; | |
| 65411 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 217 | val empty = make_data (empty_infos, [], empty_equations); | 
| 45651 | 218 |   fun merge (Data {infos = infos1, monos = monos1, equations = equations1},
 | 
| 219 |       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 | 220 | make_data (Item_Net.merge (infos1, infos2), | 
| 45651 | 221 | Thm.merge_thms (monos1, monos2), | 
| 222 | Item_Net.merge (equations1, equations2)); | |
| 223 | ); | |
| 224 | ||
| 225 | fun map_data f = | |
| 226 |   Data.map (fn Data {infos, monos, equations} => make_data (f (infos, monos, equations)));
 | |
| 227 | ||
| 228 | fun rep_data ctxt = Data.get (Context.Proof ctxt) |> (fn Data rep => rep); | |
| 229 | ||
| 59917 
9830c944670f
more uniform "verbose" option to print name space;
 wenzelm parents: 
59880diff
changeset | 230 | fun print_inductives verbose ctxt = | 
| 45651 | 231 | let | 
| 232 |     val {infos, monos, ...} = rep_data ctxt;
 | |
| 233 | 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 | 234 | val consts = | 
| 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 235 | Item_Net.content infos | 
| 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 236 |       |> maps (fn ({names, ...}, result) => map (rpair result) names)
 | 
| 45651 | 237 | in | 
| 50301 | 238 | [Pretty.block | 
| 239 | (Pretty.breaks | |
| 240 | (Pretty.str "(co)inductives:" :: | |
| 59917 
9830c944670f
more uniform "verbose" option to print name space;
 wenzelm parents: 
59880diff
changeset | 241 | map (Pretty.mark_str o #1) | 
| 65411 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 242 | (Name_Space.markup_entries verbose ctxt space consts))), | 
| 61268 | 243 | 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 | 244 | end |> Pretty.writeln_chunks; | 
| 45651 | 245 | |
| 246 | ||
| 247 | (* inductive info *) | |
| 248 | ||
| 65411 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 249 | fun the_inductive ctxt term = | 
| 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 250 | 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 | 251 | |> the_single | 
| 67664 | 252 | |> apsnd (transform_result (Morphism.transfer_morphism' ctxt)) | 
| 45651 | 253 | |
| 65411 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 254 | fun the_inductive_global ctxt name = | 
| 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 255 | #infos (rep_data ctxt) | 
| 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 256 | |> Item_Net.content | 
| 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 257 |   |> filter (fn ({names, ...}, _) => member op = names name)
 | 
| 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 258 | |> the_single | 
| 67664 | 259 | |> 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 | 260 | |
| 
3c628937899d
use Item_Net to store inductive info
 Lars Hupel <lars.hupel@mytum.de> parents: 
63863diff
changeset | 261 | fun put_inductives info = | 
| 45651 | 262 | map_data (fn (infos, monos, equations) => | 
| 67637 | 263 | (Item_Net.update (apsnd (transform_result Morphism.trim_context_morphism) info) infos, | 
| 264 | monos, equations)); | |
| 45651 | 265 | |
| 266 | ||
| 267 | (* monotonicity rules *) | |
| 268 | ||
| 67637 | 269 | fun get_monos ctxt = | 
| 270 | #monos (rep_data ctxt) | |
| 67649 | 271 | |> map (Thm.transfer' ctxt); | 
| 45651 | 272 | |
| 273 | fun mk_mono ctxt thm = | |
| 274 | let | |
| 275 |     fun eq_to_mono thm' = thm' RS (thm' RS @{thm eq_to_mono});
 | |
| 276 |     fun dest_less_concl thm = dest_less_concl (thm RS @{thm le_funD})
 | |
| 277 |       handle THM _ => thm RS @{thm le_boolD}
 | |
| 278 | in | |
| 59582 | 279 | (case Thm.concl_of thm of | 
| 80727 | 280 | \<^Const_>\<open>Pure.eq _ for _ _\<close> => eq_to_mono (HOLogic.mk_obj_eq thm) | 
| 281 | | _ $ \<^Const_>\<open>HOL.eq _ for _ _\<close> => eq_to_mono thm | |
| 282 | | _ $ \<^Const_>\<open>less_eq _ for _ _\<close> => | |
| 45651 | 283 | 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 | 284 |         (resolve_tac ctxt [@{thm le_funI}, @{thm le_boolI'}])) thm))
 | 
| 45651 | 285 | | _ => thm) | 
| 61268 | 286 |   end handle THM _ => error ("Bad monotonicity theorem:\n" ^ Thm.string_of_thm ctxt thm);
 | 
| 45651 | 287 | |
| 288 | val mono_add = | |
| 289 | Thm.declaration_attribute (fn thm => fn context => | |
| 290 | map_data (fn (infos, monos, equations) => | |
| 67637 | 291 | (infos, Thm.add_thm (Thm.trim_context (mk_mono (Context.proof_of context) thm)) monos, | 
| 292 | equations)) context); | |
| 45651 | 293 | |
| 294 | val mono_del = | |
| 295 | Thm.declaration_attribute (fn thm => fn context => | |
| 296 | map_data (fn (infos, monos, equations) => | |
| 297 | (infos, Thm.del_thm (mk_mono (Context.proof_of context) thm) monos, equations)) context); | |
| 298 | ||
| 58815 | 299 | val _ = | 
| 300 | Theory.setup | |
| 67149 | 301 | (Attrib.setup \<^binding>\<open>mono\<close> (Attrib.add_del mono_add mono_del) | 
| 58815 | 302 | "declaration of monotonicity rule"); | 
| 303 | ||
| 45651 | 304 | |
| 305 | (* equations *) | |
| 306 | ||
| 67637 | 307 | fun retrieve_equations ctxt = | 
| 308 | Item_Net.retrieve (#equations (rep_data ctxt)) | |
| 67649 | 309 | #> map (Thm.transfer' ctxt); | 
| 45651 | 310 | |
| 45652 
18214436e1d3
permissive update for improved "tool compliance";
 wenzelm parents: 
45651diff
changeset | 311 | val equation_add_permissive = | 
| 45651 | 312 | Thm.declaration_attribute (fn thm => | 
| 45652 
18214436e1d3
permissive update for improved "tool compliance";
 wenzelm parents: 
45651diff
changeset | 313 | map_data (fn (infos, monos, equations) => | 
| 67637 | 314 | (infos, monos, perhaps (try (Item_Net.update (Thm.trim_context thm))) equations))); | 
| 45651 | 315 | |
| 316 | ||
| 317 | ||
| 10729 | 318 | (** process rules **) | 
| 319 | ||
| 320 | local | |
| 5094 | 321 | |
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 322 | fun err_in_rule ctxt name t msg = | 
| 42381 
309ec68442c6
added Binding.print convenience, which includes quote already;
 wenzelm parents: 
42364diff
changeset | 323 | error (cat_lines ["Ill-formed introduction rule " ^ Binding.print name, | 
| 24920 | 324 | Syntax.string_of_term ctxt t, msg]); | 
| 10729 | 325 | |
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 326 | fun err_in_prem ctxt name t p msg = | 
| 24920 | 327 | 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 | 328 | "in introduction rule " ^ Binding.print name, Syntax.string_of_term ctxt t, msg]); | 
| 5094 | 329 | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 330 | val bad_concl = "Conclusion of introduction rule must be an inductive predicate"; | 
| 10729 | 331 | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 332 | 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 | 333 | |
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 334 | 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 | 335 | |
| 41228 
e1fce873b814
renamed structure MetaSimplifier to raw_Simplifer, to emphasize its meaning;
 wenzelm parents: 
41075diff
changeset | 336 | fun atomize_term thy = Raw_Simplifier.rewrite_term thy inductive_atomize []; | 
| 10729 | 337 | |
| 338 | in | |
| 5094 | 339 | |
| 28083 
103d9282a946
explicit type Name.binding for higher-specification elements;
 wenzelm parents: 
27882diff
changeset | 340 | fun check_rule ctxt cs params ((binding, att), rule) = | 
| 10729 | 341 | let | 
| 81525 
3e55334ef5af
clarified names context: proper context, without consts;
 wenzelm parents: 
81519diff
changeset | 342 | val params' = Variable.variant_names (Variable.declare_names rule ctxt) (Logic.strip_params rule); | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 343 | val frees = rev (map Free params'); | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 344 | val concl = subst_bounds (frees, Logic.strip_assums_concl rule); | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 345 | 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 | 346 | val rule' = Logic.list_implies (prems, concl); | 
| 42361 | 347 | 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 | 348 | 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 | 349 | |
| 45647 | 350 | fun check_ind err t = | 
| 351 | (case dest_predicate cs params t of | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 352 | NONE => err (bad_app ^ | 
| 24920 | 353 | commas (map (Syntax.string_of_term ctxt) params)) | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 354 | | SOME (_, _, ys, _) => | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 355 | if exists (fn c => exists (fn t => Logic.occs (c, t)) ys) cs | 
| 45647 | 356 | then err bad_ind_occ else ()); | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 357 | |
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 358 | 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 | 359 | if member (op =) cs (head_of t) then | 
| 42381 
309ec68442c6
added Binding.print convenience, which includes quote already;
 wenzelm parents: 
42364diff
changeset | 360 | check_ind (err_in_prem ctxt binding rule prem) t | 
| 45647 | 361 | else | 
| 362 | (case t of | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 363 | Abs (_, _, t) => check_prem' prem t | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 364 | | t $ u => (check_prem' prem t; check_prem' prem u) | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 365 | | _ => ()); | 
| 5094 | 366 | |
| 10729 | 367 | fun check_prem (prem, aprem) = | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 368 | 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 | 369 | else err_in_prem ctxt binding rule prem "Non-atomic premise"; | 
| 45647 | 370 | |
| 371 | val _ = | |
| 372 | (case concl of | |
| 80727 | 373 | \<^Const_>\<open>Trueprop for t\<close> => | 
| 45647 | 374 | if member (op =) cs (head_of t) then | 
| 42381 
309ec68442c6
added Binding.print convenience, which includes quote already;
 wenzelm parents: 
42364diff
changeset | 375 | (check_ind (err_in_rule ctxt binding rule') t; | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 376 | List.app check_prem (prems ~~ aprems)) | 
| 45647 | 377 | else err_in_rule ctxt binding rule' bad_concl | 
| 378 | | _ => err_in_rule ctxt binding rule' bad_concl); | |
| 379 | in | |
| 28083 
103d9282a946
explicit type Name.binding for higher-specification elements;
 wenzelm parents: 
27882diff
changeset | 380 | ((binding, att), arule) | 
| 10729 | 381 | end; | 
| 5094 | 382 | |
| 51717 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51658diff
changeset | 383 | fun rulify ctxt = | 
| 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51658diff
changeset | 384 | hol_simplify ctxt inductive_conj | 
| 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51658diff
changeset | 385 | #> hol_simplify ctxt inductive_rulify | 
| 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51658diff
changeset | 386 | #> hol_simplify ctxt inductive_rulify_fallback | 
| 54883 
dd04a8b654fc
proper context for norm_hhf and derived operations;
 wenzelm parents: 
54742diff
changeset | 387 | #> Simplifier.norm_hhf ctxt; | 
| 10729 | 388 | |
| 389 | end; | |
| 390 | ||
| 5094 | 391 | |
| 6424 | 392 | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 393 | (** proofs for (co)inductive predicates **) | 
| 6424 | 394 | |
| 26534 | 395 | (* prove monotonicity *) | 
| 5094 | 396 | |
| 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 | 397 | fun prove_mono quiet_mode skip_mono predT fp_fun monos ctxt = | 
| 52059 | 398 | (message (quiet_mode orelse skip_mono andalso Config.get ctxt quick_and_dirty) | 
| 26534 | 399 | " Proving monotonicity ..."; | 
| 51551 | 400 | (if skip_mono then Goal.prove_sorry else Goal.prove_future) ctxt | 
| 36642 | 401 | [] [] | 
| 17985 | 402 | (HOLogic.mk_Trueprop | 
| 76054 
a4b47c684445
moved mono and strict_mono to Fun and redefined them as abbreviations
 desharna parents: 
74561diff
changeset | 403 | (\<^Const>\<open>monotone_on predT predT for | 
| 
a4b47c684445
moved mono and strict_mono to Fun and redefined them as abbreviations
 desharna parents: 
74561diff
changeset | 404 | \<^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 | 405 |     (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 | 406 |       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 | 407 | REPEAT (FIRST | 
| 58963 
26bf09b95dda
proper context for assume_tac (atac remains as fall-back without context);
 wenzelm parents: 
58936diff
changeset | 408 | [assume_tac ctxt 1, | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 409 | 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 | 410 |          eresolve_tac ctxt @{thms le_funE} 1,
 | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 411 |          dresolve_tac ctxt @{thms le_boolD} 1])]));
 | 
| 5094 | 412 | |
| 6424 | 413 | |
| 10735 | 414 | (* prove introduction rules *) | 
| 5094 | 415 | |
| 36642 | 416 | fun prove_intrs quiet_mode coind mono fp_def k intr_ts rec_preds_defs ctxt ctxt' = | 
| 5094 | 417 | let | 
| 52059 | 418 | val _ = clean_message ctxt quiet_mode " Proving the introduction rules ..."; | 
| 5094 | 419 | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 420 | val unfold = funpow k (fn th => th RS fun_cong) | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 421 | (mono RS (fp_def RS | 
| 32652 | 422 |         (if coind then @{thm def_gfp_unfold} else @{thm def_lfp_unfold})));
 | 
| 5094 | 423 | |
| 67091 | 424 |     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 | 425 | |
| 36642 | 426 | val intrs = map_index (fn (i, intr) => | 
| 51551 | 427 | 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 | 428 | [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 | 429 | resolve_tac ctxt [unfold RS iffD2] 1, | 
| 59532 | 430 | select_disj_tac ctxt (length intr_ts) (i + 1) 1, | 
| 17985 | 431 | (*Not ares_tac, since refl must be tried before any equality assumptions; | 
| 432 | 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 | 433 | DEPTH_SOLVE_1 (resolve_tac ctxt rules 1 APPEND assume_tac ctxt 1)]) | 
| 42361 | 434 | |> singleton (Proof_Context.export ctxt ctxt')) intr_ts | 
| 5094 | 435 | |
| 436 | in (intrs, unfold) end; | |
| 437 | ||
| 6424 | 438 | |
| 10735 | 439 | (* prove elimination rules *) | 
| 5094 | 440 | |
| 36642 | 441 | fun prove_elims quiet_mode cs params intr_ts intr_names unfold rec_preds_defs ctxt ctxt''' = | 
| 5094 | 442 | let | 
| 52059 | 443 | val _ = clean_message ctxt quiet_mode " Proving the elimination rules ..."; | 
| 5094 | 444 | |
| 36642 | 445 | val ([pname], ctxt') = Variable.variant_fixes ["P"] ctxt; | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 446 | val P = HOLogic.mk_Trueprop (Free (pname, HOLogic.boolT)); | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 447 | |
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 448 | fun dest_intr r = | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 449 | (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 | 450 | Logic.strip_assums_hyp r, Logic.strip_params r); | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 451 | |
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 452 | val intrs = map dest_intr intr_ts ~~ intr_names; | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 453 | |
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 454 | val rules1 = [disjE, exE, FalseE]; | 
| 67091 | 455 |     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 | 456 | |
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 457 | fun prove_elim c = | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 458 | let | 
| 33077 
3c9cf88ec841
arg_types_of auxiliary function; using multiset operations
 haftmann parents: 
33056diff
changeset | 459 | val Ts = arg_types_of (length params) c; | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 460 | 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 | 461 | val frees = map Free (anames ~~ Ts); | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 462 | |
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 463 | 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 | 464 | Logic.list_all (params', | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 465 | Logic.list_implies (map (HOLogic.mk_Trueprop o HOLogic.mk_eq) | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 466 | (frees ~~ us) @ ts, P)); | 
| 33317 | 467 | 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 | 468 | val prems = HOLogic.mk_Trueprop (list_comb (c, params @ frees)) :: | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 469 | map mk_elim_prem (map #1 c_intrs) | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 470 | in | 
| 51551 | 471 | (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 | 472 |           (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 | 473 | [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 | 474 | 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 | 475 | dresolve_tac ctxt4 [unfold RS iffD1] 1, | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 476 | REPEAT (FIRSTGOAL (eresolve_tac ctxt4 rules1)), | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 477 | REPEAT (FIRSTGOAL (eresolve_tac ctxt4 rules2)), | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 478 | EVERY (map (fn prem => | 
| 59499 | 479 | DEPTH_SOLVE_1 (assume_tac ctxt4 1 ORELSE | 
| 480 | 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 | 481 | (tl prems))]) | 
| 42361 | 482 | |> singleton (Proof_Context.export ctxt'' ctxt'''), | 
| 34986 
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
 berghofe parents: 
33966diff
changeset | 483 | map #2 c_intrs, length Ts) | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 484 | end | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 485 | |
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 486 | in map prove_elim cs end; | 
| 5094 | 487 | |
| 45647 | 488 | |
| 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 | 489 | (* prove simplification equations *) | 
| 6424 | 490 | |
| 45647 | 491 | fun prove_eqs quiet_mode cs params intr_ts intrs | 
| 492 | (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 | 493 | let | 
| 52059 | 494 | val _ = clean_message ctxt quiet_mode " Proving the simplification rules ..."; | 
| 45647 | 495 | |
| 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 | 496 | 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 | 497 | (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 | 498 | 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 | 499 | val intr_ts' = map dest_intr intr_ts; | 
| 45647 | 500 | |
| 37901 | 501 | 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 | 502 | 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 | 503 | 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 | 504 | 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 | 505 | 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 | 506 | 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 | 507 | 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 | 508 | 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 | 509 | fun list_ex ([], t) = t | 
| 45647 | 510 | | list_ex ((a, T) :: vars, t) = | 
| 511 | 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 | 512 | 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 | 513 | in | 
| 80727 | 514 | 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 | 515 | end; | 
| 45647 | 516 | 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 | 517 | val rhs = | 
| 80727 | 518 | if null c_intrs then \<^Const>\<open>False\<close> | 
| 45647 | 519 | else foldr1 HOLogic.mk_disj (map mk_intr_conj c_intrs); | 
| 520 | 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 | 521 |         fun prove_intr1 (i, _) = Subgoal.FOCUS_PREMS (fn {context = ctxt'', params, prems, ...} =>
 | 
| 59532 | 522 | 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 | 523 |             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 | 524 |             (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 | 525 | else | 
| 
0521ee2e504d
tweaked Inductive.prove_eqs to allow degenerate definition like "inductive TRUE where TRUE";
 wenzelm parents: 
46961diff
changeset | 526 | let | 
| 
0521ee2e504d
tweaked Inductive.prove_eqs to allow degenerate definition like "inductive TRUE where TRUE";
 wenzelm parents: 
46961diff
changeset | 527 | 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 | 528 | in | 
| 58839 | 529 | EVERY (map (fn prem => | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 530 |                   (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 | 531 | 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 | 532 | 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 | 533 | 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 | 534 |           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 | 535 | (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 | 536 | else | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 537 |             EVERY (replicate (length ts + length us - 1) (eresolve_tac ctxt' @{thms conjE} 1)) THEN
 | 
| 59059 | 538 |             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 | 539 | let | 
| 
0521ee2e504d
tweaked Inductive.prove_eqs to allow degenerate definition like "inductive TRUE where TRUE";
 wenzelm parents: 
46961diff
changeset | 540 | 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 | 541 |                 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 | 542 | in | 
| 54742 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
53995diff
changeset | 543 | 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 | 544 | resolve_tac ctxt'' [intr] 1 THEN | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 545 | 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 | 546 | 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 | 547 | in | 
| 51551 | 548 | Goal.prove_sorry ctxt' [] [] eq (fn _ => | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 549 |           resolve_tac ctxt' @{thms iffI} 1 THEN
 | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 550 | eresolve_tac ctxt' [#1 elim] 1 THEN | 
| 45647 | 551 | 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 | 552 |           (if null c_intrs then eresolve_tac ctxt' @{thms FalseE} 1
 | 
| 45647 | 553 | 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 | 554 | 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 | 555 |               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 | 556 | 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 | 557 | end)) | 
| 51717 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51658diff
changeset | 558 | |> rulify ctxt' | 
| 42361 | 559 | |> singleton (Proof_Context.export ctxt' ctxt'') | 
| 45647 | 560 | 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 | 561 | 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 | 562 | 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 | 563 | end; | 
| 45647 | 564 | |
| 565 | ||
| 10735 | 566 | (* derivation of simplified elimination rules *) | 
| 5094 | 567 | |
| 11682 
d9063229b4a1
simp_case_tac is back again from induct_method.ML;
 wenzelm parents: 
11628diff
changeset | 568 | local | 
| 
d9063229b4a1
simp_case_tac is back again from induct_method.ML;
 wenzelm parents: 
11628diff
changeset | 569 | |
| 
d9063229b4a1
simp_case_tac is back again from induct_method.ML;
 wenzelm parents: 
11628diff
changeset | 570 | (*delete needless equality assumptions*) | 
| 69593 | 571 | 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 | 572 |   (fn {context = ctxt, ...} => assume_tac ctxt 1);
 | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 573 | 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 | 574 | 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 | 575 | |
| 51717 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51658diff
changeset | 576 | fun simp_case_tac ctxt i = | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 577 | EVERY' [elim_tac ctxt, | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 578 | asm_full_simp_tac ctxt, | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 579 | elim_tac ctxt, | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 580 | REPEAT o bound_hyp_subst_tac ctxt] i; | 
| 21367 
7a0cc1bb4dcc
inductive: canonical specification syntax (flattened result only);
 wenzelm parents: 
21350diff
changeset | 581 | |
| 11682 
d9063229b4a1
simp_case_tac is back again from induct_method.ML;
 wenzelm parents: 
11628diff
changeset | 582 | in | 
| 9598 | 583 | |
| 54742 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
53995diff
changeset | 584 | fun mk_cases_tac ctxt = ALLGOALS (simp_case_tac ctxt) THEN prune_params_tac ctxt; | 
| 53994 | 585 | |
| 21367 
7a0cc1bb4dcc
inductive: canonical specification syntax (flattened result only);
 wenzelm parents: 
21350diff
changeset | 586 | fun mk_cases ctxt prop = | 
| 7107 | 587 | let | 
| 21526 
1e6bd5ed7abc
added morh_result, the_inductive, add_inductive_global;
 wenzelm parents: 
21508diff
changeset | 588 | fun err msg = | 
| 
1e6bd5ed7abc
added morh_result, the_inductive, add_inductive_global;
 wenzelm parents: 
21508diff
changeset | 589 | error (Pretty.string_of (Pretty.block | 
| 24920 | 590 | [Pretty.str msg, Pretty.fbrk, Syntax.pretty_term ctxt prop])); | 
| 21526 
1e6bd5ed7abc
added morh_result, the_inductive, add_inductive_global;
 wenzelm parents: 
21508diff
changeset | 591 | |
| 24861 
cc669ca5f382
tuned Induct interface: prefer pred'' over set'';
 wenzelm parents: 
24830diff
changeset | 592 | val elims = Induct.find_casesP ctxt prop; | 
| 21367 
7a0cc1bb4dcc
inductive: canonical specification syntax (flattened result only);
 wenzelm parents: 
21350diff
changeset | 593 | |
| 59642 | 594 | val cprop = Thm.cterm_of ctxt prop; | 
| 21367 
7a0cc1bb4dcc
inductive: canonical specification syntax (flattened result only);
 wenzelm parents: 
21350diff
changeset | 595 | fun mk_elim rl = | 
| 53994 | 596 | Thm.implies_intr cprop | 
| 597 | (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 | 598 | |> singleton (Proof_Context.export (Proof_Context.augment prop ctxt) ctxt); | 
| 7107 | 599 | in | 
| 600 | (case get_first (try mk_elim) elims of | |
| 15531 | 601 | SOME r => r | 
| 21526 
1e6bd5ed7abc
added morh_result, the_inductive, add_inductive_global;
 wenzelm parents: 
21508diff
changeset | 602 | | NONE => err "Proposition not an inductive predicate:") | 
| 7107 | 603 | end; | 
| 604 | ||
| 11682 
d9063229b4a1
simp_case_tac is back again from induct_method.ML;
 wenzelm parents: 
11628diff
changeset | 605 | end; | 
| 
d9063229b4a1
simp_case_tac is back again from induct_method.ML;
 wenzelm parents: 
11628diff
changeset | 606 | |
| 45647 | 607 | |
| 21367 
7a0cc1bb4dcc
inductive: canonical specification syntax (flattened result only);
 wenzelm parents: 
21350diff
changeset | 608 | (* inductive_cases *) | 
| 7107 | 609 | |
| 79732 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 610 | fun gen_inductive_cases prep_att prep_prop args int lthy = | 
| 9598 | 611 | let | 
| 46915 | 612 | val thmss = | 
| 613 | 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 | 614 | |> burrow (grouped 10 Par_List.map_independent (mk_cases lthy o prep_prop lthy)); | 
| 46915 | 615 | val facts = | 
| 55997 
9dc5ce83202c
modernized Attrib.check_name/check_src similar to methods (see also a989bdaf8121);
 wenzelm parents: 
55111diff
changeset | 616 | map2 (fn ((a, atts), _) => fn thms => ((a, map (prep_att lthy) atts), [(thms, [])])) | 
| 46915 | 617 | args thmss; | 
| 79732 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 618 | val (res, lthy') = lthy |> Local_Theory.notes facts | 
| 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 619 | val _ = | 
| 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 620 | Proof_Display.print_results | 
| 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 621 |         {interactive = int, pos = Position.thread_data (), proof_state = false}
 | 
| 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 622 | lthy' ((Thm.theoremK, ""), res); | 
| 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 623 | in (res, lthy') end; | 
| 5094 | 624 | |
| 69709 | 625 | val inductive_cases = gen_inductive_cases (K I) Syntax.check_prop; | 
| 626 | val inductive_cases_cmd = gen_inductive_cases Attrib.check_src Syntax.read_prop; | |
| 7107 | 627 | |
| 59845 | 628 | |
| 629 | (* ind_cases *) | |
| 630 | ||
| 631 | fun ind_cases_rules ctxt raw_props raw_fixes = | |
| 632 | let | |
| 63180 | 633 | val (props, ctxt') = Specification.read_props raw_props raw_fixes ctxt; | 
| 59845 | 634 | val rules = Proof_Context.export ctxt' ctxt (map (mk_cases ctxt') props); | 
| 635 | in rules end; | |
| 636 | ||
| 58815 | 637 | val _ = | 
| 638 | Theory.setup | |
| 67149 | 639 | (Method.setup \<^binding>\<open>ind_cases\<close> | 
| 59845 | 640 | (Scan.lift (Scan.repeat1 Parse.prop -- Parse.for_fixes) >> | 
| 641 | (fn (props, fixes) => fn ctxt => | |
| 642 | Method.erule ctxt 0 (ind_cases_rules ctxt props fixes))) | |
| 643 | "case analysis for inductive definitions, based on simplified elimination rule"); | |
| 9598 | 644 | |
| 45647 | 645 | |
| 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 | 646 | (* derivation of simplified equation *) | 
| 9598 | 647 | |
| 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 | 648 | 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 | 649 | let | 
| 45647 | 650 | val thy = Proof_Context.theory_of ctxt; | 
| 70308 | 651 | val ctxt' = Proof_Context.augment prop ctxt; | 
| 45647 | 652 | val lhs_of = fst o HOLogic.dest_eq o HOLogic.dest_Trueprop o Thm.prop_of; | 
| 653 | val substs = | |
| 67637 | 654 | 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 | 655 | |> 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 | 656 | (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 | 657 | (Vartab.empty, Vartab.empty), eq) | 
| 45647 | 658 | handle Pattern.MATCH => NONE); | 
| 659 | val (subst, eq) = | |
| 660 | (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 | 661 | [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 | 662 | | _ => error | 
| 45647 | 663 |         ("equations matching pattern " ^ Syntax.string_of_term ctxt prop ^ " is not unique"));
 | 
| 664 | val inst = | |
| 60784 | 665 | map (fn v => (fst v, Thm.cterm_of ctxt' (Envir.subst_term subst (Var v)))) | 
| 45647 | 666 | (Term.add_vars (lhs_of eq) []); | 
| 667 | in | |
| 60784 | 668 | infer_instantiate ctxt' inst eq | 
| 669 | |> 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 | 670 | |> 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 | 671 | 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 | 672 | |
| 45647 | 673 | |
| 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 | 674 | (* 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 | 675 | |
| 79732 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 676 | 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 | 677 | 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 | 678 | 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 | 679 | ((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 | 680 | 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 | 681 | val (res, lthy') = lthy |> Local_Theory.notes facts | 
| 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 682 | val _ = | 
| 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 683 | Proof_Display.print_results | 
| 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 684 |         {interactive = int, pos = Position.thread_data (), proof_state = false}
 | 
| 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 685 | lthy' ((Thm.theoremK, ""), res) | 
| 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 686 | 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 | 687 | |
| 69709 | 688 | val inductive_simps = gen_inductive_simps (K I) Syntax.check_prop; | 
| 689 | val inductive_simps_cmd = gen_inductive_simps Attrib.check_src Syntax.read_prop; | |
| 40902 | 690 | |
| 45647 | 691 | |
| 10735 | 692 | (* prove induction rule *) | 
| 5094 | 693 | |
| 26477 
ecf06644f6cb
eliminated quiete_mode ref (turned into proper argument);
 wenzelm parents: 
26336diff
changeset | 694 | fun prove_indrule quiet_mode cs argTs bs xs rec_const params intr_ts mono | 
| 45647 | 695 | fp_def rec_preds_defs ctxt ctxt''' = (* FIXME ctxt''' ?? *) | 
| 5094 | 696 | let | 
| 52059 | 697 | val _ = clean_message ctxt quiet_mode " Proving the induction rule ..."; | 
| 5094 | 698 | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 699 | (* predicates for induction rule *) | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 700 | |
| 36642 | 701 | val (pnames, ctxt') = Variable.variant_fixes (mk_names "P" (length cs)) ctxt; | 
| 45647 | 702 | val preds = | 
| 703 | map2 (curry Free) pnames | |
| 704 | (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 | 705 | |
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 706 | (* transform an introduction rule into a premise for induction rule *) | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 707 | |
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 708 | fun mk_ind_prem r = | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 709 | let | 
| 33669 | 710 | fun subst s = | 
| 711 | (case dest_predicate cs params s of | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 712 | SOME (_, i, ys, (_, Ts)) => | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 713 | let | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 714 | val k = length Ts; | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 715 | val bs = map Bound (k - 1 downto 0); | 
| 42364 | 716 | 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 | 717 | val Q = | 
| 
426ed18eba43
discontinued old-style Term.list_abs in favour of plain Term.abs;
 wenzelm parents: 
46218diff
changeset | 718 | fold_rev Term.abs (mk_names "x" k ~~ Ts) | 
| 67149 | 719 | (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 | 720 | (list_comb (incr_boundvars k s, bs), P)); | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 721 | in (Q, case Ts of [] => SOME (s, P) | _ => NONE) end | 
| 33669 | 722 | | NONE => | 
| 723 | (case s of | |
| 45647 | 724 | t $ u => (fst (subst t) $ fst (subst u), NONE) | 
| 725 | | Abs (a, T, t) => (Abs (a, T, fst (subst t)), NONE) | |
| 33669 | 726 | | _ => (s, NONE))); | 
| 7293 | 727 | |
| 33338 | 728 | fun mk_prem s prems = | 
| 729 | (case subst s of | |
| 730 | (_, SOME (t, u)) => t :: u :: prems | |
| 731 | | (t, _) => t :: prems); | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 732 | |
| 45647 | 733 | val SOME (_, i, ys, _) = | 
| 734 | dest_predicate cs params (HOLogic.dest_Trueprop (Logic.strip_assums_concl r)); | |
| 42364 | 735 | in | 
| 46215 
0da9433f959e
discontinued old-style Term.list_all_free in favour of plain Logic.all;
 wenzelm parents: 
45740diff
changeset | 736 | 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 | 737 | (Logic.list_implies (map HOLogic.mk_Trueprop (fold_rev mk_prem | 
| 42364 | 738 | (map HOLogic.dest_Trueprop (Logic.strip_assums_hyp r)) []), | 
| 739 | HOLogic.mk_Trueprop (list_comb (nth preds i, ys)))) | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 740 | end; | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 741 | |
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 742 | val ind_prems = map mk_ind_prem intr_ts; | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 743 | |
| 21526 
1e6bd5ed7abc
added morh_result, the_inductive, add_inductive_global;
 wenzelm parents: 
21508diff
changeset | 744 | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 745 | (* make conclusions for induction rules *) | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 746 | |
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 747 | val Tss = map (binder_types o fastype_of) preds; | 
| 45647 | 748 | val (xnames, ctxt'') = Variable.variant_fixes (mk_names "x" (length (flat Tss))) ctxt'; | 
| 749 | val mutual_ind_concl = | |
| 750 | HOLogic.mk_Trueprop (foldr1 HOLogic.mk_conj | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 751 | (map (fn (((xnames, Ts), c), P) => | 
| 45647 | 752 | let val frees = map Free (xnames ~~ Ts) | 
| 753 | in HOLogic.mk_imp (list_comb (c, params @ frees), list_comb (P, frees)) end) | |
| 754 | (unflat Tss xnames ~~ Tss ~~ cs ~~ preds))); | |
| 5094 | 755 | |
| 13626 
282fbabec862
Fixed bug involving inductive definitions having equalities in the premises,
 paulson parents: 
13197diff
changeset | 756 | |
| 5094 | 757 | (* make predicate for instantiation of abstract induction rule *) | 
| 758 | ||
| 45647 | 759 | val ind_pred = | 
| 760 | fold_rev lambda (bs @ xs) (foldr1 HOLogic.mk_conj | |
| 761 | (map_index (fn (i, P) => fold_rev (curry HOLogic.mk_imp) | |
| 762 | (make_bool_args HOLogic.mk_not I bs i) | |
| 763 | (list_comb (P, make_args' argTs xs (binder_types (fastype_of P))))) preds)); | |
| 5094 | 764 | |
| 45647 | 765 | val ind_concl = | 
| 766 | HOLogic.mk_Trueprop | |
| 67149 | 767 | (HOLogic.mk_binrel \<^const_name>\<open>Orderings.less_eq\<close> (rec_const, ind_pred)); | 
| 5094 | 768 | |
| 45647 | 769 |     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 | 770 | |
| 51551 | 771 | 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 | 772 |       (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 | 773 | [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 | 774 | 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 | 775 |          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 | 776 | rewrite_goals_tac ctxt3 simp_thms2, | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 777 | (*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 | 778 | REPEAT (FIRSTGOAL (eresolve_tac ctxt3 [disjE, exE, FalseE])), | 
| 5094 | 779 | (*Now break down the individual cases. No disjE here in case | 
| 780 | some premise involves disjunction.*) | |
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 781 | 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 | 782 | REPEAT (FIRSTGOAL | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 783 | (resolve_tac ctxt3 [conjI, impI] ORELSE' | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 784 | (eresolve_tac ctxt3 [notE] THEN' assume_tac ctxt3))), | 
| 59499 | 785 | EVERY (map (fn prem => | 
| 786 | DEPTH_SOLVE_1 (assume_tac ctxt3 1 ORELSE | |
| 787 | resolve_tac ctxt3 | |
| 788 | [rewrite_rule ctxt3 (inductive_conj_def :: rec_preds_defs @ simp_thms2) prem, | |
| 789 | conjI, refl] 1)) prems)]); | |
| 5094 | 790 | |
| 51551 | 791 | 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 | 792 |       (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 | 793 | [rewrite_goals_tac ctxt3 rec_preds_defs, | 
| 5094 | 794 | REPEAT (EVERY | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 795 | [REPEAT (resolve_tac ctxt3 [conjI, impI] 1), | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59060diff
changeset | 796 |             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 | 797 | 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 | 798 | rewrite_goals_tac ctxt3 simp_thms1, | 
| 58963 
26bf09b95dda
proper context for assume_tac (atac remains as fall-back without context);
 wenzelm parents: 
58936diff
changeset | 799 | assume_tac ctxt3 1])]); | 
| 5094 | 800 | |
| 42361 | 801 | in singleton (Proof_Context.export ctxt'' ctxt''') (induct RS lemma) end; | 
| 5094 | 802 | |
| 63863 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 803 | (* prove coinduction rule *) | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 804 | |
| 80727 | 805 | 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 | 806 | |
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 807 | 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 | 808 | 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 | 809 | let | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 810 | 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 | 811 | val n = length cs; | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 812 | 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 | 813 | 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 | 814 | 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 | 815 | val (Rs_names, names_ctxt) = Variable.variant_fixes (mk_names "X" n) ctxt; | 
| 80727 | 816 | 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 | 817 | 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 | 818 | 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 | 819 | 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 | 820 | val bss = map (make_bool_args | 
| 80727 | 821 | (fn b => HOLogic.mk_eq (b, \<^Const>\<open>False\<close>)) | 
| 822 | (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 | 823 | val eq_undefinedss = map (fn ys => map (fn x => | 
| 80727 | 824 | let val T = fastype_of x | 
| 825 | 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 | 826 | (subtract (op =) ys xs)) xss; | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 827 | val R = | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 828 |       @{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 | 829 | mk_If (Library.foldr1 HOLogic.mk_conj (bs @ eqs)) R t) | 
| 80727 | 830 | 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 | 831 | |> abstract_list (bs @ xs); | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 832 | |
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 833 | fun subst t = | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 834 | (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 | 835 | SOME (_, i, ts, (_, Us)) => | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 836 | let | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 837 | val l = length Us; | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 838 | 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 | 839 | 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 | 840 | in | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 841 | 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 | 842 | 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 | 843 | |> fold_rev absdummy Us | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 844 | end | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 845 | | NONE => | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 846 | (case t of | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 847 | t1 $ t2 => subst t1 $ subst t2 | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 848 | | 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 | 849 | | _ => t)); | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 850 | |
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 851 | fun mk_coind_prem r = | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 852 | let | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 853 | val SOME (_, i, ts, (Ts, _)) = | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 854 | 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 | 855 | val ps = | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 856 | 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 | 857 | 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 | 858 | in | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 859 | (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 | 860 | (Logic.strip_params r) | 
| 80727 | 861 | (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 | 862 | end; | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 863 | |
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 864 | 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 | 865 |         ((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 | 866 | |> 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 | 867 | |
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 868 | 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 | 869 | |> map (uncurry mk_prem); | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 870 | |
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 871 |     val concl = @{map 3} (fn xs =>
 | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 872 | 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 | 873 | |> 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 | 874 | |
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 875 | |
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 876 | 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 | 877 |         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 | 878 | ns rec_preds_defs; | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 879 | val simps = simp_thms3 @ pred_defs_sym; | 
| 80701 | 880 | val simproc = Simplifier.the_simproc ctxt "HOL.defined_All"; | 
| 881 | val simplify = | |
| 882 | 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 | 883 |     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 | 884 | |> 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 | 885 | |> simplify; | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 886 | 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 | 887 | 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 | 888 | 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 | 889 |       |> 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 | 890 | 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 | 891 | 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 | 892 | ((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 | 893 | 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 | 894 |       (fn {context = ctxt, prems = _} =>
 | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 895 | HEADGOAL (EVERY' [resolve_tac ctxt [iffI], | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 896 | 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 | 897 | 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 | 898 | 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 | 899 | 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 | 900 | reorder_bound_goals; | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 901 |     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 | 902 | HEADGOAL (full_simp_tac | 
| 80701 | 903 | (Ctr_Sugar_Util.ss_only (simps @ reorder_bound_thms) ctxt | 
| 904 | |> Simplifier.add_proc simproc) THEN' | |
| 63863 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 905 | resolve_tac ctxt [coind]) THEN | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 906 | 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 | 907 | 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 | 908 | 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 | 909 | 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 | 910 | 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 | 911 | in | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 912 | coinduction | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 913 | |> 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 | 914 | |> 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 | 915 | end | 
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 916 | |
| 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 917 | |
| 6424 | 918 | |
| 919 | ||
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 920 | (** specification of (co)inductive predicates **) | 
| 10729 | 921 | |
| 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 | 922 | 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 | 923 | let | 
| 33077 
3c9cf88ec841
arg_types_of auxiliary function; using multiset operations
 haftmann parents: 
33056diff
changeset | 924 | 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 | 925 | val k = log 2 1 (length cs); | 
| 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 926 | val predT = replicate k HOLogic.boolT ---> argTs ---> HOLogic.boolT; | 
| 80727 | 927 | val fp_const = if coind then \<^Const>\<open>gfp predT\<close> else \<^Const>\<open>lfp predT\<close>; | 
| 928 | ||
| 81519 | 929 | val ctxt1 = fold Variable.declare_names intr_ts lthy | 
| 45647 | 930 | val p :: xs = | 
| 81519 | 931 | map Free (Variable.variant_names ctxt1 | 
| 45647 | 932 |         (("p", predT) :: (mk_names "x" (length argTs) ~~ argTs)));
 | 
| 81519 | 933 | val ctxt2 = fold Variable.declare_names (p :: xs) ctxt1 | 
| 934 | val bs = map Free (Variable.variant_names ctxt2 (map (rpair HOLogic.boolT) (mk_names "b" k))); | |
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 935 | |
| 33458 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 936 | fun subst t = | 
| 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 937 | (case dest_predicate cs params t of | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 938 | SOME (_, i, ts, (Ts, Us)) => | 
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 939 | let | 
| 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 940 | val l = length Us; | 
| 33669 | 941 | val zs = map Bound (l - 1 downto 0); | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 942 | in | 
| 46219 
426ed18eba43
discontinued old-style Term.list_abs in favour of plain Term.abs;
 wenzelm parents: 
46218diff
changeset | 943 | 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 | 944 | (list_comb (p, | 
| 
426ed18eba43
discontinued old-style Term.list_abs in favour of plain Term.abs;
 wenzelm parents: 
46218diff
changeset | 945 | 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 | 946 | ((map (incr_boundvars l) ts ~~ Ts) @ (zs ~~ Us)))) | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 947 | end | 
| 33669 | 948 | | NONE => | 
| 949 | (case t of | |
| 950 | t1 $ t2 => subst t1 $ subst t2 | |
| 951 | | Abs (x, T, u) => Abs (x, T, subst u) | |
| 952 | | _ => t)); | |
| 5149 | 953 | |
| 5094 | 954 | (* transform an introduction rule into a conjunction *) | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 955 | (* [| p_i t; ... |] ==> p_j u *) | 
| 5094 | 956 | (* is transformed into *) | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 957 | (* b_j & x_j = u & p b_j t & ... *) | 
| 5094 | 958 | |
| 959 | fun transform_rule r = | |
| 960 | let | |
| 45647 | 961 | val SOME (_, i, ts, (Ts, _)) = | 
| 962 | dest_predicate cs params (HOLogic.dest_Trueprop (Logic.strip_assums_concl r)); | |
| 963 | val ps = | |
| 964 | make_bool_args HOLogic.mk_not I bs i @ | |
| 21048 
e57e91f72831
Restructured and repaired code dealing with case names
 berghofe parents: 
21024diff
changeset | 965 | map HOLogic.mk_eq (make_args' argTs xs Ts ~~ ts) @ | 
| 45647 | 966 | map (subst o HOLogic.dest_Trueprop) (Logic.strip_assums_hyp r); | 
| 33338 | 967 | in | 
| 968 | fold_rev (fn (x, T) => fn P => HOLogic.exists_const T $ Abs (x, T, P)) | |
| 969 | (Logic.strip_params r) | |
| 80727 | 970 | (if null ps then \<^Const>\<open>True\<close> else foldr1 HOLogic.mk_conj ps) | 
| 45647 | 971 | end; | 
| 5094 | 972 | |
| 973 | (* make a disjunction of all introduction rules *) | |
| 974 | ||
| 45647 | 975 | val fp_fun = | 
| 976 | fold_rev lambda (p :: bs @ xs) | |
| 80727 | 977 | (if null intr_ts then \<^Const>\<open>False\<close> | 
| 45647 | 978 | else foldr1 HOLogic.mk_disj (map transform_rule intr_ts)); | 
| 5094 | 979 | |
| 61308 | 980 | (* add definition of recursive predicates to theory *) | 
| 5094 | 981 | |
| 61948 | 982 | val is_auxiliary = length cs > 1; | 
| 983 | ||
| 61681 
ca53150406c9
option "inductive_defs" controls exposure of def and mono facts;
 wenzelm parents: 
61308diff
changeset | 984 | val rec_binding = | 
| 63006 | 985 | 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 | 986 | val rec_name = Binding.name_of rec_binding; | 
| 5094 | 987 | |
| 62093 | 988 | val internals = Config.get lthy inductive_internals; | 
| 61681 
ca53150406c9
option "inductive_defs" controls exposure of def and mono facts;
 wenzelm parents: 
61308diff
changeset | 989 | |
| 33458 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 990 | 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 | 991 | |> is_auxiliary ? Proof_Context.concealed | 
| 33766 
c679f05600cd
adapted Local_Theory.define -- eliminated odd thm kind;
 wenzelm parents: 
33726diff
changeset | 992 | |> Local_Theory.define | 
| 61951 | 993 | ((rec_binding, case cnames_syn of [(_, mx)] => mx | _ => NoSyn), | 
| 62093 | 994 |          ((Thm.make_def_binding internals rec_binding, @{attributes [nitpick_unfold]}),
 | 
| 80727 | 995 | 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 | 996 | ||> Proof_Context.restore_naming lthy; | 
| 45647 | 997 | val fp_def' = | 
| 51717 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51658diff
changeset | 998 | 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 | 999 | (Thm.cterm_of lthy' (list_comb (rec_const, params))); | 
| 33278 | 1000 | val specs = | 
| 61681 
ca53150406c9
option "inductive_defs" controls exposure of def and mono facts;
 wenzelm parents: 
61308diff
changeset | 1001 | if is_auxiliary then | 
| 61951 | 1002 | map_index (fn (i, ((b, mx), c)) => | 
| 33278 | 1003 | let | 
| 1004 | val Ts = arg_types_of (length params) c; | |
| 81519 | 1005 | val ctxt = fold Variable.declare_names intr_ts lthy'; | 
| 1006 | val xs = map Free (Variable.variant_names ctxt (mk_names "x" (length Ts) ~~ Ts)); | |
| 33278 | 1007 | in | 
| 61951 | 1008 | ((b, mx), | 
| 62093 | 1009 | ((Thm.make_def_binding internals b, []), fold_rev lambda (params @ xs) | 
| 61951 | 1010 | (list_comb (rec_const, params @ make_bool_args' bs i @ | 
| 1011 | make_args argTs (xs ~~ Ts))))) | |
| 61681 
ca53150406c9
option "inductive_defs" controls exposure of def and mono facts;
 wenzelm parents: 
61308diff
changeset | 1012 | end) (cnames_syn ~~ cs) | 
| 
ca53150406c9
option "inductive_defs" controls exposure of def and mono facts;
 wenzelm parents: 
61308diff
changeset | 1013 | else []; | 
| 33458 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 1014 | val (consts_defs, lthy'') = lthy' | 
| 39248 
4a3747517552
only conceal primitive definition theorems, not predicate names
 haftmann parents: 
38864diff
changeset | 1015 | |> fold_map Local_Theory.define specs; | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 1016 | val preds = (case cs of [_] => [rec_const] | _ => map #1 consts_defs); | 
| 5094 | 1017 | |
| 61063 | 1018 | val (_, ctxt'') = Variable.add_fixes (map (fst o dest_Free) params) lthy''; | 
| 1019 | val mono = prove_mono quiet_mode skip_mono predT fp_fun monos ctxt''; | |
| 1020 | val (_, lthy''') = lthy'' | |
| 61681 
ca53150406c9
option "inductive_defs" controls exposure of def and mono facts;
 wenzelm parents: 
61308diff
changeset | 1021 | |> Local_Theory.note | 
| 62093 | 1022 | ((if internals | 
| 61681 
ca53150406c9
option "inductive_defs" controls exposure of def and mono facts;
 wenzelm parents: 
61308diff
changeset | 1023 | then Binding.qualify true rec_name (Binding.name "mono") | 
| 
ca53150406c9
option "inductive_defs" controls exposure of def and mono facts;
 wenzelm parents: 
61308diff
changeset | 1024 | else Binding.empty, []), | 
| 
ca53150406c9
option "inductive_defs" controls exposure of def and mono facts;
 wenzelm parents: 
61308diff
changeset | 1025 | Proof_Context.export ctxt'' lthy'' [mono]); | 
| 61063 | 1026 | in | 
| 1027 | (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 | 1028 | rec_binding, mono, fp_def', map (#2 o #2) consts_defs, | 
| 61063 | 1029 | list_comb (rec_const, params), preds, argTs, bs, xs) | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 1030 | end; | 
| 5094 | 1031 | |
| 71179 | 1032 | 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 | 1033 | 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 | 1034 | 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 | 1035 | val rec_name = Binding.name_of rec_binding; | 
| 32773 | 1036 | 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 | 1037 | val intr_names = map Binding.name_of intr_bindings; | 
| 61308 | 1038 | val ind_case_names = | 
| 1039 | if forall (equal "") intr_names then [] | |
| 63019 | 1040 | else [Attrib.case_names intr_names]; | 
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 1041 | val induct = | 
| 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 1042 | 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 | 1043 | (raw_induct, | 
| 63019 | 1044 | [Attrib.case_names [rec_name], | 
| 1045 | Attrib.case_conclusion (rec_name, intr_names), | |
| 1046 | Attrib.consumes (1 - Thm.nprems_of raw_induct), | |
| 78095 | 1047 | Attrib.internal \<^here> (K (Induct.coinduct_pred (hd cnames)))]) | 
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 1048 | else if no_ind orelse length cnames > 1 then | 
| 63019 | 1049 | (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 | 1050 | 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 | 1051 | (raw_induct RSN (2, rev_mp), | 
| 63019 | 1052 | ind_case_names @ [Attrib.consumes (~ (Thm.nprems_of raw_induct))]); | 
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 1053 | |
| 33458 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 1054 | val (intrs', lthy1) = | 
| 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 1055 | lthy |> | 
| 71179 | 1056 | Spec_Rules.add spec_name | 
| 1057 | (if coind then Spec_Rules.Co_Inductive else Spec_Rules.Inductive) preds intrs |> | |
| 33671 | 1058 | Local_Theory.notes | 
| 33278 | 1059 | (map (rec_qualified false) intr_bindings ~~ intr_atts ~~ | 
| 63019 | 1060 |           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 | 1061 | map (hd o snd); | 
| 33458 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 1062 | val (((_, elims'), (_, [induct'])), lthy2) = | 
| 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 1063 | lthy1 |> | 
| 33671 | 1064 | 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 | 1065 | fold_map (fn (name, (elim, cases, k)) => | 
| 33671 | 1066 | Local_Theory.note | 
| 33458 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 1067 | ((Binding.qualify true (Long_Name.base_name name) (Binding.name "cases"), | 
| 63019 | 1068 | ((if forall (equal "") cases then [] else [Attrib.case_names cases]) @ | 
| 1069 | [Attrib.consumes (1 - Thm.nprems_of elim), Attrib.constraints k, | |
| 78095 | 1070 |                Attrib.internal \<^here> (K (Induct.cases_pred name))] @ @{attributes [Pure.elim?]})),
 | 
| 63019 | 1071 | [elim]) #> | 
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 1072 | apfst (hd o snd)) (if null elims then [] else cnames ~~ elims) ||>> | 
| 33671 | 1073 | Local_Theory.note | 
| 61308 | 1074 | ((rec_qualified true (Binding.name (coind_prefix coind ^ "induct")), #2 induct), | 
| 1075 | [rulify lthy1 (#1 induct)]); | |
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 1076 | |
| 45647 | 1077 | 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 | 1078 | 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 | 1079 | ((Binding.qualify true (Long_Name.base_name name) (Binding.name "simps"), | 
| 78095 | 1080 | [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 | 1081 | #> 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 | 1082 | (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 | 1083 | 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 | 1084 | 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 | 1085 | 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 | 1086 | 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 | 1087 | lthy3 |> | 
| 33671 | 1088 | 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 | 1089 | inducts |> map (fn (name, th) => ([th], | 
| 61308 | 1090 | ind_case_names @ | 
| 63019 | 1091 | [Attrib.consumes (1 - Thm.nprems_of th), | 
| 78095 | 1092 | 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 | 1093 | 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 | 1094 | in (intrs', elims', eqs', induct', inducts, lthy4) end; | 
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 1095 | |
| 69709 | 1096 | type flags = | 
| 33669 | 1097 |   {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 | 1098 | no_elim: bool, no_ind: bool, skip_mono: bool}; | 
| 26534 | 1099 | |
| 1100 | type add_ind_def = | |
| 69709 | 1101 | flags -> | 
| 28084 
a05ca48ef263
type Attrib.binding abbreviates Name.binding without attributes;
 wenzelm parents: 
28083diff
changeset | 1102 | term list -> (Attrib.binding * term) list -> thm list -> | 
| 29581 | 1103 | term list -> (binding * mixfix) list -> | 
| 69709 | 1104 | local_theory -> result * local_theory; | 
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 1105 | |
| 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 | 1106 | 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 | 1107 | cs intros monos params cnames_syn lthy = | 
| 9072 
a4896cf23638
Now also proves monotonicity when in quick_and_dirty mode.
 berghofe parents: 
8720diff
changeset | 1108 | let | 
| 25288 | 1109 | 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 | 1110 | val names = map (Binding.name_of o fst) cnames_syn; | 
| 26477 
ecf06644f6cb
eliminated quiete_mode ref (turned into proper argument);
 wenzelm parents: 
26336diff
changeset | 1111 | val _ = message (quiet_mode andalso not verbose) | 
| 28083 
103d9282a946
explicit type Name.binding for higher-specification elements;
 wenzelm parents: 
27882diff
changeset | 1112 |       ("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 | 1113 | |
| 71214 
5727bcc3c47c
proper spec_rule name via naming/binding/Morphism.binding;
 wenzelm parents: 
71179diff
changeset | 1114 | val spec_name = Binding.conglomerate (map #1 cnames_syn); | 
| 33671 | 1115 | 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 | 1116 | 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 | 1117 | 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 | 1118 | |
| 61681 
ca53150406c9
option "inductive_defs" controls exposure of def and mono facts;
 wenzelm parents: 
61308diff
changeset | 1119 | 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 | 1120 | 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 | 1121 | monos params cnames_syn lthy; | 
| 9072 
a4896cf23638
Now also proves monotonicity when in quick_and_dirty mode.
 berghofe parents: 
8720diff
changeset | 1122 | |
| 26477 
ecf06644f6cb
eliminated quiete_mode ref (turned into proper argument);
 wenzelm parents: 
26336diff
changeset | 1123 | val (intrs, unfold) = prove_intrs quiet_mode coind mono fp_def (length bs + length xs) | 
| 36642 | 1124 | intr_ts rec_preds_defs lthy2 lthy1; | 
| 33459 | 1125 | val elims = | 
| 1126 | if no_elim then [] | |
| 1127 | else | |
| 1128 | prove_elims quiet_mode cs params intr_ts (map Binding.name_of intr_names) | |
| 36642 | 1129 | unfold rec_preds_defs lthy2 lthy1; | 
| 22605 
41b092e7d89a
- Removed occurrences of ProofContext.export in add_ind_def that
 berghofe parents: 
22460diff
changeset | 1130 | val raw_induct = zero_var_indexes | 
| 33459 | 1131 | (if no_ind then Drule.asm_rl | 
| 1132 | else if coind then | |
| 63863 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 1133 | 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 | 1134 | rec_preds_defs lthy2 lthy1 | 
| 21024 
63ab84bb64d1
Completely rewrote inductive definition package. Now allows to
 berghofe parents: 
20901diff
changeset | 1135 | else | 
| 26477 
ecf06644f6cb
eliminated quiete_mode ref (turned into proper argument);
 wenzelm parents: 
26336diff
changeset | 1136 | prove_indrule quiet_mode cs argTs bs xs rec_const params intr_ts mono fp_def | 
| 36642 | 1137 | rec_preds_defs lthy2 lthy1); | 
| 63863 
d14e580c3b8f
don't expose internal construction in the coinduction rule for mutual coinductive predicates
 traytel parents: 
63395diff
changeset | 1138 | |
| 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 | 1139 | val eqs = | 
| 45647 | 1140 | if no_elim then [] else prove_eqs quiet_mode cs params intr_ts intrs elims lthy2 lthy1; | 
| 5094 | 1141 | |
| 51717 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51658diff
changeset | 1142 | 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 | 1143 | 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 | 1144 | |
| 45647 | 1145 | val (intrs'', elims'', eqs', induct, inducts, lthy3) = | 
| 61681 
ca53150406c9
option "inductive_defs" controls exposure of def and mono facts;
 wenzelm parents: 
61308diff
changeset | 1146 | declare_rules rec_binding coind no_ind | 
| 71179 | 1147 | 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 | 1148 | |
| 
e57e91f72831
Restructured and repaired code dealing with case names
 berghofe parents: 
21024diff
changeset | 1149 | val result = | 
| 
e57e91f72831
Restructured and repaired code dealing with case names
 berghofe parents: 
21024diff
changeset | 1150 |       {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 | 1151 | 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 | 1152 | elims = elims'', | 
| 51717 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
51658diff
changeset | 1153 | raw_induct = rulify lthy3 raw_induct, | 
| 35646 | 1154 | 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 | 1155 | inducts = inducts, | 
| 81810 
6cd42e67c0a8
store the {l,g}fp-definition and the monotonicity theorem for inductive predicates (by Jan van Brügge)
 traytel parents: 
81525diff
changeset | 1156 | def = fp_def, | 
| 
6cd42e67c0a8
store the {l,g}fp-definition and the monotonicity theorem for inductive predicates (by Jan van Brügge)
 traytel parents: 
81525diff
changeset | 1157 | mono = mono, | 
| 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 | 1158 | eqs = eqs'}; | 
| 21367 
7a0cc1bb4dcc
inductive: canonical specification syntax (flattened result only);
 wenzelm parents: 
21350diff
changeset | 1159 | |
| 36642 | 1160 | val lthy4 = lthy3 | 
| 78095 | 1161 |       |> Local_Theory.declaration {syntax = false, pervasive = false, pos = \<^here>} (fn phi =>
 | 
| 45290 | 1162 | 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 | 1163 |         in put_inductives ({names = cnames, coind = coind}, result') end);
 | 
| 36642 | 1164 | in (result, lthy4) end; | 
| 5094 | 1165 | |
| 6424 | 1166 | |
| 10735 | 1167 | (* external interfaces *) | 
| 5094 | 1168 | |
| 69709 | 1169 | fun gen_add_inductive mk_def | 
| 59059 | 1170 | flags cnames_syn pnames spec monos lthy = | 
| 5094 | 1171 | let | 
| 21766 
3eb48154388e
Abbreviations can now be specified simultaneously
 berghofe parents: 
21658diff
changeset | 1172 | |
| 25029 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1173 | (* abbrevs *) | 
| 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1174 | |
| 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 | 1175 | 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 | 1176 | |
| 25029 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1177 | fun get_abbrev ((name, atts), t) = | 
| 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1178 | 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 | 1179 | let | 
| 29006 | 1180 | 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 | 1181 | error "Abbreviations may not have names or attributes"; | 
| 63395 | 1182 | 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 | 1183 | 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 | 1184 | (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 | 1185 |               NONE => error ("Undeclared head of abbreviation " ^ quote x)
 | 
| 28083 
103d9282a946
explicit type Name.binding for higher-specification elements;
 wenzelm parents: 
27882diff
changeset | 1186 | | SOME ((b, T'), mx) => | 
| 25029 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1187 |                 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 | 1188 | else (b, mx)); | 
| 
103d9282a946
explicit type Name.binding for higher-specification elements;
 wenzelm parents: 
27882diff
changeset | 1189 | in SOME (var, rhs) end | 
| 25029 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1190 | else NONE; | 
| 21766 
3eb48154388e
Abbreviations can now be specified simultaneously
 berghofe parents: 
21658diff
changeset | 1191 | |
| 25029 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1192 | 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 | 1193 | 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 | 1194 | |
| 21766 
3eb48154388e
Abbreviations can now be specified simultaneously
 berghofe parents: 
21658diff
changeset | 1195 | |
| 25029 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1196 | (* predicates *) | 
| 21766 
3eb48154388e
Abbreviations can now be specified simultaneously
 berghofe parents: 
21658diff
changeset | 1197 | |
| 25029 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1198 | 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 | 1199 | 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 | 1200 | 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 | 1201 | val ps = map Free pnames; | 
| 5094 | 1202 | |
| 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 | 1203 | val (_, ctxt2) = lthy |> Variable.add_fixes (map (Binding.name_of o fst o fst) cnames_syn'); | 
| 35624 | 1204 | val ctxt3 = ctxt2 |> fold (snd oo Local_Defs.fixed_abbrev) abbrevs; | 
| 42361 | 1205 | 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 | 1206 | |
| 46215 
0da9433f959e
discontinued old-style Term.list_all_free in favour of plain Logic.all;
 wenzelm parents: 
45740diff
changeset | 1207 | fun close_rule r = | 
| 
0da9433f959e
discontinued old-style Term.list_all_free in favour of plain Logic.all;
 wenzelm parents: 
45740diff
changeset | 1208 | 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 | 1209 | (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 | 1210 | 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 | 1211 | 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 | 1212 | | _ => I) r []) r; | 
| 5094 | 1213 | |
| 26736 
e6091328718f
added explicit check phase after reading of specification
 haftmann parents: 
26534diff
changeset | 1214 | 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 | 1215 | val preds = map (fn ((c, _), mx) => (c, mx)) cnames_syn'; | 
| 21048 
e57e91f72831
Restructured and repaired code dealing with case names
 berghofe parents: 
21024diff
changeset | 1216 | in | 
| 25029 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1217 | lthy | 
| 
3a72718c5ddd
gen_add_inductive_i: treat abbrevs as local defs, expand by export;
 wenzelm parents: 
25016diff
changeset | 1218 | |> mk_def flags cs intros monos ps preds | 
| 33671 | 1219 | ||> fold (snd oo Local_Theory.abbrev Syntax.mode_default) abbrevs | 
| 21048 
e57e91f72831
Restructured and repaired code dealing with case names
 berghofe parents: 
21024diff
changeset | 1220 | end; | 
| 5094 | 1221 | |
| 69709 | 1222 | fun gen_add_inductive_cmd mk_def verbose coind cnames_syn pnames_syn intro_srcs raw_monos lthy = | 
| 5094 | 1223 | let | 
| 30486 
9cdc7ce0e389
simplified preparation and outer parsing of specification;
 wenzelm parents: 
30435diff
changeset | 1224 | val ((vars, intrs), _) = lthy | 
| 42361 | 1225 | |> Proof_Context.set_mode Proof_Context.mode_abbrev | 
| 63064 
2f18172214c8
support 'assumes' in specifications, e.g. 'definition', 'inductive';
 wenzelm parents: 
63019diff
changeset | 1226 | |> Specification.read_multi_specs (cnames_syn @ pnames_syn) intro_srcs; | 
| 24721 | 1227 | val (cs, ps) = chop (length cnames_syn) vars; | 
| 1228 | 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 | 1229 | 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 | 1230 |      {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 | 1231 | coind = coind, no_elim = false, no_ind = false, skip_mono = false}; | 
| 26128 | 1232 | in | 
| 1233 | lthy | |
| 69709 | 1234 | |> gen_add_inductive mk_def flags cs (map (apfst Binding.name_of o fst) ps) intrs monos | 
| 26128 | 1235 | end; | 
| 5094 | 1236 | |
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 1237 | val add_inductive = gen_add_inductive add_ind_def; | 
| 69709 | 1238 | 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 | 1239 | |
| 6424 | 1240 | |
| 22789 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1241 | (* read off arities of inductive predicates from raw induction rule *) | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1242 | fun arities_of induct = | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1243 | map (fn (_ $ t $ u) => | 
| 80636 
4041e7c8059d
tuned: more explicit dest_Const_name and dest_Const_type;
 wenzelm parents: 
79732diff
changeset | 1244 | (dest_Const_name (head_of t), length (snd (strip_comb u)))) | 
| 59582 | 1245 | (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 | 1246 | |
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1247 | (* read off parameters of inductive predicate from raw induction rule *) | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1248 | fun params_of induct = | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1249 | let | 
| 59582 | 1250 | 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 | 1251 | val (_, ts) = strip_comb t; | 
| 45647 | 1252 | val (_, us) = strip_comb u; | 
| 22789 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1253 | in | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1254 | List.take (ts, length ts - length us) | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1255 | end; | 
| 
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 | val pname_of_intr = | 
| 80636 
4041e7c8059d
tuned: more explicit dest_Const_name and dest_Const_type;
 wenzelm parents: 
79732diff
changeset | 1258 | 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 | 1259 | |
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1260 | (* partition introduction rules according to predicate name *) | 
| 25822 | 1261 | fun gen_partition_rules f induct intros = | 
| 1262 | 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 | 1263 | (map (rpair [] o fst) (arities_of induct)); | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1264 | |
| 25822 | 1265 | val partition_rules = gen_partition_rules I; | 
| 1266 | fun partition_rules' induct = gen_partition_rules fst induct; | |
| 1267 | ||
| 22789 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1268 | fun unpartition_rules intros xs = | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1269 | 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 | 1270 | (fn x :: xs => (x, xs)) #>> the) intros xs |> fst; | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1271 | |
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1272 | (* infer order of variables in intro rules from order of quantifiers in elim rule *) | 
| 60362 | 1273 | fun infer_intro_vars thy elim arity intros = | 
| 22789 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1274 | let | 
| 59582 | 1275 | val _ :: cases = Thm.prems_of elim; | 
| 1276 | 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 | 1277 | fun mtch (t, u) = | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1278 | let | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1279 | val params = Logic.strip_params t; | 
| 45647 | 1280 | val vars = | 
| 1281 | map (Var o apfst (rpair 0)) | |
| 1282 | (Name.variant_list used (map fst params) ~~ map snd params); | |
| 1283 | val ts = | |
| 1284 | map (curry subst_bounds (rev vars)) | |
| 1285 | (List.drop (Logic.strip_assums_hyp t, arity)); | |
| 22789 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1286 | val us = Logic.strip_imp_prems u; | 
| 45647 | 1287 | val tab = | 
| 1288 | 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 | 1289 | in | 
| 32035 | 1290 | map (Envir.subst_term tab) vars | 
| 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 | in | 
| 59582 | 1293 | map (mtch o apsnd Thm.prop_of) (cases ~~ intros) | 
| 22789 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1294 | end; | 
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1295 | |
| 
4d03dc1cad04
Added functions arities_of, params_of, partition_rules, and
 berghofe parents: 
22675diff
changeset | 1296 | |
| 25978 | 1297 | |
| 58815 | 1298 | (** outer syntax **) | 
| 6424 | 1299 | |
| 23762 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 1300 | fun gen_ind_decl mk_def coind = | 
| 63285 | 1301 | Parse.vars -- Parse.for_fixes -- | 
| 63064 
2f18172214c8
support 'assumes' in specifications, e.g. 'definition', 'inductive';
 wenzelm parents: 
63019diff
changeset | 1302 | Scan.optional Parse_Spec.where_multi_specs [] -- | 
| 67149 | 1303 | Scan.optional (\<^keyword>\<open>monos\<close> |-- Parse.!!! Parse.thms1) [] | 
| 26988 
742e26213212
more uniform treatment of OuterSyntax.local_theory commands;
 wenzelm parents: 
26928diff
changeset | 1304 | >> (fn (((preds, params), specs), monos) => | 
| 69709 | 1305 | (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 | 1306 | |
| 
24eef53a9ad3
Reorganization due to introduction of inductive_set wrapper.
 berghofe parents: 
23577diff
changeset | 1307 | val ind_decl = gen_ind_decl add_ind_def; | 
| 6424 | 1308 | |
| 33458 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 1309 | val _ = | 
| 67149 | 1310 | 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 | 1311 | (ind_decl false); | 
| 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 1312 | |
| 
ae1f5d89b082
proper naming convention lthy: local_theory, but ctxt: Proof.context for arbitrary context;
 wenzelm parents: 
33457diff
changeset | 1313 | val _ = | 
| 67149 | 1314 | 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 | 1315 | (ind_decl true); | 
| 6723 | 1316 | |
| 24867 | 1317 | val _ = | 
| 79732 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 1318 | Outer_Syntax.local_theory' \<^command_keyword>\<open>inductive_cases\<close> | 
| 50214 | 1319 | "create simplified instances of elimination rules" | 
| 79732 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 1320 | (Parse.and_list1 Parse_Spec.simple_specs >> (#2 ooo inductive_cases_cmd)); | 
| 7107 | 1321 | |
| 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 | 1322 | val _ = | 
| 79732 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 1323 | 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 | 1324 | "create simplification rules for inductive predicates" | 
| 79732 
a53287d9add3
improved output in inductive module;
 Fabian Huch <huch@in.tum.de> parents: 
78095diff
changeset | 1325 | (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 | 1326 | |
| 50302 | 1327 | val _ = | 
| 67149 | 1328 | Outer_Syntax.command \<^command_keyword>\<open>print_inductives\<close> | 
| 50302 | 1329 | "print (co)inductive definitions and monotonicity rules" | 
| 60097 
d20ca79d50e4
discontinued pointless warnings: commands are only defined inside a theory context;
 wenzelm parents: 
59940diff
changeset | 1330 | (Parse.opt_bang >> (fn b => Toplevel.keep (print_inductives b o Toplevel.context_of))); | 
| 50302 | 1331 | |
| 5094 | 1332 | end; |