src/HOL/Nominal/nominal_inductive2.ML
changeset 60754 02924903a6fd
parent 60642 48dd1cefb4ae
child 60787 12cd198f07af
equal deleted inserted replaced
60753:80ca4a065a48 60754:02924903a6fd
   107           (subst_bounds (pis, strip_all pis t)))
   107           (subst_bounds (pis, strip_all pis t)))
   108       else NONE
   108       else NONE
   109   | inst_conj_all _ _ _ _ _ = NONE;
   109   | inst_conj_all _ _ _ _ _ = NONE;
   110 
   110 
   111 fun inst_conj_all_tac ctxt k = EVERY
   111 fun inst_conj_all_tac ctxt k = EVERY
   112   [TRY (EVERY [etac conjE 1, rtac conjI 1, atac 1]),
   112   [TRY (EVERY [eresolve_tac ctxt [conjE] 1, resolve_tac ctxt [conjI] 1, assume_tac ctxt 1]),
   113    REPEAT_DETERM_N k (etac allE 1),
   113    REPEAT_DETERM_N k (eresolve_tac ctxt [allE] 1),
   114    simp_tac (put_simpset HOL_basic_ss ctxt addsimps [@{thm id_apply}]) 1];
   114    simp_tac (put_simpset HOL_basic_ss ctxt addsimps [@{thm id_apply}]) 1];
   115 
   115 
   116 fun map_term f t u = (case f t u of
   116 fun map_term f t u = (case f t u of
   117       NONE => map_term' f t u | x => x)
   117       NONE => map_term' f t u | x => x)
   118 and map_term' f (t $ u) (t' $ u') = (case (map_term f t t', map_term f u u') of
   118 and map_term' f (t $ u) (t' $ u') = (case (map_term f t t', map_term f u u') of
   132 fun map_thm ctxt f tac monos opt th =
   132 fun map_thm ctxt f tac monos opt th =
   133   let
   133   let
   134     val prop = Thm.prop_of th;
   134     val prop = Thm.prop_of th;
   135     fun prove t =
   135     fun prove t =
   136       Goal.prove ctxt [] [] t (fn _ =>
   136       Goal.prove ctxt [] [] t (fn _ =>
   137         EVERY [cut_facts_tac [th] 1, etac rev_mp 1,
   137         EVERY [cut_facts_tac [th] 1, eresolve_tac ctxt [rev_mp] 1,
   138           REPEAT_DETERM (FIRSTGOAL (resolve_tac ctxt monos)),
   138           REPEAT_DETERM (FIRSTGOAL (resolve_tac ctxt monos)),
   139           REPEAT_DETERM (rtac impI 1 THEN (atac 1 ORELSE tac))])
   139           REPEAT_DETERM (resolve_tac ctxt [impI] 1 THEN (assume_tac ctxt 1 ORELSE tac))])
   140   in Option.map prove (map_term f prop (the_default prop opt)) end;
   140   in Option.map prove (map_term f prop (the_default prop opt)) end;
   141 
   141 
   142 fun abs_params params t =
   142 fun abs_params params t =
   143   let val vs =  map (Var o apfst (rpair 0)) (Term.rename_wrt_term t params)
   143   let val vs =  map (Var o apfst (rpair 0)) (Term.rename_wrt_term t params)
   144   in (Logic.list_all (params, t), (rev vs, subst_bounds (vs, t))) end;
   144   in (Logic.list_all (params, t), (rev vs, subst_bounds (vs, t))) end;
   319         val avoid_th = Drule.instantiate'
   319         val avoid_th = Drule.instantiate'
   320           [SOME (Thm.global_ctyp_of thy (fastype_of p))] [SOME (Thm.global_cterm_of thy p)]
   320           [SOME (Thm.global_ctyp_of thy (fastype_of p))] [SOME (Thm.global_cterm_of thy p)]
   321           ([at_inst, fin, fs_atom] MRS @{thm at_set_avoiding});
   321           ([at_inst, fin, fs_atom] MRS @{thm at_set_avoiding});
   322         val (([(_, cx)], th1 :: th2 :: ths), ctxt') = Obtain.result
   322         val (([(_, cx)], th1 :: th2 :: ths), ctxt') = Obtain.result
   323           (fn ctxt' => EVERY
   323           (fn ctxt' => EVERY
   324             [rtac avoid_th 1,
   324             [resolve_tac ctxt' [avoid_th] 1,
   325              full_simp_tac (put_simpset HOL_ss ctxt' addsimps [@{thm fresh_star_prod_set}]) 1,
   325              full_simp_tac (put_simpset HOL_ss ctxt' addsimps [@{thm fresh_star_prod_set}]) 1,
   326              full_simp_tac (put_simpset HOL_basic_ss ctxt' addsimps [@{thm id_apply}]) 1,
   326              full_simp_tac (put_simpset HOL_basic_ss ctxt' addsimps [@{thm id_apply}]) 1,
   327              rotate_tac 1 1,
   327              rotate_tac 1 1,
   328              REPEAT (etac conjE 1)])
   328              REPEAT (eresolve_tac ctxt' [conjE] 1)])
   329           [] ctxt;
   329           [] ctxt;
   330         val (Ts1, _ :: Ts2) = take_prefix (not o equal T) (map snd sets);
   330         val (Ts1, _ :: Ts2) = take_prefix (not o equal T) (map snd sets);
   331         val pTs = map NominalAtoms.mk_permT (Ts1 @ Ts2);
   331         val pTs = map NominalAtoms.mk_permT (Ts1 @ Ts2);
   332         val (pis1, pis2) = chop (length Ts1)
   332         val (pis1, pis2) = chop (length Ts1)
   333           (map Bound (length pTs - 1 downto 0));
   333           (map Bound (length pTs - 1 downto 0));
   346       end;
   346       end;
   347 
   347 
   348     fun mk_ind_proof ctxt' thss =
   348     fun mk_ind_proof ctxt' thss =
   349       Goal.prove ctxt' [] prems' concl' (fn {prems = ihyps, context = ctxt} =>
   349       Goal.prove ctxt' [] prems' concl' (fn {prems = ihyps, context = ctxt} =>
   350         let val th = Goal.prove ctxt [] [] concl (fn {context, ...} =>
   350         let val th = Goal.prove ctxt [] [] concl (fn {context, ...} =>
   351           rtac raw_induct 1 THEN
   351           resolve_tac ctxt [raw_induct] 1 THEN
   352           EVERY (maps (fn (((((_, sets, oprems, _),
   352           EVERY (maps (fn (((((_, sets, oprems, _),
   353               vc_compat_ths), vc_compat_vs), ihyp), vs_ihypt) =>
   353               vc_compat_ths), vc_compat_vs), ihyp), vs_ihypt) =>
   354             [REPEAT (rtac allI 1), simp_tac (put_simpset eqvt_ss context) 1,
   354             [REPEAT (resolve_tac ctxt [allI] 1), simp_tac (put_simpset eqvt_ss context) 1,
   355              SUBPROOF (fn {prems = gprems, params, concl, context = ctxt', ...} =>
   355              SUBPROOF (fn {prems = gprems, params, concl, context = ctxt', ...} =>
   356                let
   356                let
   357                  val (cparams', (pis, z)) =
   357                  val (cparams', (pis, z)) =
   358                    chop (length params - length atomTs - 1) (map #2 params) ||>
   358                    chop (length params - length atomTs - 1) (map #2 params) ||>
   359                    (map Thm.term_of #> split_last);
   359                    (map Thm.term_of #> split_last);
   364                  val (P, ts) = strip_comb (HOLogic.dest_Trueprop (Thm.term_of concl));
   364                  val (P, ts) = strip_comb (HOLogic.dest_Trueprop (Thm.term_of concl));
   365                  val gprems1 = map_filter (fn (th, t) =>
   365                  val gprems1 = map_filter (fn (th, t) =>
   366                    if null (preds_of ps t) then SOME th
   366                    if null (preds_of ps t) then SOME th
   367                    else
   367                    else
   368                      map_thm ctxt' (split_conj (K o I) names)
   368                      map_thm ctxt' (split_conj (K o I) names)
   369                        (etac conjunct1 1) monos NONE th)
   369                        (eresolve_tac ctxt' [conjunct1] 1) monos NONE th)
   370                    (gprems ~~ oprems);
   370                    (gprems ~~ oprems);
   371                  val vc_compat_ths' = map2 (fn th => fn p =>
   371                  val vc_compat_ths' = map2 (fn th => fn p =>
   372                    let
   372                    let
   373                      val th' = gprems1 MRS inst_params thy p th cparams';
   373                      val th' = gprems1 MRS inst_params thy p th cparams';
   374                      val (h, ts) =
   374                      val (h, ts) =
   376                    in
   376                    in
   377                      Goal.prove ctxt' [] []
   377                      Goal.prove ctxt' [] []
   378                        (HOLogic.mk_Trueprop (list_comb (h,
   378                        (HOLogic.mk_Trueprop (list_comb (h,
   379                           map (fold_rev (NominalDatatype.mk_perm []) pis) ts)))
   379                           map (fold_rev (NominalDatatype.mk_perm []) pis) ts)))
   380                        (fn _ => simp_tac (put_simpset HOL_basic_ss ctxt' addsimps
   380                        (fn _ => simp_tac (put_simpset HOL_basic_ss ctxt' addsimps
   381                           (fresh_star_bij @ finite_ineq)) 1 THEN rtac th' 1)
   381                           (fresh_star_bij @ finite_ineq)) 1 THEN resolve_tac ctxt' [th'] 1)
   382                    end) vc_compat_ths vc_compat_vs;
   382                    end) vc_compat_ths vc_compat_vs;
   383                  val (vc_compat_ths1, vc_compat_ths2) =
   383                  val (vc_compat_ths1, vc_compat_ths2) =
   384                    chop (length vc_compat_ths - length sets) vc_compat_ths';
   384                    chop (length vc_compat_ths - length sets) vc_compat_ths';
   385                  val vc_compat_ths1' = map
   385                  val vc_compat_ths1' = map
   386                    (Conv.fconv_rule (Conv.arg_conv (Conv.arg_conv
   386                    (Conv.fconv_rule (Conv.arg_conv (Conv.arg_conv
   414                    th RS the (AList.lookup op = perm_freshs_freshs T))
   414                    th RS the (AList.lookup op = perm_freshs_freshs T))
   415                      (fresh_ths2 ~~ sets);
   415                      (fresh_ths2 ~~ sets);
   416                  val th = Goal.prove ctxt'' [] []
   416                  val th = Goal.prove ctxt'' [] []
   417                    (HOLogic.mk_Trueprop (list_comb (P $ hd ts,
   417                    (HOLogic.mk_Trueprop (list_comb (P $ hd ts,
   418                      map (fold_rev (NominalDatatype.mk_perm []) pis') (tl ts))))
   418                      map (fold_rev (NominalDatatype.mk_perm []) pis') (tl ts))))
   419                    (fn _ => EVERY ([simp_tac (put_simpset eqvt_ss ctxt'') 1, rtac ihyp' 1] @
   419                    (fn _ => EVERY ([simp_tac (put_simpset eqvt_ss ctxt'') 1,
   420                      map (fn th => rtac th 1) fresh_ths3 @
   420                      resolve_tac ctxt'' [ihyp'] 1] @
       
   421                      map (fn th => resolve_tac ctxt'' [th] 1) fresh_ths3 @
   421                      [REPEAT_DETERM_N (length gprems)
   422                      [REPEAT_DETERM_N (length gprems)
   422                        (simp_tac (put_simpset HOL_basic_ss ctxt''
   423                        (simp_tac (put_simpset HOL_basic_ss ctxt''
   423                           addsimps [inductive_forall_def']
   424                           addsimps [inductive_forall_def']
   424                           addsimprocs [NominalDatatype.perm_simproc]) 1 THEN
   425                           addsimprocs [NominalDatatype.perm_simproc]) 1 THEN
   425                         resolve_tac ctxt'' gprems2 1)]));
   426                         resolve_tac ctxt'' gprems2 1)]));
   429                        perm_freshs_freshs') 1);
   430                        perm_freshs_freshs') 1);
   430                  val final' = Proof_Context.export ctxt'' ctxt' [final];
   431                  val final' = Proof_Context.export ctxt'' ctxt' [final];
   431                in resolve_tac ctxt' final' 1 end) context 1])
   432                in resolve_tac ctxt' final' 1 end) context 1])
   432                  (prems ~~ thss ~~ vc_compat' ~~ ihyps ~~ prems'')))
   433                  (prems ~~ thss ~~ vc_compat' ~~ ihyps ~~ prems'')))
   433         in
   434         in
   434           cut_facts_tac [th] 1 THEN REPEAT (etac conjE 1) THEN
   435           cut_facts_tac [th] 1 THEN REPEAT (eresolve_tac ctxt' [conjE] 1) THEN
   435           REPEAT (REPEAT (resolve_tac ctxt' [conjI, impI] 1) THEN
   436           REPEAT (REPEAT (resolve_tac ctxt' [conjI, impI] 1) THEN
   436             etac impE 1 THEN atac 1 THEN REPEAT (etac @{thm allE_Nil} 1) THEN
   437             eresolve_tac ctxt' [impE] 1 THEN
       
   438             assume_tac ctxt' 1 THEN REPEAT (eresolve_tac ctxt' @{thms allE_Nil} 1) THEN
   437             asm_full_simp_tac ctxt 1)
   439             asm_full_simp_tac ctxt 1)
   438         end) |>
   440         end) |>
   439         fresh_postprocess ctxt' |>
   441         fresh_postprocess ctxt' |>
   440         singleton (Proof_Context.export ctxt' ctxt);
   442         singleton (Proof_Context.export ctxt' ctxt);
   441 
   443