5 Isar commands. |
5 Isar commands. |
6 *) |
6 *) |
7 |
7 |
8 signature FUNCTION = |
8 signature FUNCTION = |
9 sig |
9 sig |
10 include FUNCTION_DATA |
10 include FUNCTION_DATA |
11 |
11 |
12 val add_function : (binding * typ option * mixfix) list |
12 val add_function: (binding * typ option * mixfix) list -> |
13 -> (Attrib.binding * term) list |
13 (Attrib.binding * term) list -> Function_Common.function_config -> |
14 -> Function_Common.function_config |
14 local_theory -> Proof.state |
15 -> local_theory |
15 |
16 -> Proof.state |
16 val add_function_cmd: (binding * string option * mixfix) list -> |
17 val add_function_cmd : (binding * string option * mixfix) list |
17 (Attrib.binding * string) list -> Function_Common.function_config -> |
18 -> (Attrib.binding * string) list |
18 local_theory -> Proof.state |
19 -> Function_Common.function_config |
19 |
20 -> local_theory |
20 val termination_proof : term option -> local_theory -> Proof.state |
21 -> Proof.state |
21 val termination_proof_cmd : string option -> local_theory -> Proof.state |
22 |
22 |
23 val termination_proof : term option -> local_theory -> Proof.state |
23 val setup : theory -> theory |
24 val termination_proof_cmd : string option -> local_theory -> Proof.state |
24 val get_congs : Proof.context -> thm list |
25 |
25 |
26 val setup : theory -> theory |
26 val get_info : Proof.context -> term -> info |
27 val get_congs : Proof.context -> thm list |
|
28 |
|
29 val get_info : Proof.context -> term -> info |
|
30 end |
27 end |
31 |
28 |
32 |
29 |
33 structure Function : FUNCTION = |
30 structure Function : FUNCTION = |
34 struct |
31 struct |
35 |
32 |
36 open Function_Lib |
33 open Function_Lib |
37 open Function_Common |
34 open Function_Common |
38 |
35 |
39 val simp_attribs = map (Attrib.internal o K) |
36 val simp_attribs = map (Attrib.internal o K) |
40 [Simplifier.simp_add, |
37 [Simplifier.simp_add, |
41 Code.add_default_eqn_attribute, |
38 Code.add_default_eqn_attribute, |
42 Nitpick_Simps.add] |
39 Nitpick_Simps.add] |
43 |
40 |
44 val psimp_attribs = map (Attrib.internal o K) |
41 val psimp_attribs = map (Attrib.internal o K) |
45 [Simplifier.simp_add, |
42 [Simplifier.simp_add, |
46 Nitpick_Psimps.add] |
43 Nitpick_Psimps.add] |
47 |
44 |
48 fun mk_defname fixes = fixes |> map (fst o fst) |> space_implode "_" |
45 fun mk_defname fixes = fixes |> map (fst o fst) |> space_implode "_" |
49 |
46 |
50 fun add_simps fnames post sort extra_qualify label mod_binding moreatts simps lthy = |
47 fun add_simps fnames post sort extra_qualify label mod_binding moreatts |
51 let |
48 simps lthy = |
52 val spec = post simps |
49 let |
53 |> map (apfst (apsnd (fn ats => moreatts @ ats))) |
50 val spec = post simps |
54 |> map (apfst (apfst extra_qualify)) |
51 |> map (apfst (apsnd (fn ats => moreatts @ ats))) |
55 |
52 |> map (apfst (apfst extra_qualify)) |
56 val (saved_spec_simps, lthy) = |
53 |
57 fold_map Local_Theory.note spec lthy |
54 val (saved_spec_simps, lthy) = |
58 |
55 fold_map Local_Theory.note spec lthy |
59 val saved_simps = maps snd saved_spec_simps |
56 |
60 val simps_by_f = sort saved_simps |
57 val saved_simps = maps snd saved_spec_simps |
61 |
58 val simps_by_f = sort saved_simps |
62 fun add_for_f fname simps = |
59 |
63 Local_Theory.note |
60 fun add_for_f fname simps = |
64 ((mod_binding (Binding.qualify true fname (Binding.name label)), []), simps) |
61 Local_Theory.note |
65 #> snd |
62 ((mod_binding (Binding.qualify true fname (Binding.name label)), []), simps) |
66 in |
63 #> snd |
67 (saved_simps, |
64 in |
68 fold2 add_for_f fnames simps_by_f lthy) |
65 (saved_simps, fold2 add_for_f fnames simps_by_f lthy) |
69 end |
66 end |
70 |
67 |
71 fun gen_add_function is_external prep default_constraint fixspec eqns config lthy = |
68 fun gen_add_function is_external prep default_constraint fixspec eqns config lthy = |
72 let |
69 let |
73 val constrn_fxs = map (fn (b, T, mx) => (b, SOME (the_default default_constraint T), mx)) |
70 val constrn_fxs = map (fn (b, T, mx) => (b, SOME (the_default default_constraint T), mx)) |
74 val ((fixes0, spec0), ctxt') = prep (constrn_fxs fixspec) eqns lthy |
71 val ((fixes0, spec0), ctxt') = prep (constrn_fxs fixspec) eqns lthy |
75 val fixes = map (apfst (apfst Binding.name_of)) fixes0; |
72 val fixes = map (apfst (apfst Binding.name_of)) fixes0; |
76 val spec = map (fn (bnd, prop) => (bnd, [prop])) spec0; |
73 val spec = map (fn (bnd, prop) => (bnd, [prop])) spec0; |
77 val (eqs, post, sort_cont, cnames) = get_preproc lthy config ctxt' fixes spec |
74 val (eqs, post, sort_cont, cnames) = get_preproc lthy config ctxt' fixes spec |
78 |
75 |
79 val defname = mk_defname fixes |
76 val defname = mk_defname fixes |
80 val FunctionConfig {partials, ...} = config |
77 val FunctionConfig {partials, ...} = config |
81 |
78 |
82 val ((goalstate, cont), lthy) = |
79 val ((goalstate, cont), lthy) = |
83 Function_Mutual.prepare_function_mutual config defname fixes eqs lthy |
80 Function_Mutual.prepare_function_mutual config defname fixes eqs lthy |
84 |
81 |
85 fun afterqed [[proof]] lthy = |
82 fun afterqed [[proof]] lthy = |
|
83 let |
|
84 val FunctionResult {fs, R, psimps, trsimps, simple_pinducts, |
|
85 termination, domintros, cases, ...} = |
|
86 cont (Thm.close_derivation proof) |
|
87 |
|
88 val fnames = map (fst o fst) fixes |
|
89 fun qualify n = Binding.name n |
|
90 |> Binding.qualify true defname |
|
91 val conceal_partial = if partials then I else Binding.conceal |
|
92 |
|
93 val addsmps = add_simps fnames post sort_cont |
|
94 |
|
95 val (((psimps', pinducts'), (_, [termination'])), lthy) = |
|
96 lthy |
|
97 |> addsmps (conceal_partial o Binding.qualify false "partial") |
|
98 "psimps" conceal_partial psimp_attribs psimps |
|
99 ||> fold_option (snd oo addsmps I "simps" I simp_attribs) trsimps |
|
100 ||>> Local_Theory.note ((conceal_partial (qualify "pinduct"), |
|
101 [Attrib.internal (K (Rule_Cases.case_names cnames)), |
|
102 Attrib.internal (K (Rule_Cases.consumes 1)), |
|
103 Attrib.internal (K (Induct.induct_pred ""))]), simple_pinducts) |
|
104 ||>> Local_Theory.note ((Binding.conceal (qualify "termination"), []), [termination]) |
|
105 ||> (snd o Local_Theory.note ((qualify "cases", |
|
106 [Attrib.internal (K (Rule_Cases.case_names cnames))]), [cases])) |
|
107 ||> fold_option (snd oo curry Local_Theory.note (qualify "domintros", [])) domintros |
|
108 |
|
109 val info = { add_simps=addsmps, case_names=cnames, psimps=psimps', |
|
110 pinducts=snd pinducts', simps=NONE, inducts=NONE, termination=termination', |
|
111 fs=fs, R=R, defname=defname, is_partial=true } |
|
112 |
|
113 val _ = |
|
114 if not is_external then () |
|
115 else Specification.print_consts lthy (K false) (map fst fixes) |
|
116 in |
|
117 lthy |
|
118 |> Local_Theory.declaration false (add_function_data o morph_function_data info) |
|
119 end |
|
120 in |
|
121 lthy |
|
122 |> Proof.theorem_i NONE afterqed [[(Logic.unprotect (concl_of goalstate), [])]] |
|
123 |> Proof.refine (Method.primitive_text (fn _ => goalstate)) |> Seq.hd |
|
124 end |
|
125 |
|
126 val add_function = |
|
127 gen_add_function false Specification.check_spec (TypeInfer.anyT HOLogic.typeS) |
|
128 val add_function_cmd = gen_add_function true Specification.read_spec "_::type" |
|
129 |
|
130 fun gen_termination_proof prep_term raw_term_opt lthy = |
|
131 let |
|
132 val term_opt = Option.map (prep_term lthy) raw_term_opt |
|
133 val info = the (case term_opt of |
|
134 SOME t => (import_function_data t lthy |
|
135 handle Option.Option => |
|
136 error ("Not a function: " ^ quote (Syntax.string_of_term lthy t))) |
|
137 | NONE => (import_last_function lthy handle Option.Option => error "Not a function")) |
|
138 |
|
139 val { termination, fs, R, add_simps, case_names, psimps, |
|
140 pinducts, defname, ...} = info |
|
141 val domT = domain_type (fastype_of R) |
|
142 val goal = HOLogic.mk_Trueprop |
|
143 (HOLogic.mk_all ("x", domT, mk_acc domT R $ Free ("x", domT))) |
|
144 fun afterqed [[totality]] lthy = |
86 let |
145 let |
87 val FunctionResult {fs, R, psimps, trsimps, simple_pinducts, termination, |
146 val totality = Thm.close_derivation totality |
88 domintros, cases, ...} = |
147 val remove_domain_condition = |
89 cont (Thm.close_derivation proof) |
148 full_simplify (HOL_basic_ss addsimps [totality, True_implies_equals]) |
90 |
149 val tsimps = map remove_domain_condition psimps |
91 val fnames = map (fst o fst) fixes |
150 val tinduct = map remove_domain_condition pinducts |
|
151 |
92 fun qualify n = Binding.name n |
152 fun qualify n = Binding.name n |
93 |> Binding.qualify true defname |
153 |> Binding.qualify true defname |
94 val conceal_partial = if partials then I else Binding.conceal |
|
95 |
|
96 val addsmps = add_simps fnames post sort_cont |
|
97 |
|
98 val (((psimps', pinducts'), (_, [termination'])), lthy) = |
|
99 lthy |
|
100 |> addsmps (conceal_partial o Binding.qualify false "partial") |
|
101 "psimps" conceal_partial psimp_attribs psimps |
|
102 ||> fold_option (snd oo addsmps I "simps" I simp_attribs) trsimps |
|
103 ||>> Local_Theory.note ((conceal_partial (qualify "pinduct"), |
|
104 [Attrib.internal (K (Rule_Cases.case_names cnames)), |
|
105 Attrib.internal (K (Rule_Cases.consumes 1)), |
|
106 Attrib.internal (K (Induct.induct_pred ""))]), simple_pinducts) |
|
107 ||>> Local_Theory.note ((Binding.conceal (qualify "termination"), []), [termination]) |
|
108 ||> (snd o Local_Theory.note ((qualify "cases", |
|
109 [Attrib.internal (K (Rule_Cases.case_names cnames))]), [cases])) |
|
110 ||> fold_option (snd oo curry Local_Theory.note (qualify "domintros", [])) domintros |
|
111 |
|
112 val info = { add_simps=addsmps, case_names=cnames, psimps=psimps', |
|
113 pinducts=snd pinducts', simps=NONE, inducts=NONE, termination=termination', |
|
114 fs=fs, R=R, defname=defname, is_partial=true } |
|
115 |
|
116 val _ = |
|
117 if not is_external then () |
|
118 else Specification.print_consts lthy (K false) (map fst fixes) |
|
119 in |
154 in |
120 lthy |
155 lthy |
121 |> Local_Theory.declaration false (add_function_data o morph_function_data info) |
156 |> add_simps I "simps" I simp_attribs tsimps |
|
157 ||>> Local_Theory.note |
|
158 ((qualify "induct", |
|
159 [Attrib.internal (K (Rule_Cases.case_names case_names))]), |
|
160 tinduct) |
|
161 |-> (fn (simps, (_, inducts)) => |
|
162 let val info' = { is_partial=false, defname=defname, add_simps=add_simps, |
|
163 case_names=case_names, fs=fs, R=R, psimps=psimps, pinducts=pinducts, |
|
164 simps=SOME simps, inducts=SOME inducts, termination=termination } |
|
165 in |
|
166 Local_Theory.declaration false (add_function_data o morph_function_data info') |
|
167 end) |
122 end |
168 end |
123 in |
169 in |
124 lthy |
170 lthy |
125 |> Proof.theorem_i NONE afterqed [[(Logic.unprotect (concl_of goalstate), [])]] |
171 |> ProofContext.note_thmss "" |
126 |> Proof.refine (Method.primitive_text (fn _ => goalstate)) |> Seq.hd |
172 [((Binding.empty, [Context_Rules.rule_del]), [([allI], [])])] |> snd |
127 end |
173 |> ProofContext.note_thmss "" |
128 |
174 [((Binding.empty, [Context_Rules.intro_bang (SOME 1)]), [([allI], [])])] |> snd |
129 val add_function = gen_add_function false Specification.check_spec (TypeInfer.anyT HOLogic.typeS) |
175 |> ProofContext.note_thmss "" |
130 val add_function_cmd = gen_add_function true Specification.read_spec "_::type" |
176 [((Binding.name "termination", [Context_Rules.intro_bang (SOME 0)]), |
131 |
177 [([Goal.norm_result termination], [])])] |> snd |
132 fun gen_termination_proof prep_term raw_term_opt lthy = |
178 |> Proof.theorem_i NONE afterqed [[(goal, [])]] |
133 let |
179 end |
134 val term_opt = Option.map (prep_term lthy) raw_term_opt |
|
135 val info = the (case term_opt of |
|
136 SOME t => (import_function_data t lthy |
|
137 handle Option.Option => |
|
138 error ("Not a function: " ^ quote (Syntax.string_of_term lthy t))) |
|
139 | NONE => (import_last_function lthy handle Option.Option => error "Not a function")) |
|
140 |
|
141 val { termination, fs, R, add_simps, case_names, psimps, |
|
142 pinducts, defname, ...} = info |
|
143 val domT = domain_type (fastype_of R) |
|
144 val goal = HOLogic.mk_Trueprop |
|
145 (HOLogic.mk_all ("x", domT, mk_acc domT R $ Free ("x", domT))) |
|
146 fun afterqed [[totality]] lthy = |
|
147 let |
|
148 val totality = Thm.close_derivation totality |
|
149 val remove_domain_condition = |
|
150 full_simplify (HOL_basic_ss addsimps [totality, True_implies_equals]) |
|
151 val tsimps = map remove_domain_condition psimps |
|
152 val tinduct = map remove_domain_condition pinducts |
|
153 |
|
154 fun qualify n = Binding.name n |
|
155 |> Binding.qualify true defname |
|
156 in |
|
157 lthy |
|
158 |> add_simps I "simps" I simp_attribs tsimps |
|
159 ||>> Local_Theory.note |
|
160 ((qualify "induct", |
|
161 [Attrib.internal (K (Rule_Cases.case_names case_names))]), |
|
162 tinduct) |
|
163 |-> (fn (simps, (_, inducts)) => |
|
164 let val info' = { is_partial=false, defname=defname, add_simps=add_simps, |
|
165 case_names=case_names, fs=fs, R=R, psimps=psimps, pinducts=pinducts, |
|
166 simps=SOME simps, inducts=SOME inducts, termination=termination } |
|
167 in |
|
168 Local_Theory.declaration false (add_function_data o morph_function_data info') |
|
169 end) |
|
170 end |
|
171 in |
|
172 lthy |
|
173 |> ProofContext.note_thmss "" |
|
174 [((Binding.empty, [Context_Rules.rule_del]), [([allI], [])])] |> snd |
|
175 |> ProofContext.note_thmss "" |
|
176 [((Binding.empty, [Context_Rules.intro_bang (SOME 1)]), [([allI], [])])] |> snd |
|
177 |> ProofContext.note_thmss "" |
|
178 [((Binding.name "termination", [Context_Rules.intro_bang (SOME 0)]), |
|
179 [([Goal.norm_result termination], [])])] |> snd |
|
180 |> Proof.theorem_i NONE afterqed [[(goal, [])]] |
|
181 end |
|
182 |
180 |
183 val termination_proof = gen_termination_proof Syntax.check_term |
181 val termination_proof = gen_termination_proof Syntax.check_term |
184 val termination_proof_cmd = gen_termination_proof Syntax.read_term |
182 val termination_proof_cmd = gen_termination_proof Syntax.read_term |
185 |
183 |
186 |
184 |
187 (* Datatype hook to declare datatype congs as "function_congs" *) |
185 (* Datatype hook to declare datatype congs as "function_congs" *) |
188 |
186 |
189 |
187 |
190 fun add_case_cong n thy = |
188 fun add_case_cong n thy = |
191 Context.theory_map (Function_Ctx_Tree.map_function_congs (Thm.add_thm |
189 let |
192 (Datatype.the_info thy n |
190 val cong = #case_cong (Datatype.the_info thy n) |
193 |> #case_cong |
191 |> safe_mk_meta_eq |
194 |> safe_mk_meta_eq))) |
192 in |
195 thy |
193 Context.theory_map |
|
194 (Function_Ctx_Tree.map_function_congs (Thm.add_thm cong)) thy |
|
195 end |
196 |
196 |
197 val setup_case_cong = Datatype.interpretation (K (fold add_case_cong)) |
197 val setup_case_cong = Datatype.interpretation (K (fold add_case_cong)) |
198 |
198 |
199 |
199 |
200 (* setup *) |
200 (* setup *) |