theory utp_subst imports
utp_expr
utp_unrest begin
subsection‹ Substitution definitions ›
text‹ Variable substitution, like unrestriction, will be characterised semantically using lenses
and state-spaces. Effectively a substitution $\sigma$ is simply a function on the state-space which
can be applied to an expression $e$ using the syntax $\sigma\mathop{\dagger} e$. We introduce
a polymorphic constant that will be used to represent application of a substitution, and also a
set of theorems to represent laws. ›
consts
usubst :: "'s ==> 'a ==> 'b" (infixr‹†›80)
named_theorems usubst
text‹ A substitution is simply a transformation on the alphabet; it shows how variables
should be mapped to different values. Most of the time these will be homogeneous functions
but for flexibility we also allow some operations to be heterogeneous. ›
text‹ Application of a substitution simply applies the function $\sigma$ to the state binding
$b$ before it is handed to $e$ as an input. This effectively ensures all variables are updated
in $e$. ›
lift_definition subst :: "('α, 'β) psubst ==> ('a, 'β) uexpr ==> ('a, 'α) uexpr"is "λ σ e b. e (σ b)" .
adhoc_overloading
usubst ⇌ subst
text‹ Substitutions can be updated by associating variables with expressions. We thus create an
additional polymorphic constant to represent updating the value of a variable to an expression
in a substitution, where the variable is modelled by type @{typ "'v"}. This again allows us
to support different notions of variables, such as deep variables, later. ›
text‹ The following function takes a substitution form state-space @{typ "'α"} to @{typ "'β"}, a
lens with source @{typ "'β"} and view "'a", and an expression over @{typ "'α"} and returning
a value of type "@{typ "'a"}, and produces an updated substitution. It does this by constructing
a substitution function that takes state binding $b$, and updates the state first by applying
the original substitution $\sigma$, and then updating the part of the state associated with lens
$x$ with expression evaluated in the context of $b$. This effectively means that $x$ is now
associated with expression $v$. We add this definition to our overloaded constant. ›
definition subst_upd_uvar :: "('α,'β) psubst ==> ('a ==> 'β) ==> ('a, 'α) uexpr ==> ('α,'β) psubst"where "subst_upd_uvar σ x v = (λ b. put (σ b) ([v]eb))"
adhoc_overloading
subst_upd ⇌ subst_upd_uvar
text‹ The next function looks up the expression associated with a variable in a substitution
by use of the \emph{get} lens function. ›
lift_definition usubst_lookup :: "('α,'β) psubst ==> ('a ==> 'β) ==> ('a, 'α) uexpr" (‹⟨_⟩s›) is"λ σ x b. get (σ b)" .
text‹ Substitutions also exhibit a natural notion of unrestriction which states that $\sigma$
does not restrict $x$ if application of $\sigma$ to an arbitrary state $\rho$ will not effect
the valuation of $x$. Put another way, it requires that \emph{put} and the substitution commute. ›
definition unrest_usubst :: "('a ==> 'α) ==> 'α usubst ==> bool" where"unrest_usubst x σ = (∀ ρ v. σ (put ρ v) = put (σ ρ) v)"
adhoc_overloading
unrest ⇌ unrest_usubst
text‹ A conditional substitution deterministically picks one of the two substitutions based on a
Booolean expression which is evaluated on the present state-space. It is analogous to a functional
if-then-else. ›
definition cond_subst :: "'α usubst ==> (bool, 'α) uexpr ==> 'α usubst ==> 'α usubst" (‹(3_ ◃ _ ▹s/ _)› [52,0,53] 52) where "cond_subst σ b ρ = (λ s. if [b]e s then σ(s) else ρ(s))"
text‹ Parallel substitutions allow us to divide the state space into three segments using two
lens, A and B. They correspond to the part of the state that should be updated by the
respective substitution. The two lenses should be independent. If any part of the state
is not covered by either lenses then this area is left unchanged (framed). ›
definition par_subst :: "'α usubst ==> ('a ==> 'α) ==> ('b ==> 'α) ==> 'α usubst ==> 'α usubst"where "par_subst σ1 A B σ2 = (λ s. (s ⊕L (σ1 s) on A) ⊕L (σ2 s) on B)"
subsection‹ Syntax translations ›
text‹ We support two kinds of syntax for substitutions, one where we construct a substitution
using a maplet-style syntax, with variables mapping to expressions. Such a constructed substitution
can be applied to an expression. Alternatively, we support the more traditional notation,
$P \llbracket v / x \rrbracket$, which also support multiple simultaneous substitutions. We
have to use double square brackets as the single ones are already well used.
We set up non-terminals to represent a single substitution maplet, a sequence of maplets, a
list of expressions, and a list of alphabets. The parser effectively uses @{term subst_upd}
to construct substitutions from multiple variables. ›
nonterminal smaplet and smaplets and uexp and uexprs and salphas
translations "_SubstUpd m (_SMaplets xy ms)" == "_SubstUpd (_SubstUpd m xy) ms" "_SubstUpd m (_smaplet x y)" == "CONST subst_upd m x y" "_Subst ms" == "_SubstUpd (CONST id) ms" "_Subst (_SMaplets ms1 ms2)" <= "_SubstUpd (_Subst ms1) ms2" "_SMaplets ms1 (_SMaplets ms2 ms3)" <= "_SMaplets (_SMaplets ms1 ms2) ms3" "_subst P es vs" => "CONST subst (_psubst (CONST id) vs es) P" "_psubst m (_salphas x xs) (_uexprs v vs)" => "_psubst (_psubst m x v) xs vs" "_psubst m x v" => "CONST subst_upd m x v" "_subst P v x" <= "CONST usubst (CONST subst_upd (CONST id) x v) P" "_subst P v x" <= "_subst P (_spvar x) v" "_par_subst σ1 A B σ2" == "CONST par_subst σ1 A B σ2" "_uexp_l e" => "e"
text‹ Thus we can write things like @{term "σ(x ↦s v)"} to update a variable $x$ in $\sigma$ with
expression $v$, @{term "[x ↦s e, y ↦s f]"} to construct a substitution with two variables,
and finally @{term "P[v/x]"}, the traditional syntax.
We can now express deletion of a substitution maplet. ›
text‹ We set up a simple substitution tactic that applies substitution and unrestriction laws ›
method subst_tac = (simp add: usubst unrest)?
text‹ Evaluation of a substitution expression involves application of the substitution to different
variables. Thus we first prove laws for these cases. The simplest substitution, $id$, when applied
to any variable $x$ simply returns the variable expression, since $id$ has no effect. ›
lemma usubst_lookup_id [usubst]: "⟨id⟩s x = var x" by (transfer, simp)
lemma subst_upd_id_lam [usubst]: "subst_upd (λ x. x) x v = subst_upd id x v" by (simp add: id_def)
text‹ A substitution update naturally yields the given expression. ›
lemma usubst_lookup_upd [usubst]: assumes"weak_lens x" shows"⟨σ(x ↦s v)⟩s x = v" using assms by (simp add: subst_upd_uvar_def, transfer) (simp)
lemma usubst_upd_idem [usubst]: assumes"mwb_lens x" shows"σ(x ↦s u, x ↦s v) = σ(x ↦s v)" by (simp add: subst_upd_uvar_def assms comp_def)
lemma usubst_upd_idem_sub [usubst]: assumes"x ⊆L y""mwb_lens y" shows"σ(x ↦s u, y ↦s v) = σ(y ↦s v)" by (simp add: subst_upd_uvar_def assms comp_def fun_eq_iff sublens_put_put)
text‹ Substitution updates commute when the lenses are independent. ›
lemma usubst_upd_comm: assumes"x ⋈ y" shows"σ(x ↦s u, y ↦s v) = σ(y ↦s v, x ↦s u)" using assms by (rule_tac ext, auto simp add: subst_upd_uvar_def assms comp_def lens_indep_comm)
lemma usubst_upd_comm2: assumes"z ⋈ y" shows"σ(x ↦s u, y ↦s v, z ↦s s) = σ(x ↦s u, z ↦s s, y ↦s v)" using assms by (rule_tac ext, auto simp add: subst_upd_uvar_def assms comp_def lens_indep_comm)
text‹ A substitution which swaps two independent variables is an injective function. ›
lemma swap_usubst_inj: fixes x y :: "('a ==> 'α)" assumes"vwb_lens x""vwb_lens y""x ⋈ y" shows"inj [x ↦s &y, y ↦s &x]" proof (rule injI) fix b1 :: 'α and b2 :: 'α assume"[x ↦s &y, y ↦s &x] b1 = [x ↦s &y, y ↦s &x] b2" hence a: "put (put b1 ([&y]e b1)) ([&x]e b1) = put (put b2 ([&y]e b2)) ([&xtyle='font-size: 18px;'>]e b2)" by (auto simp add: subst_upd_uvar_def) thenhave"(∀a b c. put (put a b) c = put (put a c) b) ∧ (∀a b. get (put a b) = get a) ∧ (∀a b. get (put a b) = get a)" by (simp add: assms(3) lens_indep.lens_put_irr2 lens_indep_comm) thenshow"b1 = b2" by (metis a assms(1) assms(2) pr_var_def var.rep_eq vwb_lens.source_determination vwb_lens_def wb_lens_def weak_lens.put_get) qed
text‹ We now prove the key laws that show how a substitution should be performed for every
expression operator, including the core function operators, literals, variables, and the
arithmetic operators. They are all added to the \emph{usubst} theorem attribute so that
we can apply them using the substitution tactic. ›
lemma id_subst [usubst]: "id † v = v" by (transfer, simp)
lemma subst_lit [usubst]: "σ †«v¬ = «v¬" by (transfer, simp)
lemma subst_var [usubst]: "σ † var x = ⟨σ⟩s x" by (transfer, simp)
lemma usubst_ulambda [usubst]: "σ † (λ x ∙ P(x)) = (λ x ∙ σ † P(x))" by (transfer, simp)
lemma unrest_usubst_del [unrest]: "[ vwb_lens x; x ♯ (⟨σ⟩s x); x ♯ σ -s x ]==> x ♯ (σ † P)" by (simp add: subst_del_def subst_upd_uvar_def unrest_uexpr_def unrest_usubst_def subst.rep_eq usubst_lookup.rep_eq)
(metis vwb_lens.put_eq)
text‹ We add the symmetric definition of input and output variables to substitution laws
so that the variables are correctly normalised after substitution. ›
lemma subst_uop [usubst]: "σ † uop f v = uop f (σ † v)" by (transfer, simp)
lemma subst_bop [usubst]: "σ † bop f u v = bop f (σ † u) (σ † v)" by (transfer, simp)
lemma subst_trop [usubst]: "σ † trop f u v w = trop f (σ † u) (σ † v) (σ † w)" by (transfer, simp)
lemma subst_qtop [usubst]: "σ † qtop f u v w x = qtop f (σ † u) (σ † v) (σ † w) (σ † x)" by (transfer, simp)
lemma subst_case_prod [usubst]: fixes P :: "'i ==> 'j ==> ('a, 'α) uexpr" shows"σ † case_prod (λ x y. P x y) v = case_prod (λ x y. σ † P x y) v" by (simp add: case_prod_beta')
text‹ A simplification procedure to reorder substitutions maplets lexicographically by variable syntax ›
simproc_setup subst_order ("subst_upd_uvar (subst_upd_uvar σ x u) y v") = ‹(fn _ => fn ctxt => fn ct =>
case (Thm.term_of ct) of
Const ("utp_subst.subst_upd_uvar", _) $ (Const ("utp_subst.subst_upd_uvar", _) $ s $ x $ u) $ y $ v
=> if (Protocol_Message.clean_output (Syntax.string_of_term ctxt x) > Protocol_Message.clean_output(Syntax.string_of_term ctxt y))
then SOME (mk_meta_eq @{thm usubst_upd_comm})
else NONE |
_ => NONE) ›
subsection‹ Unrestriction laws ›
text‹ These are the key unrestriction theorems for substitutions and expressions involving substitutions. ›
lemma unrest_usubst_single [unrest]: "[ mwb_lens x; x ♯ v ]==> x ♯ P[v/x]" by (transfer, auto simp add: subst_upd_uvar_def unrest_uexpr_def)
lemma unrest_usubst_id [unrest]: "mwb_lens x ==> x ♯ id" by (simp add: unrest_usubst_def)
lemma unrest_usubst_upd [unrest]: "[ x ⋈ y; x ♯ σ; x ♯ v ]==> x ♯ σ(y ↦s v)" by (simp add: subst_upd_uvar_def unrest_usubst_def unrest_uexpr.rep_eq lens_indep_comm)
lemma unrest_subst [unrest]: "[ x ♯ P; x ♯ σ ]==> x ♯ (σ † P)" by (transfer, simp add: unrest_usubst_def)
subsection‹ Conditional Substitution Laws ›
lemma usubst_cond_upd_1 [usubst]: "σ(x ↦s u) ◃ b ▹s ρ(x ↦s v) = (σ ◃ b ▹s ρ)(x ↦s u ◃ b ▹ v)" by (simp add: cond_subst_def subst_upd_uvar_def uexpr_defs, transfer, auto)
lemma usubst_cond_upd_2 [usubst]: "[ vwb_lens x; x ♯ ρ ]==> σ(x ↦s u) ◃ b ▹s ρ = (σ ◃ b ▹s ρ)(x ↦s u ◃ b ▹ &x)" by (simp add: cond_subst_def subst_upd_uvar_def unrest_usubst_def uexpr_defs, transfer)
(metis (full_types, opaque_lifting) id_apply pr_var_def subst_upd_uvar_def usubst_upd_pr_var_id var.rep_eq)
lemma usubst_cond_upd_3 [usubst]: "[ vwb_lens x; x ♯ σ ]==> σ ◃ b ▹s ρ(x ↦s v) = (σ ◃ b ▹s ρ)(x ↦s &x ◃ b ▹ v)" by (simp add: cond_subst_def subst_upd_uvar_def unrest_usubst_def uexpr_defs, transfer)
(metis (full_types, opaque_lifting) id_apply pr_var_def subst_upd_uvar_def usubst_upd_pr_var_id var.rep_eq)
lemma usubst_cond_id [usubst]: "σ ◃ b ▹s σ = σ" by (auto simp add: cond_subst_def)
subsection‹ Parallel Substitution Laws ›
lemma par_subst_id [usubst]: "[ vwb_lens A; vwb_lens B ]==> id [A|B]s id = id" by (simp add: par_subst_def id_def)
lemma par_subst_left_empty [usubst]: "[ vwb_lens A ]==> σ [∅|A]s ρ = id [∅|A]s ρ" by (simp add: par_subst_def pr_var_def)
lemma par_subst_right_empty [usubst]: "[ vwb_lens A ]==> σ [A|∅]s ρ = σ [A|∅]s id" by (simp add: par_subst_def pr_var_def)
lemma par_subst_comm: "[ A ⋈ B ]==> σ [A|B]s ρ = ρ [B|A]s σ" by (simp add: par_subst_def lens_override_def lens_indep_comm)
lemma par_subst_upd_left_in [usubst]: "[ vwb_lens A; A ⋈ B; x ⊆L A ]==> σ(x ↦s v) [A|B]s ρ = (σ [A|B]s ρ)(x ↦s v)" by (simp add: par_subst_def subst_upd_uvar_def lens_override_put_right_in)
(simp add: lens_indep_comm lens_override_def sublens_pres_indep)
lemma par_subst_upd_left_out [usubst]: "[ vwb_lens A; x ⋈ A ]==> σ(x ↦s v) [A|B]s ρ = (σ [A|B]s ρ)" by (simp add: par_subst_def subst_upd_uvar_def lens_override_put_right_out)
lemma par_subst_upd_right_in [usubst]: "[ vwb_lens B; A ⋈ B; x ⊆L B ]==> σ [A|B]s ρ(x ↦s v) = (σ [A|B]s ρ)(x ↦s v)" using lens_indep_sym par_subst_comm par_subst_upd_left_in by fastforce
lemma par_subst_upd_right_out [usubst]: "[ vwb_lens B; A ⋈ B; x ⋈ B ]==> σ [A|B]s ρ(x ↦s v) = (σ [A|B]s ρ)" by (simp add: par_subst_comm par_subst_upd_left_out)
end
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.18 Sekunden
(vorverarbeitet am 2026-06-10)
¤
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.