src/HOL/Tools/inductive.ML
changeset 33077 3c9cf88ec841
parent 33056 791a4655cae3
child 33095 bbd52d2f8696
equal deleted inserted replaced
33065:1cefea81ec4f 33077:3c9cf88ec841
   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 @