equal
deleted
inserted
replaced
207 (if i mod 2 = 0 then f x else g x) :: make_bool_args f g xs (i div 2); |
207 (if i mod 2 = 0 then f x else g x) :: make_bool_args f g xs (i div 2); |
208 |
208 |
209 fun make_bool_args' xs = |
209 fun make_bool_args' xs = |
210 make_bool_args (K HOLogic.false_const) (K HOLogic.true_const) xs; |
210 make_bool_args (K HOLogic.false_const) (K HOLogic.true_const) xs; |
211 |
211 |
|
212 fun arg_types_of k c = Library.drop (k, binder_types (fastype_of c)); |
|
213 |
212 fun find_arg T x [] = sys_error "find_arg" |
214 fun find_arg T x [] = sys_error "find_arg" |
213 | find_arg T x ((p as (_, (SOME _, _))) :: ps) = |
215 | find_arg T x ((p as (_, (SOME _, _))) :: ps) = |
214 apsnd (cons p) (find_arg T x ps) |
216 apsnd (cons p) (find_arg T x ps) |
215 | find_arg T x ((p as (U, (NONE, y))) :: ps) = |
217 | find_arg T x ((p as (U, (NONE, y))) :: ps) = |
216 if (T: typ) = U then (y, (U, (SOME x, y)) :: ps) |
218 if (T: typ) = U then (y, (U, (SOME x, y)) :: ps) |
229 val (c, ts) = strip_comb t; |
231 val (c, ts) = strip_comb t; |
230 val (xs, ys) = chop k ts; |
232 val (xs, ys) = chop k ts; |
231 val i = find_index (fn c' => c' = c) cs; |
233 val i = find_index (fn c' => c' = c) cs; |
232 in |
234 in |
233 if xs = params andalso i >= 0 then |
235 if xs = params andalso i >= 0 then |
234 SOME (c, i, ys, chop (length ys) |
236 SOME (c, i, ys, chop (length ys) (arg_types_of k c)) |
235 (List.drop (binder_types (fastype_of c), k))) |
|
236 else NONE |
237 else NONE |
237 end; |
238 end; |
238 |
239 |
239 fun mk_names a 0 = [] |
240 fun mk_names a 0 = [] |
240 | mk_names a 1 = [a] |
241 | mk_names a 1 = [a] |
381 val rules1 = [disjE, exE, FalseE]; |
382 val rules1 = [disjE, exE, FalseE]; |
382 val rules2 = [conjE, FalseE, notTrueE]; |
383 val rules2 = [conjE, FalseE, notTrueE]; |
383 |
384 |
384 fun prove_elim c = |
385 fun prove_elim c = |
385 let |
386 let |
386 val Ts = List.drop (binder_types (fastype_of c), length params); |
387 val Ts = arg_types_of (length params) c; |
387 val (anames, ctxt'') = Variable.variant_fixes (mk_names "a" (length Ts)) ctxt'; |
388 val (anames, ctxt'') = Variable.variant_fixes (mk_names "a" (length Ts)) ctxt'; |
388 val frees = map Free (anames ~~ Ts); |
389 val frees = map Free (anames ~~ Ts); |
389 |
390 |
390 fun mk_elim_prem ((_, _, us, _), ts, params') = |
391 fun mk_elim_prem ((_, _, us, _), ts, params') = |
391 list_all (params', |
392 list_all (params', |
491 (* predicates for induction rule *) |
492 (* predicates for induction rule *) |
492 |
493 |
493 val (pnames, ctxt') = ctxt |> |
494 val (pnames, ctxt') = ctxt |> |
494 Variable.add_fixes (map (fst o dest_Free) params) |> snd |> |
495 Variable.add_fixes (map (fst o dest_Free) params) |> snd |> |
495 Variable.variant_fixes (mk_names "P" (length cs)); |
496 Variable.variant_fixes (mk_names "P" (length cs)); |
496 val preds = map Free (pnames ~~ |
497 val preds = map2 (curry Free) pnames |
497 map (fn c => List.drop (binder_types (fastype_of c), length params) ---> |
498 (map (fn c => arg_types_of (length params) c ---> HOLogic.boolT) cs); |
498 HOLogic.boolT) cs); |
|
499 |
499 |
500 (* transform an introduction rule into a premise for induction rule *) |
500 (* transform an introduction rule into a premise for induction rule *) |
501 |
501 |
502 fun mk_ind_prem r = |
502 fun mk_ind_prem r = |
503 let |
503 let |
589 |
589 |
590 |
590 |
591 |
591 |
592 (** specification of (co)inductive predicates **) |
592 (** specification of (co)inductive predicates **) |
593 |
593 |
594 fun drop_first f [] = [] |
|
595 | drop_first f (x :: xs) = if f x then xs else x :: drop_first f xs; |
|
596 |
|
597 fun mk_ind_def quiet_mode skip_mono fork_mono alt_name coind cs intr_ts monos params cnames_syn ctxt = |
594 fun mk_ind_def quiet_mode skip_mono fork_mono alt_name coind cs intr_ts monos params cnames_syn ctxt = |
598 let |
595 let |
599 val fp_name = if coind then @{const_name Inductive.gfp} else @{const_name Inductive.lfp}; |
596 val fp_name = if coind then @{const_name Inductive.gfp} else @{const_name Inductive.lfp}; |
600 |
597 |
601 val argTs = fold (fn c => fn Ts => Ts @ |
598 val argTs = fold (combine (op =) o arg_types_of (length params)) cs []; |
602 (fold (fn T => drop_first (curry (op =) T)) Ts (List.drop (binder_types (fastype_of c), length params)))) cs []; |
|
603 val k = log 2 1 (length cs); |
599 val k = log 2 1 (length cs); |
604 val predT = replicate k HOLogic.boolT ---> argTs ---> HOLogic.boolT; |
600 val predT = replicate k HOLogic.boolT ---> argTs ---> HOLogic.boolT; |
605 val p :: xs = map Free (Variable.variant_frees ctxt intr_ts |
601 val p :: xs = map Free (Variable.variant_frees ctxt intr_ts |
606 (("p", predT) :: (mk_names "x" (length argTs) ~~ argTs))); |
602 (("p", predT) :: (mk_names "x" (length argTs) ~~ argTs))); |
607 val bs = map Free (Variable.variant_frees ctxt (p :: xs @ intr_ts) |
603 val bs = map Free (Variable.variant_frees ctxt (p :: xs @ intr_ts) |
661 val fp_def' = Simplifier.rewrite (HOL_basic_ss addsimps [fp_def]) |
657 val fp_def' = Simplifier.rewrite (HOL_basic_ss addsimps [fp_def]) |
662 (cterm_of (ProofContext.theory_of ctxt') (list_comb (rec_const, params))); |
658 (cterm_of (ProofContext.theory_of ctxt') (list_comb (rec_const, params))); |
663 val specs = if length cs < 2 then [] else |
659 val specs = if length cs < 2 then [] else |
664 map_index (fn (i, (name_mx, c)) => |
660 map_index (fn (i, (name_mx, c)) => |
665 let |
661 let |
666 val Ts = List.drop (binder_types (fastype_of c), length params); |
662 val Ts = arg_types_of (length params) c; |
667 val xs = map Free (Variable.variant_frees ctxt intr_ts |
663 val xs = map Free (Variable.variant_frees ctxt intr_ts |
668 (mk_names "x" (length Ts) ~~ Ts)) |
664 (mk_names "x" (length Ts) ~~ Ts)) |
669 in |
665 in |
670 (name_mx, (Attrib.empty_binding, fold_rev lambda (params @ xs) |
666 (name_mx, (Attrib.empty_binding, fold_rev lambda (params @ xs) |
671 (list_comb (rec_const, params @ make_bool_args' bs i @ |
667 (list_comb (rec_const, params @ make_bool_args' bs i @ |