13 |
13 |
14 val setup : theory -> theory |
14 val setup : theory -> theory |
15 |
15 |
16 val add_fun : FundefCommon.fundef_config -> |
16 val add_fun : FundefCommon.fundef_config -> |
17 (binding * typ option * mixfix) list -> (Attrib.binding * term) list -> |
17 (binding * typ option * mixfix) list -> (Attrib.binding * term) list -> |
18 bool list -> bool -> local_theory -> Proof.context |
18 bool -> local_theory -> Proof.context |
19 val add_fun_cmd : FundefCommon.fundef_config -> |
19 val add_fun_cmd : FundefCommon.fundef_config -> |
20 (binding * string option * mixfix) list -> (Attrib.binding * string) list -> |
20 (binding * string option * mixfix) list -> (Attrib.binding * string) list -> |
21 bool list -> bool -> local_theory -> Proof.context |
21 bool -> local_theory -> Proof.context |
22 end |
22 end |
23 |
23 |
24 structure FundefDatatype : FUNDEF_DATATYPE = |
24 structure FundefDatatype : FUNDEF_DATATYPE = |
25 struct |
25 struct |
26 |
26 |
233 in |
233 in |
234 map mk_eqn fixes |
234 map mk_eqn fixes |
235 end |
235 end |
236 |
236 |
237 fun add_catchall ctxt fixes spec = |
237 fun add_catchall ctxt fixes spec = |
238 let |
238 spec @ mk_catchall fixes (mk_arities (map (split_def ctxt) spec)) |
239 val catchalls = mk_catchall fixes (mk_arities (map (split_def ctxt) (map snd spec))) |
|
240 in |
|
241 spec @ map (pair true) catchalls |
|
242 end |
|
243 |
239 |
244 fun warn_if_redundant ctxt origs tss = |
240 fun warn_if_redundant ctxt origs tss = |
245 let |
241 let |
246 fun msg t = "Ignoring redundant equation: " ^ quote (Syntax.string_of_term ctxt t) |
242 fun msg t = "Ignoring redundant equation: " ^ quote (Syntax.string_of_term ctxt t) |
247 |
243 |
248 val (tss', _) = chop (length origs) tss |
244 val (tss', _) = chop (length origs) tss |
249 fun check ((_, t), []) = (Output.warning (msg t); []) |
245 fun check (t, []) = (Output.warning (msg t); []) |
250 | check ((_, t), s) = s |
246 | check (t, s) = s |
251 in |
247 in |
252 (map check (origs ~~ tss'); tss) |
248 (map check (origs ~~ tss'); tss) |
253 end |
249 end |
254 |
250 |
255 |
251 |
256 fun sequential_preproc (config as FundefConfig {sequential, ...}) flags ctxt fixes spec = |
252 fun sequential_preproc (config as FundefConfig {sequential, ...}) ctxt fixes spec = |
257 let |
253 if sequential then |
258 val enabled = sequential orelse exists I flags |
|
259 in |
|
260 if enabled then |
|
261 let |
254 let |
262 val flags' = if sequential then map (K true) flags else flags |
|
263 |
|
264 val (nas, eqss) = split_list spec |
255 val (nas, eqss) = split_list spec |
265 |
256 |
266 val eqs = map the_single eqss |
257 val eqs = map the_single eqss |
267 |
258 |
268 val feqs = eqs |
259 val feqs = eqs |
269 |> tap (check_defs ctxt fixes) (* Standard checks *) |
260 |> tap (check_defs ctxt fixes) (* Standard checks *) |
270 |> tap (map (check_pats ctxt)) (* More checks for sequential mode *) |
261 |> tap (map (check_pats ctxt)) (* More checks for sequential mode *) |
271 |> curry op ~~ flags' |
|
272 |
262 |
273 val compleqs = add_catchall ctxt fixes feqs (* Completion *) |
263 val compleqs = add_catchall ctxt fixes feqs (* Completion *) |
274 |
264 |
275 val spliteqs = warn_if_redundant ctxt feqs |
265 val spliteqs = warn_if_redundant ctxt feqs |
276 (FundefSplit.split_some_equations ctxt compleqs) |
266 (FundefSplit.split_all_equations ctxt compleqs) |
277 |
267 |
278 fun restore_spec thms = |
268 fun restore_spec thms = |
279 nas ~~ Library.take (length nas, Library.unflat spliteqs thms) |
269 nas ~~ Library.take (length nas, Library.unflat spliteqs thms) |
280 |
270 |
281 val spliteqs' = flat (Library.take (length nas, spliteqs)) |
271 val spliteqs' = flat (Library.take (length nas, spliteqs)) |
294 |> flat |
284 |> flat |
295 in |
285 in |
296 (flat spliteqs, restore_spec, sort, case_names) |
286 (flat spliteqs, restore_spec, sort, case_names) |
297 end |
287 end |
298 else |
288 else |
299 FundefCommon.empty_preproc check_defs config flags ctxt fixes spec |
289 FundefCommon.empty_preproc check_defs config ctxt fixes spec |
300 end |
|
301 |
290 |
302 val setup = |
291 val setup = |
303 Method.setup @{binding pat_completeness} (Scan.succeed pat_completeness) |
292 Method.setup @{binding pat_completeness} (Scan.succeed pat_completeness) |
304 "Completeness prover for datatype patterns" |
293 "Completeness prover for datatype patterns" |
305 #> Context.theory_map (FundefCommon.set_preproc sequential_preproc) |
294 #> Context.theory_map (FundefCommon.set_preproc sequential_preproc) |
306 |
295 |
307 |
296 |
308 val fun_config = FundefConfig { sequential=true, default="%x. undefined" (*FIXME dynamic scoping*), |
297 val fun_config = FundefConfig { sequential=true, default="%x. undefined" (*FIXME dynamic scoping*), |
309 domintros=false, tailrec=false } |
298 domintros=false, tailrec=false } |
310 |
299 |
311 fun gen_fun add config fixes statements flags int lthy = |
300 fun gen_fun add config fixes statements int lthy = |
312 let val group = serial_string () in |
301 let val group = serial_string () in |
313 lthy |
302 lthy |
314 |> LocalTheory.set_group group |
303 |> LocalTheory.set_group group |
315 |> add fixes statements config flags |
304 |> add fixes statements config |
316 |> by_pat_completeness_auto int |
305 |> by_pat_completeness_auto int |
317 |> LocalTheory.restore |
306 |> LocalTheory.restore |
318 |> LocalTheory.set_group group |
307 |> LocalTheory.set_group group |
319 |> termination_by (FundefCommon.get_termination_prover lthy) int |
308 |> termination_by (FundefCommon.get_termination_prover lthy) int |
320 end; |
309 end; |
327 local structure P = OuterParse and K = OuterKeyword in |
316 local structure P = OuterParse and K = OuterKeyword in |
328 |
317 |
329 val _ = |
318 val _ = |
330 OuterSyntax.local_theory' "fun" "define general recursive functions (short version)" K.thy_decl |
319 OuterSyntax.local_theory' "fun" "define general recursive functions (short version)" K.thy_decl |
331 (fundef_parser fun_config |
320 (fundef_parser fun_config |
332 >> (fn ((config, fixes), (flags, statements)) => add_fun_cmd config fixes statements flags)); |
321 >> (fn ((config, fixes), statements) => add_fun_cmd config fixes statements)); |
333 |
322 |
334 end |
323 end |
335 |
324 |
336 end |
325 end |