src/HOL/Nominal/nominal_inductive.ML
changeset 22788 3038bd211582
parent 22755 e268f608669a
child 22901 481cd919c47f
equal deleted inserted replaced
22787:85e7e32e6004 22788:3038bd211582
    52 fun prove_strong_ind s avoids thy =
    52 fun prove_strong_ind s avoids thy =
    53   let
    53   let
    54     val ctxt = ProofContext.init thy;
    54     val ctxt = ProofContext.init thy;
    55     val ({names, ...}, {raw_induct, ...}) =
    55     val ({names, ...}, {raw_induct, ...}) =
    56       InductivePackage.the_inductive ctxt (Sign.intern_const thy s);
    56       InductivePackage.the_inductive ctxt (Sign.intern_const thy s);
       
    57     val eqvt_thms = NominalThmDecls.get_eqvt_thms thy;
       
    58     val _ = (case names \\ foldl (apfst prop_of #> add_term_consts) [] eqvt_thms of
       
    59         [] => ()
       
    60       | xs => error ("Missing equivariance theorem for predicate(s): " ^
       
    61           commas_quote xs));
    57     val induct_cases = map fst (fst (RuleCases.get (the
    62     val induct_cases = map fst (fst (RuleCases.get (the
    58       (InductAttrib.lookup_inductS ctxt (hd names)))));
    63       (InductAttrib.lookup_inductS ctxt (hd names)))));
    59     val raw_induct' = Logic.unvarify (prop_of raw_induct);
    64     val raw_induct' = Logic.unvarify (prop_of raw_induct);
    60     val concls = raw_induct' |> Logic.strip_imp_concl |> HOLogic.dest_Trueprop |>
    65     val concls = raw_induct' |> Logic.strip_imp_concl |> HOLogic.dest_Trueprop |>
    61       HOLogic.dest_conj |> map (HOLogic.dest_imp ##> strip_comb);
    66       HOLogic.dest_conj |> map (HOLogic.dest_imp ##> strip_comb);
   166         (mk_distinct bvars @
   171         (mk_distinct bvars @
   167          maps (fn (t, T) => map (fn (u, U) => HOLogic.mk_Trueprop
   172          maps (fn (t, T) => map (fn (u, U) => HOLogic.mk_Trueprop
   168            (Const ("Nominal.fresh", U --> T --> HOLogic.boolT) $ u $ t)) bvars)
   173            (Const ("Nominal.fresh", U --> T --> HOLogic.boolT) $ u $ t)) bvars)
   169              (ts ~~ binder_types (fastype_of p)))) prems;
   174              (ts ~~ binder_types (fastype_of p)))) prems;
   170 
   175 
   171     val eqvt_ss = HOL_basic_ss addsimps NominalThmDecls.get_eqvt_thms thy;
   176     val eqvt_ss = HOL_basic_ss addsimps eqvt_thms;
   172     val fresh_bij = PureThy.get_thms thy (Name "fresh_bij");
   177     val fresh_bij = PureThy.get_thms thy (Name "fresh_bij");
   173     val perm_bij = PureThy.get_thms thy (Name "perm_bij");
   178     val perm_bij = PureThy.get_thms thy (Name "perm_bij");
   174     val fs_atoms = map (fn aT => PureThy.get_thm thy
   179     val fs_atoms = map (fn aT => PureThy.get_thm thy
   175       (Name ("fs_" ^ Sign.base_name (fst (dest_Type aT)) ^ "1"))) atomTs;
   180       (Name ("fs_" ^ Sign.base_name (fst (dest_Type aT)) ^ "1"))) atomTs;
   176     val exists_fresh' = PureThy.get_thms thy (Name "exists_fresh'");
   181     val exists_fresh' = PureThy.get_thms thy (Name "exists_fresh'");
   317   end;
   322   end;
   318 
   323 
   319 fun prove_eqvt s xatoms thy =
   324 fun prove_eqvt s xatoms thy =
   320   let
   325   let
   321     val ctxt = ProofContext.init thy;
   326     val ctxt = ProofContext.init thy;
   322     val ({names, ...}, {raw_induct, intrs, ...}) =
   327     val ({names, ...}, {raw_induct, intrs, elims, ...}) =
   323       InductivePackage.the_inductive ctxt (Sign.intern_const thy s);
   328       InductivePackage.the_inductive ctxt (Sign.intern_const thy s);
       
   329     val intrs' = InductivePackage.unpartition_rules intrs
       
   330       (map (fn (((s, ths), (_, k)), th) =>
       
   331            (s, ths ~~ InductivePackage.infer_intro_vars th k ths))
       
   332          (InductivePackage.partition_rules raw_induct intrs ~~
       
   333           InductivePackage.arities_of raw_induct ~~ elims));
   324     val atoms' = NominalAtoms.atoms_of thy;
   334     val atoms' = NominalAtoms.atoms_of thy;
   325     val atoms =
   335     val atoms =
   326       if null xatoms then atoms' else
   336       if null xatoms then atoms' else
   327       let val atoms = map (Sign.intern_type thy) xatoms
   337       let val atoms = map (Sign.intern_type thy) xatoms
   328       in
   338       in
   337     val eqvt_ss = HOL_basic_ss addsimps NominalThmDecls.get_eqvt_thms thy;
   347     val eqvt_ss = HOL_basic_ss addsimps NominalThmDecls.get_eqvt_thms thy;
   338     val t = Logic.unvarify (concl_of raw_induct);
   348     val t = Logic.unvarify (concl_of raw_induct);
   339     val pi = Name.variant (add_term_names (t, [])) "pi";
   349     val pi = Name.variant (add_term_names (t, [])) "pi";
   340     val ps = map (fst o HOLogic.dest_imp)
   350     val ps = map (fst o HOLogic.dest_imp)
   341       (HOLogic.dest_conj (HOLogic.dest_Trueprop t));
   351       (HOLogic.dest_conj (HOLogic.dest_Trueprop t));
   342     fun eqvt_tac th intr st =
   352     fun eqvt_tac th pi (intr, vs) st =
   343       let
   353       let
   344         fun eqvt_err s = error
   354         fun eqvt_err s = error
   345           ("Could not prove equivariance for introduction rule\n" ^
   355           ("Could not prove equivariance for introduction rule\n" ^
   346            Sign.string_of_term (theory_of_thm intr)
   356            Sign.string_of_term (theory_of_thm intr)
   347              (Logic.unvarify (prop_of intr)) ^ "\n" ^ s);
   357              (Logic.unvarify (prop_of intr)) ^ "\n" ^ s);
   348         val res = SUBPROOF (fn {prems, ...} =>
   358         val res = SUBPROOF (fn {prems, params, ...} =>
   349           let val prems' = map (fn th' => Simplifier.simplify eqvt_ss
   359           let
   350             (if null (names inter term_consts (prop_of th')) then th' RS th
   360             val prems' = map (fn th' => Simplifier.simplify eqvt_ss
   351              else th')) prems
   361               (if null (names inter term_consts (prop_of th')) then th' RS th
   352             (* FIXME: instantiate intr? *)
   362                else th')) prems;
   353           in (rtac intr THEN_ALL_NEW resolve_tac prems') 1
   363             val intr' = Drule.cterm_instantiate (map (cterm_of thy) vs ~~
       
   364                map (cterm_of thy o NominalPackage.mk_perm [] pi o term_of) params)
       
   365                intr
       
   366           in (rtac intr' THEN_ALL_NEW (TRY o resolve_tac prems')) 1
   354           end) ctxt 1 st
   367           end) ctxt 1 st
   355       in
   368       in
   356         case (Seq.pull res handle THM (s, _, _) => eqvt_err s) of
   369         case (Seq.pull res handle THM (s, _, _) => eqvt_err s) of
   357           NONE => eqvt_err ("Rule does not match goal\n" ^
   370           NONE => eqvt_err ("Rule does not match goal\n" ^
   358             Sign.string_of_term (theory_of_thm st) (hd (prems_of st)))
   371             Sign.string_of_term (theory_of_thm st) (hd (prems_of st)))
   366       in map (fn th => zero_var_indexes (th RS mp))
   379       in map (fn th => zero_var_indexes (th RS mp))
   367         (DatatypeAux.split_conj_thm (Goal.prove_global thy [] []
   380         (DatatypeAux.split_conj_thm (Goal.prove_global thy [] []
   368           (HOLogic.mk_Trueprop (foldr1 HOLogic.mk_conj (map (fn p =>
   381           (HOLogic.mk_Trueprop (foldr1 HOLogic.mk_conj (map (fn p =>
   369             HOLogic.mk_imp (p, list_comb
   382             HOLogic.mk_imp (p, list_comb
   370              (apsnd (map (NominalPackage.mk_perm [] pi')) (strip_comb p)))) ps)))
   383              (apsnd (map (NominalPackage.mk_perm [] pi')) (strip_comb p)))) ps)))
   371           (fn _ => EVERY (rtac raw_induct 1 :: map (fn intr =>
   384           (fn _ => EVERY (rtac raw_induct 1 :: map (fn intr_vs =>
   372               full_simp_tac eqvt_ss 1 THEN eqvt_tac perm_boolI' intr) intrs))))
   385               full_simp_tac eqvt_ss 1 THEN
       
   386               eqvt_tac perm_boolI' pi' intr_vs) intrs'))))
   373       end) atoms
   387       end) atoms
   374   in
   388   in
   375     fold (fn (name, ths) =>
   389     fold (fn (name, ths) =>
   376       Theory.add_path (Sign.base_name name) #>
   390       Theory.add_path (Sign.base_name name) #>
   377       PureThy.add_thmss [(("eqvt", ths), [NominalThmDecls.eqvt_add])] #> snd #>
   391       PureThy.add_thmss [(("eqvt", ths), [NominalThmDecls.eqvt_add])] #> snd #>