Theory Process_Normalization
chapter ‹ProcOmata: Functional Automata embedded into CSP Processes›
theory Process_Normalization
imports "HOL-CSP_PTick"
begin
text ‹
We will often have to perform induction on both the list of automata
and the list of states, provided that they have the same length.›
lemma induct_2_lists012 [consumes 1, case_names Nil single Cons] :
‹⟦length xs = length ys; P [] []; ⋀x1 y1. P [x1] [y1];
⋀x1 x2 xs y1 y2 ys. length xs = length ys ⟹ P xs ys ⟹
P (x2 # xs) (y2 # ys) ⟹ P (x1 # x2 # xs) (y1 # y2 # ys)⟧
⟹ P xs ys›
by (induct xs arbitrary: ys rule: induct_list012)
(auto simp add: Suc_length_conv length_Suc_conv)
lemma nat_induct_012 [case_names 0 1 2 Suc]:
‹⟦P 0; P (Suc 0); P (Suc (Suc 0)); ⋀k. Suc (Suc 0) ≤ k ⟹ P k ⟹ P (Suc k)⟧ ⟹ P n›
by (metis One_nat_def Suc_1 less_2_cases_iff linorder_not_le nat_induct)
text ‹
The following results will be moved to \<^session>‹Restriction_Spaces› in the future.
›
lemma restriction_shift_iterated :
‹restriction_shift (f ^^ k) (int k * m)›
if ‹restriction_shift f m› for f :: ‹'a ⇒ 'a :: restriction_space›
proof (induct k)
show ‹restriction_shift (f ^^ 0) (int 0 * m)›
by (simp add: restriction_shiftI)
next
fix k assume * : ‹restriction_shift (f ^^ k) (int k * m)›
have ‹restriction_shift (f ^^ Suc k) (int (Suc k) * m) ⟷
restriction_shift (λx. f ((f ^^ k) x)) (int k * m + m)›
by (simp add: comp_def distrib_left mult.commute add.commute)
also have … by (fact restriction_shift_comp_restriction_shift[OF that "*"])
finally show ‹restriction_shift (f ^^ Suc k) (int (Suc k) * m)› .
qed
lemma non_destructive_iterated :
‹non_destructive f ⟹ non_destructive (f ^^ k)›
for f :: ‹'a ⇒ 'a :: restriction_space›
by (metis mult.commute mult_zero_left non_destructive_def non_destructive_on_def
restriction_shift_def restriction_shift_iterated)
lemma constructive_iterated :
‹constructive (f ^^ k)› if ‹0 < k› ‹constructive f›
for f :: ‹'a ⇒ 'a :: restriction_space›
proof -
from ‹constructive f› have ‹restriction_shift f 1›
unfolding constructive_def constructive_on_def restriction_shift_def by blast
with restriction_shift_iterated
have ‹restriction_shift (f ^^ k) (int k * 1)› .
hence ‹restriction_shift (f ^^ k) (int k)› by simp
with ‹0 < k› show ‹constructive (f ^^ k)›
by (metis One_nat_def constructive_def constructive_on_def
less_eq_Suc_le nat_int_comparison(3) of_nat_1_eq_iff
restriction_shift_def restriction_shift_imp_restriction_shift_le )
qed
lemma restriction_fix_unique_iterated :
‹⟦0 < k; constructive f; (f ^^ k) x = x⟧ ⟹ (υ x. f x) = x›
by (metis constructive_iterated funpow_swap1 restriction_fix_unique)
lemma restriction_fix_iterated :
‹0 < k ⟹ constructive f ⟹ (υ x. (f ^^ k) x) = (υ x. f x)›
by (metis constructive_iterated restriction_fix_eq restriction_fix_unique_iterated)
corollary restriction_fix_ind_iterated
[consumes 1, case_names constructive adm base step]:
‹P (υ x. f x)› if ‹0 < k› ‹constructive f› ‹adm⇩↓ P› ‹P x› ‹⋀x. P x ⟹ P ((f ^^ k) x)›
proof -
from constructive_iterated that(1, 2) have ‹constructive (f ^^ k)› .
from restriction_fix_ind[OF this that(3-5)] have ‹P (υ x. (f ^^ k) x)› .
also from restriction_fix_iterated that(1, 2) have ‹(υ x. (f ^^ k) x) = (υ x. f x)› .
finally show ‹P (υ x. f x)› .
qed
section ‹Definitions›
subsection ‹Non-deterministic and deterministic Automata›
unbundle option_type_syntax
type_synonym ('σ, 'a) enabl = ‹'σ ⇒ 'a set›
type_synonym ('σ, 'a, 'σ') trans = ‹'σ ⇒ 'a ⇒ 'σ'›
type_synonym ('σ, 'a) trans⇩d = ‹('σ, 'a, 'σ option) trans›
type_synonym ('σ, 'a) trans⇩n⇩d = ‹('σ, 'a, 'σ set) trans›
record ('σ, 'a, 'σ', 'r) A =
τ :: ‹('σ, 'a, 'σ') trans›
ω :: ‹'σ ⇒ 'r›
type_synonym ('σ, 'a, 'r) A⇩d = ‹('σ, 'a, 'σ option, 'r option) A›
type_synonym ('σ, 'a, 'r, 'α) A⇩d_scheme = ‹('σ, 'a, 'σ option, 'r option, 'α) A_scheme›
type_synonym ('σ, 'a, 'r) A⇩n⇩d = ‹('σ, 'a, 'σ set, 'r set) A›
type_synonym ('σ, 'a, 'r, 'α) A⇩n⇩d_scheme = ‹('σ, 'a, 'σ set, 'r set, 'α) A_scheme›
subsection ‹Enableness›
consts ε :: ‹('σ, 'a, 'σ', 'r', 'α) A_scheme ⇒ ('σ, 'a) enabl›
overloading
ε⇩d ≡ ‹ε :: ('σ, 'a, 'σ option, 'r', 'α) A_scheme ⇒ ('σ, 'a) enabl›
ε⇩n⇩d ≡ ‹ε :: ('σ, 'a, 'σ set, 'r', 'α) A_scheme ⇒ ('σ, 'a) enabl›
begin
fun ε⇩d :: ‹('σ, 'a, 'σ option, 'r', 'α) A_scheme ⇒ ('σ, 'a) enabl›
where ‹ε⇩d A σ = {a. τ A σ a ≠ ◇}›
fun ε⇩n⇩d :: ‹('σ, 'a, 'σ set, 'r', 'α) A_scheme ⇒ ('σ, 'a) enabl›
where ‹ε⇩n⇩d A σ = {a. τ A σ a ≠ {}}›
end
lemmas ε_simps[simp del] = ε⇩d.simps ε⇩n⇩d.simps
subsection ‹States allowing Termination›
consts ρ :: ‹('σ, 'a, 'σ', 'r', 'α) A_scheme ⇒ 'σ set›
overloading
ρ⇩d ≡ ‹ρ :: ('σ, 'a, 'σ', 'r option, 'α) A_scheme ⇒ 'σ set›
ρ⇩n⇩d ≡ ‹ρ :: ('σ, 'a, 'σ', 'r set, 'α) A_scheme ⇒ 'σ set›
begin
fun ρ⇩d :: ‹('σ, 'a, 'σ', 'r option, 'α) A_scheme ⇒ 'σ set›
where ‹ρ⇩d A = {σ. ω A σ ≠ ◇}›
fun ρ⇩n⇩d :: ‹('σ, 'a, 'σ', 'r set, 'α) A_scheme ⇒ 'σ set›
where ‹ρ⇩n⇩d A = {σ. ω A σ ≠ {}}›
end
lemmas ρ_simps[simp del] = ρ⇩d.simps ρ⇩n⇩d.simps
subsection ‹Reachability›
inductive_set ℛ⇩d :: ‹('σ, 'a, 'r, 'α) A⇩d_scheme ⇒ 'σ ⇒ 'σ set›
for A :: ‹('σ, 'a, 'r, 'α) A⇩d_scheme› and σ :: 'σ
where init : ‹σ ∈ ℛ⇩d A σ›
| step : ‹σ' ∈ ℛ⇩d A σ ⟹ ⌊σ''⌋ = τ A σ' a ⟹ σ'' ∈ ℛ⇩d A σ›
inductive_set ℛ⇩n⇩d :: ‹('σ, 'a, 'r, 'α) A⇩n⇩d_scheme ⇒ 'σ ⇒ 'σ set›
for A :: ‹('σ, 'a, 'r, 'α) A⇩n⇩d_scheme› and σ :: 'σ
where init : ‹σ ∈ ℛ⇩n⇩d A σ›
| step : ‹σ' ∈ ℛ⇩n⇩d A σ ⟹ σ'' ∈ τ A σ' a ⟹ σ'' ∈ ℛ⇩n⇩d A σ›
lemma ℛ⇩d_trans: ‹σ'' ∈ ℛ⇩d A σ' ⟹ σ' ∈ ℛ⇩d A σ ⟹ σ'' ∈ ℛ⇩d A σ›
by (induct rule: ℛ⇩d.induct, simp add: ℛ⇩d.init) (meson ℛ⇩d.step)
lemma ℛ⇩n⇩d_trans: ‹σ'' ∈ ℛ⇩n⇩d A σ' ⟹ σ' ∈ ℛ⇩n⇩d A σ ⟹ σ'' ∈ ℛ⇩n⇩d A σ›
by (induct rule: ℛ⇩n⇩d.induct, simp add: ℛ⇩n⇩d.init) (meson ℛ⇩n⇩d.step)
subsection ‹Morphisms›
text ‹
Our morphisms are defined considering that,
except from \<^const>‹τ›, the fields remain unchanged.›
definition from_det_to_ndet ::
‹('σ, 'a, 'r, 'α) A⇩d_scheme ⇒ ('σ, 'a, 'r, 'α) A⇩n⇩d_scheme›
where ‹from_det_to_ndet A ≡
⦇τ = λσ a. case τ A σ a of ⌊σ'⌋ ⇒ {σ'} | ◇ ⇒ {},
ω = λσ. case ω A σ of ⌊r⌋ ⇒ {r} | ◇ ⇒ {}, … = more A⦈›
definition from_ndet_to_det ::
‹('σ, 'a, 'r, 'α) A⇩n⇩d_scheme ⇒ ('σ, 'a, 'r, 'α) A⇩d_scheme›
where ‹from_ndet_to_det A ≡
⦇τ = λσ a. if τ A σ a = {} then ◇ else ⌊THE σ'. σ' ∈ τ A σ a⌋,
ω = λσ. if ω A σ = {} then ◇ else ⌊THE r. r ∈ ω A σ⌋, … = more A⦈›
definition from_σ_to_σs⇩d ::
‹('σ, 'a, 'r, 'α) A⇩d_scheme ⇒ ('σ list, 'a, 'r, 'α) A⇩d_scheme›
where ‹from_σ_to_σs⇩d A ≡
⦇τ = λσs a. case τ A (hd σs) a of ⌊σ'⌋ ⇒ ⌊[σ']⌋ | ◇ ⇒ ◇,
ω = λσs. ω A (hd σs), … = more A⦈›
definition from_σ_to_σs⇩n⇩d ::
‹('σ, 'a, 'r, 'α) A⇩n⇩d_scheme ⇒ ('σ list, 'a, 'r, 'α) A⇩n⇩d_scheme›
where ‹from_σ_to_σs⇩n⇩d A ≡
⦇τ = λσs a. {[σ'] |σ'. σ' ∈ τ A (hd σs) a},
ω = λσs. ω A (hd σs), … = more A⦈›
definition from_σs_to_σ⇩d ::
‹('σ list, 'a, 'r, 'α) A⇩d_scheme ⇒ ('σ, 'a, 'r, 'α) A⇩d_scheme›
where ‹from_σs_to_σ⇩d A ≡
⦇τ = λσ a. case τ A [σ] a of ⌊σs'⌋ ⇒ ⌊hd σs'⌋ | ◇ ⇒ ◇,
ω = λσ. ω A [σ], … = more A⦈›
definition from_σs_to_σ⇩n⇩d ::
‹('σ list, 'a, 'r, 'α) A⇩n⇩d_scheme ⇒ ('σ, 'a, 'r, 'α) A⇩n⇩d_scheme›
where ‹from_σs_to_σ⇩n⇩d A ≡
⦇τ = λσ a. {hd σs' |σs'. σs' ∈ τ A [σ] a},
ω = λσ. ω A [σ], … = more A⦈›
definition from_singl_to_list⇩d ::
‹('σ, 'a, 'r, 'α) A⇩d_scheme ⇒ ('σ list, 'a, 'r list, 'α) A⇩d_scheme›
where ‹from_singl_to_list⇩d A ≡
⦇τ = λσs a. case τ A (hd σs) a of ⌊σ'⌋ ⇒ ⌊[σ']⌋ | ◇ ⇒ ◇,
ω = λσs. case ω A (hd σs) of ⌊r⌋ ⇒ ⌊[r]⌋ | ◇ ⇒ ◇, … = more A⦈›
definition from_singl_to_list⇩n⇩d ::
‹('σ, 'a, 'r, 'α) A⇩n⇩d_scheme ⇒ ('σ list, 'a, 'r list, 'α) A⇩n⇩d_scheme›
where ‹from_singl_to_list⇩n⇩d A ≡
⦇τ = λσs a. {[σ'] |σ'. σ' ∈ τ A (hd σs) a},
ω = λσs. {[r] |r. r ∈ ω A (hd σs)}, … = more A⦈›
definition from_list_to_singl⇩d ::
‹('σ list, 'a, 'r list, 'α) A⇩d_scheme ⇒ ('σ, 'a, 'r, 'α) A⇩d_scheme›
where ‹from_list_to_singl⇩d A ≡
⦇τ = λσ a. case τ A [σ] a of ⌊σs'⌋ ⇒ ⌊hd σs'⌋ | ◇ ⇒ ◇,
ω = λσ. case ω A [σ] of ⌊rs⌋ ⇒ ⌊hd rs⌋ | ◇ ⇒ ◇, … = more A⦈›
definition from_list_to_singl⇩n⇩d ::
‹('σ list, 'a, 'r list, 'α) A⇩n⇩d_scheme ⇒ ('σ, 'a, 'r, 'α) A⇩n⇩d_scheme›
where ‹from_list_to_singl⇩n⇩d A ≡
⦇τ = λσ a. {hd σs' |σs'. σs' ∈ τ A [σ] a},
ω = λσ. {hd rs |rs. rs ∈ ω A [σ]}, … = more A⦈›
lemmas det_ndet_conv_defs = from_det_to_ndet_def from_ndet_to_det_def
and σ_σs_conv_defs = from_σ_to_σs⇩d_def from_σ_to_σs⇩n⇩d_def
from_σs_to_σ⇩d_def from_σs_to_σ⇩n⇩d_def
and singl_list_conv_defs = from_singl_to_list⇩d_def from_singl_to_list⇩n⇩d_def
from_list_to_singl⇩d_def from_list_to_singl⇩n⇩d_def
bundle functional_automata_morphisms_syntax begin
notation from_det_to_ndet (‹⟪_⟫⇩d⇩↪⇩n⇩d› [0])
notation from_ndet_to_det (‹⟪_⟫⇩n⇩d⇩↝⇩d› [0])
notation from_σ_to_σs⇩d (‹⇩d⟪_⟫⇩σ⇩↪⇩σ⇩s› [0])
notation from_σ_to_σs⇩n⇩d (‹⇩n⇩d⟪_⟫⇩σ⇩↪⇩σ⇩s› [0])
notation from_σs_to_σ⇩d (‹⇩d⟪_⟫⇩σ⇩s⇩↝⇩σ› [0])
notation from_σs_to_σ⇩n⇩d (‹⇩n⇩d⟪_⟫⇩σ⇩s⇩↝⇩σ› [0])
notation from_singl_to_list⇩d (‹⇩d⟪_⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t› [0])
notation from_singl_to_list⇩n⇩d (‹⇩n⇩d⟪_⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t› [0])
notation from_list_to_singl⇩d (‹⇩d⟪_⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l› [0])
notation from_list_to_singl⇩n⇩d (‹⇩n⇩d⟪_⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l› [0])
end
unbundle functional_automata_morphisms_syntax
lemma morphisms_A_scheme_more_simps [simp] :
‹more ⟪A⟫⇩d⇩↪⇩n⇩d = more A› ‹more ⟪B⟫⇩n⇩d⇩↝⇩d = more B›
‹more ⇩d⟪C⟫⇩σ⇩↪⇩σ⇩s = more C› ‹more ⇩n⇩d⟪D⟫⇩σ⇩↪⇩σ⇩s = more D›
‹more ⇩d⟪E⟫⇩σ⇩s⇩↝⇩σ = more E› ‹more ⇩n⇩d⟪F⟫⇩σ⇩s⇩↝⇩σ = more F›
‹more ⇩d⟪G⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t = more G› ‹more ⇩n⇩d⟪H⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t = more H›
‹more ⇩d⟪I⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l = more I› ‹more ⇩n⇩d⟪J⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l = more J›
by (simp_all add: det_ndet_conv_defs σ_σs_conv_defs singl_list_conv_defs)
subsection ‹Generic update Functions›
definition update_both where ‹update_both A⇩0 A⇩1 σ⇩0 σ⇩1 e f ≡ f (τ A⇩0 σ⇩0 e) (τ A⇩1 σ⇩1 e)›
definition update_left where ‹update_left A⇩0 σ⇩0 σ⇩1 e f g ≡ f (τ A⇩0 σ⇩0 e) (g σ⇩1)›
definition update_right where ‹update_right A⇩1 σ⇩0 σ⇩1 e f g ≡ f (g σ⇩0) (τ A⇩1 σ⇩1 e)›
lemmas update_defs[simp] = update_both_def update_left_def update_right_def
abbreviation f_up_set where ‹f_up_set f B C ≡ {f s t| s t. (s, t) ∈ B × C}›
abbreviation f_up_opt where ‹f_up_opt f s t ≡ case s of ◇ ⇒ ◇ | ⌊s'⌋ ⇒ map_option (f s') t›
subsection ‹Assumptions on Automata›
definition finite_trans :: ‹('σ, 'a, 'r, 'α) A⇩n⇩d_scheme ⇒ bool›
where ‹finite_trans A ≡ ∀σ a. finite (τ A σ a)›
lemma finite_trans_morphisms_simps[simp]:
‹finite_trans ⟪A⟫⇩d⇩↪⇩n⇩d›
‹finite_trans B ⟹ finite_trans ⇩n⇩d⟪B⟫⇩σ⇩↪⇩σ⇩s›
‹finite_trans C ⟹ finite_trans ⇩n⇩d⟪C⟫⇩σ⇩s⇩↝⇩σ›
‹finite_trans D ⟹ finite_trans ⇩n⇩d⟪D⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t›
‹finite_trans E ⟹ finite_trans ⇩n⇩d⟪E⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l›
unfolding det_ndet_conv_defs σ_σs_conv_defs singl_list_conv_defs finite_trans_def
by (simp_all add: option.case_eq_if)
definition at_most_1_elem :: ‹('σ, 'a, 'r, 'α) A⇩n⇩d_scheme ⇒ bool›
where ‹at_most_1_elem A ≡
(∀σ a. τ A σ a = {} ∨ (∃σ'. τ A σ a = {σ'})) ∧
(∀σ. ω A σ = {} ∨ (∃r. ω A σ = {r}))›
lemma at_most_1_elem_def_bis :
‹at_most_1_elem A ⟷ (∀σ a. ∃σ'. τ A σ a ⊆ {σ'}) ∧ (∀σ. ∃r. ω A σ ⊆ {r})›
by (auto simp add: at_most_1_elem_def subset_iff)
(((metis empty_iff singleton_iff)+)[2],
((metis equals0D is_singletonI' is_singleton_some_elem)+)[2])
lemma at_most_1_elemI :
‹⟦⋀σ a. τ A σ a = {} ∨ (∃σ'. τ A σ a = {σ'});
⋀σ. ω A σ = {} ∨ (∃r. ω A σ = {r})⟧ ⟹ at_most_1_elem A›
by (simp add: at_most_1_elem_def)
lemma at_most_1_elemE :
‹⟦τ A σ a = {} ⟹ thesis; ⋀σ'. τ A σ a = {σ'} ⟹ thesis⟧ ⟹ thesis›
‹⟦ω A σ = {} ⟹ thesis; ⋀r. ω A σ = {r} ⟹ thesis⟧ ⟹ thesis›
if ‹at_most_1_elem A›
by (meson at_most_1_elem_def ‹at_most_1_elem A›)+
definition at_most_1_elem_trans :: ‹('σ, 'a, 'r, 'α) A⇩n⇩d_scheme ⇒ bool›
where ‹at_most_1_elem_trans A ≡ ∀σ a. τ A σ a = {} ∨ (∃σ'. τ A σ a = {σ'})›
lemma at_most_1_elem_trans_def_bis :
‹at_most_1_elem_trans A ⟷ (∀σ a. ∃σ'. τ A σ a ⊆ {σ'})›
by (auto simp add: at_most_1_elem_trans_def subset_iff)
(metis empty_iff singleton_iff,
metis equals0D is_singletonI' is_singleton_some_elem)
lemma at_most_1_elem_transI :
‹⟦⋀σ a. τ A σ a = {} ∨ (∃σ'. τ A σ a = {σ'})⟧ ⟹ at_most_1_elem_trans A›
by (simp add: at_most_1_elem_trans_def)
lemma at_most_1_elem_transE :
‹⟦τ A σ a = {} ⟹ thesis; ⋀σ'. τ A σ a = {σ'} ⟹ thesis⟧ ⟹ thesis›
if ‹at_most_1_elem_trans A›
by (meson at_most_1_elem_trans_def ‹at_most_1_elem_trans A›)+
lemma at_most_1_elem_imp_at_most_1_elem_trans :
‹at_most_1_elem A ⟹ at_most_1_elem_trans A›
by (simp add: at_most_1_elem_def at_most_1_elem_trans_def)
definition length_1_trans⇩d :: ‹('σ list, 'a, 'r, 'α) A⇩d_scheme ⇒ bool›
where ‹length_1_trans⇩d A ≡
∀σs a. case τ A σs a of ◇ ⇒ True | ⌊σs'⌋ ⇒ length σs' = Suc 0›
lemma length_1_trans⇩dI :
‹⟦⋀σs a σs'. τ A σs a = ⌊σs'⌋ ⟹ length σs' = Suc 0⟧ ⟹ length_1_trans⇩d A›
by (simp add: length_1_trans⇩d_def split: option.split)
lemma length_1_trans⇩dE :
‹⟦length_1_trans⇩d A; τ A σs a = ⌊σs'⌋; ⋀σ. σs' = [σ] ⟹ thesis⟧ ⟹ thesis›
by (simp add: length_1_trans⇩d_def split: option.split_asm)
(metis (no_types) length_0_conv length_Suc_conv)
definition length_1_trans⇩n⇩d :: ‹('σ list, 'a, 'r, 'α) A⇩n⇩d_scheme ⇒ bool›
where ‹length_1_trans⇩n⇩d A ≡ ∀σs a. ∀σs' ∈ τ A σs a. length σs' = Suc 0›
lemma length_1_trans⇩n⇩dI :
‹⟦⋀σs a σs'. σs' ∈ τ A σs a ⟹ length σs' = Suc 0⟧ ⟹ length_1_trans⇩n⇩d A›
by (simp add: length_1_trans⇩n⇩d_def split: option.split)
lemma length_1_trans⇩n⇩dE :
‹⟦length_1_trans⇩n⇩d A; σs' ∈ τ A σs a; ⋀σ. σs' = [σ] ⟹ thesis⟧ ⟹ thesis›
by (simp add: length_1_trans⇩n⇩d_def split: option.split_asm)
(metis (no_types) length_0_conv length_Suc_conv)
definition length_1⇩d :: ‹('σ list, 'a, 'r list, 'α) A⇩d_scheme ⇒ bool›
where ‹length_1⇩d A ≡
(∀σs a. case τ A σs a of ◇ ⇒ True | ⌊σs'⌋ ⇒ length σs' = Suc 0) ∧
(∀σs. case ω A σs of ◇ ⇒ True | ⌊rs⌋ ⇒ length rs = Suc 0)›
lemma length_1⇩dI :
‹⟦⋀σs a σs'. τ A σs a = ⌊σs'⌋ ⟹ length σs' = Suc 0;
⋀σs rs. ω A σs = ⌊rs⌋ ⟹ length rs = Suc 0⟧ ⟹ length_1⇩d A›
by (simp add: length_1⇩d_def split: option.split)
lemma length_1⇩dE :
‹⟦length_1⇩d A; τ A σs a = ⌊σs'⌋; ⋀σ. σs' = [σ] ⟹ thesis⟧ ⟹ thesis›
‹⟦length_1⇩d A; ω A σs = ⌊rs⌋; ⋀r. rs = [r] ⟹ thesis⟧ ⟹ thesis›
by (simp add: length_1⇩d_def split: option.split_asm,
metis (no_types) length_0_conv length_Suc_conv)+
definition length_1⇩n⇩d :: ‹('σ list, 'a, 'r list, 'α) A⇩n⇩d_scheme ⇒ bool›
where ‹length_1⇩n⇩d A ≡ (∀σs a. ∀σs' ∈ τ A σs a. length σs' = Suc 0) ∧
(∀σs. ∀rs ∈ ω A σs. length rs = Suc 0)›
lemma length_1⇩n⇩dI :
‹⟦⋀σs a σs'. σs' ∈ τ A σs a ⟹ length σs' = Suc 0;
⋀σs rs. rs ∈ ω A σs ⟹ length rs = Suc 0⟧ ⟹ length_1⇩n⇩d A›
by (simp add: length_1⇩n⇩d_def split: option.split)
lemma length_1⇩n⇩dE :
‹⟦length_1⇩n⇩d A; σs' ∈ τ A σs a; ⋀σ. σs' = [σ] ⟹ thesis⟧ ⟹ thesis›
‹⟦length_1⇩n⇩d A; rs ∈ ω A σs; ⋀r. rs = [r] ⟹ thesis⟧ ⟹ thesis›
by (simp add: length_1⇩n⇩d_def split: option.split_asm,
metis (no_types) length_0_conv length_Suc_conv)+
definition indep_enabl :: ‹('σ⇩0, 'a, 'r⇩0, 'α) A⇩d_scheme ⇒ 'σ⇩0 ⇒ 'a set ⇒ ('σ⇩1, 'a, 'r⇩1, 'β) A⇩d_scheme ⇒ 'σ⇩1 ⇒ bool›
where ‹indep_enabl A⇩0 σ⇩0 E A⇩1 σ⇩1 ≡ ∀t⇩0 ∈ ℛ⇩d A⇩0 σ⇩0. ∀t⇩1 ∈ ℛ⇩d A⇩1 σ⇩1. ε A⇩0 t⇩0 ∩ ε A⇩1 t⇩1 ⊆ E›
lemma indep_enablI :
‹(⋀t⇩0 t⇩1. t⇩0 ∈ ℛ⇩d A⇩0 σ⇩0 ⟹ t⇩1 ∈ ℛ⇩d A⇩1 σ⇩1 ⟹ ε A⇩0 t⇩0 ∩ ε A⇩1 t⇩1 ⊆ E)
⟹ indep_enabl A⇩0 σ⇩0 E A⇩1 σ⇩1›
and indep_enablD :
‹⟦indep_enabl A⇩0 σ⇩0 E A⇩1 σ⇩1; t⇩0 ∈ ℛ⇩d A⇩0 σ⇩0; t⇩1 ∈ ℛ⇩d A⇩1 σ⇩1⟧ ⟹ ε A⇩0 t⇩0 ∩ ε A⇩1 t⇩1 ⊆ E›
by (simp_all add: indep_enabl_def)
definition ρ_disjoint_ε :: ‹('σ, 'a, 'σ', 'r', 'α) A_scheme ⇒ bool›
where ‹ρ_disjoint_ε A ≡ ∀σ ∈ ρ A. ε A σ = {}›
lemma ρ_disjoint_εI : ‹(⋀σ. σ ∈ ρ A ⟹ ε A σ = {}) ⟹ ρ_disjoint_ε A›
and ρ_disjoint_εD : ‹ρ_disjoint_ε A ⟹ σ ∈ ρ A ⟹ ε A σ = {}›
by (simp_all add: ρ_disjoint_ε_def)
definition at_most_1_elem_term :: ‹('σ, 'a, 'r, 'α) A⇩n⇩d_scheme ⇒ bool›
where ‹at_most_1_elem_term A ≡ ∀σ. ω A σ = {} ∨ (∃r. ω A σ = {r})›
lemma at_most_1_elem_term_def_bis :
‹at_most_1_elem_term A ⟷ (∀σ. ∃r. ω A σ ⊆ {r})›
by (auto simp add: at_most_1_elem_term_def subset_iff)
(metis empty_iff singleton_iff,
metis equals0D is_singletonI' is_singleton_some_elem)
lemma at_most_1_elem_termI :
‹⟦⋀σ. ω A σ = {} ∨ (∃r. ω A σ = {r})⟧ ⟹ at_most_1_elem_term A›
by (simp add: at_most_1_elem_term_def)
lemma at_most_1_elem_termE :
‹⟦ω A σ = {} ⟹ thesis; ⋀r. ω A σ = {r} ⟹ thesis⟧ ⟹ thesis›
if ‹at_most_1_elem_term A›
by (meson at_most_1_elem_term_def ‹at_most_1_elem_term A›)+
lemma at_most_1_elem_imp_at_most_1_elem_term :
‹at_most_1_elem A ⟹ at_most_1_elem_term A›
by (simp add: at_most_1_elem_def at_most_1_elem_term_def)
section ‹First Properties›
subsection ‹\<^const>‹ε›, \<^const>‹ρ› and \<^const>‹ω› first equalities›
lemma base_trans_ε[simp]:
‹ε (⦇τ = λσ a. ◇, ω = λσ. ◇, … = some⦈ :: ('σ, 'a, 'r, 'α) A⇩d_scheme) σ = {}›
‹ε (⦇τ = λσ a. {}, ω = λσ. {}, … = some⦈ :: ('σ, 'a, 'r, 'α) A⇩n⇩d_scheme) σ = {}›
by (simp_all add: ε_simps)
lemma base_trans_ρ[simp]:
‹ρ (⦇τ = λσ a. ◇, ω = λσ. ◇, … = some⦈ :: ('σ, 'a, 'r, 'α) A⇩d_scheme) = {}›
‹ρ (⦇τ = λσ a. {}, ω = λσ. {}, … = some⦈ :: ('σ, 'a, 'r, 'α) A⇩n⇩d_scheme) = {}›
by (simp_all add: ρ_simps)
lemma σ_σs_conv_ε[simp]:
‹ε ⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s σs = ε A (hd σs)› ‹ε ⇩n⇩d⟪B⟫⇩σ⇩↪⇩σ⇩s σs = ε B (hd σs)›
‹ε ⇩d⟪C⟫⇩σ⇩s⇩↝⇩σ σ = ε C [σ]› ‹ε ⇩n⇩d⟪D⟫⇩σ⇩s⇩↝⇩σ σ = ε D [σ]›
by (simp_all add: σ_σs_conv_defs ε_simps option.case_eq_if)
lemma σ_σs_conv_ρ[simp]:
‹ρ ⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s = {σs. hd σs ∈ ρ A}› ‹ρ ⇩n⇩d⟪B⟫⇩σ⇩↪⇩σ⇩s = {σs. hd σs ∈ ρ B}›
‹ρ ⇩d⟪C⟫⇩σ⇩s⇩↝⇩σ = {σ. [σ] ∈ ρ C}› ‹ρ ⇩n⇩d⟪D⟫⇩σ⇩s⇩↝⇩σ = {σ. [σ] ∈ ρ D}›
by (simp_all add: σ_σs_conv_defs ρ_simps option.case_eq_if)
lemma singl_list_conv_ε[simp]:
‹ε ⇩d⟪A⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t σs = ε A (hd σs)› ‹ε ⇩n⇩d⟪B⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t σs = ε B (hd σs)›
‹ε ⇩d⟪C⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l σ = ε C [σ]› ‹ε ⇩n⇩d⟪D⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l σ = ε D [σ]›
by (simp_all add: singl_list_conv_defs ε_simps option.case_eq_if)
lemma singl_list_conv_ρ[simp]:
‹ρ ⇩d⟪A⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t = {σs. hd σs ∈ ρ A}› ‹ρ ⇩n⇩d⟪B⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t = {σs. hd σs ∈ ρ B}›
‹ρ ⇩d⟪C⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l = {σ. [σ] ∈ ρ C}› ‹ρ ⇩n⇩d⟪D⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l = {σ. [σ] ∈ ρ D}›
by (simp_all add: singl_list_conv_defs ρ_simps option.case_eq_if)
lemma det_ndet_conv_ε[simp]: ‹ε ⟪A⟫⇩d⇩↪⇩n⇩d = ε A› ‹ε ⟪B⟫⇩n⇩d⇩↝⇩d = ε B›
by (rule ext, simp add: det_ndet_conv_defs ε_simps option.case_eq_if)+
lemma det_ndet_conv_ρ[simp]: ‹ρ ⟪A⟫⇩d⇩↪⇩n⇩d = ρ A› ‹ρ ⟪B⟫⇩n⇩d⇩↝⇩d = ρ B›
by (simp_all add: det_ndet_conv_defs ρ_simps option.case_eq_if)
lemma ω_from_det_to_ndet :
‹ω ⟪A⟫⇩d⇩↪⇩n⇩d = (λσ. case ω A σ of ⌊r⌋ ⇒ {r} | ◇ ⇒ {})›
by (auto simp add: det_ndet_conv_defs)
lemma ε_ω_useless [simp] :
‹ε (A⦇ω := some_ω⦈) = ε A› ‹ε (B⦇ω := some_ω'⦈) = ε B›
for A :: ‹('σ, 'a, 'σ option, 'r option, 'α) A_scheme›
and B :: ‹('σ, 'a, 'σ set, 'r set, 'α) A_scheme›
by (rule ext, simp add: ε_simps)+
lemma ρ_disjoint_ε_updated_ω [simp] :
‹ρ_disjoint_ε (A⦇ω := λσ. ◇⦈)›
‹ρ_disjoint_ε (B⦇ω := λσ. {}⦈)›
by (simp_all add: ρ_disjoint_ε_def ρ_simps)
lemma ρ_disjoint_ε_det_ndet_conv_iff [simp] :
‹ρ_disjoint_ε ⟪A⟫⇩d⇩↪⇩n⇩d ⟷ ρ_disjoint_ε A›
‹ρ_disjoint_ε ⟪B⟫⇩n⇩d⇩↝⇩d ⟷ ρ_disjoint_ε B›
by (simp_all add: ρ_disjoint_ε_def)
lemma at_most_1_elem_term_updated_ω [simp] :
‹at_most_1_elem_term (A⦇ω := λσ. {}⦈)›
by (simp add: at_most_1_elem_term_def)
lemma at_most_1_elem_term_from_det_to_ndet [simp] :
‹at_most_1_elem_term ⟪A⟫⇩d⇩↪⇩n⇩d›
by (simp add: det_ndet_conv_defs at_most_1_elem_term_def split: option.split)
lemma at_most_1_elem_term_unit [simp] :
‹at_most_1_elem_term (A :: ('σ, 'a, unit, 'α) A⇩n⇩d_scheme)›
by (auto simp add: at_most_1_elem_term_def)
subsection ‹Properties of our morphisms›
method expand_A_scheme =
match conclusion in ‹A = B› for A B :: ‹('σ, 'a, 'σ', 'r', 'α) A_scheme› ⇒
‹cases A, cases B›
lemma base_trans_det_ndet_conv:
‹⟪⦇τ = λσ a. ◇, ω = λσ. ◇, … = some⦈⟫⇩d⇩↪⇩n⇩d =
⦇τ = λσ a. {}, ω = λσ. {}, … = some⦈›
‹⟪⦇τ = λσ a. {}, ω = λσ. {}, … = some⦈⟫⇩n⇩d⇩↝⇩d =
⦇τ = λσ a. ◇, ω = λσ. ◇, … = some⦈›
unfolding det_ndet_conv_defs by simp_all
lemma from_det_to_ndet_σ_σs_conv_commute:
‹⇩n⇩d⟪⟪A⟫⇩d⇩↪⇩n⇩d⟫⇩σ⇩↪⇩σ⇩s = ⟪⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s⟫⇩d⇩↪⇩n⇩d› ‹⇩n⇩d⟪⟪B⟫⇩d⇩↪⇩n⇩d⟫⇩σ⇩s⇩↝⇩σ = ⟪⇩d⟪B⟫⇩σ⇩s⇩↝⇩σ⟫⇩d⇩↪⇩n⇩d›
by (simp add: det_ndet_conv_defs σ_σs_conv_defs, rule ext,
auto simp add: option.case_eq_if split: if_splits)+
lemma from_det_to_ndet_singl_list_conv_commute:
‹⇩n⇩d⟪⟪A⟫⇩d⇩↪⇩n⇩d⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t = ⟪⇩d⟪A⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t⟫⇩d⇩↪⇩n⇩d› ‹⇩n⇩d⟪⟪B⟫⇩d⇩↪⇩n⇩d⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l = ⟪⇩d⟪B⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l⟫⇩d⇩↪⇩n⇩d›
by (simp add: det_ndet_conv_defs singl_list_conv_defs,
solves ‹intro conjI ext, auto split: option.split›)+
lemma from_ndet_to_det_σ_σs_conv_commute:
‹at_most_1_elem_trans A ⟹ ⇩d⟪⟪A⟫⇩n⇩d⇩↝⇩d⟫⇩σ⇩↪⇩σ⇩s = ⟪⇩n⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s⟫⇩n⇩d⇩↝⇩d›
‹at_most_1_elem_trans B ⟹ ⇩d⟪⟪B⟫⇩n⇩d⇩↝⇩d⟫⇩σ⇩s⇩↝⇩σ = ⟪⇩n⇩d⟪B⟫⇩σ⇩s⇩↝⇩σ⟫⇩n⇩d⇩↝⇩d›
proof -
assume * : ‹at_most_1_elem_trans A›
from "*" have ‹τ ⇩d⟪⟪A⟫⇩n⇩d⇩↝⇩d⟫⇩σ⇩↪⇩σ⇩s σs a = τ ⟪⇩n⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s⟫⇩n⇩d⇩↝⇩d σs a› for σs a
by (auto simp add: det_ndet_conv_defs σ_σs_conv_defs
elim: at_most_1_elem_transE)
moreover have ‹ω ⇩d⟪⟪A⟫⇩n⇩d⇩↝⇩d⟫⇩σ⇩↪⇩σ⇩s σs = ω ⟪⇩n⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s⟫⇩n⇩d⇩↝⇩d σs› for σs
by (auto simp add: det_ndet_conv_defs σ_σs_conv_defs)
moreover have ‹more ⇩d⟪⟪A⟫⇩n⇩d⇩↝⇩d⟫⇩σ⇩↪⇩σ⇩s = more ⟪⇩n⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s⟫⇩n⇩d⇩↝⇩d› by simp
ultimately show ‹⇩d⟪⟪A⟫⇩n⇩d⇩↝⇩d⟫⇩σ⇩↪⇩σ⇩s = ⟪⇩n⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s⟫⇩n⇩d⇩↝⇩d› by expand_A_scheme auto
next
assume * : ‹at_most_1_elem_trans B›
from "*" have ‹τ ⇩d⟪⟪B⟫⇩n⇩d⇩↝⇩d⟫⇩σ⇩s⇩↝⇩σ σ a = τ ⟪⇩n⇩d⟪B⟫⇩σ⇩s⇩↝⇩σ⟫⇩n⇩d⇩↝⇩d σ a› for σ a
by (auto simp add: det_ndet_conv_defs σ_σs_conv_defs
elim: at_most_1_elem_transE)
moreover have ‹ω ⇩d⟪⟪B⟫⇩n⇩d⇩↝⇩d⟫⇩σ⇩s⇩↝⇩σ σ = ω ⟪⇩n⇩d⟪B⟫⇩σ⇩s⇩↝⇩σ⟫⇩n⇩d⇩↝⇩d σ› for σ
by (auto simp add: det_ndet_conv_defs σ_σs_conv_defs)
moreover have ‹more ⇩d⟪⟪B⟫⇩n⇩d⇩↝⇩d⟫⇩σ⇩s⇩↝⇩σ = more ⟪⇩n⇩d⟪B⟫⇩σ⇩s⇩↝⇩σ⟫⇩n⇩d⇩↝⇩d› by simp
ultimately show ‹⇩d⟪⟪B⟫⇩n⇩d⇩↝⇩d⟫⇩σ⇩s⇩↝⇩σ = ⟪⇩n⇩d⟪B⟫⇩σ⇩s⇩↝⇩σ⟫⇩n⇩d⇩↝⇩d› by expand_A_scheme auto
qed
lemma from_ndet_to_det_singl_list_conv_commute:
‹at_most_1_elem A ⟹ ⇩d⟪⟪A⟫⇩n⇩d⇩↝⇩d⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t = ⟪⇩n⇩d⟪A⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t⟫⇩n⇩d⇩↝⇩d›
‹at_most_1_elem B ⟹ ⇩d⟪⟪B⟫⇩n⇩d⇩↝⇩d⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l = ⟪⇩n⇩d⟪B⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l⟫⇩n⇩d⇩↝⇩d›
proof -
assume * : ‹at_most_1_elem A›
from "*" have ‹τ ⇩d⟪⟪A⟫⇩n⇩d⇩↝⇩d⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t σs a = τ ⟪⇩n⇩d⟪A⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t⟫⇩n⇩d⇩↝⇩d σs a› for σs a
by (auto simp add: det_ndet_conv_defs singl_list_conv_defs
elim: at_most_1_elemE(1))
moreover from "*" have ‹ω ⇩d⟪⟪A⟫⇩n⇩d⇩↝⇩d⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t σs = ω ⟪⇩n⇩d⟪A⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t⟫⇩n⇩d⇩↝⇩d σs› for σs
by (auto simp add: det_ndet_conv_defs singl_list_conv_defs
elim: at_most_1_elemE(2))
moreover have ‹more ⇩d⟪⟪A⟫⇩n⇩d⇩↝⇩d⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t = more ⟪⇩n⇩d⟪A⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t⟫⇩n⇩d⇩↝⇩d› by simp
ultimately show ‹⇩d⟪⟪A⟫⇩n⇩d⇩↝⇩d⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t = ⟪⇩n⇩d⟪A⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t⟫⇩n⇩d⇩↝⇩d› by expand_A_scheme auto
next
assume * : ‹at_most_1_elem B›
from "*" have ‹τ ⇩d⟪⟪B⟫⇩n⇩d⇩↝⇩d⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l σ a = τ ⟪⇩n⇩d⟪B⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l⟫⇩n⇩d⇩↝⇩d σ a› for σ a
by (auto simp add: det_ndet_conv_defs singl_list_conv_defs
elim: at_most_1_elemE(1))
moreover from "*" have ‹ω ⇩d⟪⟪B⟫⇩n⇩d⇩↝⇩d⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l σ = ω ⟪⇩n⇩d⟪B⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l⟫⇩n⇩d⇩↝⇩d σ› for σ
by (auto simp add: det_ndet_conv_defs singl_list_conv_defs
elim: at_most_1_elemE(2))
moreover have ‹more ⇩d⟪⟪B⟫⇩n⇩d⇩↝⇩d⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l = more ⟪⇩n⇩d⟪B⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l⟫⇩n⇩d⇩↝⇩d› by simp
ultimately show ‹⇩d⟪⟪B⟫⇩n⇩d⇩↝⇩d⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l = ⟪⇩n⇩d⟪B⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l⟫⇩n⇩d⇩↝⇩d› by expand_A_scheme auto
qed
lemma behaviour_σ_σs_conv:
‹ε ⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s [σ] = ε A σ›
‹τ ⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s [σ] a = (case τ A σ a of ◇ ⇒ ◇ | ⌊t⌋ ⇒ ⌊[t]⌋)›
‹ρ ⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s = {σs. hd σs ∈ ρ A}›
‹ω ⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s [σ] = ω A σ›
‹ε ⇩n⇩d⟪B⟫⇩σ⇩↪⇩σ⇩s [σ] = ε B σ›
‹τ ⇩n⇩d⟪B⟫⇩σ⇩↪⇩σ⇩s [σ] a = {[σ'] |σ'. σ' ∈ τ B σ a}›
‹ρ ⇩n⇩d⟪B⟫⇩σ⇩↪⇩σ⇩s = {σs. hd σs ∈ ρ B}›
‹ω ⇩n⇩d⟪B⟫⇩σ⇩↪⇩σ⇩s [σ] = ω B σ›
‹ε ⇩d⟪C⟫⇩σ⇩s⇩↝⇩σ σ = ε C [σ]›
‹τ ⇩d⟪C⟫⇩σ⇩s⇩↝⇩σ σ a = (case τ C [σ] a of ◇ ⇒ ◇ | ⌊σs'⌋ ⇒ ⌊hd σs'⌋)›
‹ρ ⇩d⟪C⟫⇩σ⇩s⇩↝⇩σ = {σ. [σ] ∈ ρ C}›
‹ω ⇩d⟪C⟫⇩σ⇩s⇩↝⇩σ σ = ω C [σ]›
‹ε ⇩n⇩d⟪D⟫⇩σ⇩s⇩↝⇩σ σ = ε D [σ]›
‹τ ⇩n⇩d⟪D⟫⇩σ⇩s⇩↝⇩σ σ a = {hd σs'| σs'. σs' ∈ τ D [σ] a}›
‹ρ ⇩n⇩d⟪D⟫⇩σ⇩s⇩↝⇩σ = {σ. [σ] ∈ ρ D}› ‹ω ⇩n⇩d⟪D⟫⇩σ⇩s⇩↝⇩σ σ = ω D [σ]›
by simp_all (simp_all add: σ_σs_conv_defs)
lemma behaviour_singl_list_conv:
‹ε ⇩d⟪A⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t [σ] = ε A σ›
‹τ ⇩d⟪A⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t [σ] a = (case τ A σ a of ◇ ⇒ ◇ | ⌊t⌋ ⇒ ⌊[t]⌋)›
‹ρ ⇩d⟪A⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t = {σs. hd σs ∈ ρ A}›
‹ω ⇩d⟪A⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t [σ] = (case ω A σ of ◇ ⇒ ◇ | ⌊r⌋ ⇒ ⌊[r]⌋)›
‹ε ⇩n⇩d⟪B⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t [σ] = ε B σ›
‹τ ⇩n⇩d⟪B⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t [σ] a = {[σ'] |σ'. σ' ∈ τ B σ a}›
‹ρ ⇩n⇩d⟪B⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t = {σs. hd σs ∈ ρ B}›
‹ω ⇩n⇩d⟪B⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t [σ] = {[r] |r. r ∈ ω B σ}›
‹ε ⇩d⟪C⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l σ = ε C [σ]›
‹τ ⇩d⟪C⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l σ a = (case τ C [σ] a of ◇ ⇒ ◇ | ⌊σs'⌋ ⇒ ⌊hd σs'⌋)›
‹ρ ⇩d⟪C⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l = {σ. [σ] ∈ ρ C}›
‹ω ⇩d⟪C⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l σ = (case ω C [σ] of ◇ ⇒ ◇ | ⌊rs⌋ ⇒ ⌊hd rs⌋)›
‹ε ⇩n⇩d⟪D⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l σ = ε D [σ]›
‹τ ⇩n⇩d⟪D⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l σ a = {hd σs'| σs'. σs' ∈ τ D [σ] a}›
‹ρ ⇩n⇩d⟪D⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l = {σ. [σ] ∈ ρ D}›
‹ω ⇩n⇩d⟪D⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l σ = {hd rs |rs. rs ∈ ω D [σ]}›
by simp_all (simp_all add: singl_list_conv_defs)
lemma empty_from_det_to_ndet_is_None_trans [simp] : ‹τ ⟪A⟫⇩d⇩↪⇩n⇩d σ a = {} ⟷ τ A σ a = ◇›
by (simp add: ε_simps det_ndet_conv_defs option.case_eq_if)
lemma at_most_1_elem_from_det_to_ndet [simp] : ‹at_most_1_elem ⟪A⟫⇩d⇩↪⇩n⇩d›
by (rule at_most_1_elemI)
(simp_all add: det_ndet_conv_defs split: option.split)
lemma from_ndet_to_det_from_det_to_ndet [simp] : ‹⟪⟪A⟫⇩d⇩↪⇩n⇩d⟫⇩n⇩d⇩↝⇩d = A›
by (cases A, simp add: det_ndet_conv_defs)
(intro conjI ext, simp_all split: option.split)
lemma from_det_to_ndet_from_ndet_to_det [simp] :
‹⟪⟪A⟫⇩n⇩d⇩↝⇩d⟫⇩d⇩↪⇩n⇩d = A› if ‹at_most_1_elem A›
proof -
from that have ‹τ ⟪⟪A⟫⇩n⇩d⇩↝⇩d⟫⇩d⇩↪⇩n⇩d σ a = τ A σ a› for σ a
by (auto simp add: det_ndet_conv_defs elim: at_most_1_elemE(1))
moreover from that have ‹ω ⟪⟪A⟫⇩n⇩d⇩↝⇩d⟫⇩d⇩↪⇩n⇩d σ = ω A σ› for σ
by (auto simp add: det_ndet_conv_defs elim: at_most_1_elemE(2))
moreover have ‹more ⟪⟪A⟫⇩n⇩d⇩↝⇩d⟫⇩d⇩↪⇩n⇩d = more A› by simp
ultimately show ‹⟪⟪A⟫⇩n⇩d⇩↝⇩d⟫⇩d⇩↪⇩n⇩d = A› by expand_A_scheme fastforce
qed
theorem bij_betw_from_det_to_ndet :
‹bij_betw (λA. ⟪A⟫⇩d⇩↪⇩n⇩d) UNIV {A. at_most_1_elem A}›
unfolding bij_betw_iff_bijections
by (rule exI[where x = ‹λA. ⟪A⟫⇩n⇩d⇩↝⇩d›]) simp
lemma bij_betw_from_ndet_to_det :
‹bij_betw (λA. ⟪A⟫⇩n⇩d⇩↝⇩d) {A. at_most_1_elem A} UNIV›
unfolding bij_betw_iff_bijections
by (rule exI[where x = ‹λA. ⟪A⟫⇩d⇩↪⇩n⇩d›]) simp
lemma length_1_trans_from_σ_to_σs [simp] :
‹length_1_trans⇩d ⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s› ‹length_1_trans⇩n⇩d ⇩n⇩d⟪B⟫⇩σ⇩↪⇩σ⇩s›
by (rule length_1_trans⇩dI, solves ‹auto simp add: σ_σs_conv_defs split: option.split_asm›)
(rule length_1_trans⇩n⇩dI, solves ‹auto simp add: σ_σs_conv_defs split: option.split_asm›)
lemma τ_hd_from_σ_to_σs_eq [simp] :
‹τ ⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s [hd σs] a = τ ⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s σs a›
‹τ ⇩n⇩d⟪B⟫⇩σ⇩↪⇩σ⇩s [hd σs] a = τ ⇩n⇩d⟪B⟫⇩σ⇩↪⇩σ⇩s σs a›
by (simp_all add: σ_σs_conv_defs)
lemma ω_hd_from_σ_to_σs_eq [simp] :
‹ω ⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s [hd σs] = ω ⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s σs›
‹ω ⇩n⇩d⟪B⟫⇩σ⇩↪⇩σ⇩s [hd σs] = ω ⇩n⇩d⟪B⟫⇩σ⇩↪⇩σ⇩s σs›
by (simp_all add: σ_σs_conv_defs)
lemma from_σs_to_σ_from_σ_to_σs [simp] :
‹⇩d⟪⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s⟫⇩σ⇩s⇩↝⇩σ = A› ‹⇩n⇩d⟪⇩n⇩d⟪B⟫⇩σ⇩↪⇩σ⇩s⟫⇩σ⇩s⇩↝⇩σ = B›
by (cases A, simp add: σ_σs_conv_defs, intro conjI ext;
simp add: option.case_eq_if set_eq_iff; metis list.sel(1))
(cases B, simp add: σ_σs_conv_defs, intro conjI ext;
simp add: option.case_eq_if set_eq_iff; metis list.sel(1))
lemma from_σ_to_σs_from_σs_to_σ [simp] :
‹⟦length_1_trans⇩d A; ⋀σs a. τ A [hd σs] a = τ A σs a;
⋀σs. ω A [hd σs] = ω A σs⟧ ⟹ ⇩d⟪⇩d⟪A⟫⇩σ⇩s⇩↝⇩σ⟫⇩σ⇩↪⇩σ⇩s = A›
‹⟦length_1_trans⇩n⇩d B; ⋀σs a. τ B [hd σs] a = τ B σs a;
⋀σs. ω B [hd σs] = ω B σs⟧ ⟹ ⇩n⇩d⟪⇩n⇩d⟪B⟫⇩σ⇩s⇩↝⇩σ⟫⇩σ⇩↪⇩σ⇩s = B›
proof -
assume * : ‹length_1_trans⇩d A› ‹⋀σs a. τ A [hd σs] a = τ A σs a›
‹⋀σs. ω A [hd σs] = ω A σs›
from "*"(1) have ‹τ ⇩d⟪⇩d⟪A⟫⇩σ⇩s⇩↝⇩σ⟫⇩σ⇩↪⇩σ⇩s σs a = τ A σs a› for σs a
by (auto simp add: σ_σs_conv_defs "*"(2) split: option.split
elim: length_1_trans⇩dE)
moreover have ‹ω ⇩d⟪⇩d⟪A⟫⇩σ⇩s⇩↝⇩σ⟫⇩σ⇩↪⇩σ⇩s σs = ω A σs› for σs
by (simp add: σ_σs_conv_defs "*"(3))
moreover have ‹more ⇩d⟪⇩d⟪A⟫⇩σ⇩s⇩↝⇩σ⟫⇩σ⇩↪⇩σ⇩s = more A› by simp
ultimately show ‹⇩d⟪⇩d⟪A⟫⇩σ⇩s⇩↝⇩σ⟫⇩σ⇩↪⇩σ⇩s = A› by expand_A_scheme auto
next
assume * : ‹length_1_trans⇩n⇩d B› ‹⋀σs a. τ B [hd σs] a = τ B σs a›
‹⋀σs. ω B [hd σs] = ω B σs›
from "*"(1) have ‹τ ⇩n⇩d⟪⇩n⇩d⟪B⟫⇩σ⇩s⇩↝⇩σ⟫⇩σ⇩↪⇩σ⇩s σs a = τ B σs a› for σs a
by (auto simp add: σ_σs_conv_defs "*"(2) elim: length_1_trans⇩n⇩dE)
(metis length_1_trans⇩n⇩dE list.sel(1))
moreover have ‹ω ⇩n⇩d⟪⇩n⇩d⟪B⟫⇩σ⇩s⇩↝⇩σ⟫⇩σ⇩↪⇩σ⇩s σs = ω B σs› for σs
by (simp add: σ_σs_conv_defs "*"(3))
moreover have ‹more ⇩n⇩d⟪⇩n⇩d⟪B⟫⇩σ⇩s⇩↝⇩σ⟫⇩σ⇩↪⇩σ⇩s = more B› by simp
ultimately show ‹⇩n⇩d⟪⇩n⇩d⟪B⟫⇩σ⇩s⇩↝⇩σ⟫⇩σ⇩↪⇩σ⇩s = B› by expand_A_scheme fastforce
qed
theorem bij_betw_from_σ_to_σs :
‹bij_betw (λA. ⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s) UNIV
{A. length_1_trans⇩d A ∧ (∀σs a. τ A [hd σs] a = τ A σs a) ∧ (∀σs. ω A [hd σs] = ω A σs)}›
(is ‹bij_betw (λA. ⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s) UNIV ?S⇩d›)
‹bij_betw (λB. ⇩n⇩d⟪B⟫⇩σ⇩↪⇩σ⇩s) UNIV
{B. length_1_trans⇩n⇩d B ∧ (∀σs a. τ B σs a = τ B [hd σs] a) ∧ (∀σs. ω B [hd σs] = ω B σs)}›
unfolding bij_betw_iff_bijections
by (rule exI[where x = ‹λA. ⇩d⟪A⟫⇩σ⇩s⇩↝⇩σ›], simp)
(rule exI[where x = ‹λA. ⇩n⇩d⟪A⟫⇩σ⇩s⇩↝⇩σ›], simp)
lemma bij_betw_from_σs_to_σ :
‹bij_betw (λA. ⇩d⟪A⟫⇩σ⇩s⇩↝⇩σ)
{A. length_1_trans⇩d A ∧ (∀σs a. τ A [hd σs] a = τ A σs a) ∧ (∀σs. ω A [hd σs] = ω A σs)} UNIV›
‹bij_betw (λB. ⇩n⇩d⟪B⟫⇩σ⇩s⇩↝⇩σ)
{B. length_1_trans⇩n⇩d B ∧ (∀σs a. τ B σs a = τ B [hd σs] a) ∧ (∀σs. ω B [hd σs] = ω B σs)} UNIV›
unfolding bij_betw_iff_bijections
by (rule exI[where x = ‹λA. ⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s›], simp)
(rule exI[where x = ‹λA. ⇩n⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s›], simp)
lemma length_1_from_singl_to_list [simp] :
‹length_1⇩d ⇩d⟪A⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t› ‹length_1⇩n⇩d ⇩n⇩d⟪B⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t›
by (rule length_1⇩dI; solves ‹auto simp add: singl_list_conv_defs split: option.split_asm›)
(rule length_1⇩n⇩dI; solves ‹auto simp add: singl_list_conv_defs split: option.split_asm›)
lemma τ_hd_from_singl_to_list_eq [simp] :
‹τ ⇩d⟪A⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t [hd σs] a = τ ⇩d⟪A⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t σs a›
‹τ ⇩n⇩d⟪B⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t [hd σs] a = τ ⇩n⇩d⟪B⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t σs a›
by (simp_all add: singl_list_conv_defs)
lemma ω_hd_from_singl_to_list_eq [simp] :
‹ω ⇩d⟪A⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t [hd σs] = ω ⇩d⟪A⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t σs›
‹ω ⇩n⇩d⟪B⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t [hd σs] = ω ⇩n⇩d⟪B⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t σs›
by (simp_all add: singl_list_conv_defs)
lemma from_list_to_singl_from_singl_to_list [simp] :
‹⇩d⟪⇩d⟪A⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l = A› ‹⇩n⇩d⟪⇩n⇩d⟪B⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l = B›
by (cases A, simp add: singl_list_conv_defs, intro conjI ext;
simp add: option.case_eq_if set_eq_iff; metis list.sel(1))
(cases B, simp add: singl_list_conv_defs, intro conjI ext;
simp add: option.case_eq_if set_eq_iff; metis list.sel(1))
lemma from_singl_to_list_from_list_to_singl [simp] :
‹⟦length_1⇩d A; ⋀σs a. τ A [hd σs] a = τ A σs a;
⋀σs. ω A [hd σs] = ω A σs⟧ ⟹ ⇩d⟪⇩d⟪A⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t = A›
‹⟦length_1⇩n⇩d B; ⋀σs a. τ B [hd σs] a = τ B σs a;
⋀σs. ω B [hd σs] = ω B σs⟧ ⟹ ⇩n⇩d⟪⇩n⇩d⟪B⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t = B›
proof -
assume * : ‹length_1⇩d A› ‹⋀σs a. τ A [hd σs] a = τ A σs a›
‹⋀σs. ω A [hd σs] = ω A σs›
from "*"(1) have ‹τ ⇩d⟪⇩d⟪A⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t σs a = τ A σs a› for σs a
by (auto simp add: singl_list_conv_defs "*"(2)
split: option.split elim: length_1⇩dE(1))
moreover from "*"(1) have ‹ω ⇩d⟪⇩d⟪A⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t σs = ω A σs› for σs
by (auto simp add: singl_list_conv_defs "*"(3)
split: option.split elim: length_1⇩dE(2))
moreover have ‹more ⇩d⟪⇩d⟪A⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t = more A› by simp
ultimately show ‹⇩d⟪⇩d⟪A⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t = A› by expand_A_scheme auto
next
assume * : ‹length_1⇩n⇩d B› ‹⋀σs a. τ B [hd σs] a = τ B σs a›
‹⋀σs. ω B [hd σs] = ω B σs›
from "*"(1) have ‹τ ⇩n⇩d⟪⇩n⇩d⟪B⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t σs a = τ B σs a› for σs a
by (auto simp add: singl_list_conv_defs "*"(2) elim: length_1⇩n⇩dE(1))
(metis length_1⇩n⇩dE(1) list.sel(1))
moreover from "*"(1) have ‹ω ⇩n⇩d⟪⇩n⇩d⟪B⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t σs = ω B σs› for σs
by (auto simp add: singl_list_conv_defs "*"(3) elim: length_1⇩n⇩dE(2))
(metis length_1⇩n⇩dE(2) list.sel(1))
moreover have ‹more ⇩n⇩d⟪⇩n⇩d⟪B⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t = more B› by simp
ultimately show ‹⇩n⇩d⟪⇩n⇩d⟪B⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t = B› by expand_A_scheme fastforce
qed
theorem bij_betw_from_singl_to_list :
‹bij_betw (λA. ⇩d⟪A⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t) UNIV
{A. length_1⇩d A ∧ (∀σs a. τ A [hd σs] a = τ A σs a) ∧ (∀σs. ω A [hd σs] = ω A σs)}›
(is ‹bij_betw (λA. ⇩d⟪A⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t) UNIV ?S⇩d›)
‹bij_betw (λB. ⇩n⇩d⟪B⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t) UNIV
{B. length_1⇩n⇩d B ∧ (∀σs a. τ B σs a = τ B [hd σs] a) ∧ (∀σs. ω B [hd σs] = ω B σs)}›
unfolding bij_betw_iff_bijections
by (rule exI[where x = ‹λA. ⇩d⟪A⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l›], simp)
(rule exI[where x = ‹λA. ⇩n⇩d⟪A⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l›], simp)
lemma bij_betw_from_list_to_singl :
‹bij_betw (λA. ⇩d⟪A⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l)
{A. length_1⇩d A ∧ (∀σs a. τ A [hd σs] a = τ A σs a) ∧ (∀σs. ω A [hd σs] = ω A σs)} UNIV›
‹bij_betw (λB. ⇩n⇩d⟪B⟫⇩l⇩i⇩s⇩t⇩↝⇩s⇩i⇩n⇩g⇩l)
{B. length_1⇩n⇩d B ∧ (∀σs a. τ B σs a = τ B [hd σs] a) ∧ (∀σs. ω B [hd σs] = ω B σs)} UNIV›
unfolding bij_betw_iff_bijections
by (rule exI[where x = ‹λA. ⇩d⟪A⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t›], simp)
(rule exI[where x = ‹λA. ⇩n⇩d⟪A⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t›], simp)
subsection ‹Reachability results (for \<^const>‹ℛ⇩d› and \<^const>‹ℛ⇩n⇩d›)›
lemma ℛ_base_trans[simp]: ‹ℛ⇩d ⦇τ = λσ a. ◇, ω = λσ. ◇, … = some⦈ = (λσ. {σ})›
‹ℛ⇩n⇩d ⦇τ = λσ a. {}, ω = λσ. {}, … = some⦈ = (λσ. {σ})›
by (rule ext, safe, subst (asm) ℛ⇩d.simps ℛ⇩n⇩d.simps, simp_all add: ℛ⇩d.init ℛ⇩n⇩d.init)+
theorem ℛ⇩n⇩d_from_det_to_ndet : ‹ℛ⇩n⇩d ⟪A⟫⇩d⇩↪⇩n⇩d σ = ℛ⇩d A σ›
proof safe
show ‹σ' ∈ ℛ⇩n⇩d ⟪A⟫⇩d⇩↪⇩n⇩d σ ⟹ σ' ∈ ℛ⇩d A σ› for σ'
by (induct rule: ℛ⇩n⇩d.induct, fact ℛ⇩d.init, erule ℛ⇩d.step)
(simp add: from_det_to_ndet_def option.case_eq_if split: if_split_asm)
next
show ‹σ' ∈ ℛ⇩d A σ ⟹ σ' ∈ ℛ⇩n⇩d ⟪A⟫⇩d⇩↪⇩n⇩d σ› for σ'
by (induct rule: ℛ⇩d.induct, fact ℛ⇩n⇩d.init)
(metis ℛ⇩n⇩d.step det_ndet_conv_defs(1) option.case(2)
option.set_intros option.simps(15) select_convs(1))
qed
lemma bij_betw_ℛ⇩n⇩d_if_same_τ : ‹bij_betw f (ℛ⇩n⇩d B⇩0 σ⇩0) (ℛ⇩n⇩d B⇩1 (f σ⇩0))›
if ‹inj_on f (ℛ⇩n⇩d B⇩0 σ⇩0)› and ‹⋀σ⇩0' a. σ⇩0' ∈ ℛ⇩n⇩d B⇩0 σ⇩0 ⟹ τ B⇩1 (f σ⇩0') a = f ` τ B⇩0 σ⇩0' a›
proof (rule bij_betw_imageI, fact that(1), auto simp add: image_def, goal_cases)
show ‹s ∈ ℛ⇩n⇩d B⇩0 σ⇩0 ⟹ f s ∈ ℛ⇩n⇩d B⇩1 (f σ⇩0)› for s
by (induct rule: ℛ⇩n⇩d.induct, simp add: ℛ⇩n⇩d.init, metis ℛ⇩n⇩d.step that(2) image_eqI)
next
show ‹s ∈ ℛ⇩n⇩d B⇩1 (f σ⇩0) ⟹ ∃t ∈ ℛ⇩n⇩d B⇩0 σ⇩0. s = f t› for s
by (induct rule: ℛ⇩n⇩d.induct, metis ℛ⇩n⇩d.simps, metis (mono_tags, lifting) ℛ⇩n⇩d.step that(2) image_iff)
qed
lemma bij_betw_ℛ⇩d_if_same_τ: ‹bij_betw f (ℛ⇩d A⇩0 σ⇩0) (ℛ⇩d A⇩1 (f σ⇩0))›
if ‹inj_on f (ℛ⇩d A⇩0 σ⇩0)› and ‹⋀σ⇩0' a. σ⇩0' ∈ ℛ⇩d A⇩0 σ⇩0 ⟹ τ A⇩1 (f σ⇩0') a = map_option f (τ A⇩0 σ⇩0' a)›
by (subst (1 2) ℛ⇩n⇩d_from_det_to_ndet[symmetric], rule bij_betw_ℛ⇩n⇩d_if_same_τ)
(simp_all add: ℛ⇩n⇩d_from_det_to_ndet that(1),
simp add: det_ndet_conv_defs that(2) option.case_eq_if map_option_case)
lemmas same_τ_implies_same_ℛ⇩n⇩d = bij_betw_ℛ⇩n⇩d_if_same_τ[where f = id, simplified bij_betw_def, simplified]
and same_τ_implies_same_ℛ⇩d = bij_betw_ℛ⇩d_if_same_τ[where f = id, simplified bij_betw_def option.map_id, simplified]
corollary ℛ⇩d_ω_useless [simp] : ‹ℛ⇩d (A⦇ω := some_ω⦈) σ = ℛ⇩d A σ›
by (auto intro!: same_τ_implies_same_ℛ⇩d)
corollary ℛ⇩n⇩d_ω_useless [simp] : ‹ℛ⇩n⇩d (A⦇ω := some_ω⦈) σ = ℛ⇩n⇩d A σ›
by (auto intro!: same_τ_implies_same_ℛ⇩n⇩d)
corollary indep_enabl_ω_useless [simp] :
‹indep_enabl (A⇩0⦇ω := some_ω⦈) σ⇩0 E A⇩1 σ⇩1 ⟷ indep_enabl A⇩0 σ⇩0 E A⇩1 σ⇩1›
‹indep_enabl A⇩0 σ⇩0 E (A⇩1⦇ω := some_ω⦈) σ⇩1 ⟷ indep_enabl A⇩0 σ⇩0 E A⇩1 σ⇩1›
by (simp_all add: indep_enabl_def)
method ℛ_subset_method uses defs opt induct init simps =
induct rule: induct, auto simp add: init defs ε_simps split: if_splits,
(metis (no_types, opaque_lifting) simps)+
method ℛ⇩d_subset_method uses defs opt =
ℛ_subset_method defs: defs opt: opt induct: ℛ⇩d.induct init: ℛ⇩d.init simps: ℛ⇩d.simps
method ℛ⇩n⇩d_subset_method uses defs opt =
ℛ_subset_method defs: defs opt: opt induct: ℛ⇩n⇩d.induct init: ℛ⇩n⇩d.init simps: ℛ⇩n⇩d.simps
lemma ℛ⇩n⇩d_from_σ_to_σs_description: ‹ℛ⇩n⇩d ⇩n⇩d⟪B⟫⇩σ⇩↪⇩σ⇩s [σ] = {[σ']| σ'. σ' ∈ ℛ⇩n⇩d B σ}›
proof safe
show ‹σs ∈ ℛ⇩n⇩d ⇩n⇩d⟪B⟫⇩σ⇩↪⇩σ⇩s [σ] ⟹ ∃σ'. σs = [σ'] ∧ σ' ∈ ℛ⇩n⇩d B σ› for σs
by (induct rule: ℛ⇩n⇩d.induct, auto simp add: ℛ⇩n⇩d.init behaviour_σ_σs_conv(6), metis ℛ⇩n⇩d.step)
next
show ‹σ' ∈ ℛ⇩n⇩d B σ ⟹ [σ'] ∈ ℛ⇩n⇩d ⇩n⇩d⟪B⟫⇩σ⇩↪⇩σ⇩s [σ]› for σ'
by (induct rule: ℛ⇩n⇩d.induct) (simp_all add: ℛ⇩n⇩d.init ℛ⇩n⇩d.step behaviour_σ_σs_conv(6))
qed
lemma ℛ⇩d_from_σ_to_σs_description: ‹ℛ⇩d ⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s [σ] = {[σ']| σ'. σ' ∈ ℛ⇩d A σ}›
by (simp add: ℛ⇩n⇩d_from_σ_to_σs_description
flip: ℛ⇩n⇩d_from_det_to_ndet from_det_to_ndet_σ_σs_conv_commute(1))
lemma ℛ⇩n⇩d_from_singl_to_list_description: ‹ℛ⇩n⇩d ⇩n⇩d⟪B⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t [σ] = {[σ']| σ'. σ' ∈ ℛ⇩n⇩d B σ}›
proof safe
show ‹σs ∈ ℛ⇩n⇩d ⇩n⇩d⟪B⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t [σ] ⟹ ∃σ'. σs = [σ'] ∧ σ' ∈ ℛ⇩n⇩d B σ› for σs
by (induct rule: ℛ⇩n⇩d.induct, auto simp add: ℛ⇩n⇩d.init behaviour_singl_list_conv(6), metis ℛ⇩n⇩d.step)
next
show ‹σ' ∈ ℛ⇩n⇩d B σ ⟹ [σ'] ∈ ℛ⇩n⇩d ⇩n⇩d⟪B⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t [σ]› for σ'
by (induct rule: ℛ⇩n⇩d.induct) (simp_all add: ℛ⇩n⇩d.init ℛ⇩n⇩d.step behaviour_singl_list_conv(6))
qed
lemma ℛ⇩d_from_singl_to_list_description: ‹ℛ⇩d ⇩d⟪A⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t [σ] = {[σ']| σ'. σ' ∈ ℛ⇩d A σ}›
by (simp add: ℛ⇩n⇩d_from_singl_to_list_description
flip: ℛ⇩n⇩d_from_det_to_ndet from_det_to_ndet_singl_list_conv_commute(1))
lemma length_ℛ⇩d_from_σ_to_σs:
‹σs' ∈ ℛ⇩d ⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s σs ⟹ σs' = σs ∨ length σs' = 1›
by (simp add: σ_σs_conv_defs)
(induct rule: ℛ⇩d.induct, simp_all split: option.split_asm)
lemma length_ℛ⇩n⇩d_from_σ_to_σs:
‹σs' ∈ ℛ⇩n⇩d ⇩n⇩d⟪B⟫⇩σ⇩↪⇩σ⇩s σs ⟹ σs' = σs ∨ length σs' = 1›
by (simp add: σ_σs_conv_defs)
(induct rule: ℛ⇩n⇩d.induct, auto)
lemma length_ℛ⇩d_from_singl_to_list:
‹σs' ∈ ℛ⇩d ⇩d⟪A⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t σs ⟹ σs' = σs ∨ length σs' = 1›
by (simp add: singl_list_conv_defs)
(induct rule: ℛ⇩d.induct, simp_all split: option.split_asm)
lemma length_ℛ⇩n⇩d_from_singl_to_list:
‹σs' ∈ ℛ⇩n⇩d ⇩n⇩d⟪B⟫⇩s⇩i⇩n⇩g⇩l⇩↪⇩l⇩i⇩s⇩t σs ⟹ σs' = σs ∨ length σs' = 1›
by (simp add: singl_list_conv_defs)
(induct rule: ℛ⇩n⇩d.induct, auto)
section ‹Normalization›
subsection ‹Non-deterministic Case›
text ‹First version, without final state notion›
abbreviation P_nd_step :: ‹[('σ, 'a) enabl, ('σ, 'a) trans⇩n⇩d, 'σ ⇒ ('a, 'r) process⇩p⇩t⇩i⇩c⇩k, 'σ] ⇒ ('a, 'r) process⇩p⇩t⇩i⇩c⇩k›
where ‹P_nd_step ε⇩A τ⇩A X σ ≡ □ e ∈ ε⇩A σ → ⊓ σ' ∈ τ⇩A σ e. X σ'›
definition P_nd :: ‹('σ, 'a, 'r, 'α) A⇩n⇩d_scheme ⇒ 'σ ⇒ ('a, 'r) process⇩p⇩t⇩i⇩c⇩k› (‹P⟪_⟫⇩n⇩d› 1000)
where ‹P⟪A⟫⇩n⇩d ≡ υ X. P_nd_step (ε A) (τ A) X›
lemma P_nd_step_constructive [simp] : ‹constructive (P_nd_step ε⇩A τ⇩A)› by simp
lemma P_nd_step_cont [simp] : ‹∀σ a. finite (τ⇩A σ a) ⟹ cont (P_nd_step ε⇩A τ⇩A)›
by (simp add: cont_fun)
lemma P_nd_step_constructive_bis : ‹constructive (P_nd_step (ε A) (τ A))› by simp
lemma P_nd_step_cont_bis [simp] : ‹finite_trans A ⟹ cont (P_nd_step (ε A) (τ A))›
by (simp add: finite_trans_def)
lemma P_nd_rec: ‹P⟪A⟫⇩n⇩d = (λσ. P_nd_step (ε A) (τ A) P⟪A⟫⇩n⇩d σ)›
by (unfold P_nd_def, rule ext, subst restriction_fix_eq, simp_all)
lemma P_nd_is_fix : ‹finite_trans A ⟹ P⟪A⟫⇩n⇩d = (μ X. P_nd_step (ε A) (τ A) X)›
by (simp add: P_nd_def restriction_fix_is_fix)
lemma non_destructive_imp_restriction_cont [simp] :
‹non_destructive f ⟹ restriction_cont f›
by (simp add: non_destructive_on_def)
lemma P_nd_ω_useless: ‹P⟪A⟫⇩n⇩d = P⟪A⦇ω := some_ω⦈⟫⇩n⇩d›
by (simp add: P_nd_def ε_simps)
lemma P_nd_ω_useless_bis : ‹P⟪A⟫⇩n⇩d = P⟪A⦇ω := λσ. {}⦈⟫⇩n⇩d›
by (fact P_nd_ω_useless)
lemma P_nd_induct [case_names adm base step] :
‹adm⇩↓ P ⟹ P σ ⟹ (⋀X. P X ⟹ P (P_nd_step (ε A) (τ A) X)) ⟹ P P⟪A⟫⇩n⇩d›
unfolding P_nd_def
by (rule restriction_fix_ind[OF P_nd_step_constructive_bis]) simp_all
lemma P_nd_induct_iterated [consumes 1, case_names adm base step] :
‹⟦0 < k; adm⇩↓ P; P σ; ⋀X. P X ⟹ P ((P_nd_step (ε A) (τ A) ^^ k) X)⟧ ⟹ P P⟪A⟫⇩n⇩d›
unfolding P_nd_def
by (rule restriction_fix_ind_iterated[where f = ‹P_nd_step (ε A) (τ A)›]) auto
text ‹New version with final state notion where we just have \<^const>‹SKIPS›.›
abbreviation P⇩S⇩K⇩I⇩P⇩S_nd_step ::
‹[('σ, 'a) enabl, ('σ, 'a) trans⇩n⇩d, 'σ ⇒ 'r set, 'σ ⇒ ('a, 'r) process⇩p⇩t⇩i⇩c⇩k, 'σ] ⇒ ('a, 'r) process⇩p⇩t⇩i⇩c⇩k›
where ‹P⇩S⇩K⇩I⇩P⇩S_nd_step ε⇩A τ⇩A ω⇩A X σ ≡ if ω⇩A σ = {} then P_nd_step ε⇩A τ⇩A X σ else SKIPS (ω⇩A σ)›
definition P⇩S⇩K⇩I⇩P⇩S_nd :: ‹('σ, 'a, 'r, 'α) A⇩n⇩d_scheme ⇒ 'σ ⇒ ('a, 'r) process⇩p⇩t⇩i⇩c⇩k› (‹P⇩S⇩K⇩I⇩P⇩S⟪_⟫⇩n⇩d› 1000)
where ‹P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩n⇩d ≡ υ X. P⇩S⇩K⇩I⇩P⇩S_nd_step (ε A) (τ A) (ω A) X›
lemma P⇩S⇩K⇩I⇩P⇩S_nd_step_constructive [simp] : ‹constructive (P⇩S⇩K⇩I⇩P⇩S_nd_step ε⇩A τ⇩A ω⇩A)› by auto
lemma P⇩S⇩K⇩I⇩P⇩S_nd_step_cont [simp] : ‹∀σ a. finite (τ⇩A σ a) ⟹ cont (P⇩S⇩K⇩I⇩P⇩S_nd_step ε⇩A τ⇩A ω⇩A)›
by (simp add: cont_fun)
lemma P⇩S⇩K⇩I⇩P⇩S_nd_step_constructive_bis : ‹constructive (P⇩S⇩K⇩I⇩P⇩S_nd_step (ε A) (τ A) (ω A))› by simp
lemma P⇩S⇩K⇩I⇩P⇩S_nd_step_cont_bis [simp] : ‹finite_trans A ⟹ cont (P⇩S⇩K⇩I⇩P⇩S_nd_step (ε A) (τ A) (ω A))›
by (simp add: finite_trans_def)
lemma P⇩S⇩K⇩I⇩P⇩S_nd_rec: ‹P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩n⇩d = (λσ. P⇩S⇩K⇩I⇩P⇩S_nd_step (ε A) (τ A) (ω A) P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩n⇩d σ)›
by (unfold P⇩S⇩K⇩I⇩P⇩S_nd_def, rule ext, subst restriction_fix_eq, simp_all)
lemma P⇩S⇩K⇩I⇩P⇩S_nd_is_fix : ‹finite_trans A ⟹ P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩n⇩d = (μ X. P⇩S⇩K⇩I⇩P⇩S_nd_step (ε A) (τ A) (ω A) X)›
by (simp add: P⇩S⇩K⇩I⇩P⇩S_nd_def restriction_fix_is_fix)
lemma P⇩S⇩K⇩I⇩P⇩S_nd_induct [case_names adm base step] :
‹adm⇩↓ P ⟹ P σ ⟹ (⋀X. P X ⟹ P (P⇩S⇩K⇩I⇩P⇩S_nd_step (ε A) (τ A) (ω A) X)) ⟹ P P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩n⇩d›
unfolding P⇩S⇩K⇩I⇩P⇩S_nd_def
by (rule restriction_fix_ind[OF P⇩S⇩K⇩I⇩P⇩S_nd_step_constructive_bis]) simp_all
lemma P⇩S⇩K⇩I⇩P⇩S_nd_induct_iterated [consumes 1, case_names adm base step] :
‹⟦0 < k; adm⇩↓ P; P σ; ⋀X. P X ⟹ P ((P⇩S⇩K⇩I⇩P⇩S_nd_step (ε A) (τ A) (ω A) ^^ k) X)⟧ ⟹ P P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩n⇩d›
unfolding P⇩S⇩K⇩I⇩P⇩S_nd_def
by (rule restriction_fix_ind_iterated[where f = ‹P⇩S⇩K⇩I⇩P⇩S_nd_step (ε A) (τ A) (ω A)›]) auto
text ‹Correspondence when we always have \<^term>‹ω A σ = {}›.›
lemma P⇩S⇩K⇩I⇩P⇩S_nd_empty_ρ : ‹ρ A = {} ⟹ P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩n⇩d = P⟪A⟫⇩n⇩d›
by (simp add: P⇩S⇩K⇩I⇩P⇩S_nd_def P_nd_def ρ_simps)
lemma P⇩S⇩K⇩I⇩P⇩S_nd_updated_ω: ‹P⟪A⟫⇩n⇩d = P⇩S⇩K⇩I⇩P⇩S⟪A⦇ω := λσ. {}⦈⟫⇩n⇩d›
by (metis (mono_tags, lifting) P⇩S⇩K⇩I⇩P⇩S_nd_empty_ρ P_nd_ω_useless_bis ρ⇩n⇩d.simps
empty_Collect_eq select_convs(2) surjective update_convs(2))
lemma P⇩S⇩K⇩I⇩P⇩S_nd_empty_ρ_inter_ℛ⇩n⇩d:
‹P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩n⇩d σ = P⟪A⟫⇩n⇩d σ› if ‹ρ A ∩ ℛ⇩n⇩d A σ = {}›
proof -
have ‹σ' ∈ ℛ⇩n⇩d A σ ⟹ P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩n⇩d σ' = P⟪A⟫⇩n⇩d σ'› for σ'
proof (induct A arbitrary: σ' rule: P⇩S⇩K⇩I⇩P⇩S_nd_induct)
case adm show ?case by simp
next
case base show ‹P⟪A⟫⇩n⇩d σ' = P⟪A⟫⇩n⇩d σ'› ..
next
case (step X)
from step.prems(1) that have ‹σ' ∉ ρ A› by blast
hence ‹ω A σ' = {}› by (simp add: ρ_simps)
thus ?case
by (subst P_nd_rec, auto intro!: mono_Mprefix_eq mono_GlobalNdet_eq)
(metis (lifting) ℛ⇩n⇩d.simps step.hyps step.prems)
qed
thus ‹P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩n⇩d σ = P⟪A⟫⇩n⇩d σ› by (simp add: ℛ⇩n⇩d.init)
qed
lemma P⇩S⇩K⇩I⇩P⇩S_nd_rec_notin_ρ:
‹σ ∉ ρ A ⟹ P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩n⇩d σ = P_nd_step (ε A) (τ A) P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩n⇩d σ›
by (subst P⇩S⇩K⇩I⇩P⇩S_nd_rec) (simp add: ρ_simps)
lemma P⇩S⇩K⇩I⇩P⇩S_nd_rec_in_ρ: ‹σ ∈ ρ A ⟹ P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩n⇩d σ = SKIPS (ω A σ)›
by (subst P⇩S⇩K⇩I⇩P⇩S_nd_rec, simp add: ρ_simps)
subsection ‹Deterministic Case›
text ‹First version, without final state notion.›
abbreviation P_d_step :: ‹[('σ, 'a) enabl, ('σ, 'a) trans⇩d, 'σ ⇒ ('a, 'r) process⇩p⇩t⇩i⇩c⇩k, 'σ] ⇒ ('a, 'r) process⇩p⇩t⇩i⇩c⇩k›
where ‹P_d_step ε⇩A τ⇩A X s ≡ □ e ∈ ε⇩A s → X ⌈τ⇩A s e⌉›
definition P_d :: ‹('σ, 'a, 'r, 'α) A⇩d_scheme ⇒ 'σ ⇒ ('a, 'r) process⇩p⇩t⇩i⇩c⇩k› (‹P⟪_⟫⇩d› 1000)
where ‹P⟪A⟫⇩d ≡ υ X. P_d_step (ε A) (τ A) X›
lemma P_d_step_constructive[simp] : ‹constructive (P_d_step ε⇩A τ⇩A)› by simp
lemmas P_d_step_constructive_bis = P_d_step_constructive[of ‹ε A› ‹τ A›] for A
lemma P_d_step_cont[simp]: ‹cont (P_d_step ε⇩A τ⇩A)›
by (simp add: cont_fun)
lemmas P_d_step_cont_bis = P_d_step_cont[of ‹ε A› ‹τ A›] for A
lemma P_d_rec: ‹P⟪A⟫⇩d = (λs. P_d_step (ε A) (τ A) P⟪A⟫⇩d s)›
by (unfold P_d_def, subst restriction_fix_eq) simp_all
lemma P_d_is_fix : ‹P⟪A⟫⇩d = (μ X. P_d_step (ε A) (τ A) X)›
by (simp add: P_d_def restriction_fix_is_fix)
lemma P_d_ω_useless: ‹P⟪A⟫⇩d = P⟪A⦇ω := some_ω⦈⟫⇩d›
by (simp add: P_d_def ε_simps)
lemma P_d_ω_useless_bis: ‹P⟪A⟫⇩d = P⟪A⦇ω := λσ. ◇⦈⟫⇩d›
by (fact P_d_ω_useless)
lemma P_d_induct [case_names adm base step] :
‹⟦adm⇩↓ P; P σ; ⋀X. P X ⟹ P (P_d_step (ε A) (τ A) X)⟧ ⟹ P P⟪A⟫⇩d›
unfolding P_d_def
by (rule restriction_fix_ind[OF P_d_step_constructive_bis]) simp_all
lemma P_d_induct_iterated [consumes 1, case_names adm base step] :
‹⟦0 < k; adm⇩↓ P; P σ; ⋀X. P X ⟹ P ((P_d_step (ε A) (τ A) ^^ k) X)⟧ ⟹ P P⟪A⟫⇩d›
unfolding P_d_def
by (rule restriction_fix_ind_iterated[where f = ‹P_d_step (ε A) (τ A)›]) auto
text ‹New version with final state notion where we just \<^const>‹SKIP›.›
abbreviation P⇩S⇩K⇩I⇩P⇩S_d_step ::
‹[('σ, 'a) enabl, ('σ, 'a) trans⇩d, 'σ ⇒ 'r option, 'σ ⇒ ('a, 'r) process⇩p⇩t⇩i⇩c⇩k, 'σ] ⇒ ('a, 'r) process⇩p⇩t⇩i⇩c⇩k›
where ‹P⇩S⇩K⇩I⇩P⇩S_d_step ε⇩A τ⇩A ω⇩A X σ ≡ case ω⇩A σ of ⌊r⌋ ⇒ SKIP r | ◇ ⇒ P_d_step ε⇩A τ⇩A X σ›
definition P⇩S⇩K⇩I⇩P⇩S_d :: ‹('σ, 'a, 'r, 'α) A⇩d_scheme ⇒ 'σ ⇒ ('a, 'r) process⇩p⇩t⇩i⇩c⇩k› (‹P⇩S⇩K⇩I⇩P⇩S⟪_⟫⇩d› 1000)
where ‹P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩d ≡ υ X. P⇩S⇩K⇩I⇩P⇩S_d_step (ε A) (τ A) (ω A) X›
lemma P⇩S⇩K⇩I⇩P⇩S_d_step_constructive[simp]: ‹constructive (P⇩S⇩K⇩I⇩P⇩S_d_step ε⇩A τ⇩A 𝒮⇩F⇩A)›
by (auto simp add: option.case_eq_if)
lemmas P⇩S⇩K⇩I⇩P⇩S_d_step_constructive_bis = P⇩S⇩K⇩I⇩P⇩S_d_step_constructive[of ‹ε A› ‹τ A› ‹ω A›] for A
lemma P⇩S⇩K⇩I⇩P⇩S_d_step_cont[simp]: ‹cont (P⇩S⇩K⇩I⇩P⇩S_d_step ε⇩A τ⇩A 𝒮⇩F⇩A)›
by (simp add: cont_fun option.case_eq_if)
lemmas P⇩S⇩K⇩I⇩P⇩S_d_step_cont_bis = P⇩S⇩K⇩I⇩P⇩S_d_step_cont[of ‹ε A› ‹τ A› ‹ω A›] for A
lemma P⇩S⇩K⇩I⇩P⇩S_d_rec: ‹P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩d = (λσ. P⇩S⇩K⇩I⇩P⇩S_d_step (ε A) (τ A) (ω A) P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩d σ)›
by (unfold P⇩S⇩K⇩I⇩P⇩S_d_def, subst restriction_fix_eq) auto
lemma P⇩S⇩K⇩I⇩P⇩S_d_is_fix : ‹P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩d = (μ X. P⇩S⇩K⇩I⇩P⇩S_d_step (ε A) (τ A) (ω A) X)›
by (simp add: P⇩S⇩K⇩I⇩P⇩S_d_def restriction_fix_is_fix)
lemma P⇩S⇩K⇩I⇩P⇩S_d_induct [case_names adm base step] :
‹adm⇩↓ P ⟹ P σ ⟹ (⋀X. P X ⟹ P (P⇩S⇩K⇩I⇩P⇩S_d_step (ε A) (τ A) (ω A) X)) ⟹ P P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩d›
unfolding P⇩S⇩K⇩I⇩P⇩S_d_def
by (rule restriction_fix_ind[OF P⇩S⇩K⇩I⇩P⇩S_d_step_constructive_bis]) simp_all
lemma P⇩S⇩K⇩I⇩P⇩S_d_induct_iterated [consumes 1, case_names adm base step] :
‹⟦0 < k; adm⇩↓ P; P σ; ⋀X. P X ⟹ P ((P⇩S⇩K⇩I⇩P⇩S_d_step (ε A) (τ A) (ω A) ^^ k) X)⟧ ⟹ P P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩d›
unfolding P⇩S⇩K⇩I⇩P⇩S_d_def
by (rule restriction_fix_ind_iterated[where f = ‹P⇩S⇩K⇩I⇩P⇩S_d_step (ε A) (τ A) (ω A)›]) auto
text ‹Correspondence when we always have \<^term>‹ω A σ = {}›.›
lemma P⇩S⇩K⇩I⇩P⇩S_d_empty_ρ : ‹ρ A = {} ⟹ P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩d = P⟪A⟫⇩d›
by (simp add: ρ_simps P_d_def P⇩S⇩K⇩I⇩P⇩S_d_def)
lemma P⇩S⇩K⇩I⇩P⇩S_d_updated_ω: ‹P⟪A⟫⇩d = P⇩S⇩K⇩I⇩P⇩S⟪A⦇ω := λσ. ◇⦈⟫⇩d›
by (simp add: P⇩S⇩K⇩I⇩P⇩S_d_empty_ρ P_d_ω_useless ρ_simps)
lemma P⇩S⇩K⇩I⇩P⇩S_d_empty_ρ_inter_ℛ⇩d:
‹P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩d σ = P⟪A⟫⇩d σ› if ‹ρ A ∩ ℛ⇩d A σ = {}›
proof -
have ‹σ' ∈ ℛ⇩d A σ ⟹ P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩d σ' = P⟪A⟫⇩d σ'› for σ'
proof (induct A arbitrary: σ' rule: P⇩S⇩K⇩I⇩P⇩S_d_induct)
case adm show ?case by simp
next
case base show ‹P⟪A⟫⇩d σ' = P⟪A⟫⇩d σ'› ..
next
case (step X)
from step.prems(1) that have ‹σ' ∉ ρ A› by blast
hence ‹ω A σ' = ◇› by (simp add: ρ_simps)
thus ?case
by (subst P_d_rec, auto intro!: mono_Mprefix_eq mono_GlobalNdet_eq)
(subst (asm) ε_simps, auto, metis (lifting) ℛ⇩d.step step.hyps step.prems)
qed
thus ‹P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩d σ = P⟪A⟫⇩d σ› by (simp add: ℛ⇩d.init)
qed
lemma P⇩S⇩K⇩I⇩P⇩S_d_rec_notin_ρ:
‹σ ∉ ρ A ⟹ P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩d σ = P_d_step (ε A) (τ A) P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩d σ›
by (subst P⇩S⇩K⇩I⇩P⇩S_d_rec) (simp add: ρ_simps)
lemma P⇩S⇩K⇩I⇩P⇩S_d_rec_in_ρ: ‹σ ∈ ρ A ⟹ P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩d σ = SKIP ⌈ω A σ⌉›
by (subst P⇩S⇩K⇩I⇩P⇩S_d_rec, simp add: ρ_simps split: option.split)
subsection ‹Link between deterministic and non-deterministic ProcOmata›
lemma P⇩S⇩K⇩I⇩P⇩S_nd_from_det_to_ndet_is_P⇩S⇩K⇩I⇩P⇩S_d : ‹P⇩S⇩K⇩I⇩P⇩S⟪⟪A⟫⇩d⇩↪⇩n⇩d⟫⇩n⇩d = P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩d›
proof (subst P⇩S⇩K⇩I⇩P⇩S_nd_def, rule restriction_fix_unique)
show ‹constructive (P⇩S⇩K⇩I⇩P⇩S_nd_step (ε ⟪A⟫⇩d⇩↪⇩n⇩d) (τ ⟪A⟫⇩d⇩↪⇩n⇩d) (ω ⟪A⟫⇩d⇩↪⇩n⇩d))› by simp
next
show ‹P⇩S⇩K⇩I⇩P⇩S_nd_step (ε ⟪A⟫⇩d⇩↪⇩n⇩d) (τ ⟪A⟫⇩d⇩↪⇩n⇩d) (ω ⟪A⟫⇩d⇩↪⇩n⇩d) P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩d = P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩d›
by (subst (3) P⇩S⇩K⇩I⇩P⇩S_d_rec)
(rule ext, auto simp add: from_det_to_ndet_def ε_simps
split: option.split intro: mono_Mprefix_eq)
qed
corollary P_nd_from_det_to_ndet_is_P_d : ‹P⟪⟪A⟫⇩d⇩↪⇩n⇩d⟫⇩n⇩d = P⟪A⟫⇩d›
proof -
have ‹P⟪⟪A⟫⇩d⇩↪⇩n⇩d⟫⇩n⇩d = P⇩S⇩K⇩I⇩P⇩S⟪⟪A⟫⇩d⇩↪⇩n⇩d⦇ω := λσ. {}⦈⟫⇩n⇩d›
by (fact P⇩S⇩K⇩I⇩P⇩S_nd_updated_ω)
also have ‹⟪A⟫⇩d⇩↪⇩n⇩d⦇ω := λσ. {}⦈ = ⟪A⦇ω := λσ. ◇⦈⟫⇩d⇩↪⇩n⇩d›
by (simp add: from_det_to_ndet_def)
finally show ‹P⟪⟪A⟫⇩d⇩↪⇩n⇩d⟫⇩n⇩d = P⟪A⟫⇩d›
by (simp add: P⇩S⇩K⇩I⇩P⇩S_d_updated_ω P⇩S⇩K⇩I⇩P⇩S_nd_from_det_to_ndet_is_P⇩S⇩K⇩I⇩P⇩S_d)
qed
subsection ‹Prove Equality between ProcOmata›
subsubsection ‹This is the easiest method we can think about.›
lemma P_d_eqI : ‹(⋀σ a. τ A σ a = τ B σ a) ⟹ P⟪A⟫⇩d = P⟪B⟫⇩d›
by (simp add: P_d_def ε_simps)
lemma P_nd_eqI : ‹(⋀σ a. τ A σ a = τ B σ a) ⟹ P⟪A⟫⇩n⇩d = P⟪B⟫⇩n⇩d›
by (simp add: P_nd_def ε_simps)
lemma P⇩S⇩K⇩I⇩P⇩S_d_eqI :
‹(⋀σ a. σ ∉ ρ A ⟹ τ A σ a = τ B σ a) ⟹ (⋀σ. ω A σ = ω B σ) ⟹ P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩d = P⇩S⇩K⇩I⇩P⇩S⟪B⟫⇩d›
by (subst P⇩S⇩K⇩I⇩P⇩S_d_def, rule restriction_fix_unique, simp)
(subst (2) P⇩S⇩K⇩I⇩P⇩S_d_rec, auto simp add: ε_simps ρ_simps split: option.split)
lemma P⇩S⇩K⇩I⇩P⇩S_nd_eqI :
‹(⋀σ a. σ ∉ ρ A ⟹ τ A σ a = τ B σ a) ⟹ (⋀σ. ω A σ = ω B σ) ⟹ P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩n⇩d = P⇩S⇩K⇩I⇩P⇩S⟪B⟫⇩n⇩d›
by (subst P⇩S⇩K⇩I⇩P⇩S_nd_def, rule restriction_fix_unique[OF P⇩S⇩K⇩I⇩P⇩S_nd_step_constructive])
(subst (2) P⇩S⇩K⇩I⇩P⇩S_nd_rec, auto simp add: ε_simps ρ_simps split: option.split)
subsubsection ‹We establish now a much more powerful theorem.›
theorem P⇩S⇩K⇩I⇩P⇩S_nd_eqI_strong:
assumes inj_on_f : ‹inj_on f (ℛ⇩n⇩d A⇩0 σ⇩0)›
and eq_trans : ‹⋀σ⇩0' a. σ⇩0' ∈ ℛ⇩n⇩d A⇩0 σ⇩0 ⟹ τ A⇩1 (f σ⇩0') a = f ` (τ A⇩0 σ⇩0' a)›
and eq_fin : ‹⋀σ⇩0'. σ⇩0' ∈ ℛ⇩n⇩d A⇩0 σ⇩0 ⟹ ω A⇩1 (f σ⇩0') = ω A⇩0 σ⇩0'›
shows ‹P⇩S⇩K⇩I⇩P⇩S⟪A⇩0⟫⇩n⇩d σ⇩0 = P⇩S⇩K⇩I⇩P⇩S⟪A⇩1⟫⇩n⇩d (f σ⇩0)›
proof -
have ‹σ⇩0' ∈ ℛ⇩n⇩d A⇩0 σ⇩0 ⟹ P⇩S⇩K⇩I⇩P⇩S⟪A⇩1⟫⇩n⇩d (f σ⇩0') = P⇩S⇩K⇩I⇩P⇩S⟪A⇩0⟫⇩n⇩d σ⇩0'› for σ⇩0'
proof (induct A⇩1 arbitrary: σ⇩0' rule: P⇩S⇩K⇩I⇩P⇩S_nd_induct)
case adm show ?case by simp
next
show ‹σ⇩0' ∈ ℛ⇩n⇩d A⇩0 σ⇩0 ⟹ P⇩S⇩K⇩I⇩P⇩S⟪A⇩0⟫⇩n⇩d (inv_into (ℛ⇩n⇩d A⇩0 σ⇩0) f (f σ⇩0')) = P⇩S⇩K⇩I⇩P⇩S⟪A⇩0⟫⇩n⇩d σ⇩0'› for σ⇩0'
by (simp add: inj_on_f)
next
case (step X)
from step.prems eq_trans have ‹ε A⇩0 σ⇩0' = ε A⇩1 (f σ⇩0')›
by (auto simp add: ε_simps)
moreover have ‹ω A⇩1 (f σ⇩0') = ω A⇩0 σ⇩0'› by (simp add: eq_fin step.prems)
ultimately show ?case
by (subst P⇩S⇩K⇩I⇩P⇩S_nd_rec, auto)
(metis (mono_tags, lifting) ℛ⇩n⇩d.step eq_trans mono_GlobalNdet_eq2
step.hyps step.prems)
qed
thus ‹P⇩S⇩K⇩I⇩P⇩S⟪A⇩0⟫⇩n⇩d σ⇩0 = P⇩S⇩K⇩I⇩P⇩S⟪A⇩1⟫⇩n⇩d (f σ⇩0)› by (simp add: ℛ⇩n⇩d.init)
qed
theorem P_nd_eqI_strong:
‹⟦inj_on f (ℛ⇩n⇩d A⇩0 σ⇩0);
⋀σ⇩0' a. σ⇩0' ∈ ℛ⇩n⇩d A⇩0 σ⇩0 ⟹ τ A⇩1 (f σ⇩0') a = f ` (τ A⇩0 σ⇩0' a)⟧
⟹ P⟪A⇩0⟫⇩n⇩d σ⇩0 = P⟪A⇩1⟫⇩n⇩d (f σ⇩0)›
by (unfold P⇩S⇩K⇩I⇩P⇩S_nd_updated_ω, rule P⇩S⇩K⇩I⇩P⇩S_nd_eqI_strong) simp_all
theorem P⇩S⇩K⇩I⇩P⇩S_d_eqI_strong:
assumes ‹inj_on f (ℛ⇩d A⇩0 σ⇩0)›
and ‹⋀σ⇩0' a. σ⇩0' ∈ ℛ⇩d A⇩0 σ⇩0 ⟹ τ A⇩1 (f σ⇩0') a = map_option f (τ A⇩0 σ⇩0' a)›
and ‹⋀σ⇩0'. σ⇩0' ∈ ℛ⇩d A⇩0 σ⇩0 ⟹ ω A⇩1 (f σ⇩0') = ω A⇩0 σ⇩0'›
shows ‹P⇩S⇩K⇩I⇩P⇩S⟪A⇩0⟫⇩d σ⇩0 = P⇩S⇩K⇩I⇩P⇩S⟪A⇩1⟫⇩d (f σ⇩0)›
by (fold P⇩S⇩K⇩I⇩P⇩S_nd_from_det_to_ndet_is_P⇩S⇩K⇩I⇩P⇩S_d, rule P⇩S⇩K⇩I⇩P⇩S_nd_eqI_strong)
(unfold ℛ⇩n⇩d_from_det_to_ndet,
simp_all add: assms from_det_to_ndet_def map_option_case split: option.split)
theorem P_d_eqI_strong:
‹⟦inj_on f (ℛ⇩d A⇩0 σ⇩0);
⋀σ⇩0' a. σ⇩0' ∈ ℛ⇩d A⇩0 σ⇩0 ⟹ τ A⇩1 (f σ⇩0') a = map_option f (τ A⇩0 σ⇩0' a)⟧
⟹ P⟪A⇩0⟫⇩d σ⇩0 = P⟪A⇩1⟫⇩d (f σ⇩0)›
by (unfold P⇩S⇩K⇩I⇩P⇩S_d_updated_ω, rule P⇩S⇩K⇩I⇩P⇩S_d_eqI_strong) simp_all
lemmas P⇩S⇩K⇩I⇩P⇩S_nd_eqI_strong_id = P⇩S⇩K⇩I⇩P⇩S_nd_eqI_strong[of id, simplified]
and P⇩S⇩K⇩I⇩P⇩S_d_eqI_strong_id = P⇩S⇩K⇩I⇩P⇩S_d_eqI_strong
[of id, simplified id_def option.map_ident, simplified]
and P_nd_eqI_strong_id = P_nd_eqI_strong[of id, simplified]
and P_d_eqI_strong_id = P_d_eqI_strong
[of id, simplified id_def option.map_ident, simplified]
corollary P⇩S⇩K⇩I⇩P⇩S_nd_from_σ_to_σs_is_P⇩S⇩K⇩I⇩P⇩S_nd : ‹P⇩S⇩K⇩I⇩P⇩S⟪⇩n⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s⟫⇩n⇩d [σ] = P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩n⇩d σ›
by (auto simp add: image_iff behaviour_σ_σs_conv(6, 8)
intro!: inj_onI P⇩S⇩K⇩I⇩P⇩S_nd_eqI_strong[symmetric])
corollary P⇩S⇩K⇩I⇩P⇩S_d_from_σ_to_σs_is_P⇩S⇩K⇩I⇩P⇩S_d : ‹P⇩S⇩K⇩I⇩P⇩S⟪⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s⟫⇩d [σ] = P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩d σ›
by (auto simp add: image_iff behaviour_σ_σs_conv(2, 4)
intro!: inj_onI P⇩S⇩K⇩I⇩P⇩S_d_eqI_strong[symmetric] split: option.split)
corollary P_nd_from_σ_to_σs_is_P_nd : ‹P⟪⇩n⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s⟫⇩n⇩d [σ] = P⟪A⟫⇩n⇩d σ›
by (auto simp add: image_iff behaviour_σ_σs_conv(6, 8)
intro!: inj_onI P_nd_eqI_strong[symmetric])
corollary P_d_from_σ_to_σs_is_P_d : ‹P⟪⇩d⟪A⟫⇩σ⇩↪⇩σ⇩s⟫⇩d [σ] = P⟪A⟫⇩d σ›
by (auto simp add: image_iff behaviour_σ_σs_conv(2, 4)
intro!: inj_onI P_d_eqI_strong[symmetric] split: option.split)
text ‹Behaviour of normalizations. We will use the following methods in combining theories.›
fun recursive_modifier_fun⇩d :: ‹[('σ × 'a) ⇒ 'σ option, (('σ × 'a) × 'σ option) list] ⇒ ('σ × 'a) ⇒ 'σ option›
where ‹recursive_modifier_fun⇩d f [] = f›
| ‹recursive_modifier_fun⇩d f (((s, e), t) # 𝒢⇩A) = recursive_modifier_fun⇩d (f((s, e) := t)) 𝒢⇩A›
abbreviation recursive_constructor_A⇩d :: ‹[(('σ × 'a) × 'σ option) list, 'σ ⇒ 'r option] ⇒ ('σ, 'a, 'r) A⇩d›
where ‹recursive_constructor_A⇩d 𝒢⇩A ω⇩A ≡ ⦇τ = curry (recursive_modifier_fun⇩d (λ(s, e). ◇) 𝒢⇩A), ω = ω⇩A⦈›
lemma ε_det_breaker:
‹ε (⦇τ = curry (g((σ'::'σ, a) ↦ σ''::'σ)), ω = some_ω, … = some_more⦈ ) σ =
(if σ = σ' then {a} ∪ ε ⦇τ = curry g, ω = some_ω⦈ σ' else ε ⦇τ = curry g, ω = some_ω⦈ σ)›
by (auto simp add: ε_simps split: if_splits)
method ε_det_calc = (unfold recursive_modifier_fun⇩d.simps ε_det_breaker, simp cong: if_cong)[1]
method τ_det_calc = (unfold recursive_modifier_fun⇩d.simps, simp cong: if_cong)[1]
lemma bij_Renaming_P⇩S⇩K⇩I⇩P⇩S_nd :
fixes A :: ‹('σ, 'a, 'r, 'α) A⇩n⇩d_scheme› and f :: ‹'a ⇒ 'b› and g :: ‹'r ⇒ 's›
assumes ‹bij f›
defines B_def : ‹B ≡ ⦇τ = λσ b. τ A σ (inv f b), ω = λσ. g ` (ω A σ)⦈›
shows ‹Renaming (P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩n⇩d σ) f g = P⇩S⇩K⇩I⇩P⇩S⟪B⟫⇩n⇩d σ› (is ‹?lhs σ = _›)
proof (rule fun_cong[of ?lhs ‹P⇩S⇩K⇩I⇩P⇩S⟪B⟫⇩n⇩d› σ])
show ‹?lhs = P⇩S⇩K⇩I⇩P⇩S⟪B⟫⇩n⇩d›
proof (rule restriction_fix_unique[OF P⇩S⇩K⇩I⇩P⇩S_nd_step_constructive_bis[of B],
symmetric, folded P⇩S⇩K⇩I⇩P⇩S_nd_def])
show ‹P⇩S⇩K⇩I⇩P⇩S_nd_step (ε B) (τ B) (ω B) ?lhs = ?lhs›
proof (rule ext)
have * : ‹ε B σ = f ` ε A σ› for σ
by (simp add: B_def ε_simps image_def) (metis ‹bij f› bij_inv_eq_iff)
have ** : ‹inv f (f a) = a› for a
by (metis ‹bij f› bij_inv_eq_iff)
have *** : ‹(THE a'. f a' = f a) = a› for a
by (rule the1_equality', metis (mono_tags, lifting) Uniq_I assms(1) bij_betw_def injD, simp)
show ‹P⇩S⇩K⇩I⇩P⇩S_nd_step (ε B) (τ B) (ω B) ?lhs σ = ?lhs σ› for σ
by (subst (2) P⇩S⇩K⇩I⇩P⇩S_nd_rec, simp add: "*")
(auto simp add: "**" "***" B_def Renaming_distrib_GlobalNdet
Renaming_Mprefix_image_inj[OF ‹bij f›[THEN bij_is_inj]]
intro: mono_Mprefix_eq)
qed
qed
qed
lemma bij_Renaming_P⇩S⇩K⇩I⇩P⇩S_d :
‹bij f ⟹ Renaming (P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩d σ) f g =
P⇩S⇩K⇩I⇩P⇩S⟪⦇τ = λσ b. τ A σ (inv f b), ω = λσ. map_option g (ω A σ)⦈⟫⇩d σ›
by (subst (1 2) P⇩S⇩K⇩I⇩P⇩S_nd_from_det_to_ndet_is_P⇩S⇩K⇩I⇩P⇩S_d[symmetric],
subst bij_Renaming_P⇩S⇩K⇩I⇩P⇩S_nd, assumption)
(rule fun_cong[of _ _ σ], rule P⇩S⇩K⇩I⇩P⇩S_nd_eqI,
simp_all add: from_det_to_ndet_def split: option.split)
lemma RenamingTick_P⇩S⇩K⇩I⇩P⇩S_nd :
‹RenamingTick (P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩n⇩d σ) g = P⇩S⇩K⇩I⇩P⇩S⟪⦇τ = τ A, ω = λσ. g ` ω A σ⦈⟫⇩n⇩d σ›
by (simp add: bij_Renaming_P⇩S⇩K⇩I⇩P⇩S_nd)
lemma RenamingTick_P⇩S⇩K⇩I⇩P⇩S_d :
‹RenamingTick (P⇩S⇩K⇩I⇩P⇩S⟪A⟫⇩d σ) g = P⇩S⇩K⇩I⇩P⇩S⟪⦇τ = τ A, ω = λσ. map_option g (ω A σ)⦈⟫⇩d σ›
by (simp add: bij_Renaming_P⇩S⇩K⇩I⇩P⇩S_d)
end