diff -r 41137dc935ff -r 8193bbaa07fe Nominal-General/nominal_eqvt.ML --- a/Nominal-General/nominal_eqvt.ML Sun Nov 14 12:09:14 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,142 +0,0 @@ -(* Title: nominal_eqvt.ML - Author: Stefan Berghofer (original code) - Author: Christian Urban - - Automatic proofs for equivariance of inductive predicates. -*) - -signature NOMINAL_EQVT = -sig - val eqvt_rel_tac: Proof.context -> string list -> term -> thm -> thm list -> int -> tactic - val eqvt_rel_single_case_tac: Proof.context -> string list -> term -> thm -> int -> tactic - - val equivariance: bool -> term list -> thm -> thm list -> Proof.context -> thm list * local_theory - val equivariance_cmd: string -> Proof.context -> local_theory -end - -structure Nominal_Eqvt : NOMINAL_EQVT = -struct - -open Nominal_Permeq; -open Nominal_ThmDecls; - -val atomize_conv = - MetaSimplifier.rewrite_cterm (true, false, false) (K (K NONE)) - (HOL_basic_ss addsimps @{thms induct_atomize}); -val atomize_intr = Conv.fconv_rule (Conv.prems_conv ~1 atomize_conv); -fun atomize_induct ctxt = Conv.fconv_rule (Conv.prems_conv ~1 - (Conv.params_conv ~1 (K (Conv.prems_conv ~1 atomize_conv)) ctxt)); - - -(** equivariance tactics **) - -val perm_boolE = @{thm permute_boolE} -val perm_cancel = @{thms permute_minus_cancel(2)} - -fun eqvt_rel_single_case_tac ctxt pred_names pi intro = - let - val thy = ProofContext.theory_of ctxt - val cpi = Thm.cterm_of thy (mk_minus pi) - val pi_intro_rule = Drule.instantiate' [] [SOME cpi] perm_boolE - val simps1 = HOL_basic_ss addsimps @{thms permute_fun_def minus_minus split_paired_all} - val simps2 = HOL_basic_ss addsimps @{thms permute_bool_def} - in - eqvt_strict_tac ctxt [] pred_names THEN' - SUBPROOF (fn {prems, context as ctxt, ...} => - let - val prems' = map (transform_prem2 ctxt pred_names) prems - val tac1 = resolve_tac prems' - val tac2 = EVERY' [ rtac pi_intro_rule, - eqvt_strict_tac ctxt perm_cancel pred_names, resolve_tac prems' ] - val tac3 = EVERY' [ rtac pi_intro_rule, - eqvt_strict_tac ctxt perm_cancel pred_names, simp_tac simps1, - simp_tac simps2, resolve_tac prems'] - in - (rtac intro THEN_ALL_NEW FIRST' [tac1, tac2, tac3]) 1 - end) ctxt - end - -fun eqvt_rel_tac ctxt pred_names pi induct intros = - let - val cases = map (eqvt_rel_single_case_tac ctxt pred_names pi) intros - in - EVERY' (rtac induct :: cases) - end - - -(** equivariance procedure *) - -fun prepare_goal pi pred = - let - val (c, xs) = strip_comb pred; - in - HOLogic.mk_imp (pred, list_comb (c, map (mk_perm pi) xs)) - end - -(* stores thm under name.eqvt and adds [eqvt]-attribute *) - -fun note_named_thm (name, thm) ctxt = - let - val thm_name = Binding.qualified_name - (Long_Name.qualify (Long_Name.base_name name) "eqvt") - val attr = Attrib.internal (K eqvt_add) - val ((_, [thm']), ctxt') = Local_Theory.note ((thm_name, [attr]), [thm]) ctxt - in - (thm', ctxt') - end - -fun equivariance note_flag pred_trms raw_induct intrs ctxt = - let - val is_already_eqvt = - filter (is_eqvt ctxt) pred_trms - |> map (Syntax.string_of_term ctxt) - val _ = if null is_already_eqvt then () - else error ("Already equivariant: " ^ commas is_already_eqvt) - - val pred_names = map (fst o dest_Const) pred_trms - val raw_induct' = atomize_induct ctxt raw_induct - val intrs' = map atomize_intr intrs - - val (([raw_concl], [raw_pi]), ctxt') = - ctxt - |> Variable.import_terms false [concl_of raw_induct'] - ||>> Variable.variant_fixes ["p"] - val pi = Free (raw_pi, @{typ perm}) - - val preds = map (fst o HOLogic.dest_imp) - (HOLogic.dest_conj (HOLogic.dest_Trueprop raw_concl)); - - val goal = HOLogic.mk_Trueprop - (foldr1 HOLogic.mk_conj (map (prepare_goal pi) preds)) - - val thms = Goal.prove ctxt' [] [] goal - (fn {context,...} => eqvt_rel_tac context pred_names pi raw_induct' intrs' 1) - |> Datatype_Aux.split_conj_thm - |> ProofContext.export ctxt' ctxt - |> map (fn th => th RS mp) - |> map zero_var_indexes - in - if note_flag - then fold_map note_named_thm (pred_names ~~ thms) ctxt - else (thms, ctxt) - end - -fun equivariance_cmd pred_name ctxt = - let - val thy = ProofContext.theory_of ctxt - val (_, {preds, raw_induct, intrs, ...}) = - Inductive.the_inductive ctxt (Sign.intern_const thy pred_name) - in - equivariance true preds raw_induct intrs ctxt |> snd - end - -local structure P = Parse and K = Keyword in - -val _ = - Outer_Syntax.local_theory "equivariance" - "Proves equivariance for inductive predicate involving nominal datatypes." - K.thy_decl (P.xname >> equivariance_cmd); - -end; - -end (* structure *)