Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Isabelle/Archive-of-Formal-Proofs/thys/Nominal2/   (Sammlung formaler Beweise Version 2026-5©)  Datei vom 29.4.2026 mit Größe 4 kB image not shown  

Quelle  nominal_eqvt.ML

  Sprache: SML
 

(*  Title:      nominal_eqvt.ML
    Author:     Stefan Berghofer (original code)
    Author:     Christian Urban
    Author:     Tjark Weber

    Automatic proofs for equivariance of inductive predicates.
*)


signature NOMINAL_EQVT =
sig
  val raw_equivariance: Proof.context -> term list -> thm -> thm list -> thm list
  val equivariance_cmd: string -> Proof.context -> local_theory
end

structure Nominal_Eqvt : NOMINAL_EQVT =
struct

open Nominal_Permeq;
open Nominal_ThmDecls;

fun atomize_conv ctxt =
  Simplifier.rewrite_cterm (truefalsefalse) (K (K NONE))
    (put_simpset HOL_basic_ss ctxt addsimps @{thms induct_atomize})

fun atomize_intr ctxt = Conv.fconv_rule (Conv.prems_conv ~1 (atomize_conv ctxt))

fun atomize_induct ctxt = Conv.fconv_rule (Conv.prems_conv ~1
  (Conv.params_conv ~1 (Conv.prems_conv ~1 o atomize_conv) ctxt))


(** equivariance tactics **)

fun eqvt_rel_single_case_tac ctxt pred_names pi intro =
  let
    val cpi = Thm.cterm_of ctxt pi
    val pi_intro_rule = Thm.instantiate' [] [NONE, SOME cpi] @{thm permute_boolI}
    val eqvt_sconfig = eqvt_strict_config addexcls pred_names
  in
    eqvt_tac ctxt eqvt_sconfig THEN'
    SUBPROOF (fn {prems, context = goal_ctxt, ...} =>
      let
        val simps1 =
          put_simpset HOL_basic_ss goal_ctxt addsimps @{thms permute_fun_def permute_self split_paired_all}
        val simps2 =
          put_simpset HOL_basic_ss goal_ctxt addsimps @{thms permute_bool_def permute_minus_cancel(2)}
        val prems' = map (transform_prem2 goal_ctxt pred_names) prems
        val prems'' = map (fn thm => eqvt_rule goal_ctxt eqvt_sconfig (thm RS pi_intro_rule)) prems'
        val prems''' = map (simplify simps2 o simplify simps1) prems''
      in
        HEADGOAL (resolve_tac goal_ctxt [intro] THEN_ALL_NEW
          resolve_tac goal_ctxt (prems' @ prems'' @ prems'''))
      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' ((DETERM o resolve_tac ctxt [induct]) :: cases)
  end


(** equivariance procedure **)

fun prepare_goal ctxt pi pred_with_args =
  let
    val (c, xs) = strip_comb pred_with_args
    fun is_nonfixed_Free (Free (s, _)) = not (Variable.is_fixed ctxt s)
      | is_nonfixed_Free _ = false
    fun mk_perm_nonfixed_Free t =
      if is_nonfixed_Free t then mk_perm pi t else t
  in
    HOLogic.mk_imp (pred_with_args,
      list_comb (c, map mk_perm_nonfixed_Free xs))
  end

fun name_of (Const (s, _)) = s

fun raw_equivariance ctxt preds raw_induct intrs =
  let
    (* FIXME: polymorphic predicates should either be rejected or
              specialized to arguments of sort pt *)


    val is_already_eqvt = filter (is_eqvt ctxt) preds
    val _ = if null is_already_eqvt then ()
      else error ("Already equivariant: " ^ commas
        (map (Syntax.string_of_term ctxt) is_already_eqvt))

    val pred_names = map (name_of o head_of) preds
    val raw_induct' = atomize_induct ctxt raw_induct
    val intrs' = map (atomize_intr ctxt) intrs

    val (([raw_concl], [raw_pi]), ctxt') =
      ctxt
      |> Variable.import_terms false [Thm.concl_of raw_induct']
      ||>> Variable.variant_fixes ["p"]
    val pi = Free (raw_pi, \<^Type>\<open>perm\<close>)

    val preds_with_args = raw_concl
      |> HOLogic.dest_Trueprop
      |> HOLogic.dest_conj
      |> map (fst o HOLogic.dest_imp)

    val goal = preds_with_args
      |> map (prepare_goal ctxt pi)
      |> foldr1 HOLogic.mk_conj
      |> HOLogic.mk_Trueprop
  in
    Goal.prove ctxt' [] [] goal
      (fn {context = goal_ctxt, ...} => eqvt_rel_tac goal_ctxt pred_names pi raw_induct' intrs' 1)
      |> Old_Datatype_Aux.split_conj_thm
      |> Proof_Context.export ctxt' ctxt
      |> map (fn th => th RS mp)
      |> map zero_var_indexes
  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 ((_, [thm']), ctxt') = Local_Theory.note ((thm_name, @{attributes [eqvt]}), [thm]) ctxt
  in
    (thm', ctxt')
  end


(** equivariance command **)

fun equivariance_cmd pred_name ctxt =
  let
    val ({names, ...}, {preds, raw_induct, intrs, ...}) =
      Inductive.the_inductive_global ctxt (long_name ctxt pred_name)
    val thms = raw_equivariance ctxt preds raw_induct intrs
  in
    fold_map note_named_thm (names ~~ thms) ctxt |> snd
  end

val _ =
  Outer_Syntax.local_theory @{command_keyword equivariance}
    "Proves equivariance for inductive predicate involving nominal datatypes."
      (Parse.const >> equivariance_cmd)

end (* structure *)

Messung V0.5 in Prozent
C=93 H=99 G=95

¤ Dauer der Verarbeitung: 0.2 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.