5 *) |
5 *) |
6 |
6 |
7 signature PARTIAL_FUNCTION = |
7 signature PARTIAL_FUNCTION = |
8 sig |
8 sig |
9 val init: string -> term -> term -> thm -> thm -> thm option -> declaration |
9 val init: string -> term -> term -> thm -> thm -> thm option -> declaration |
10 |
|
11 val mono_tac: Proof.context -> int -> tactic |
10 val mono_tac: Proof.context -> int -> tactic |
12 |
|
13 val add_partial_function: string -> (binding * typ option * mixfix) list -> |
11 val add_partial_function: string -> (binding * typ option * mixfix) list -> |
14 Attrib.binding * term -> local_theory -> local_theory |
12 Attrib.binding * term -> local_theory -> local_theory |
15 |
|
16 val add_partial_function_cmd: string -> (binding * string option * mixfix) list -> |
13 val add_partial_function_cmd: string -> (binding * string option * mixfix) list -> |
17 Attrib.binding * string -> local_theory -> local_theory |
14 Attrib.binding * string -> local_theory -> local_theory |
18 end; |
15 end; |
19 |
16 |
20 |
|
21 structure Partial_Function: PARTIAL_FUNCTION = |
17 structure Partial_Function: PARTIAL_FUNCTION = |
22 struct |
18 struct |
23 |
19 |
24 (*** Context Data ***) |
20 (*** Context Data ***) |
25 |
21 |
26 datatype setup_data = Setup_Data of |
22 datatype setup_data = Setup_Data of |
27 {fixp: term, |
23 {fixp: term, |
28 mono: term, |
24 mono: term, |
29 fixp_eq: thm, |
25 fixp_eq: thm, |
30 fixp_induct: thm, |
26 fixp_induct: thm, |
31 fixp_induct_user: thm option}; |
27 fixp_induct_user: thm option}; |
|
28 |
|
29 fun transform_setup_data phi (Setup_Data {fixp, mono, fixp_eq, fixp_induct, fixp_induct_user}) = |
|
30 let |
|
31 val term = Morphism.term phi; |
|
32 val thm = Morphism.thm phi; |
|
33 in |
|
34 Setup_Data |
|
35 {fixp = term fixp, mono = term mono, fixp_eq = thm fixp_eq, |
|
36 fixp_induct = thm fixp_induct, fixp_induct_user = Option.map thm fixp_induct_user} |
|
37 end; |
32 |
38 |
33 structure Modes = Generic_Data |
39 structure Modes = Generic_Data |
34 ( |
40 ( |
35 type T = setup_data Symtab.table; |
41 type T = setup_data Symtab.table; |
36 val empty = Symtab.empty; |
42 val empty = Symtab.empty; |
38 fun merge data = Symtab.merge (K true) data; |
44 fun merge data = Symtab.merge (K true) data; |
39 ) |
45 ) |
40 |
46 |
41 fun init mode fixp mono fixp_eq fixp_induct fixp_induct_user phi = |
47 fun init mode fixp mono fixp_eq fixp_induct fixp_induct_user phi = |
42 let |
48 let |
43 val term = Morphism.term phi; |
49 val data' = |
44 val thm = Morphism.thm phi; |
50 Setup_Data |
45 val data' = Setup_Data |
51 {fixp = fixp, mono = mono, fixp_eq = fixp_eq, |
46 {fixp=term fixp, mono=term mono, fixp_eq=thm fixp_eq, |
52 fixp_induct = fixp_induct, fixp_induct_user = fixp_induct_user} |
47 fixp_induct=thm fixp_induct, fixp_induct_user=Option.map thm fixp_induct_user}; |
53 |> transform_setup_data (phi $> Morphism.trim_context_morphism); |
48 in |
54 in Modes.map (Symtab.update (mode, data')) end; |
49 Modes.map (Symtab.update (mode, data')) |
|
50 end |
|
51 |
55 |
52 val known_modes = Symtab.keys o Modes.get o Context.Proof; |
56 val known_modes = Symtab.keys o Modes.get o Context.Proof; |
53 val lookup_mode = Symtab.lookup o Modes.get o Context.Proof; |
57 |
|
58 fun lookup_mode ctxt = |
|
59 Symtab.lookup (Modes.get (Context.Proof ctxt)) |
|
60 #> Option.map (transform_setup_data (Morphism.transfer_morphism (Proof_Context.theory_of ctxt))); |
54 |
61 |
55 |
62 |
56 (*** Automated monotonicity proofs ***) |
63 (*** Automated monotonicity proofs ***) |
57 |
64 |
58 fun strip_cases ctac = ctac #> Seq.map snd; |
65 fun strip_cases ctac = ctac #> Seq.map snd; |
157 curry induction predicate *) |
164 curry induction predicate *) |
158 fun specialize_fixp_induct ctxt args fT fT_uc F curry uncurry mono_thm f_def rule = |
165 fun specialize_fixp_induct ctxt args fT fT_uc F curry uncurry mono_thm f_def rule = |
159 let |
166 let |
160 val ([P], ctxt') = Variable.variant_fixes ["P"] ctxt |
167 val ([P], ctxt') = Variable.variant_fixes ["P"] ctxt |
161 val P_inst = Abs ("f", fT_uc, Free (P, fT --> HOLogic.boolT) $ (curry $ Bound 0)) |
168 val P_inst = Abs ("f", fT_uc, Free (P, fT --> HOLogic.boolT) $ (curry $ Bound 0)) |
162 in |
169 in |
163 (* FIXME ctxt vs. ctxt' (!?) *) |
170 (* FIXME ctxt vs. ctxt' (!?) *) |
164 rule |
171 rule |
165 |> infer_instantiate' ctxt |
172 |> infer_instantiate' ctxt |
166 ((map o Option.map) (Thm.cterm_of ctxt) [SOME uncurry, NONE, SOME curry, NONE, SOME P_inst]) |
173 ((map o Option.map) (Thm.cterm_of ctxt) [SOME uncurry, NONE, SOME curry, NONE, SOME P_inst]) |
167 |> Tactic.rule_by_tactic ctxt |
174 |> Tactic.rule_by_tactic ctxt |
180 val ([P], ctxt') = Variable.variant_fixes ["P"] ctxt |
187 val ([P], ctxt') = Variable.variant_fixes ["P"] ctxt |
181 |
188 |
182 val split_paired_all_conv = |
189 val split_paired_all_conv = |
183 Conv.every_conv (replicate (length args - 1) (Conv.rewr_conv @{thm split_paired_all})) |
190 Conv.every_conv (replicate (length args - 1) (Conv.rewr_conv @{thm split_paired_all})) |
184 |
191 |
185 val split_params_conv = |
192 val split_params_conv = |
186 Conv.params_conv ~1 (fn ctxt' => |
193 Conv.params_conv ~1 (fn ctxt' => |
187 Conv.implies_conv split_paired_all_conv Conv.all_conv) |
194 Conv.implies_conv split_paired_all_conv Conv.all_conv) |
188 |
195 |
189 val (P_var, x_var) = |
196 val (P_var, x_var) = |
190 Thm.prop_of inst_rule |> Logic.strip_imp_concl |> HOLogic.dest_Trueprop |
197 Thm.prop_of inst_rule |> Logic.strip_imp_concl |> HOLogic.dest_Trueprop |
262 val unfold = |
269 val unfold = |
263 (infer_instantiate' lthy' (map (SOME o Thm.cterm_of lthy') [uncurry, F, curry]) fixp_eq |
270 (infer_instantiate' lthy' (map (SOME o Thm.cterm_of lthy') [uncurry, F, curry]) fixp_eq |
264 OF [inst_mono_thm, f_def]) |
271 OF [inst_mono_thm, f_def]) |
265 |> Tactic.rule_by_tactic lthy' (Simplifier.simp_tac (put_simpset curry_uncurry_ss lthy') 1); |
272 |> Tactic.rule_by_tactic lthy' (Simplifier.simp_tac (put_simpset curry_uncurry_ss lthy') 1); |
266 |
273 |
267 val specialized_fixp_induct = |
274 val specialized_fixp_induct = |
268 specialize_fixp_induct lthy' args fT fT_uc F curry uncurry inst_mono_thm f_def fixp_induct |
275 specialize_fixp_induct lthy' args fT fT_uc F curry uncurry inst_mono_thm f_def fixp_induct |
269 |> Drule.rename_bvars' (map SOME (fname :: fname :: argnames)); |
276 |> Drule.rename_bvars' (map SOME (fname :: fname :: argnames)); |
270 |
277 |
271 val mk_raw_induct = |
278 val mk_raw_induct = |
272 infer_instantiate' args_ctxt |
279 infer_instantiate' args_ctxt |
286 lthy' |
293 lthy' |
287 |> Local_Theory.note (eq_abinding, [rec_rule]) |
294 |> Local_Theory.note (eq_abinding, [rec_rule]) |
288 |-> (fn (_, rec') => |
295 |-> (fn (_, rec') => |
289 Spec_Rules.add Spec_Rules.Equational ([f], rec') |
296 Spec_Rules.add Spec_Rules.Equational ([f], rec') |
290 #> Local_Theory.note ((Binding.qualify true fname (Binding.name "simps"), []), rec') #> snd) |
297 #> Local_Theory.note ((Binding.qualify true fname (Binding.name "simps"), []), rec') #> snd) |
291 |> (Local_Theory.note ((Binding.qualify true fname (Binding.name "mono"), []), [mono_thm]) #> snd) |
298 |> (Local_Theory.note ((Binding.qualify true fname (Binding.name "mono"), []), [mono_thm]) #> snd) |
292 |> (case raw_induct of NONE => I | SOME thm => |
299 |> (case raw_induct of NONE => I | SOME thm => |
293 Local_Theory.note ((Binding.qualify true fname (Binding.name "raw_induct"), []), [thm]) #> snd) |
300 Local_Theory.note ((Binding.qualify true fname (Binding.name "raw_induct"), []), [thm]) #> snd) |
294 |> (Local_Theory.note ((Binding.qualify true fname (Binding.name "fixp_induct"), []), [specialized_fixp_induct]) #> snd) |
301 |> (Local_Theory.note ((Binding.qualify true fname (Binding.name "fixp_induct"), []), [specialized_fixp_induct]) #> snd) |
295 end; |
302 end; |
296 |
303 |
297 val add_partial_function = gen_add_partial_function Specification.check_spec; |
304 val add_partial_function = gen_add_partial_function Specification.check_spec; |
298 val add_partial_function_cmd = gen_add_partial_function Specification.read_spec; |
305 val add_partial_function_cmd = gen_add_partial_function Specification.read_spec; |
299 |
306 |