src/HOL/Nominal/nominal_primrec.ML
changeset 60792 722cb21ab680
parent 60003 ba8fa0c38d66
child 61841 4d3527b94f2a
equal deleted inserted replaced
60791:e3f2262786ea 60792:722cb21ab680
   279     val (defs_thms, lthy') = lthy |>
   279     val (defs_thms, lthy') = lthy |>
   280       fold_map (apfst (snd o snd) oo Local_Theory.define o fst) defs';
   280       fold_map (apfst (snd o snd) oo Local_Theory.define o fst) defs';
   281     val qualify = Binding.qualify false
   281     val qualify = Binding.qualify false
   282       (space_implode "_" (map (Long_Name.base_name o #1) defs));
   282       (space_implode "_" (map (Long_Name.base_name o #1) defs));
   283     val names_atts' = map (apfst qualify) names_atts;
   283     val names_atts' = map (apfst qualify) names_atts;
   284     val cert = Thm.cterm_of lthy';
       
   285 
   284 
   286     fun mk_idx eq =
   285     fun mk_idx eq =
   287       let
   286       let
   288         val Free (name, _) = head_of (fst (HOLogic.dest_eq (HOLogic.dest_Trueprop
   287         val Free (name, _) = head_of (fst (HOLogic.dest_eq (HOLogic.dest_Trueprop
   289           (Logic.strip_imp_concl eq))));
   288           (Logic.strip_imp_concl eq))));
   303       (subtract (op =)
   302       (subtract (op =)
   304         (Term.add_vars (Thm.concl_of (hd rec_rewrites)) [])
   303         (Term.add_vars (Thm.concl_of (hd rec_rewrites)) [])
   305         (fold_rev (Term.add_vars o Logic.strip_assums_concl)
   304         (fold_rev (Term.add_vars o Logic.strip_assums_concl)
   306            (Thm.prems_of (hd rec_rewrites)) []));
   305            (Thm.prems_of (hd rec_rewrites)) []));
   307     val cfs = defs' |> hd |> snd |> strip_comb |> snd |>
   306     val cfs = defs' |> hd |> snd |> strip_comb |> snd |>
   308       curry (List.take o swap) (length fvars) |> map cert;
   307       curry (List.take o swap) (length fvars) |> map (Thm.cterm_of lthy');
   309     val invs' = (case invs of
   308     val invs' = (case invs of
   310         NONE => map (fn (i, _) =>
   309         NONE => map (fn (i, _) =>
   311           Abs ("x", fastype_of (snd (nth defs' i)), @{term True})) descr
   310           Abs ("x", fastype_of (snd (nth defs' i)), @{term True})) descr
   312       | SOME invs' => map (prep_term lthy') invs');
   311       | SOME invs' => map (prep_term lthy') invs');
   313     val inst = (map cert fvars ~~ cfs) @
   312     val inst = (map (#1 o dest_Var) fvars ~~ cfs) @
   314       (map (cert o Var) pvars ~~ map cert invs') @
   313       (map #1 pvars ~~ map (Thm.cterm_of lthy') invs') @
   315       (case ctxtvars of
   314       (case ctxtvars of
   316          [ctxtvar] => [(cert (Var ctxtvar),
   315          [ctxtvar] => [(#1 ctxtvar,
   317            cert (the_default HOLogic.unit (Option.map (prep_term lthy') fctxt)))]
   316            Thm.cterm_of lthy' (the_default HOLogic.unit (Option.map (prep_term lthy') fctxt)))]
   318        | _ => []);
   317        | _ => []);
   319     val rec_rewrites' = map (fn eq =>
   318     val rec_rewrites' = map (fn eq =>
   320       let
   319       let
   321         val (i, j, cargs) = mk_idx eq
   320         val (i, j, cargs) = mk_idx eq
   322         val th = nth (nth rec_rewritess i) j;
   321         val th = nth (nth rec_rewritess i) j;
   323         val cargs' = th |> Thm.concl_of |> HOLogic.dest_Trueprop |>
   322         val cargs' = th |> Thm.concl_of |> HOLogic.dest_Trueprop |>
   324           HOLogic.dest_eq |> fst |> strip_comb |> snd |> List.last |>
   323           HOLogic.dest_eq |> fst |> strip_comb |> snd |> List.last |>
   325           strip_comb |> snd
   324           strip_comb |> snd
   326       in (cargs, Logic.strip_imp_prems eq,
   325       in (cargs, Logic.strip_imp_prems eq,
   327         Drule.cterm_instantiate (inst @
   326         infer_instantiate lthy' (inst @
   328           (map cert cargs' ~~ map (cert o Free) cargs)) th)
   327           (map (#1 o dest_Var) cargs' ~~ map (Thm.cterm_of lthy' o Free) cargs)) th)
   329       end) eqns';
   328       end) eqns';
   330 
   329 
   331     val prems = foldr1 (common_prefix op aconv) (map (Thm.prems_of o #3) rec_rewrites');
   330     val prems = foldr1 (common_prefix op aconv) (map (Thm.prems_of o #3) rec_rewrites');
   332     val cprems = map cert prems;
   331     val cprems = map (Thm.cterm_of lthy') prems;
   333     val asms = map Thm.assume cprems;
   332     val asms = map Thm.assume cprems;
   334     val premss = map (fn (cargs, eprems, eqn) =>
   333     val premss = map (fn (cargs, eprems, eqn) =>
   335       map (fn t => fold_rev (Logic.all o Free) cargs (Logic.list_implies (eprems, t)))
   334       map (fn t => fold_rev (Logic.all o Free) cargs (Logic.list_implies (eprems, t)))
   336         (List.drop (Thm.prems_of eqn, length prems))) rec_rewrites';
   335         (List.drop (Thm.prems_of eqn, length prems))) rec_rewrites';
   337     val cpremss = map (map cert) premss;
   336     val cpremss = map (map (Thm.cterm_of lthy')) premss;
   338     val asmss = map (map Thm.assume) cpremss;
   337     val asmss = map (map Thm.assume) cpremss;
   339 
   338 
   340     fun mk_eqn ((cargs, eprems, eqn), asms') =
   339     fun mk_eqn ((cargs, eprems, eqn), asms') =
   341       let
   340       let
   342         val ceprems = map cert eprems;
   341         val ceprems = map (Thm.cterm_of lthy') eprems;
   343         val asms'' = map Thm.assume ceprems;
   342         val asms'' = map Thm.assume ceprems;
   344         val ccargs = map (cert o Free) cargs;
   343         val ccargs = map (Thm.cterm_of lthy' o Free) cargs;
   345         val asms''' = map (fn th => implies_elim_list
   344         val asms''' = map (fn th => implies_elim_list
   346           (forall_elim_list ccargs th) asms'') asms'
   345           (forall_elim_list ccargs th) asms'') asms'
   347       in
   346       in
   348         implies_elim_list eqn (asms @ asms''') |>
   347         implies_elim_list eqn (asms @ asms''') |>
   349         implies_intr_list ceprems |>
   348         implies_intr_list ceprems |>
   408     (options -- Parse.fixes -- Parse.for_fixes -- Parse_Spec.where_alt_specs
   407     (options -- Parse.fixes -- Parse.for_fixes -- Parse_Spec.where_alt_specs
   409       >> (fn ((((invs, fctxt), fixes), params), specs) =>
   408       >> (fn ((((invs, fctxt), fixes), params), specs) =>
   410         primrec_cmd invs fctxt fixes params specs));
   409         primrec_cmd invs fctxt fixes params specs));
   411 
   410 
   412 end;
   411 end;
   413