34 val unify_consts: Sign.sg -> term list -> term list -> term list * term list |
34 val unify_consts: Sign.sg -> term list -> term list -> term list * term list |
35 val get_inductive: theory -> string -> |
35 val get_inductive: theory -> string -> |
36 {names: string list, coind: bool} * {defs: thm list, elims: thm list, raw_induct: thm, |
36 {names: string list, coind: bool} * {defs: thm list, elims: thm list, raw_induct: thm, |
37 induct: thm, intrs: thm list, mk_cases: string -> thm, mono: thm, unfold: thm} |
37 induct: thm, intrs: thm list, mk_cases: string -> thm, mono: thm, unfold: thm} |
38 val print_inductives: theory -> unit |
38 val print_inductives: theory -> unit |
|
39 val mono_add_global: theory attribute |
|
40 val mono_del_global: theory attribute |
|
41 val get_monos: theory -> thm list |
39 val add_inductive_i: bool -> bool -> bstring -> bool -> bool -> bool -> term list -> |
42 val add_inductive_i: bool -> bool -> bstring -> bool -> bool -> bool -> term list -> |
40 theory attribute list -> ((bstring * term) * theory attribute list) list -> |
43 theory attribute list -> ((bstring * term) * theory attribute list) list -> |
41 thm list -> thm list -> theory -> theory * |
44 thm list -> thm list -> theory -> theory * |
42 {defs: thm list, elims: thm list, raw_induct: thm, induct: thm, |
45 {defs: thm list, elims: thm list, raw_induct: thm, induct: thm, |
43 intrs: thm list, mk_cases: string -> thm, mono: thm, unfold: thm} |
46 intrs: thm list, mk_cases: string -> thm, mono: thm, unfold: thm} |
53 val setup: (theory -> theory) list |
56 val setup: (theory -> theory) list |
54 end; |
57 end; |
55 |
58 |
56 structure InductivePackage: INDUCTIVE_PACKAGE = |
59 structure InductivePackage: INDUCTIVE_PACKAGE = |
57 struct |
60 struct |
|
61 |
|
62 (*** theory data ***) |
|
63 |
|
64 (* data kind 'HOL/inductive' *) |
|
65 |
|
66 type inductive_info = |
|
67 {names: string list, coind: bool} * {defs: thm list, elims: thm list, raw_induct: thm, |
|
68 induct: thm, intrs: thm list, mk_cases: string -> thm, mono: thm, unfold: thm}; |
|
69 |
|
70 structure InductiveArgs = |
|
71 struct |
|
72 val name = "HOL/inductive"; |
|
73 type T = inductive_info Symtab.table * thm list; |
|
74 |
|
75 val empty = (Symtab.empty, []); |
|
76 val copy = I; |
|
77 val prep_ext = I; |
|
78 fun merge ((tab1, monos1), (tab2, monos2)) = (Symtab.merge (K true) (tab1, tab2), |
|
79 Library.generic_merge Thm.eq_thm I I monos1 monos2); |
|
80 |
|
81 fun print sg (tab, monos) = |
|
82 (Pretty.writeln (Pretty.strs ("(co)inductives:" :: |
|
83 map #1 (Sign.cond_extern_table sg Sign.constK tab))); |
|
84 Pretty.writeln (Pretty.big_list "monotonicity rules:" (map Display.pretty_thm monos))); |
|
85 end; |
|
86 |
|
87 structure InductiveData = TheoryDataFun(InductiveArgs); |
|
88 val print_inductives = InductiveData.print; |
|
89 |
|
90 |
|
91 (* get and put data *) |
|
92 |
|
93 fun get_inductive thy name = |
|
94 (case Symtab.lookup (fst (InductiveData.get thy), name) of |
|
95 Some info => info |
|
96 | None => error ("Unknown (co)inductive set " ^ quote name)); |
|
97 |
|
98 fun put_inductives names info thy = |
|
99 let |
|
100 fun upd ((tab, monos), name) = (Symtab.update_new ((name, info), tab), monos); |
|
101 val tab_monos = foldl upd (InductiveData.get thy, names) |
|
102 handle Symtab.DUP name => error ("Duplicate definition of (co)inductive set " ^ quote name); |
|
103 in InductiveData.put tab_monos thy end; |
|
104 |
|
105 val get_monos = snd o InductiveData.get; |
|
106 |
|
107 fun put_monos thms thy = InductiveData.put (fst (InductiveData.get thy), thms) thy; |
|
108 |
|
109 (** monotonicity rules **) |
|
110 |
|
111 fun mk_mono thm = |
|
112 let |
|
113 fun eq2mono thm' = [standard (thm' RS (thm' RS eq_to_mono))] @ |
|
114 (case concl_of thm of |
|
115 (_ $ (_ $ (Const ("Not", _) $ _) $ _)) => [] |
|
116 | _ => [standard (thm' RS (thm' RS eq_to_mono2))]); |
|
117 val concl = concl_of thm |
|
118 in |
|
119 if Logic.is_equals concl then |
|
120 eq2mono (thm RS meta_eq_to_obj_eq) |
|
121 else if can (HOLogic.dest_eq o HOLogic.dest_Trueprop) concl then |
|
122 eq2mono thm |
|
123 else [thm] |
|
124 end; |
|
125 |
|
126 (* mono add/del *) |
|
127 |
|
128 local |
|
129 |
|
130 fun map_rules_global f thy = put_monos (f (get_monos thy)) thy; |
|
131 |
|
132 fun add_mono thm rules = Library.gen_union Thm.eq_thm (mk_mono thm, rules); |
|
133 fun del_mono thm rules = Library.gen_rems Thm.eq_thm (rules, mk_mono thm); |
|
134 |
|
135 fun mk_att f g (x, thm) = (f (g thm) x, thm); |
|
136 |
|
137 in |
|
138 |
|
139 val mono_add_global = mk_att map_rules_global add_mono; |
|
140 val mono_del_global = mk_att map_rules_global del_mono; |
|
141 |
|
142 end; |
|
143 |
|
144 |
|
145 (* concrete syntax *) |
|
146 |
|
147 val monoN = "mono"; |
|
148 val addN = "add"; |
|
149 val delN = "del"; |
|
150 |
|
151 fun mono_att add del = |
|
152 Attrib.syntax (Scan.lift (Args.$$$ addN >> K add || Args.$$$ delN >> K del || Scan.succeed add)); |
|
153 |
|
154 val mono_attr = |
|
155 (mono_att mono_add_global mono_del_global, mono_att Attrib.undef_local_attribute Attrib.undef_local_attribute); |
|
156 |
58 |
157 |
59 |
158 |
60 (** utilities **) |
159 (** utilities **) |
61 |
160 |
62 (* messages *) |
161 (* messages *) |
99 (warning "Occurrences of recursive constant have non-unifiable types"; (cs, intr_ts)); |
198 (warning "Occurrences of recursive constant have non-unifiable types"; (cs, intr_ts)); |
100 |
199 |
101 |
200 |
102 (* misc *) |
201 (* misc *) |
103 |
202 |
104 (*for proving monotonicity of recursion operator*) |
|
105 val default_monos = basic_monos @ [vimage_mono]; |
|
106 |
|
107 val Const _ $ (vimage_f $ _) $ _ = HOLogic.dest_Trueprop (concl_of vimageD); |
203 val Const _ $ (vimage_f $ _) $ _ = HOLogic.dest_Trueprop (concl_of vimageD); |
108 |
204 |
109 (*Delete needless equality assumptions*) |
205 (*Delete needless equality assumptions*) |
110 val refl_thin = prove_goal HOL.thy "!!P. [| a=a; P |] ==> P" |
206 val refl_thin = prove_goal HOL.thy "!!P. [| a=a; P |] ==> P" |
111 (fn _ => [assume_tac 1]); |
207 (fn _ => [assume_tac 1]); |
155 (Sign.string_of_term sign p) ^ "\nin introduction rule\n" ^ |
251 (Sign.string_of_term sign p) ^ "\nin introduction rule\n" ^ |
156 (Sign.string_of_term sign t) ^ "\n" ^ msg); |
252 (Sign.string_of_term sign t) ^ "\n" ^ msg); |
157 |
253 |
158 val msg1 = "Conclusion of introduction rule must have form\ |
254 val msg1 = "Conclusion of introduction rule must have form\ |
159 \ ' t : S_i '"; |
255 \ ' t : S_i '"; |
160 val msg2 = "Premises mentioning recursive sets must have form\ |
256 val msg2 = "Non-atomic premise"; |
161 \ ' t : M S_i '"; |
|
162 val msg3 = "Recursion term on left of member symbol"; |
257 val msg3 = "Recursion term on left of member symbol"; |
163 |
258 |
164 fun check_rule sign cs r = |
259 fun check_rule sign cs r = |
165 let |
260 let |
166 fun check_prem prem = if exists (Logic.occs o (rpair prem)) cs then |
261 fun check_prem prem = if can HOLogic.dest_Trueprop prem then () |
167 (case prem of |
262 else err_in_prem sign r prem msg2; |
168 (Const ("op :", _) $ t $ u) => |
263 |
169 if exists (Logic.occs o (rpair t)) cs then |
264 in (case HOLogic.dest_Trueprop (Logic.strip_imp_concl r) of |
170 err_in_prem sign r prem msg3 else () |
265 (Const ("op :", _) $ t $ u) => |
171 | _ => err_in_prem sign r prem msg2) |
266 if u mem cs then |
172 else () |
267 if exists (Logic.occs o (rpair t)) cs then |
173 |
268 err_in_rule sign r msg3 |
174 in (case (HOLogic.dest_Trueprop o Logic.strip_imp_concl) r of |
269 else |
175 (Const ("op :", _) $ _ $ u) => |
270 seq check_prem (Logic.strip_imp_prems r) |
176 if u mem cs then seq (check_prem o HOLogic.dest_Trueprop) |
|
177 (Logic.strip_imp_prems r) |
|
178 else err_in_rule sign r msg1 |
271 else err_in_rule sign r msg1 |
179 | _ => err_in_rule sign r msg1) |
272 | _ => err_in_rule sign r msg1) |
180 end; |
273 end; |
181 |
274 |
182 fun try' f msg sign t = (case (try f t) of |
275 fun try' f msg sign t = (case (try f t) of |
183 Some x => x |
276 Some x => x |
184 | None => error (msg ^ Sign.string_of_term sign t)); |
277 | None => error (msg ^ Sign.string_of_term sign t)); |
185 |
|
186 |
|
187 |
|
188 (*** theory data ***) |
|
189 |
|
190 (* data kind 'HOL/inductive' *) |
|
191 |
|
192 type inductive_info = |
|
193 {names: string list, coind: bool} * {defs: thm list, elims: thm list, raw_induct: thm, |
|
194 induct: thm, intrs: thm list, mk_cases: string -> thm, mono: thm, unfold: thm}; |
|
195 |
|
196 structure InductiveArgs = |
|
197 struct |
|
198 val name = "HOL/inductive"; |
|
199 type T = inductive_info Symtab.table; |
|
200 |
|
201 val empty = Symtab.empty; |
|
202 val copy = I; |
|
203 val prep_ext = I; |
|
204 val merge: T * T -> T = Symtab.merge (K true); |
|
205 |
|
206 fun print sg tab = |
|
207 Pretty.writeln (Pretty.strs ("(co)inductives:" :: |
|
208 map #1 (Sign.cond_extern_table sg Sign.constK tab))); |
|
209 end; |
|
210 |
|
211 structure InductiveData = TheoryDataFun(InductiveArgs); |
|
212 val print_inductives = InductiveData.print; |
|
213 |
|
214 |
|
215 (* get and put data *) |
|
216 |
|
217 fun get_inductive thy name = |
|
218 (case Symtab.lookup (InductiveData.get thy, name) of |
|
219 Some info => info |
|
220 | None => error ("Unknown (co)inductive set " ^ quote name)); |
|
221 |
|
222 fun put_inductives names info thy = |
|
223 let |
|
224 fun upd (tab, name) = Symtab.update_new ((name, info), tab); |
|
225 val tab = foldl upd (InductiveData.get thy, names) |
|
226 handle Symtab.DUP name => error ("Duplicate definition of (co)inductive set " ^ quote name); |
|
227 in InductiveData.put tab thy end; |
|
228 |
278 |
229 |
279 |
230 |
280 |
231 (*** properties of (co)inductive sets ***) |
281 (*** properties of (co)inductive sets ***) |
232 |
282 |
278 |
328 |
279 fun mk_ind_prem r = |
329 fun mk_ind_prem r = |
280 let |
330 let |
281 val frees = map dest_Free ((add_term_frees (r, [])) \\ params); |
331 val frees = map dest_Free ((add_term_frees (r, [])) \\ params); |
282 |
332 |
283 fun subst (prem as (Const ("op :", T) $ t $ u), prems) = |
333 val pred_of = curry (Library.gen_assoc (op aconv)) (cs ~~ preds); |
284 let val n = find_index_eq u cs in |
334 |
285 if n >= 0 then prem :: (nth_elem (n, preds)) $ t :: prems else |
335 fun subst (s as ((m as Const ("op :", T)) $ t $ u)) = |
286 (subst_free (map (fn (c, P) => (c, HOLogic.mk_binop "op Int" |
336 (case pred_of u of |
287 (c, HOLogic.Collect_const (HOLogic.dest_setT |
337 None => (m $ fst (subst t) $ fst (subst u), None) |
288 (fastype_of c)) $ P))) (cs ~~ preds)) prem)::prems |
338 | Some P => (HOLogic.conj $ s $ (P $ t), Some (s, P $ t))) |
289 end |
339 | subst s = |
290 | subst (prem, prems) = prem::prems; |
340 (case pred_of s of |
291 |
341 Some P => (HOLogic.mk_binop "op Int" |
|
342 (s, HOLogic.Collect_const (HOLogic.dest_setT |
|
343 (fastype_of s)) $ P), None) |
|
344 | None => (case s of |
|
345 (t $ u) => (fst (subst t) $ fst (subst u), None) |
|
346 | (Abs (a, T, t)) => (Abs (a, T, fst (subst t)), None) |
|
347 | _ => (s, None))); |
|
348 |
|
349 fun mk_prem (s, prems) = (case subst s of |
|
350 (_, Some (t, u)) => t :: u :: prems |
|
351 | (t, _) => t :: prems); |
|
352 |
292 val Const ("op :", _) $ t $ u = |
353 val Const ("op :", _) $ t $ u = |
293 HOLogic.dest_Trueprop (Logic.strip_imp_concl r) |
354 HOLogic.dest_Trueprop (Logic.strip_imp_concl r) |
294 |
355 |
295 in list_all_free (frees, |
356 in list_all_free (frees, |
296 Logic.list_implies (map HOLogic.mk_Trueprop (foldr subst |
357 Logic.list_implies (map HOLogic.mk_Trueprop (foldr mk_prem |
297 (map HOLogic.dest_Trueprop (Logic.strip_imp_prems r), [])), |
358 (map HOLogic.dest_Trueprop (Logic.strip_imp_prems r), [])), |
298 HOLogic.mk_Trueprop (nth_elem (find_index_eq u cs, preds) $ t))) |
359 HOLogic.mk_Trueprop (the (pred_of u) $ t))) |
299 end; |
360 end; |
300 |
361 |
301 val ind_prems = map mk_ind_prem intr_ts; |
362 val ind_prems = map mk_ind_prem intr_ts; |
302 |
363 |
303 (* make conclusions for induction rules *) |
364 (* make conclusions for induction rules *) |
310 val tuple = HOLogic.mk_tuple T frees; |
371 val tuple = HOLogic.mk_tuple T frees; |
311 in ((HOLogic.mk_binop "op -->" |
372 in ((HOLogic.mk_binop "op -->" |
312 (HOLogic.mk_mem (tuple, c), P $ tuple))::ts, x') |
373 (HOLogic.mk_mem (tuple, c), P $ tuple))::ts, x') |
313 end; |
374 end; |
314 |
375 |
315 val mutual_ind_concl = HOLogic.mk_Trueprop (foldr1 (app HOLogic.conj) |
376 val mutual_ind_concl = HOLogic.mk_Trueprop (foldr1 HOLogic.mk_conj |
316 (fst (foldr mk_ind_concl (cs ~~ preds, ([], "xa"))))) |
377 (fst (foldr mk_ind_concl (cs ~~ preds, ([], "xa"))))) |
317 |
378 |
318 in (preds, ind_prems, mutual_ind_concl) |
379 in (preds, ind_prems, mutual_ind_concl) |
319 end; |
380 end; |
320 |
381 |
372 |
433 |
373 fun prove_elims cs cTs params intr_ts unfold rec_sets_defs thy = |
434 fun prove_elims cs cTs params intr_ts unfold rec_sets_defs thy = |
374 let |
435 let |
375 val _ = message " Proving the elimination rules ..."; |
436 val _ = message " Proving the elimination rules ..."; |
376 |
437 |
377 val rules1 = [CollectE, disjE, make_elim vimageD]; |
438 val rules1 = [CollectE, disjE, make_elim vimageD, exE]; |
378 val rules2 = [exE, conjE, Inl_neq_Inr, Inr_neq_Inl] @ |
439 val rules2 = [conjE, Inl_neq_Inr, Inr_neq_Inl] @ |
379 map make_elim [Inl_inject, Inr_inject]; |
440 map make_elim [Inl_inject, Inr_inject]; |
380 |
441 |
381 val elims = map (fn t => prove_goalw_cterm rec_sets_defs |
442 val elims = map (fn t => prove_goalw_cterm rec_sets_defs |
382 (cterm_of (Theory.sign_of thy) t) (fn prems => |
443 (cterm_of (Theory.sign_of thy) t) (fn prems => |
383 [cut_facts_tac [hd prems] 1, |
444 [cut_facts_tac [hd prems] 1, |
491 |
552 |
492 val induct = prove_goalw_cterm [] (cterm_of sign |
553 val induct = prove_goalw_cterm [] (cterm_of sign |
493 (Logic.list_implies (ind_prems, ind_concl))) (fn prems => |
554 (Logic.list_implies (ind_prems, ind_concl))) (fn prems => |
494 [rtac (impI RS allI) 1, |
555 [rtac (impI RS allI) 1, |
495 DETERM (etac (mono RS (fp_def RS def_induct)) 1), |
556 DETERM (etac (mono RS (fp_def RS def_induct)) 1), |
496 rewrite_goals_tac (map mk_meta_eq (vimage_Int::vimage_simps)), |
557 rewrite_goals_tac (map mk_meta_eq (vimage_Int::Int_Collect::vimage_simps)), |
497 fold_goals_tac rec_sets_defs, |
558 fold_goals_tac rec_sets_defs, |
498 (*This CollectE and disjE separates out the introduction rules*) |
559 (*This CollectE and disjE separates out the introduction rules*) |
499 REPEAT (FIRSTGOAL (eresolve_tac [CollectE, disjE])), |
560 REPEAT (FIRSTGOAL (eresolve_tac [CollectE, disjE, exE])), |
500 (*Now break down the individual cases. No disjE here in case |
561 (*Now break down the individual cases. No disjE here in case |
501 some premise involves disjunction.*) |
562 some premise involves disjunction.*) |
502 REPEAT (FIRSTGOAL (eresolve_tac [IntE, CollectE, exE, conjE] |
563 REPEAT (FIRSTGOAL (etac conjE ORELSE' hyp_subst_tac)), |
503 ORELSE' hyp_subst_tac)), |
|
504 rewrite_goals_tac sum_case_rewrites, |
564 rewrite_goals_tac sum_case_rewrites, |
505 EVERY (map (fn prem => |
565 EVERY (map (fn prem => |
506 DEPTH_SOLVE_1 (ares_tac [prem, conjI, refl] 1)) prems)]); |
566 DEPTH_SOLVE_1 (ares_tac [prem, conjI, refl] 1)) prems)]); |
507 |
567 |
508 val lemma = prove_goalw_cterm rec_sets_defs (cterm_of sign |
568 val lemma = prove_goalw_cterm rec_sets_defs (cterm_of sign |
552 (cs ~~ (map (mk_vimage cs sumT (Free (sname, setT))) cs)); |
612 (cs ~~ (map (mk_vimage cs sumT (Free (sname, setT))) cs)); |
553 val Const ("op :", _) $ t $ u = |
613 val Const ("op :", _) $ t $ u = |
554 HOLogic.dest_Trueprop (Logic.strip_imp_concl r) |
614 HOLogic.dest_Trueprop (Logic.strip_imp_concl r) |
555 |
615 |
556 in foldr (fn ((x, T), P) => HOLogic.mk_exists (x, T, P)) |
616 in foldr (fn ((x, T), P) => HOLogic.mk_exists (x, T, P)) |
557 (frees, foldr1 (app HOLogic.conj) |
617 (frees, foldr1 HOLogic.mk_conj |
558 (((HOLogic.eq_const sumT) $ Free (xname, sumT) $ (mk_inj cs sumT u t)):: |
618 (((HOLogic.eq_const sumT) $ Free (xname, sumT) $ (mk_inj cs sumT u t)):: |
559 (map (subst o HOLogic.dest_Trueprop) |
619 (map (subst o HOLogic.dest_Trueprop) |
560 (Logic.strip_imp_prems r)))) |
620 (Logic.strip_imp_prems r)))) |
561 end |
621 end |
562 |
622 |
563 (* make a disjunction of all introduction rules *) |
623 (* make a disjunction of all introduction rules *) |
564 |
624 |
565 val fp_fun = absfree (sname, setT, (HOLogic.Collect_const sumT) $ |
625 val fp_fun = absfree (sname, setT, (HOLogic.Collect_const sumT) $ |
566 absfree (xname, sumT, foldr1 (app HOLogic.disj) (map transform_rule intr_ts))); |
626 absfree (xname, sumT, foldr1 HOLogic.mk_disj (map transform_rule intr_ts))); |
567 |
627 |
568 (* add definiton of recursive sets to theory *) |
628 (* add definiton of recursive sets to theory *) |
569 |
629 |
570 val rec_name = if alt_name = "" then space_implode "_" cnames else alt_name; |
630 val rec_name = if alt_name = "" then space_implode "_" cnames else alt_name; |
571 val full_rec_name = Sign.full_name (Theory.sign_of thy) rec_name; |
631 val full_rec_name = Sign.full_name (Theory.sign_of thy) rec_name; |
649 Theory.add_consts_i |
709 Theory.add_consts_i |
650 (map (fn (c, n) => (n, paramTs ---> fastype_of c, NoSyn)) (cs ~~ cnames)) |
710 (map (fn (c, n) => (n, paramTs ---> fastype_of c, NoSyn)) (cs ~~ cnames)) |
651 else I) |
711 else I) |
652 |> Theory.add_path rec_name |
712 |> Theory.add_path rec_name |
653 |> PureThy.add_axiomss_i [(("intrs", intr_ts), atts), (("elims", elim_ts), [])] |
713 |> PureThy.add_axiomss_i [(("intrs", intr_ts), atts), (("elims", elim_ts), [])] |
654 |> (if coind then I else PureThy.add_axioms_i [(("internal_induct", ind_t), [])]); |
714 |> (if coind then I else |
|
715 PureThy.add_axioms_i [(("raw_induct", ind_t), [apsnd (standard o split_rule)])]); |
655 |
716 |
656 val intrs = PureThy.get_thms thy' "intrs"; |
717 val intrs = PureThy.get_thms thy' "intrs"; |
657 val elims = PureThy.get_thms thy' "elims"; |
718 val elims = PureThy.get_thms thy' "elims"; |
658 val raw_induct = if coind then TrueI else |
719 val raw_induct = if coind then TrueI else PureThy.get_thm thy' "raw_induct"; |
659 standard (split_rule (PureThy.get_thm thy' "internal_induct")); |
|
660 val induct = if coind orelse length cs > 1 then raw_induct |
720 val induct = if coind orelse length cs > 1 then raw_induct |
661 else standard (raw_induct RSN (2, rev_mp)); |
721 else standard (raw_induct RSN (2, rev_mp)); |
662 |
722 |
663 val thy'' = |
723 val thy'' = |
664 thy' |
724 thy' |
696 |
756 |
697 val full_cnames = map (try' (fst o dest_Const o head_of) |
757 val full_cnames = map (try' (fst o dest_Const o head_of) |
698 "Recursive set not previously declared as constant: " sign) cs; |
758 "Recursive set not previously declared as constant: " sign) cs; |
699 val cnames = map Sign.base_name full_cnames; |
759 val cnames = map Sign.base_name full_cnames; |
700 |
760 |
701 val _ = assert_all Syntax.is_identifier cnames (* FIXME why? *) |
|
702 (fn a => "Base name of recursive set not an identifier: " ^ a); |
|
703 val _ = seq (check_rule sign cs o snd o fst) intros; |
761 val _ = seq (check_rule sign cs o snd o fst) intros; |
704 |
762 |
705 val (thy1, result) = |
763 val (thy1, result) = |
706 (if ! quick_and_dirty then add_ind_axm else add_ind_def) |
764 (if ! quick_and_dirty then add_ind_axm else add_ind_def) |
707 verbose declare_consts alt_name coind no_elim no_ind cs atts intros monos |
765 verbose declare_consts alt_name coind no_elim no_ind cs atts intros monos |
714 (** external interface **) |
772 (** external interface **) |
715 |
773 |
716 fun add_inductive verbose coind c_strings srcs intro_srcs raw_monos raw_con_defs thy = |
774 fun add_inductive verbose coind c_strings srcs intro_srcs raw_monos raw_con_defs thy = |
717 let |
775 let |
718 val sign = Theory.sign_of thy; |
776 val sign = Theory.sign_of thy; |
719 val cs = map (readtm (Theory.sign_of thy) HOLogic.termTVar) c_strings; |
777 val cs = map (term_of o Thm.read_cterm sign o rpair HOLogic.termTVar) c_strings; |
720 |
778 |
721 val atts = map (Attrib.global_attribute thy) srcs; |
779 val atts = map (Attrib.global_attribute thy) srcs; |
722 val intr_names = map (fst o fst) intro_srcs; |
780 val intr_names = map (fst o fst) intro_srcs; |
723 val intr_ts = map (readtm (Theory.sign_of thy) propT o snd o fst) intro_srcs; |
781 val intr_ts = map (term_of o Thm.read_cterm sign o rpair propT o snd o fst) intro_srcs; |
724 val intr_atts = map (map (Attrib.global_attribute thy) o snd) intro_srcs; |
782 val intr_atts = map (map (Attrib.global_attribute thy) o snd) intro_srcs; |
725 val (cs', intr_ts') = unify_consts sign cs intr_ts; |
783 val (cs', intr_ts') = unify_consts sign cs intr_ts; |
726 |
784 |
727 val ((thy', con_defs), monos) = thy |
785 val ((thy', con_defs), monos) = thy |
728 |> IsarThy.apply_theorems raw_monos |
786 |> IsarThy.apply_theorems raw_monos |