329 (* assumption: mutual recursive predicates all have the same parameters. *) |
329 (* assumption: mutual recursive predicates all have the same parameters. *) |
330 fun define_predicates specs thy = |
330 fun define_predicates specs thy = |
331 if forall (fn (const, _) => defined_const thy const) specs then |
331 if forall (fn (const, _) => defined_const thy const) specs then |
332 ([], thy) |
332 ([], thy) |
333 else |
333 else |
334 let |
334 let |
335 val consts = map fst specs |
335 val consts = map fst specs |
336 val eqns = maps snd specs |
336 val eqns = maps snd specs |
337 (*val eqns = maps (Predicate_Compile_Preproc_Data.get_specification thy) consts*) |
337 (*val eqns = maps (Predicate_Compile_Preproc_Data.get_specification thy) consts*) |
338 (* create prednames *) |
338 (* create prednames *) |
339 val ((funs, argss), rhss) = map_split dest_code_eqn eqns |>> split_list |
339 val ((funs, argss), rhss) = map_split dest_code_eqn eqns |>> split_list |
340 val argss' = map (map transform_ho_arg) argss |
340 val argss' = map (map transform_ho_arg) argss |
341 (* TODO: higher order arguments also occur in tuples! *) |
341 (* TODO: higher order arguments also occur in tuples! *) |
342 val ho_argss = distinct (op =) (maps (filter (is_funtype o fastype_of)) argss) |
342 fun is_lifted (t1, t2) = (fastype_of t2 = pred_type (fastype_of t1)) |
343 val params = distinct (op =) (maps (filter (is_funtype o fastype_of)) argss') |
343 val lifted_args = distinct (op =) (filter is_lifted (flat argss ~~ flat argss')) |
344 val pnames = map dest_Free params |
344 val preds = map pred_of funs |
345 val preds = map pred_of funs |
345 (* mapping from term (Free or Const) to term *) |
346 val prednames = map (fst o dest_Free) preds |
346 val net = fold Item_Net.update |
347 val funnames = map (fst o dest_Const) funs |
347 ((funs ~~ preds) @ lifted_args) |
348 val fun_pred_names = (funnames ~~ prednames) |
348 (Fun_Pred.get thy) |
349 (* mapping from term (Free or Const) to term *) |
349 fun lookup_pred t = lookup thy net t |
350 fun map_Free f = Free o f o dest_Free |
350 (* create intro rules *) |
351 val net = fold Item_Net.update |
351 |
352 ((funs ~~ preds) @ (ho_argss ~~ params)) |
352 fun mk_intros ((func, pred), (args, rhs)) = |
353 (Fun_Pred.get thy) |
353 if (body_type (fastype_of func) = @{typ bool}) then |
354 fun lookup_pred t = lookup thy net t |
354 (*TODO: preprocess predicate definition of rhs *) |
355 (* create intro rules *) |
355 [Logic.list_implies ([HOLogic.mk_Trueprop rhs], HOLogic.mk_Trueprop (list_comb (pred, args)))] |
356 |
|
357 fun mk_intros ((func, pred), (args, rhs)) = |
|
358 if (body_type (fastype_of func) = @{typ bool}) then |
|
359 (*TODO: preprocess predicate definition of rhs *) |
|
360 [Logic.list_implies ([HOLogic.mk_Trueprop rhs], HOLogic.mk_Trueprop (list_comb (pred, args)))] |
|
361 else |
|
362 let |
|
363 val names = Term.add_free_names rhs [] |
|
364 in flatten thy lookup_pred rhs (names, []) |
|
365 |> map (fn (resultt, (names', prems)) => |
|
366 Logic.list_implies (prems, HOLogic.mk_Trueprop (list_comb (pred, args @ [resultt])))) |
|
367 end |
|
368 fun mk_rewr_thm (func, pred) = @{thm refl} |
|
369 in |
|
370 case (*try *)SOME (maps mk_intros ((funs ~~ preds) ~~ (argss' ~~ rhss))) of |
|
371 NONE => |
|
372 let val _ = tracing "error occured!" in ([], thy) end |
|
373 | SOME intr_ts => |
|
374 if is_some (try (map (cterm_of thy)) intr_ts) then |
|
375 let |
|
376 val (ind_result, thy') = |
|
377 thy |
|
378 |> Sign.map_naming Name_Space.conceal |
|
379 |> Inductive.add_inductive_global |
|
380 {quiet_mode = false, verbose = false, alt_name = Binding.empty, coind = false, |
|
381 no_elim = false, no_ind = false, skip_mono = false, fork_mono = false} |
|
382 (map (fn (s, T) => |
|
383 ((Binding.name s, T), NoSyn)) (distinct (op =) (map dest_Free preds))) |
|
384 [] |
|
385 (map (fn x => (Attrib.empty_binding, x)) intr_ts) |
|
386 [] |
|
387 ||> Sign.restore_naming thy |
|
388 val prednames = map (fst o dest_Const) (#preds ind_result) |
|
389 (* val rewr_thms = map mk_rewr_eq ((distinct (op =) funs) ~~ (#preds ind_result)) *) |
|
390 (* add constants to my table *) |
|
391 |
|
392 val specs = map (fn predname => (predname, filter (Predicate_Compile_Aux.is_intro predname) |
|
393 (#intrs ind_result))) prednames |
|
394 (* |
|
395 val thy'' = Pred_Compile_Preproc.map (fold Symtab.update_new (consts ~~ prednames)) thy' |
|
396 *) |
|
397 |
|
398 val thy'' = Fun_Pred.map |
|
399 (fold Item_Net.update (map (apfst Logic.varify_global) |
|
400 (distinct (op =) funs ~~ (#preds ind_result)))) thy' |
|
401 (*val _ = print_specs thy'' specs*) |
|
402 in |
|
403 (specs, thy'') |
|
404 end |
|
405 else |
356 else |
406 let |
357 let |
407 val _ = Output.tracing ( |
358 val names = Term.add_free_names rhs [] |
408 "Introduction rules of function_predicate are not welltyped: " ^ |
359 in flatten thy lookup_pred rhs (names, []) |
409 commas (map (Syntax.string_of_term_global thy) intr_ts)) |
360 |> map (fn (resultt, (names', prems)) => |
410 in ([], thy) end |
361 Logic.list_implies (prems, HOLogic.mk_Trueprop (list_comb (pred, args @ [resultt])))) |
411 end |
362 end |
|
363 fun mk_rewr_thm (func, pred) = @{thm refl} |
|
364 in |
|
365 case (*try *)SOME (maps mk_intros ((funs ~~ preds) ~~ (argss' ~~ rhss))) of |
|
366 NONE => |
|
367 let val _ = tracing "error occured!" in ([], thy) end |
|
368 | SOME intr_ts => |
|
369 if is_some (try (map (cterm_of thy)) intr_ts) then |
|
370 let |
|
371 val (ind_result, thy') = |
|
372 thy |
|
373 |> Sign.map_naming Name_Space.conceal |
|
374 |> Inductive.add_inductive_global |
|
375 {quiet_mode = false, verbose = false, alt_name = Binding.empty, coind = false, |
|
376 no_elim = false, no_ind = false, skip_mono = false, fork_mono = false} |
|
377 (map (fn (s, T) => |
|
378 ((Binding.name s, T), NoSyn)) (distinct (op =) (map dest_Free preds))) |
|
379 [] |
|
380 (map (fn x => (Attrib.empty_binding, x)) intr_ts) |
|
381 [] |
|
382 ||> Sign.restore_naming thy |
|
383 val prednames = map (fst o dest_Const) (#preds ind_result) |
|
384 (* val rewr_thms = map mk_rewr_eq ((distinct (op =) funs) ~~ (#preds ind_result)) *) |
|
385 (* add constants to my table *) |
|
386 |
|
387 val specs = map (fn predname => (predname, filter (Predicate_Compile_Aux.is_intro predname) |
|
388 (#intrs ind_result))) prednames |
|
389 val thy'' = Fun_Pred.map |
|
390 (fold Item_Net.update (map (apfst Logic.varify_global) |
|
391 (distinct (op =) funs ~~ (#preds ind_result)))) thy' |
|
392 (*val _ = print_specs thy'' specs*) |
|
393 in |
|
394 (specs, thy'') |
|
395 end |
|
396 else |
|
397 let |
|
398 val _ = Output.tracing ( |
|
399 "Introduction rules of function_predicate are not welltyped: " ^ |
|
400 commas (map (Syntax.string_of_term_global thy) intr_ts)) |
|
401 in ([], thy) end |
|
402 end |
412 |
403 |
413 fun rewrite_intro thy intro = |
404 fun rewrite_intro thy intro = |
414 let |
405 let |
415 (*val _ = tracing ("Rewriting intro with registered mapping for: " ^ |
406 (*val _ = tracing ("Rewriting intro with registered mapping for: " ^ |
416 commas (Symtab.keys (Pred_Compile_Preproc.get thy)))*) |
407 commas (Symtab.keys (Pred_Compile_Preproc.get thy)))*) |