Theory Transactions
section‹Protocol Transactions›
theory Transactions
imports
Stateful_Protocol_Composition_and_Typing.Typed_Model
Stateful_Protocol_Composition_and_Typing.Labeled_Stateful_Strands
begin
subsection ‹Definitions›
datatype 'b prot_atom =
is_Atom: Atom 'b
| Value
| SetType
| AttackType
| Bottom
| OccursSecType
datatype ('a,'b,'c) prot_fun =
Fu (the_Fu: 'a)
| Set (the_Set: 'c)
| Val (the_Val: "nat × bool")
| Abs (the_Abs: "'c set")
| Pair
| Attack nat
| PubConstAtom 'b nat
| PubConstSetType nat
| PubConstAttackType nat
| PubConstBottom nat
| PubConstOccursSecType nat
| OccursFact
| OccursSec
definition "is_Fun_Set t ≡ is_Fun t ∧ args t = [] ∧ is_Set (the_Fun t)"
abbreviation occurs where
"occurs t ≡ Fun OccursFact [Fun OccursSec [], t]"
type_synonym ('a,'b,'c) prot_term_type = "(('a,'b,'c) prot_fun,'b prot_atom) term_type"
type_synonym ('a,'b,'c) prot_var = "('a,'b,'c) prot_term_type × nat"
type_synonym ('a,'b,'c) prot_term = "(('a,'b,'c) prot_fun,('a,'b,'c) prot_var) term"
type_synonym ('a,'b,'c) prot_terms = "('a,'b,'c) prot_term set"
type_synonym ('a,'b,'c) prot_subst = "(('a,'b,'c) prot_fun, ('a,'b,'c) prot_var) subst"
type_synonym ('a,'b,'c,'d) prot_strand_step =
"(('a,'b,'c) prot_fun, ('a,'b,'c) prot_var, 'd) labeled_stateful_strand_step"
type_synonym ('a,'b,'c,'d) prot_strand = "('a,'b,'c,'d) prot_strand_step list"
type_synonym ('a,'b,'c,'d) prot_constr = "('a,'b,'c,'d) prot_strand_step list"
datatype ('a,'b,'c,'d) prot_transaction =
Transaction
(transaction_fresh: "('a,'b,'c) prot_var list")
(transaction_receive: "('a,'b,'c,'d) prot_strand")
(transaction_selects: "('a,'b,'c,'d) prot_strand")
(transaction_checks: "('a,'b,'c,'d) prot_strand")
(transaction_updates: "('a,'b,'c,'d) prot_strand")
(transaction_send: "('a,'b,'c,'d) prot_strand")
definition transaction_strand where
"transaction_strand T ≡
transaction_receive T@transaction_selects T@transaction_checks T@
transaction_updates T@transaction_send T"
fun transaction_proj where
"transaction_proj l (Transaction A B C D E F) = (
let f = proj l
in Transaction A (f B) (f C) (f D) (f E) (f F))"
fun transaction_star_proj where
"transaction_star_proj (Transaction A B C D E F) = (
let f = filter is_LabelS
in Transaction A (f B) (f C) (f D) (f E) (f F))"
abbreviation fv_transaction where
"fv_transaction T ≡ fv⇩l⇩s⇩s⇩t (transaction_strand T)"
abbreviation bvars_transaction where
"bvars_transaction T ≡ bvars⇩l⇩s⇩s⇩t (transaction_strand T)"
abbreviation vars_transaction where
"vars_transaction T ≡ vars⇩l⇩s⇩s⇩t (transaction_strand T)"
abbreviation trms_transaction where
"trms_transaction T ≡ trms⇩l⇩s⇩s⇩t (transaction_strand T)"
abbreviation setops_transaction where
"setops_transaction T ≡ setops⇩s⇩s⇩t (unlabel (transaction_strand T))"
definition wellformed_transaction where
"wellformed_transaction T ≡
list_all is_Receive (unlabel (transaction_receive T)) ∧
list_all is_Assignment (unlabel (transaction_selects T)) ∧
list_all is_Check (unlabel (transaction_checks T)) ∧
list_all is_Update (unlabel (transaction_updates T)) ∧
list_all is_Send (unlabel (transaction_send T)) ∧
set (transaction_fresh T) ⊆ fv⇩l⇩s⇩s⇩t (transaction_updates T) ∪ fv⇩l⇩s⇩s⇩t (transaction_send T) ∧
set (transaction_fresh T) ∩ fv⇩l⇩s⇩s⇩t (transaction_receive T) = {} ∧
set (transaction_fresh T) ∩ fv⇩l⇩s⇩s⇩t (transaction_selects T) = {} ∧
fv_transaction T ∩ bvars_transaction T = {} ∧
fv⇩l⇩s⇩s⇩t (transaction_checks T) ⊆ fv⇩l⇩s⇩s⇩t (transaction_receive T) ∪ fv⇩l⇩s⇩s⇩t (transaction_selects T) ∧
fv⇩l⇩s⇩s⇩t (transaction_updates T) ∪ fv⇩l⇩s⇩s⇩t (transaction_send T) - set (transaction_fresh T)
⊆ fv⇩l⇩s⇩s⇩t (transaction_receive T) ∪ fv⇩l⇩s⇩s⇩t (transaction_selects T) ∧
(∀x ∈ set (unlabel (transaction_selects T)).
is_Equality x ⟶ fv (the_rhs x) ⊆ fv⇩l⇩s⇩s⇩t (transaction_receive T))"
type_synonym ('a,'b,'c,'d) prot = "('a,'b,'c,'d) prot_transaction list"
abbreviation Var_Value_term ("⟨_⟩⇩v") where
"⟨n⟩⇩v ≡ Var (Var Value, n)::('a,'b,'c) prot_term"
abbreviation Fun_Fu_term ("⟨_ _⟩⇩t") where
"⟨f T⟩⇩t ≡ Fun (Fu f) T::('a,'b,'c) prot_term"
abbreviation Fun_Fu_const_term ("⟨_⟩⇩c") where
"⟨c⟩⇩c ≡ Fun (Fu c) []::('a,'b,'c) prot_term"
abbreviation Fun_Set_const_term ("⟨_⟩⇩s") where
"⟨f⟩⇩s ≡ Fun (Set f) []::('a,'b,'c) prot_term"
abbreviation Fun_Abs_const_term ("⟨_⟩⇩a") where
"⟨a⟩⇩a ≡ Fun (Abs a) []::('a,'b,'c) prot_term"
abbreviation Fun_Attack_const_term ("attack⟨_⟩") where
"attack⟨n⟩ ≡ Fun (Attack n) []::('a,'b,'c) prot_term"
abbreviation prot_transaction1 ("transaction⇩1 _ _ new _ _ _") where
"transaction⇩1 (S1::('a,'b,'c,'d) prot_strand) S2 new (B::('a,'b,'c) prot_term list) S3 S4
≡ Transaction (map the_Var B) S1 [] S2 S3 S4"
abbreviation prot_transaction2 ("transaction⇩2 _ _ _ _") where
"transaction⇩2 (S1::('a,'b,'c,'d) prot_strand) S2 S3 S4
≡ Transaction [] S1 [] S2 S3 S4"
subsection ‹Lemmata›
lemma prot_atom_UNIV:
"(UNIV::'b prot_atom set) = range Atom ∪ {Value, SetType, AttackType, Bottom, OccursSecType}"
proof -
have "a ∈ range Atom ∨ a = Value ∨ a = SetType ∨ a = AttackType ∨ a = Bottom ∨ a = OccursSecType"
for a::"'b prot_atom"
by (cases a) auto
thus ?thesis by auto
qed
instance prot_atom::(finite) finite
by intro_classes (simp add: prot_atom_UNIV)
instantiation prot_atom::(enum) enum
begin
definition "enum_prot_atom == map Atom enum_class.enum@[Value, SetType, AttackType, Bottom, OccursSecType]"
definition "enum_all_prot_atom P == list_all P (map Atom enum_class.enum@[Value, SetType, AttackType, Bottom, OccursSecType])"
definition "enum_ex_prot_atom P == list_ex P (map Atom enum_class.enum@[Value, SetType, AttackType, Bottom, OccursSecType])"
instance
proof intro_classes
have *: "set (map Atom (enum_class.enum::'a list)) = range Atom"
"distinct (enum_class.enum::'a list)"
using UNIV_enum enum_distinct by auto
show "(UNIV::'a prot_atom set) = set enum_class.enum"
using *(1) by (simp add: prot_atom_UNIV enum_prot_atom_def)
have "set (map Atom enum_class.enum) ∩ set [Value, SetType, AttackType, Bottom, OccursSecType] = {}" by auto
moreover have "inj_on Atom (set (enum_class.enum::'a list))" unfolding inj_on_def by auto
hence "distinct (map Atom (enum_class.enum::'a list))" by (metis *(2) distinct_map)
ultimately show "distinct (enum_class.enum::'a prot_atom list)" by (simp add: enum_prot_atom_def)
have "Ball UNIV P ⟷ Ball (range Atom) P ∧ Ball {Value, SetType, AttackType, Bottom, OccursSecType} P"
for P::"'a prot_atom ⇒ bool"
by (metis prot_atom_UNIV UNIV_I UnE)
thus "enum_class.enum_all P = Ball (UNIV::'a prot_atom set) P" for P
using *(1) Ball_set[of "map Atom enum_class.enum" P]
by (auto simp add: enum_all_prot_atom_def)
have "Bex UNIV P ⟷ Bex (range Atom) P ∨ Bex {Value, SetType, AttackType, Bottom, OccursSecType} P"
for P::"'a prot_atom ⇒ bool"
by (metis prot_atom_UNIV UNIV_I UnE)
thus "enum_class.enum_ex P = Bex (UNIV::'a prot_atom set) P" for P
using *(1) Bex_set[of "map Atom enum_class.enum" P]
by (auto simp add: enum_ex_prot_atom_def)
qed
end
lemma wellformed_transaction_cases:
assumes "wellformed_transaction T"
shows
"(l,x) ∈ set (transaction_receive T) ⟹ ∃t. x = receive⟨t⟩" (is "?A ⟹ ?A'")
"(l,x) ∈ set (transaction_selects T) ⟹
(∃t s. x = ⟨t := s⟩) ∨ (∃t s. x = select⟨t,s⟩)" (is "?B ⟹ ?B'")
"(l,x) ∈ set (transaction_checks T) ⟹
(∃t s. x = ⟨t == s⟩) ∨ (∃t s. x = ⟨t in s⟩) ∨ (∃X F G. x = ∀X⟨∨≠: F ∨∉: G⟩)" (is "?C ⟹ ?C'")
"(l,x) ∈ set (transaction_updates T) ⟹
(∃t s. x = insert⟨t,s⟩) ∨ (∃t s. x = delete⟨t,s⟩)" (is "?D ⟹ ?D'")
"(l,x) ∈ set (transaction_send T) ⟹ ∃t. x = send⟨t⟩" (is "?E ⟹ ?E'")
proof -
have a:
"list_all is_Receive (unlabel (transaction_receive T))"
"list_all is_Assignment (unlabel (transaction_selects T))"
"list_all is_Check (unlabel (transaction_checks T))"
"list_all is_Update (unlabel (transaction_updates T))"
"list_all is_Send (unlabel (transaction_send T))"
using assms unfolding wellformed_transaction_def by metis+
note b = Ball_set unlabel_in
note c = stateful_strand_step.collapse
show "?A ⟹ ?A'" by (metis (mono_tags, lifting) a(1) b c(2))
show "?B ⟹ ?B'" by (metis (mono_tags, lifting) a(2) b c(3,6))
show "?C ⟹ ?C'" by (metis (mono_tags, lifting) a(3) b c(3,6,7))
show "?D ⟹ ?D'" by (metis (mono_tags, lifting) a(4) b c(4,5))
show "?E ⟹ ?E'" by (metis (mono_tags, lifting) a(5) b c(1))
qed
lemma wellformed_transaction_unlabel_cases:
assumes "wellformed_transaction T"
shows
"x ∈ set (unlabel (transaction_receive T)) ⟹ ∃t. x = receive⟨t⟩" (is "?A ⟹ ?A'")
"x ∈ set (unlabel (transaction_selects T)) ⟹
(∃t s. x = ⟨t := s⟩) ∨ (∃t s. x = select⟨t,s⟩)" (is "?B ⟹ ?B'")
"x ∈ set (unlabel (transaction_checks T)) ⟹
(∃t s. x = ⟨t == s⟩) ∨ (∃t s. x = ⟨t in s⟩) ∨ (∃X F G. x = ∀X⟨∨≠: F ∨∉: G⟩)"
(is "?C ⟹ ?C'")
"x ∈ set (unlabel (transaction_updates T)) ⟹
(∃t s. x = insert⟨t,s⟩) ∨ (∃t s. x = delete⟨t,s⟩)" (is "?D ⟹ ?D'")
"x ∈ set (unlabel (transaction_send T)) ⟹ ∃t. x = send⟨t⟩" (is "?E ⟹ ?E'")
proof -
have a:
"list_all is_Receive (unlabel (transaction_receive T))"
"list_all is_Assignment (unlabel (transaction_selects T))"
"list_all is_Check (unlabel (transaction_checks T))"
"list_all is_Update (unlabel (transaction_updates T))"
"list_all is_Send (unlabel (transaction_send T))"
using assms unfolding wellformed_transaction_def by metis+
note b = Ball_set
note c = stateful_strand_step.collapse
show "?A ⟹ ?A'" by (metis (mono_tags, lifting) a(1) b c(2))
show "?B ⟹ ?B'" by (metis (mono_tags, lifting) a(2) b c(3,6))
show "?C ⟹ ?C'" by (metis (mono_tags, lifting) a(3) b c(3,6,7))
show "?D ⟹ ?D'" by (metis (mono_tags, lifting) a(4) b c(4,5))
show "?E ⟹ ?E'" by (metis (mono_tags, lifting) a(5) b c(1))
qed
lemma transaction_strand_subsets[simp]:
"set (transaction_receive T) ⊆ set (transaction_strand T)"
"set (transaction_selects T) ⊆ set (transaction_strand T)"
"set (transaction_checks T) ⊆ set (transaction_strand T)"
"set (transaction_updates T) ⊆ set (transaction_strand T)"
"set (transaction_send T) ⊆ set (transaction_strand T)"
"set (unlabel (transaction_receive T)) ⊆ set (unlabel (transaction_strand T))"
"set (unlabel (transaction_selects T)) ⊆ set (unlabel (transaction_strand T))"
"set (unlabel (transaction_checks T)) ⊆ set (unlabel (transaction_strand T))"
"set (unlabel (transaction_updates T)) ⊆ set (unlabel (transaction_strand T))"
"set (unlabel (transaction_send T)) ⊆ set (unlabel (transaction_strand T))"
unfolding transaction_strand_def unlabel_def by force+
lemma transaction_strand_subst_subsets[simp]:
"set (transaction_receive T ⋅⇩l⇩s⇩s⇩t θ) ⊆ set (transaction_strand T ⋅⇩l⇩s⇩s⇩t θ)"
"set (transaction_selects T ⋅⇩l⇩s⇩s⇩t θ) ⊆ set (transaction_strand T ⋅⇩l⇩s⇩s⇩t θ)"
"set (transaction_checks T ⋅⇩l⇩s⇩s⇩t θ) ⊆ set (transaction_strand T ⋅⇩l⇩s⇩s⇩t θ)"
"set (transaction_updates T ⋅⇩l⇩s⇩s⇩t θ) ⊆ set (transaction_strand T ⋅⇩l⇩s⇩s⇩t θ)"
"set (transaction_send T ⋅⇩l⇩s⇩s⇩t θ) ⊆ set (transaction_strand T ⋅⇩l⇩s⇩s⇩t θ)"
"set (unlabel (transaction_receive T ⋅⇩l⇩s⇩s⇩t θ)) ⊆ set (unlabel (transaction_strand T ⋅⇩l⇩s⇩s⇩t θ))"
"set (unlabel (transaction_selects T ⋅⇩l⇩s⇩s⇩t θ)) ⊆ set (unlabel (transaction_strand T ⋅⇩l⇩s⇩s⇩t θ))"
"set (unlabel (transaction_checks T ⋅⇩l⇩s⇩s⇩t θ)) ⊆ set (unlabel (transaction_strand T ⋅⇩l⇩s⇩s⇩t θ))"
"set (unlabel (transaction_updates T ⋅⇩l⇩s⇩s⇩t θ)) ⊆ set (unlabel (transaction_strand T ⋅⇩l⇩s⇩s⇩t θ))"
"set (unlabel (transaction_send T ⋅⇩l⇩s⇩s⇩t θ)) ⊆ set (unlabel (transaction_strand T ⋅⇩l⇩s⇩s⇩t θ))"
unfolding transaction_strand_def unlabel_def subst_apply_labeled_stateful_strand_def by force+
lemma transaction_dual_subst_unfold:
"unlabel (dual⇩l⇩s⇩s⇩t (transaction_strand T ⋅⇩l⇩s⇩s⇩t θ)) =
unlabel (dual⇩l⇩s⇩s⇩t (transaction_receive T ⋅⇩l⇩s⇩s⇩t θ))@
unlabel (dual⇩l⇩s⇩s⇩t (transaction_selects T ⋅⇩l⇩s⇩s⇩t θ))@
unlabel (dual⇩l⇩s⇩s⇩t (transaction_checks T ⋅⇩l⇩s⇩s⇩t θ))@
unlabel (dual⇩l⇩s⇩s⇩t (transaction_updates T ⋅⇩l⇩s⇩s⇩t θ))@
unlabel (dual⇩l⇩s⇩s⇩t (transaction_send T ⋅⇩l⇩s⇩s⇩t θ))"
by (simp add: transaction_strand_def unlabel_append dual⇩l⇩s⇩s⇩t_append subst_lsst_append)
lemma trms_transaction_unfold:
"trms_transaction T =
trms⇩l⇩s⇩s⇩t (transaction_receive T) ∪ trms⇩l⇩s⇩s⇩t (transaction_selects T) ∪
trms⇩l⇩s⇩s⇩t (transaction_checks T) ∪ trms⇩l⇩s⇩s⇩t (transaction_updates T) ∪
trms⇩l⇩s⇩s⇩t (transaction_send T)"
by (metis trms⇩s⇩s⇩t_append unlabel_append append_assoc transaction_strand_def)
lemma trms_transaction_subst_unfold:
"trms⇩l⇩s⇩s⇩t (transaction_strand T ⋅⇩l⇩s⇩s⇩t θ) =
trms⇩l⇩s⇩s⇩t (transaction_receive T ⋅⇩l⇩s⇩s⇩t θ) ∪ trms⇩l⇩s⇩s⇩t (transaction_selects T ⋅⇩l⇩s⇩s⇩t θ) ∪
trms⇩l⇩s⇩s⇩t (transaction_checks T ⋅⇩l⇩s⇩s⇩t θ) ∪ trms⇩l⇩s⇩s⇩t (transaction_updates T ⋅⇩l⇩s⇩s⇩t θ) ∪
trms⇩l⇩s⇩s⇩t (transaction_send T ⋅⇩l⇩s⇩s⇩t θ)"
by (metis trms⇩s⇩s⇩t_append unlabel_append append_assoc transaction_strand_def subst_lsst_append)
lemma vars_transaction_unfold:
"vars_transaction T =
vars⇩l⇩s⇩s⇩t (transaction_receive T) ∪ vars⇩l⇩s⇩s⇩t (transaction_selects T) ∪
vars⇩l⇩s⇩s⇩t (transaction_checks T) ∪ vars⇩l⇩s⇩s⇩t (transaction_updates T) ∪
vars⇩l⇩s⇩s⇩t (transaction_send T)"
by (metis vars⇩s⇩s⇩t_append unlabel_append append_assoc transaction_strand_def)
lemma vars_transaction_subst_unfold:
"vars⇩l⇩s⇩s⇩t (transaction_strand T ⋅⇩l⇩s⇩s⇩t θ) =
vars⇩l⇩s⇩s⇩t (transaction_receive T ⋅⇩l⇩s⇩s⇩t θ) ∪ vars⇩l⇩s⇩s⇩t (transaction_selects T ⋅⇩l⇩s⇩s⇩t θ) ∪
vars⇩l⇩s⇩s⇩t (transaction_checks T ⋅⇩l⇩s⇩s⇩t θ) ∪ vars⇩l⇩s⇩s⇩t (transaction_updates T ⋅⇩l⇩s⇩s⇩t θ) ∪
vars⇩l⇩s⇩s⇩t (transaction_send T ⋅⇩l⇩s⇩s⇩t θ)"
by (metis vars⇩s⇩s⇩t_append unlabel_append append_assoc transaction_strand_def subst_lsst_append)
lemma fv_transaction_unfold:
"fv_transaction T =
fv⇩l⇩s⇩s⇩t (transaction_receive T) ∪ fv⇩l⇩s⇩s⇩t (transaction_selects T) ∪
fv⇩l⇩s⇩s⇩t (transaction_checks T) ∪ fv⇩l⇩s⇩s⇩t (transaction_updates T) ∪
fv⇩l⇩s⇩s⇩t (transaction_send T)"
by (metis fv⇩s⇩s⇩t_append unlabel_append append_assoc transaction_strand_def)
lemma fv_transaction_subst_unfold:
"fv⇩l⇩s⇩s⇩t (transaction_strand T ⋅⇩l⇩s⇩s⇩t θ) =
fv⇩l⇩s⇩s⇩t (transaction_receive T ⋅⇩l⇩s⇩s⇩t θ) ∪ fv⇩l⇩s⇩s⇩t (transaction_selects T ⋅⇩l⇩s⇩s⇩t θ) ∪
fv⇩l⇩s⇩s⇩t (transaction_checks T ⋅⇩l⇩s⇩s⇩t θ) ∪ fv⇩l⇩s⇩s⇩t (transaction_updates T ⋅⇩l⇩s⇩s⇩t θ) ∪
fv⇩l⇩s⇩s⇩t (transaction_send T ⋅⇩l⇩s⇩s⇩t θ)"
by (metis fv⇩s⇩s⇩t_append unlabel_append append_assoc transaction_strand_def subst_lsst_append)
lemma fv_wellformed_transaction_unfold:
assumes "wellformed_transaction T"
shows "fv_transaction T =
fv⇩l⇩s⇩s⇩t (transaction_receive T) ∪ fv⇩l⇩s⇩s⇩t (transaction_selects T) ∪ set (transaction_fresh T)"
proof -
let ?A = "set (transaction_fresh T)"
let ?B = "fv⇩l⇩s⇩s⇩t (transaction_updates T)"
let ?C = "fv⇩l⇩s⇩s⇩t (transaction_send T)"
let ?D = "fv⇩l⇩s⇩s⇩t (transaction_receive T)"
let ?E = "fv⇩l⇩s⇩s⇩t (transaction_selects T)"
let ?F = "fv⇩l⇩s⇩s⇩t (transaction_checks T)"
have "?A ⊆ ?B ∪ ?C" "?A ∩ ?D = {}" "?A ∩ ?E = {}" "?F ⊆ ?D ∪ ?E" "?B ∪ ?C - ?A ⊆ ?D ∪ ?E"
using assms unfolding wellformed_transaction_def by fast+
thus ?thesis using fv_transaction_unfold by blast
qed
lemma bvars_transaction_unfold:
"bvars_transaction T =
bvars⇩l⇩s⇩s⇩t (transaction_receive T) ∪ bvars⇩l⇩s⇩s⇩t (transaction_selects T) ∪
bvars⇩l⇩s⇩s⇩t (transaction_checks T) ∪ bvars⇩l⇩s⇩s⇩t (transaction_updates T) ∪
bvars⇩l⇩s⇩s⇩t (transaction_send T)"
by (metis bvars⇩s⇩s⇩t_append unlabel_append append_assoc transaction_strand_def)
lemma bvars_transaction_subst_unfold:
"bvars⇩l⇩s⇩s⇩t (transaction_strand T ⋅⇩l⇩s⇩s⇩t θ) =
bvars⇩l⇩s⇩s⇩t (transaction_receive T ⋅⇩l⇩s⇩s⇩t θ) ∪ bvars⇩l⇩s⇩s⇩t (transaction_selects T ⋅⇩l⇩s⇩s⇩t θ) ∪
bvars⇩l⇩s⇩s⇩t (transaction_checks T ⋅⇩l⇩s⇩s⇩t θ) ∪ bvars⇩l⇩s⇩s⇩t (transaction_updates T ⋅⇩l⇩s⇩s⇩t θ) ∪
bvars⇩l⇩s⇩s⇩t (transaction_send T ⋅⇩l⇩s⇩s⇩t θ)"
by (metis bvars⇩s⇩s⇩t_append unlabel_append append_assoc transaction_strand_def subst_lsst_append)
lemma bvars_wellformed_transaction_unfold:
assumes "wellformed_transaction T"
shows "bvars_transaction T = bvars⇩l⇩s⇩s⇩t (transaction_checks T)" (is ?A)
and "bvars⇩l⇩s⇩s⇩t (transaction_receive T) = {}" (is ?B)
and "bvars⇩l⇩s⇩s⇩t (transaction_selects T) = {}" (is ?C)
and "bvars⇩l⇩s⇩s⇩t (transaction_updates T) = {}" (is ?D)
and "bvars⇩l⇩s⇩s⇩t (transaction_send T) = {}" (is ?E)
proof -
have 0: "list_all is_Receive (unlabel (transaction_receive T))"
"list_all is_Assignment (unlabel (transaction_selects T))"
"list_all is_Update (unlabel (transaction_updates T))"
"list_all is_Send (unlabel (transaction_send T))"
using assms unfolding wellformed_transaction_def by metis+
have "filter is_NegChecks (unlabel (transaction_receive T)) = []"
"filter is_NegChecks (unlabel (transaction_selects T)) = []"
"filter is_NegChecks (unlabel (transaction_updates T)) = []"
"filter is_NegChecks (unlabel (transaction_send T)) = []"
using list_all_filter_nil[OF 0(1), of is_NegChecks]
list_all_filter_nil[OF 0(2), of is_NegChecks]
list_all_filter_nil[OF 0(3), of is_NegChecks]
list_all_filter_nil[OF 0(4), of is_NegChecks]
stateful_strand_step.distinct_disc(11,21,29,35,39,41)
by blast+
thus ?A ?B ?C ?D ?E
using bvars_transaction_unfold[of T]
bvars⇩s⇩s⇩t_NegChecks[of "unlabel (transaction_receive T)"]
bvars⇩s⇩s⇩t_NegChecks[of "unlabel (transaction_selects T)"]
bvars⇩s⇩s⇩t_NegChecks[of "unlabel (transaction_updates T)"]
bvars⇩s⇩s⇩t_NegChecks[of "unlabel (transaction_send T)"]
by (metis bvars⇩s⇩s⇩t_def UnionE emptyE list.set(1) list.simps(8) subsetI subset_Un_eq sup_commute)+
qed
lemma transaction_strand_memberD[dest]:
assumes "x ∈ set (transaction_strand T)"
shows "x ∈ set (transaction_receive T) ∨ x ∈ set (transaction_selects T) ∨
x ∈ set (transaction_checks T) ∨ x ∈ set (transaction_updates T) ∨
x ∈ set (transaction_send T)"
using assms by (simp add: transaction_strand_def)
lemma transaction_strand_unlabel_memberD[dest]:
assumes "x ∈ set (unlabel (transaction_strand T))"
shows "x ∈ set (unlabel (transaction_receive T)) ∨ x ∈ set (unlabel (transaction_selects T)) ∨
x ∈ set (unlabel (transaction_checks T)) ∨ x ∈ set (unlabel (transaction_updates T)) ∨
x ∈ set (unlabel (transaction_send T))"
using assms by (simp add: unlabel_def transaction_strand_def)
lemma wellformed_transaction_strand_memberD[dest]:
assumes "wellformed_transaction T" and "(l,x) ∈ set (transaction_strand T)"
shows
"x = receive⟨t⟩ ⟹ (l,x) ∈ set (transaction_receive T)" (is "?A ⟹ ?A'")
"x = select⟨t,s⟩ ⟹ (l,x) ∈ set (transaction_selects T)" (is "?B ⟹ ?B'")
"x = ⟨t == s⟩ ⟹ (l,x) ∈ set (transaction_checks T)" (is "?C ⟹ ?C'")
"x = ⟨t in s⟩ ⟹ (l,x) ∈ set (transaction_checks T)" (is "?D ⟹ ?D'")
"x = ∀X⟨∨≠: F ∨∉: G⟩ ⟹ (l,x) ∈ set (transaction_checks T)" (is "?E ⟹ ?E'")
"x = insert⟨t,s⟩ ⟹ (l,x) ∈ set (transaction_updates T)" (is "?F ⟹ ?F'")
"x = delete⟨t,s⟩ ⟹ (l,x) ∈ set (transaction_updates T)" (is "?G ⟹ ?G'")
"x = send⟨t⟩ ⟹ (l,x) ∈ set (transaction_send T)" (is "?H ⟹ ?H'")
proof -
have "(l,x) ∈ set (transaction_receive T) ∨ (l,x) ∈ set (transaction_selects T) ∨
(l,x) ∈ set (transaction_checks T) ∨ (l,x) ∈ set (transaction_updates T) ∨
(l,x) ∈ set (transaction_send T)"
using assms(2) by auto
thus "?A ⟹ ?A'" "?B ⟹ ?B'" "?C ⟹ ?C'" "?D ⟹ ?D'"
"?E ⟹ ?E'" "?F ⟹ ?F'" "?G ⟹ ?G'" "?H ⟹ ?H'"
using wellformed_transaction_cases[OF assms(1)] by fast+
qed
lemma wellformed_transaction_strand_unlabel_memberD[dest]:
assumes "wellformed_transaction T" and "x ∈ set (unlabel (transaction_strand T))"
shows
"x = receive⟨t⟩ ⟹ x ∈ set (unlabel (transaction_receive T))" (is "?A ⟹ ?A'")
"x = select⟨t,s⟩ ⟹ x ∈ set (unlabel (transaction_selects T))" (is "?B ⟹ ?B'")
"x = ⟨t == s⟩ ⟹ x ∈ set (unlabel (transaction_checks T))" (is "?C ⟹ ?C'")
"x = ⟨t in s⟩ ⟹ x ∈ set (unlabel (transaction_checks T))" (is "?D ⟹ ?D'")
"x = ∀X⟨∨≠: F ∨∉: G⟩ ⟹ x ∈ set (unlabel (transaction_checks T))" (is "?E ⟹ ?E'")
"x = insert⟨t,s⟩ ⟹ x ∈ set (unlabel (transaction_updates T))" (is "?F ⟹ ?F'")
"x = delete⟨t,s⟩ ⟹ x ∈ set (unlabel (transaction_updates T))" (is "?G ⟹ ?G'")
"x = send⟨t⟩ ⟹ x ∈ set (unlabel (transaction_send T))" (is "?H ⟹ ?H'")
proof -
have "x ∈ set (unlabel (transaction_receive T)) ∨ x ∈ set (unlabel (transaction_selects T)) ∨
x ∈ set (unlabel (transaction_checks T)) ∨ x ∈ set (unlabel (transaction_updates T)) ∨
x ∈ set (unlabel (transaction_send T))"
using assms(2) by auto
thus "?A ⟹ ?A'" "?B ⟹ ?B'" "?C ⟹ ?C'" "?D ⟹ ?D'"
"?E ⟹ ?E'" "?F ⟹ ?F'" "?G ⟹ ?G'" "?H ⟹ ?H'"
using wellformed_transaction_unlabel_cases[OF assms(1)] by fast+
qed
lemma wellformed_transaction_send_receive_trm_cases:
assumes T: "wellformed_transaction T"
shows "t ∈ trms⇩l⇩s⇩s⇩t (transaction_receive T) ⟹ receive⟨t⟩ ∈ set (unlabel (transaction_receive T))"
and "t ∈ trms⇩l⇩s⇩s⇩t (transaction_send T) ⟹ send⟨t⟩ ∈ set (unlabel (transaction_send T))"
using wellformed_transaction_unlabel_cases(1,5)[OF T]
trms⇩s⇩s⇩t_in[of t "unlabel (transaction_receive T)"]
trms⇩s⇩s⇩t_in[of t "unlabel (transaction_send T)"]
by fastforce+
lemma wellformed_transaction_send_receive_subst_trm_cases:
assumes T: "wellformed_transaction T"
shows "t ∈ trms⇩l⇩s⇩s⇩t (transaction_receive T) ⋅⇩s⇩e⇩t θ ⟹ receive⟨t⟩ ∈ set (unlabel (transaction_receive T ⋅⇩l⇩s⇩s⇩t θ))"
and "t ∈ trms⇩l⇩s⇩s⇩t (transaction_send T) ⋅⇩s⇩e⇩t θ ⟹ send⟨t⟩ ∈ set (unlabel (transaction_send T ⋅⇩l⇩s⇩s⇩t θ))"
proof -
assume "t ∈ trms⇩l⇩s⇩s⇩t (transaction_receive T) ⋅⇩s⇩e⇩t θ"
then obtain s where s: "s ∈ trms⇩l⇩s⇩s⇩t (transaction_receive T)" "t = s ⋅ θ"
by blast
hence "receive⟨s⟩ ∈ set (unlabel (transaction_receive T))"
using wellformed_transaction_send_receive_trm_cases(1)[OF T] by simp
thus "receive⟨t⟩ ∈ set (unlabel (transaction_receive T ⋅⇩l⇩s⇩s⇩t θ))"
by (metis s(2) unlabel_subst[of _ θ] stateful_strand_step_subst_inI(2))
next
assume "t ∈ trms⇩l⇩s⇩s⇩t (transaction_send T) ⋅⇩s⇩e⇩t θ"
then obtain s where s: "s ∈ trms⇩l⇩s⇩s⇩t (transaction_send T)" "t = s ⋅ θ"
by blast
hence "send⟨s⟩ ∈ set (unlabel (transaction_send T))"
using wellformed_transaction_send_receive_trm_cases(2)[OF T] by simp
thus "send⟨t⟩ ∈ set (unlabel (transaction_send T ⋅⇩l⇩s⇩s⇩t θ))"
by (metis s(2) unlabel_subst[of _ θ] stateful_strand_step_subst_inI(1))
qed
lemma wellformed_transaction_send_receive_fv_subset:
assumes T: "wellformed_transaction T"
shows "t ∈ trms⇩l⇩s⇩s⇩t (transaction_receive T) ⟹ fv t ⊆ fv_transaction T" (is "?A ⟹ ?A'")
and "t ∈ trms⇩l⇩s⇩s⇩t (transaction_send T) ⟹ fv t ⊆ fv_transaction T" (is "?B ⟹ ?B'")
proof -
have "t ∈ trms⇩l⇩s⇩s⇩t (transaction_receive T) ⟹ receive⟨t⟩ ∈ set (unlabel (transaction_strand T))"
"t ∈ trms⇩l⇩s⇩s⇩t (transaction_send T) ⟹ send⟨t⟩ ∈ set (unlabel (transaction_strand T))"
using wellformed_transaction_send_receive_trm_cases[OF T, of t]
unfolding transaction_strand_def by force+
thus "?A ⟹ ?A'" "?B ⟹ ?B'" by (induct "transaction_strand T") auto
qed
lemma dual_wellformed_transaction_ident_cases[dest]:
"list_all is_Assignment (unlabel S) ⟹ dual⇩l⇩s⇩s⇩t S = S"
"list_all is_Check (unlabel S) ⟹ dual⇩l⇩s⇩s⇩t S = S"
"list_all is_Update (unlabel S) ⟹ dual⇩l⇩s⇩s⇩t S = S"
proof (induction S)
case (Cons s S)
obtain l x where s: "s = (l,x)" by moura
{ case 1 thus ?case using Cons s unfolding unlabel_def dual⇩l⇩s⇩s⇩t_def by (cases x) auto }
{ case 2 thus ?case using Cons s unfolding unlabel_def dual⇩l⇩s⇩s⇩t_def by (cases x) auto }
{ case 3 thus ?case using Cons s unfolding unlabel_def dual⇩l⇩s⇩s⇩t_def by (cases x) auto }
qed simp_all
lemma wellformed_transaction_wf⇩s⇩s⇩t:
fixes T::"('a, 'b, 'c, 'd) prot_transaction"
assumes T: "wellformed_transaction T"
shows "wf'⇩s⇩s⇩t (set (transaction_fresh T)) (unlabel (dual⇩l⇩s⇩s⇩t (transaction_strand T)))" (is ?A)
and "fv_transaction T ∩ bvars_transaction T = {}" (is ?B)
and "set (transaction_fresh T) ∩ bvars_transaction T = {}" (is ?C)
proof -
define T1 where "T1 ≡ unlabel (dual⇩l⇩s⇩s⇩t (transaction_receive T))"
define T2 where "T2 ≡ unlabel (dual⇩l⇩s⇩s⇩t (transaction_selects T))"
define T3 where "T3 ≡ unlabel (dual⇩l⇩s⇩s⇩t (transaction_checks T))"
define T4 where "T4 ≡ unlabel (dual⇩l⇩s⇩s⇩t (transaction_updates T))"
define T5 where "T5 ≡ unlabel (dual⇩l⇩s⇩s⇩t (transaction_send T))"
define X where "X ≡ set (transaction_fresh T)"
define Y where "Y ≡ X ∪ wfvarsoccs⇩s⇩s⇩t T1"
define Z where "Z ≡ Y ∪ wfvarsoccs⇩s⇩s⇩t T2"
define f where "f ≡ λS::(('a,'b,'c) prot_fun, ('a,'b,'c) prot_var) stateful_strand.
⋃((λx. case x of
Receive t ⇒ fv t
| Equality Assign _ t' ⇒ fv t'
| Insert t t' ⇒ fv t ∪ fv t'
| _ ⇒ {}) ` set S)"
note defs1 = T1_def T2_def T3_def T4_def T5_def
note defs2 = X_def Y_def Z_def
note defs3 = f_def
have 0: "wf'⇩s⇩s⇩t V (S @ S')"
when "wf'⇩s⇩s⇩t V S" "f S' ⊆ wfvarsoccs⇩s⇩s⇩t S ∪ V" for V S S'
by (metis that wf⇩s⇩s⇩t_append_suffix' f_def)
have 1: "unlabel (dual⇩l⇩s⇩s⇩t (transaction_strand T)) = T1@T2@T3@T4@T5"
using dual⇩l⇩s⇩s⇩t_append unlabel_append unfolding transaction_strand_def defs1 by simp
have 2:
"∀x ∈ set T1. is_Send x" "∀x ∈ set T2. is_Assignment x" "∀x ∈ set T3. is_Check x"
"∀x ∈ set T4. is_Update x" "∀x ∈ set T5. is_Receive x"
"fv⇩s⇩s⇩t T3 ⊆ fv⇩s⇩s⇩t T1 ∪ fv⇩s⇩s⇩t T2" "fv⇩s⇩s⇩t T4 ∪ fv⇩s⇩s⇩t T5 ⊆ X ∪ fv⇩s⇩s⇩t T1 ∪ fv⇩s⇩s⇩t T2"
"X ∩ fv⇩s⇩s⇩t T1 = {}" "X ∩ fv⇩s⇩s⇩t T2 = {}"
"∀x ∈ set T2. is_Equality x ⟶ fv (the_rhs x) ⊆ fv⇩s⇩s⇩t T1"
using T unfolding defs1 defs2 wellformed_transaction_def
by (auto simp add: Ball_set dual⇩l⇩s⇩s⇩t_list_all fv⇩s⇩s⇩t_unlabel_dual⇩l⇩s⇩s⇩t_eq simp del: fv⇩s⇩s⇩t_def)
have 3: "wf'⇩s⇩s⇩t X T1" using 2(1)
proof (induction T1 arbitrary: X)
case (Cons s T)
obtain t where "s = send⟨t⟩" using Cons.prems by (cases s) moura+
thus ?case using Cons by auto
qed simp
have 4: "f T1 = {}" "fv⇩s⇩s⇩t T1 = wfvarsoccs⇩s⇩s⇩t T1" using 2(1)
proof (induction T1)
case (Cons s T)
{ case 1 thus ?case using Cons unfolding defs3 by (cases s) auto }
{ case 2 thus ?case using Cons unfolding defs3 wfvarsoccs⇩s⇩s⇩t_def fv⇩s⇩s⇩t_def by (cases s) auto }
qed (simp_all add: defs3 wfvarsoccs⇩s⇩s⇩t_def fv⇩s⇩s⇩t_def)
have 5: "f T2 ⊆ wfvarsoccs⇩s⇩s⇩t T1" "fv⇩s⇩s⇩t T2 = f T2 ∪ wfvarsoccs⇩s⇩s⇩t T2" using 2(2,10)
proof (induction T2)
case (Cons s T)
{ case 1 thus ?case using Cons
proof (cases s)
case (Equality ac t t') thus ?thesis using 1 Cons 4(2) unfolding defs3 by (cases ac) auto
qed (simp_all add: defs3)
}
{ case 2 thus ?case using Cons
proof (cases s)
case (Equality ac t t')
hence "ac = Assign" "fv⇩s⇩s⇩t⇩p s = fv t' ∪ wfvarsoccs⇩s⇩s⇩t⇩p s" "f (s#T) = fv t' ∪ f T"
using 2 unfolding defs3 by auto
moreover have "fv⇩s⇩s⇩t T = f T ∪ wfvarsoccs⇩s⇩s⇩t T" using Cons.IH(2) 2 by auto
ultimately show ?thesis unfolding wfvarsoccs⇩s⇩s⇩t_def fv⇩s⇩s⇩t_def by auto
next
case (InSet ac t t')
hence "ac = Assign" "fv⇩s⇩s⇩t⇩p s = wfvarsoccs⇩s⇩s⇩t⇩p s" "f (s#T) = f T"
using 2 unfolding defs3 by auto
moreover have "fv⇩s⇩s⇩t T = f T ∪ wfvarsoccs⇩s⇩s⇩t T" using Cons.IH(2) 2 by auto
ultimately show ?thesis unfolding wfvarsoccs⇩s⇩s⇩t_def fv⇩s⇩s⇩t_def by auto
qed (simp_all add: defs3)
}
qed (simp_all add: defs3 wfvarsoccs⇩s⇩s⇩t_def fv⇩s⇩s⇩t_def)
have "f T ⊆ fv⇩s⇩s⇩t T" for T
proof
fix x show "x ∈ f T ⟹ x ∈ fv⇩s⇩s⇩t T"
proof (induction T)
case (Cons s T) thus ?case
proof (cases "x ∈ f T")
case False thus ?thesis
using Cons.prems unfolding defs3 fv⇩s⇩s⇩t_def
by (auto split: stateful_strand_step.splits poscheckvariant.splits)
qed auto
qed (simp add: defs3 fv⇩s⇩s⇩t_def)
qed
hence 6:
"f T3 ⊆ X ∪ wfvarsoccs⇩s⇩s⇩t T1 ∪ wfvarsoccs⇩s⇩s⇩t T2"
"f T4 ⊆ X ∪ wfvarsoccs⇩s⇩s⇩t T1 ∪ wfvarsoccs⇩s⇩s⇩t T2"
"f T5 ⊆ X ∪ wfvarsoccs⇩s⇩s⇩t T1 ∪ wfvarsoccs⇩s⇩s⇩t T2"
using 2(6,7) 4 5 by blast+
have 7:
"wfvarsoccs⇩s⇩s⇩t T3 = {}"
"wfvarsoccs⇩s⇩s⇩t T4 = {}"
"wfvarsoccs⇩s⇩s⇩t T5 = {}"
using 2(3,4,5) unfolding wfvarsoccs⇩s⇩s⇩t_def
by (auto split: stateful_strand_step.splits)
have 8:
"f T2 ⊆ wfvarsoccs⇩s⇩s⇩t T1 ∪ X"
"f T3 ⊆ wfvarsoccs⇩s⇩s⇩t (T1@T2) ∪ X"
"f T4 ⊆ wfvarsoccs⇩s⇩s⇩t ((T1@T2)@T3) ∪ X"
"f T5 ⊆ wfvarsoccs⇩s⇩s⇩t (((T1@T2)@T3)@T4) ∪ X"
using 4(1) 5(1) 6 7 wfvarsoccs⇩s⇩s⇩t_append[of T1 T2]
wfvarsoccs⇩s⇩s⇩t_append[of "T1@T2" T3]
wfvarsoccs⇩s⇩s⇩t_append[of "(T1@T2)@T3" T4]
by blast+
have "wf'⇩s⇩s⇩t X (T1@T2@T3@T4@T5)"
using 0[OF 0[OF 0[OF 0[OF 3 8(1)] 8(2)] 8(3)] 8(4)]
unfolding Y_def Z_def by simp
thus ?A using 1 unfolding defs1 defs2 by simp
have "set (transaction_fresh T) ⊆ fv⇩l⇩s⇩s⇩t (transaction_updates T) ∪ fv⇩l⇩s⇩s⇩t (transaction_send T)"
"fv_transaction T ∩ bvars_transaction T = {}"
using T unfolding wellformed_transaction_def by fast+
thus ?B ?C using fv_transaction_unfold[of T] bvars_transaction_unfold[of T] by blast+
qed
lemma dual_wellformed_transaction_ident_cases'[dest]:
assumes "wellformed_transaction T"
shows "dual⇩l⇩s⇩s⇩t (transaction_selects T) = transaction_selects T"
"dual⇩l⇩s⇩s⇩t (transaction_checks T) = transaction_checks T"
"dual⇩l⇩s⇩s⇩t (transaction_updates T) = transaction_updates T"
using assms unfolding wellformed_transaction_def by auto
lemma dual_transaction_strand:
assumes "wellformed_transaction T"
shows "dual⇩l⇩s⇩s⇩t (transaction_strand T) =
dual⇩l⇩s⇩s⇩t (transaction_receive T)@transaction_selects T@transaction_checks T@
transaction_updates T@dual⇩l⇩s⇩s⇩t (transaction_send T)"
using dual_wellformed_transaction_ident_cases'[OF assms] dual⇩l⇩s⇩s⇩t_append
unfolding transaction_strand_def by metis
lemma dual_unlabel_transaction_strand:
assumes "wellformed_transaction T"
shows "unlabel (dual⇩l⇩s⇩s⇩t (transaction_strand T)) =
(unlabel (dual⇩l⇩s⇩s⇩t (transaction_receive T)))@(unlabel (transaction_selects T))@
(unlabel (transaction_checks T))@(unlabel (transaction_updates T))@
(unlabel (dual⇩l⇩s⇩s⇩t (transaction_send T)))"
using dual_transaction_strand[OF assms] by (simp add: unlabel_def)
lemma dual_transaction_strand_subst:
assumes "wellformed_transaction T"
shows "dual⇩l⇩s⇩s⇩t (transaction_strand T ⋅⇩l⇩s⇩s⇩t δ) =
(dual⇩l⇩s⇩s⇩t (transaction_receive T)@transaction_selects T@transaction_checks T@
transaction_updates T@dual⇩l⇩s⇩s⇩t (transaction_send T)) ⋅⇩l⇩s⇩s⇩t δ"
proof -
have "dual⇩l⇩s⇩s⇩t (transaction_strand T ⋅⇩l⇩s⇩s⇩t δ) = dual⇩l⇩s⇩s⇩t (transaction_strand T) ⋅⇩l⇩s⇩s⇩t δ"
using dual⇩l⇩s⇩s⇩t_subst by metis
thus ?thesis using dual_transaction_strand[OF assms] by argo
qed
lemma dual_transaction_ik_is_transaction_send:
assumes "wellformed_transaction T"
shows "ik⇩s⇩s⇩t (unlabel (dual⇩l⇩s⇩s⇩t (transaction_strand T))) = trms⇩s⇩s⇩t (unlabel (transaction_send T))"
(is "?A = ?B")
proof -
{ fix t assume "t ∈ ?A"
hence "receive⟨t⟩ ∈ set (unlabel (dual⇩l⇩s⇩s⇩t (transaction_strand T)))" by (simp add: ik⇩s⇩s⇩t_def)
hence "send⟨t⟩ ∈ set (unlabel (transaction_strand T))"
using dual⇩l⇩s⇩s⇩t_unlabel_steps_iff(1) by metis
hence "t ∈ ?B" using wellformed_transaction_strand_unlabel_memberD(8)[OF assms] by force
} moreover {
fix t assume "t ∈ ?B"
hence "send⟨t⟩ ∈ set (unlabel (transaction_send T))"
using wellformed_transaction_unlabel_cases(5)[OF assms] by fastforce
hence "receive⟨t⟩ ∈ set (unlabel (dual⇩l⇩s⇩s⇩t (transaction_send T)))"
using dual⇩l⇩s⇩s⇩t_unlabel_steps_iff(1) by metis
hence "receive⟨t⟩ ∈ set (unlabel (dual⇩l⇩s⇩s⇩t (transaction_strand T)))"
using dual_unlabel_transaction_strand[OF assms] by simp
hence "t ∈ ?A" by (simp add: ik⇩s⇩s⇩t_def)
} ultimately show "?A = ?B" by auto
qed
lemma dual_transaction_ik_is_transaction_send':
fixes δ::"('a,'b,'c) prot_subst"
assumes "wellformed_transaction T"
shows "ik⇩s⇩s⇩t (unlabel (dual⇩l⇩s⇩s⇩t (transaction_strand T ⋅⇩l⇩s⇩s⇩t δ))) =
trms⇩s⇩s⇩t (unlabel (transaction_send T)) ⋅⇩s⇩e⇩t δ" (is "?A = ?B")
using dual_transaction_ik_is_transaction_send[OF assms]
subst_lsst_unlabel[of "dual⇩l⇩s⇩s⇩t (transaction_strand T)" δ]
ik⇩s⇩s⇩t_subst[of "unlabel (dual⇩l⇩s⇩s⇩t (transaction_strand T))" δ]
dual⇩l⇩s⇩s⇩t_subst[of "transaction_strand T" δ]
by auto
lemma db⇩s⇩s⇩t_transaction_prefix_eq:
assumes T: "wellformed_transaction T"
and S: "prefix S (transaction_receive T@transaction_selects T@transaction_checks T)"
shows "db⇩l⇩s⇩s⇩t A = db⇩l⇩s⇩s⇩t (A@dual⇩l⇩s⇩s⇩t (S ⋅⇩l⇩s⇩s⇩t δ))"
proof -
let ?T1 = "transaction_receive T"
let ?T2 = "transaction_selects T"
let ?T3 = "transaction_checks T"
have *: "prefix (unlabel S) (unlabel (?T1@?T2@?T3))" using S prefix_proj(1) by blast
have "list_all is_Receive (unlabel ?T1)"
"list_all is_Assignment (unlabel ?T2)"
"list_all is_Check (unlabel ?T3)"
using T by (simp_all add: wellformed_transaction_def)
hence "∀b ∈ set (unlabel ?T1). ¬is_Insert b ∧ ¬is_Delete b"
"∀b ∈ set (unlabel ?T2). ¬is_Insert b ∧ ¬is_Delete b"
"∀b ∈ set (unlabel ?T3). ¬is_Insert b ∧ ¬is_Delete b"
by (metis (mono_tags, lifting) Ball_set stateful_strand_step.distinct_disc(16,18),
metis (mono_tags, lifting) Ball_set stateful_strand_step.distinct_disc(24,26,33,37),
metis (mono_tags, lifting) Ball_set stateful_strand_step.distinct_disc(24,26,33,35,37,39))
hence "∀b ∈ set (unlabel (?T1@?T2@?T3)). ¬is_Insert b ∧ ¬is_Delete b"
by (auto simp add: unlabel_def)
hence "∀b ∈ set (unlabel S). ¬is_Insert b ∧ ¬is_Delete b"
using * unfolding prefix_def by fastforce
hence "∀b ∈ set (unlabel (dual⇩l⇩s⇩s⇩t S) ⋅⇩s⇩s⇩t δ). ¬is_Insert b ∧ ¬is_Delete b"
proof (induction S)
case (Cons a S)
then obtain l b where "a = (l,b)" by (metis surj_pair)
thus ?case
using Cons unfolding dual⇩l⇩s⇩s⇩t_def unlabel_def subst_apply_stateful_strand_def
by (cases b) auto
qed simp
hence **: "∀b ∈ set (unlabel (dual⇩l⇩s⇩s⇩t (S ⋅⇩l⇩s⇩s⇩t δ))). ¬is_Insert b ∧ ¬is_Delete b"
by (metis dual⇩l⇩s⇩s⇩t_subst_unlabel)
show ?thesis
using db⇩s⇩s⇩t_no_upd_append[OF **] unlabel_append
unfolding db⇩s⇩s⇩t_def by metis
qed
lemma db⇩l⇩s⇩s⇩t_dual⇩l⇩s⇩s⇩t_set_ex:
assumes "d ∈ set (db'⇩l⇩s⇩s⇩t (dual⇩l⇩s⇩s⇩t A ⋅⇩l⇩s⇩s⇩t θ) ℐ D)"
"∀t u. insert⟨t,u⟩ ∈ set (unlabel A) ⟶ (∃s. u = Fun (Set s) [])"
"∀t u. delete⟨t,u⟩ ∈ set (unlabel A) ⟶ (∃s. u = Fun (Set s) [])"
"∀d ∈ set D. ∃s. snd d = Fun (Set s) []"
shows "∃s. snd d = Fun (Set s) []"
using assms
proof (induction A arbitrary: D)
case (Cons a A)
obtain l b where a: "a = (l,b)" by (metis surj_pair)
have 1: "unlabel (dual⇩l⇩s⇩s⇩t (a#A) ⋅⇩l⇩s⇩s⇩t θ) = receive⟨t ⋅ θ⟩#unlabel (dual⇩l⇩s⇩s⇩t A ⋅⇩l⇩s⇩s⇩t θ)"
when "b = send⟨t⟩" for t
by (simp add: a that subst_lsst_unlabel_cons)
have 2: "unlabel (dual⇩l⇩s⇩s⇩t (a#A) ⋅⇩l⇩s⇩s⇩t θ) = send⟨t ⋅ θ⟩#unlabel (dual⇩l⇩s⇩s⇩t A ⋅⇩l⇩s⇩s⇩t θ)"
when "b = receive⟨t⟩" for t
by (simp add: a that subst_lsst_unlabel_cons)
have 3: "unlabel (dual⇩l⇩s⇩s⇩t (a#A) ⋅⇩l⇩s⇩s⇩t θ) = (b ⋅⇩s⇩s⇩t⇩p θ)#unlabel (dual⇩l⇩s⇩s⇩t A ⋅⇩l⇩s⇩s⇩t θ)"
when "∄t. b = send⟨t⟩ ∨ b = receive⟨t⟩"
using a that dual⇩l⇩s⇩s⇩t_Cons subst_lsst_unlabel_cons[of l b]
by (cases b) auto
show ?case using 1 2 3 a Cons by (cases b) fastforce+
qed simp
lemma is_Fun_SetE[elim]:
assumes t: "is_Fun_Set t"
obtains s where "t = Fun (Set s) []"
proof (cases t)
case (Fun f T)
then obtain s where "f = Set s" using t unfolding is_Fun_Set_def by (cases f) moura+
moreover have "T = []" using Fun t unfolding is_Fun_Set_def by (cases T) auto
ultimately show ?thesis using Fun that by fast
qed (use t is_Fun_Set_def in fast)
lemma Fun_Set_InSet_iff:
"(u = ⟨a: Var x ∈ Fun (Set s) []⟩) ⟷
(is_InSet u ∧ is_Var (the_elem_term u) ∧ is_Fun_Set (the_set_term u) ∧
the_Set (the_Fun (the_set_term u)) = s ∧ the_Var (the_elem_term u) = x ∧ the_check u = a)"
(is "?A ⟷ ?B")
proof
show "?A ⟹ ?B" unfolding is_Fun_Set_def by auto
assume B: ?B
thus ?A
proof (cases u)
case (InSet b t t')
hence "b = a" "t = Var x" "t' = Fun (Set s) []"
using B by (simp, fastforce, fastforce)
thus ?thesis using InSet by fast
qed auto
qed
lemma Fun_Set_NotInSet_iff:
"(u = ⟨Var x not in Fun (Set s) []⟩) ⟷
(is_NegChecks u ∧ bvars⇩s⇩s⇩t⇩p u = [] ∧ the_eqs u = [] ∧ length (the_ins u) = 1 ∧
is_Var (fst (hd (the_ins u))) ∧ is_Fun_Set (snd (hd (the_ins u)))) ∧
the_Set (the_Fun (snd (hd (the_ins u)))) = s ∧ the_Var (fst (hd (the_ins u))) = x"
(is "?A ⟷ ?B")
proof
show "?A ⟹ ?B" unfolding is_Fun_Set_def by auto
assume B: ?B
show ?A
proof (cases u)
case (NegChecks X F F')
hence "X = []" "F = []"
using B by auto
moreover have "fst (hd (the_ins u)) = Var x" "snd (hd (the_ins u)) = Fun (Set s) []"
using B is_Fun_SetE[of "snd (hd (the_ins u))"]
by (force, fastforce)
hence "F' = [(Var x, Fun (Set s) [])]"
using NegChecks B by (cases "the_ins u") auto
ultimately show ?thesis using NegChecks by fast
qed (use B in auto)
qed
lemma is_Fun_Set_exi: "is_Fun_Set x ⟷ (∃s. x = Fun (Set s) [])"
by (metis prot_fun.collapse(2) term.collapse(2) prot_fun.disc(15) term.disc(2)
term.sel(2,4) is_Fun_Set_def un_Fun1_def)
lemma is_Fun_Set_subst:
assumes "is_Fun_Set S'"
shows "is_Fun_Set (S' ⋅ σ)"
using assms by (fastforce simp add: is_Fun_Set_def)
lemma is_Update_in_transaction_updates:
assumes tu: "is_Update t"
assumes t: "t ∈ set (unlabel (transaction_strand TT))"
assumes vt: "wellformed_transaction TT"
shows "t ∈ set (unlabel (transaction_updates TT))"
using t tu vt unfolding transaction_strand_def wellformed_transaction_def list_all_iff
by (auto simp add: unlabel_append)
lemma transaction_fresh_vars_subset:
assumes "wellformed_transaction T"
shows "set (transaction_fresh T) ⊆ fv_transaction T"
using assms fv_transaction_unfold[of T]
unfolding wellformed_transaction_def
by auto
lemma transaction_fresh_vars_notin:
assumes T: "wellformed_transaction T"
and x: "x ∈ set (transaction_fresh T)"
shows "x ∉ fv⇩l⇩s⇩s⇩t (transaction_receive T)" (is ?A)
and "x ∉ fv⇩l⇩s⇩s⇩t (transaction_selects T)" (is ?B)
and "x ∉ fv⇩l⇩s⇩s⇩t (transaction_checks T)" (is ?C)
and "x ∉ vars⇩l⇩s⇩s⇩t (transaction_receive T)" (is ?D)
and "x ∉ vars⇩l⇩s⇩s⇩t (transaction_selects T)" (is ?E)
and "x ∉ vars⇩l⇩s⇩s⇩t (transaction_checks T)" (is ?F)
and "x ∉ bvars⇩l⇩s⇩s⇩t (transaction_receive T)" (is ?G)
and "x ∉ bvars⇩l⇩s⇩s⇩t (transaction_selects T)" (is ?H)
and "x ∉ bvars⇩l⇩s⇩s⇩t (transaction_checks T)" (is ?I)
proof -
have 0:
"set (transaction_fresh T) ⊆ fv⇩l⇩s⇩s⇩t (transaction_updates T) ∪ fv⇩l⇩s⇩s⇩t (transaction_send T)"
"set (transaction_fresh T) ∩ fv⇩l⇩s⇩s⇩t (transaction_receive T) = {}"
"set (transaction_fresh T) ∩ fv⇩l⇩s⇩s⇩t (transaction_selects T) = {}"
"fv_transaction T ∩ bvars_transaction T = {}"
"fv⇩l⇩s⇩s⇩t (transaction_checks T) ⊆ fv⇩l⇩s⇩s⇩t (transaction_receive T) ∪ fv⇩l⇩s⇩s⇩t (transaction_selects T)"
using T unfolding wellformed_transaction_def
by fast+
have 1: "set (transaction_fresh T) ∩ bvars⇩l⇩s⇩s⇩t (transaction_checks T) = {}"
using 0(1,4) fv_transaction_unfold[of T] bvars_transaction_unfold[of T] by blast
have 2:
"vars⇩l⇩s⇩s⇩t (transaction_receive T) = fv⇩l⇩s⇩s⇩t (transaction_receive T)"
"vars⇩l⇩s⇩s⇩t (transaction_selects T) = fv⇩l⇩s⇩s⇩t (transaction_selects T)"
"bvars⇩l⇩s⇩s⇩t (transaction_receive T) = {}"
"bvars⇩l⇩s⇩s⇩t (transaction_selects T) = {}"
using bvars_wellformed_transaction_unfold[OF T] bvars_transaction_unfold[of T]
vars⇩s⇩s⇩t_is_fv⇩s⇩s⇩t_bvars⇩s⇩s⇩t[of "unlabel (transaction_receive T)"]
vars⇩s⇩s⇩t_is_fv⇩s⇩s⇩t_bvars⇩s⇩s⇩t[of "unlabel (transaction_selects T)"]
by blast+
show ?A ?B ?C ?D ?E ?G ?H ?I using 0 1 2 x by fast+
show ?F using 0(2,3,5) 1 x vars⇩s⇩s⇩t_is_fv⇩s⇩s⇩t_bvars⇩s⇩s⇩t[of "unlabel (transaction_checks T)"] by fast
qed
lemma transaction_proj_member:
assumes "T ∈ set P"
shows "transaction_proj n T ∈ set (map (transaction_proj n) P)"
using assms by simp
lemma transaction_strand_proj:
"transaction_strand (transaction_proj n T) = proj n (transaction_strand T)"
proof -
obtain A B C D E F where "T = Transaction A B C D E F" by (cases T) simp
thus ?thesis
using transaction_proj.simps[of n A B C D E F]
unfolding transaction_strand_def proj_def Let_def by auto
qed
lemma transaction_proj_fresh_eq:
"transaction_fresh (transaction_proj n T) = transaction_fresh T"
proof -
obtain A B C D E F where "T = Transaction A B C D E F" by (cases T) simp
thus ?thesis
using transaction_proj.simps[of n A B C D E F]
unfolding transaction_fresh_def proj_def Let_def by auto
qed
lemma transaction_proj_trms_subset:
"trms_transaction (transaction_proj n T) ⊆ trms_transaction T"
proof -
obtain A B C D E F where "T = Transaction A B C D E F" by (cases T) simp
thus ?thesis
using transaction_proj.simps[of n A B C D E F] trms⇩s⇩s⇩t_proj_subset(1)[of n]
unfolding transaction_fresh_def Let_def transaction_strand_def by auto
qed
lemma transaction_proj_vars_subset:
"vars_transaction (transaction_proj n T) ⊆ vars_transaction T"
proof -
obtain A B C D E F where "T = Transaction A B C D E F" by (cases T) simp
thus ?thesis
using transaction_proj.simps[of n A B C D E F]
sst_vars_proj_subset(3)[of n "transaction_strand T"]
unfolding transaction_fresh_def Let_def transaction_strand_def by simp
qed
end
Theory Stateful_Protocol_Model
section‹Stateful Protocol Model›
theory Stateful_Protocol_Model
imports Stateful_Protocol_Composition_and_Typing.Stateful_Compositionality
Transactions Term_Abstraction
begin
subsection ‹Locale Setup›
locale stateful_protocol_model =
fixes arity⇩f::"'fun ⇒ nat"
and arity⇩s::"'sets ⇒ nat"
and public⇩f::"'fun ⇒ bool"
and Ana⇩f::"'fun ⇒ ((('fun,'atom::finite,'sets) prot_fun, nat) term list × nat list)"
and Γ⇩f::"'fun ⇒ 'atom option"
and label_witness1::"'lbl"
and label_witness2::"'lbl"
assumes Ana⇩f_assm1: "∀f. let (K, M) = Ana⇩f f in (∀k ∈ subterms⇩s⇩e⇩t (set K).
is_Fun k ⟶ (is_Fu (the_Fun k)) ∧ length (args k) = arity⇩f (the_Fu (the_Fun k)))"
and Ana⇩f_assm2: "∀f. let (K, M) = Ana⇩f f in ∀i ∈ fv⇩s⇩e⇩t (set K) ∪ set M. i < arity⇩f f"
and public⇩f_assm: "∀f. arity⇩f f > (0::nat) ⟶ public⇩f f"
and Γ⇩f_assm: "∀f. arity⇩f f = (0::nat) ⟶ Γ⇩f f ≠ None"
and label_witness_assm: "label_witness1 ≠ label_witness2"
begin
lemma Ana⇩f_assm1_alt:
assumes "Ana⇩f f = (K,M)" "k ∈ subterms⇩s⇩e⇩t (set K)"
shows "(∃x. k = Var x) ∨ (∃h T. k = Fun (Fu h) T ∧ length T = arity⇩f h)"
proof (cases k)
case (Fun g T)
let ?P = "λk. is_Fun k ⟶ is_Fu (the_Fun k) ∧ length (args k) = arity⇩f (the_Fu (the_Fun k))"
let ?Q = "λK M. ∀k ∈ subterms⇩s⇩e⇩t (set K). ?P k"
have "?Q (fst (Ana⇩f f)) (snd (Ana⇩f f))" using Ana⇩f_assm1 split_beta[of ?Q "Ana⇩f f"] by meson
hence "?Q K M" using assms(1) by simp
hence "?P k" using assms(2) by blast
thus ?thesis using Fun by (cases g) auto
qed simp
lemma Ana⇩f_assm2_alt:
assumes "Ana⇩f f = (K,M)" "i ∈ fv⇩s⇩e⇩t (set K) ∪ set M"
shows "i < arity⇩f f"
using Ana⇩f_assm2 assms by fastforce
subsection ‹Definitions›
fun arity where
"arity (Fu f) = arity⇩f f"
| "arity (Set s) = arity⇩s s"
| "arity (Val _) = 0"
| "arity (Abs _) = 0"
| "arity Pair = 2"
| "arity (Attack _) = 0"
| "arity OccursFact = 2"
| "arity OccursSec = 0"
| "arity (PubConstAtom _ _) = 0"
| "arity (PubConstSetType _) = 0"
| "arity (PubConstAttackType _) = 0"
| "arity (PubConstBottom _) = 0"
| "arity (PubConstOccursSecType _) = 0"
fun public where
"public (Fu f) = public⇩f f"
| "public (Set s) = (arity⇩s s > 0)"
| "public (Val n) = snd n"
| "public (Abs _) = False"
| "public Pair = True"
| "public (Attack _) = False"
| "public OccursFact = True"
| "public OccursSec = False"
| "public (PubConstAtom _ _) = True"
| "public (PubConstSetType _) = True"
| "public (PubConstAttackType _) = True"
| "public (PubConstBottom _) = True"
| "public (PubConstOccursSecType _) = True"
fun Ana where
"Ana (Fun (Fu f) T) = (
if arity⇩f f = length T ∧ arity⇩f f > 0
then let (K,M) = Ana⇩f f in (K ⋅⇩l⇩i⇩s⇩t (!) T, map ((!) T) M)
else ([], []))"
| "Ana _ = ([], [])"
definition Γ⇩v where
"Γ⇩v v ≡ (
if (∀t ∈ subterms (fst v).
case t of (TComp f T) ⇒ arity f > 0 ∧ arity f = length T | _ ⇒ True)
then fst v
else TAtom Bottom)"
fun Γ where
"Γ (Var v) = Γ⇩v v"
| "Γ (Fun f T) = (
if arity f = 0
then case f of
(Fu g) ⇒ TAtom (case Γ⇩f g of Some a ⇒ Atom a | None ⇒ Bottom)
| (Val _) ⇒ TAtom Value
| (Abs _) ⇒ TAtom Value
| (Set _) ⇒ TAtom SetType
| (Attack _) ⇒ TAtom AttackType
| OccursSec ⇒ TAtom OccursSecType
| (PubConstAtom a _) ⇒ TAtom (Atom a)
| (PubConstSetType _) ⇒ TAtom SetType
| (PubConstAttackType _) ⇒ TAtom AttackType
| (PubConstBottom _) ⇒ TAtom Bottom
| (PubConstOccursSecType _) ⇒ TAtom OccursSecType
| _ ⇒ TAtom Bottom
else TComp f (map Γ T))"
lemma Γ_consts_simps[simp]:
"arity⇩f g = 0 ⟹ Γ (Fun (Fu g) []) = TAtom (case Γ⇩f g of Some a ⇒ Atom a | None ⇒ Bottom)"
"Γ (Fun (Val n) []) = TAtom Value"
"Γ (Fun (Abs b) []) = TAtom Value"
"arity⇩s s = 0 ⟹ Γ (Fun (Set s) []) = TAtom SetType"
"Γ (Fun (Attack x) []) = TAtom AttackType"
"Γ (Fun OccursSec []) = TAtom OccursSecType"
"Γ (Fun (PubConstAtom a t) []) = TAtom (Atom a)"
"Γ (Fun (PubConstSetType t) []) = TAtom SetType"
"Γ (Fun (PubConstAttackType t) []) = TAtom AttackType"
"Γ (Fun (PubConstBottom t) []) = TAtom Bottom"
"Γ (Fun (PubConstOccursSecType t) []) = TAtom OccursSecType"
by simp+
lemma Γ_Set_simps[simp]:
"arity⇩s s ≠ 0 ⟹ Γ (Fun (Set s) T) = TComp (Set s) (map Γ T)"
"Γ (Fun (Set s) T) = TAtom SetType ∨ Γ (Fun (Set s) T) = TComp (Set s) (map Γ T)"
"Γ (Fun (Set s) T) ≠ TAtom Value"
"Γ (Fun (Set s) T) ≠ TAtom (Atom a)"
"Γ (Fun (Set s) T) ≠ TAtom AttackType"
"Γ (Fun (Set s) T) ≠ TAtom OccursSecType"
"Γ (Fun (Set s) T) ≠ TAtom Bottom"
by auto
subsection ‹Locale Interpretations›
lemma Ana_Fu_cases:
assumes "Ana (Fun f T) = (K,M)"
and "f = Fu g"
and "Ana⇩f g = (K',M')"
shows "(K,M) = (if arity⇩f g = length T ∧ arity⇩f g > 0
then (K' ⋅⇩l⇩i⇩s⇩t (!) T, map ((!) T) M')
else ([],[]))" (is ?A)
and "(K,M) = (K' ⋅⇩l⇩i⇩s⇩t (!) T, map ((!) T) M') ∨ (K,M) = ([],[])" (is ?B)
proof -
show ?A using assms by (cases "arity⇩f g = length T ∧ arity⇩f g > 0") auto
thus ?B by metis
qed
lemma Ana_Fu_intro:
assumes "arity⇩f f = length T" "arity⇩f f > 0"
and "Ana⇩f f = (K',M')"
shows "Ana (Fun (Fu f) T) = (K' ⋅⇩l⇩i⇩s⇩t (!) T, map ((!) T) M')"
using assms by simp
lemma Ana_Fu_elim:
assumes "Ana (Fun f T) = (K,M)"
and "f = Fu g"
and "Ana⇩f g = (K',M')"
and "(K,M) ≠ ([],[])"
shows "arity⇩f g = length T" (is ?A)
and "(K,M) = (K' ⋅⇩l⇩i⇩s⇩t (!) T, map ((!) T) M')" (is ?B)
proof -
show ?A using assms by force
moreover have "arity⇩f g > 0" using assms by force
ultimately show ?B using assms by auto
qed
lemma Ana_nonempty_inv:
assumes "Ana t ≠ ([],[])"
shows "∃f T. t = Fun (Fu f) T ∧ arity⇩f f = length T ∧ arity⇩f f > 0 ∧
(∃K M. Ana⇩f f = (K, M) ∧ Ana t = (K ⋅⇩l⇩i⇩s⇩t (!) T, map ((!) T) M))"
using assms
proof (induction t rule: Ana.induct)
case (1 f T)
hence *: "arity⇩f f = length T" "0 < arity⇩f f"
"Ana (Fun (Fu f) T) = (case Ana⇩f f of (K, M) ⇒ (K ⋅⇩l⇩i⇩s⇩t (!) T, map ((!) T) M))"
using Ana.simps(1)[of f T] unfolding Let_def by metis+
obtain K M where **: "Ana⇩f f = (K, M)" by (metis surj_pair)
hence "Ana (Fun (Fu f) T) = (K ⋅⇩l⇩i⇩s⇩t (!) T, map ((!) T) M)" using *(3) by simp
thus ?case using ** *(1,2) by blast
qed simp_all
lemma assm1:
assumes "Ana t = (K,M)"
shows "fv⇩s⇩e⇩t (set K) ⊆ fv t"
using assms
proof (induction t rule: term.induct)
case (Fun f T)
have aux: "fv⇩s⇩e⇩t (set K ⋅⇩s⇩e⇩t (!) T) ⊆ fv⇩s⇩e⇩t (set T)"
when K: "∀i ∈ fv⇩s⇩e⇩t (set K). i < length T"
for K::"(('fun,'atom,'sets) prot_fun, nat) term list"
proof
fix x assume "x ∈ fv⇩s⇩e⇩t (set K ⋅⇩s⇩e⇩t (!) T)"
then obtain k where k: "k ∈ set K" "x ∈ fv (k ⋅ (!) T)" by moura
have "∀i ∈ fv k. i < length T" using K k(1) by simp
thus "x ∈ fv⇩s⇩e⇩t (set T)"
by (metis (no_types, lifting) k(2) contra_subsetD fv_set_mono image_subsetI nth_mem
subst_apply_fv_unfold)
qed
{ fix g assume f: "f = Fu g" and K: "K ≠ []"
obtain K' M' where *: "Ana⇩f g = (K',M')" by moura
have "(K, M) ≠ ([], [])" using K by simp
hence "(K, M) = (K' ⋅⇩l⇩i⇩s⇩t (!) T, map ((!) T) M')" "arity⇩f g = length T"
using Ana_Fu_cases(1)[OF Fun.prems f *]
by presburger+
hence ?case using aux[of K'] Ana⇩f_assm2_alt[OF *] by auto
} thus ?case using Fun by (cases f) fastforce+
qed simp
lemma assm2:
assumes "Ana t = (K,M)"
and "⋀g S'. Fun g S' ⊑ t ⟹ length S' = arity g"
and "k ∈ set K"
and "Fun f T' ⊑ k"
shows "length T' = arity f"
using assms
proof (induction t rule: term.induct)
case (Fun g T)
obtain h where 2: "g = Fu h"
using Fun.prems(1,3) by (cases g) auto
obtain K' M' where 1: "Ana⇩f h = (K',M')" by moura
have "(K,M) ≠ ([],[])" using Fun.prems(3) by auto
hence "(K,M) = (K' ⋅⇩l⇩i⇩s⇩t (!) T, map ((!) T) M')"
"⋀i. i ∈ fv⇩s⇩e⇩t (set K') ∪ set M' ⟹ i < length T"
using Ana_Fu_cases(1)[OF Fun.prems(1) 2 1] Ana⇩f_assm2_alt[OF 1]
by presburger+
hence "K = K' ⋅⇩l⇩i⇩s⇩t (!) T" and 3: "∀i∈fv⇩s⇩e⇩t (set K'). i < length T" by simp_all
then obtain k' where k': "k' ∈ set K'" "k = k' ⋅ (!) T" using Fun.prems(3) by moura
hence 4: "Fun f T' ∈ subterms (k' ⋅ (!) T)" "fv k' ⊆ fv⇩s⇩e⇩t (set K')"
using Fun.prems(4) by auto
show ?case
proof (cases "∃i ∈ fv k'. Fun f T' ∈ subterms (T ! i)")
case True
hence "Fun f T' ∈ subterms⇩s⇩e⇩t (set T)" using k' Fun.prems(4) 3 by auto
thus ?thesis using Fun.prems(2) by auto
next
case False
then obtain S where "Fun f S ∈ subterms k'" "Fun f T' = Fun f S ⋅ (!) T"
using k'(2) Fun.prems(4) subterm_subst_not_img_subterm by force
thus ?thesis using Ana⇩f_assm1_alt[OF 1, of "Fun f S"] k'(1) by (cases f) auto
qed
qed simp
lemma assm4:
assumes "Ana (Fun f T) = (K, M)"
shows "set M ⊆ set T"
using assms
proof (cases f)
case (Fu g)
obtain K' M' where *: "Ana⇩f g = (K',M')" by moura
have "M = [] ∨ (arity⇩f g = length T ∧ M = map ((!) T) M')"
using Ana_Fu_cases(1)[OF assms Fu *]
by (meson prod.inject)
thus ?thesis using Ana⇩f_assm2_alt[OF *] by auto
qed auto
lemma assm5: "Ana t = (K,M) ⟹ K ≠ [] ∨ M ≠ [] ⟹ Ana (t ⋅ δ) = (K ⋅⇩l⇩i⇩s⇩t δ, M ⋅⇩l⇩i⇩s⇩t δ)"
proof (induction t rule: term.induct)
case (Fun f T) thus ?case
proof (cases f)
case (Fu g)
obtain K' M' where *: "Ana⇩f g = (K',M')" by moura
have **: "K = K' ⋅⇩l⇩i⇩s⇩t (!) T" "M = map ((!) T) M'"
"arity⇩f g = length T" "∀i ∈ fv⇩s⇩e⇩t (set K') ∪ set M'. i < arity⇩f g" "0 < arity⇩f g"
using Fun.prems(2) Ana_Fu_cases(1)[OF Fun.prems(1) Fu *] Ana⇩f_assm2_alt[OF *]
by (meson prod.inject)+
have ***: "∀i ∈ fv⇩s⇩e⇩t (set K'). i < length T" "∀i ∈ set M'. i < length T" using **(3,4) by auto
have "K ⋅⇩l⇩i⇩s⇩t δ = K' ⋅⇩l⇩i⇩s⇩t (!) (map (λt. t ⋅ δ) T)"
"M ⋅⇩l⇩i⇩s⇩t δ = map ((!) (map (λt. t ⋅ δ) T)) M'"
using subst_idx_map[OF ***(2), of δ]
subst_idx_map'[OF ***(1), of δ]
**(1,2)
by fast+
thus ?thesis using Fu * **(3,5) by auto
qed auto
qed simp
sublocale intruder_model arity public Ana
apply unfold_locales
by (metis assm1, metis assm2, rule Ana.simps, metis assm4, metis assm5)
adhoc_overloading INTRUDER_SYNTH intruder_synth
adhoc_overloading INTRUDER_DEDUCT intruder_deduct
lemma assm6: "arity c = 0 ⟹ ∃a. ∀X. Γ (Fun c X) = TAtom a" by (cases c) auto
lemma assm7: "0 < arity f ⟹ Γ (Fun f T) = TComp f (map Γ T)" by auto
lemma assm8: "infinite {c. Γ (Fun c []::('fun,'atom,'sets) prot_term) = TAtom a ∧ public c}"
(is "?P a")
proof -
let ?T = "λf. (range f)::('fun,'atom,'sets) prot_fun set"
let ?A = "λf. ∀x::nat ∈ UNIV. ∀y::nat ∈ UNIV. (f x = f y) = (x = y)"
let ?B = "λf. ∀x::nat ∈ UNIV. f x ∈ ?T f"
let ?C = "λf. ∀y::('fun,'atom,'sets) prot_fun ∈ ?T f. ∃x ∈ UNIV. y = f x"
let ?D = "λf b. ?T f ⊆ {c. Γ (Fun c []::('fun,'atom,'sets) prot_term) = TAtom b ∧ public c}"
have sub_lmm: "?P b" when "?A f" "?C f" "?C f" "?D f b" for b f
proof -
have "∃g::nat ⇒ ('fun,'atom,'sets) prot_fun. bij_betw g UNIV (?T f)"
using bij_betwI'[of UNIV f "?T f"] that(1,2,3) by blast
hence "infinite (?T f)" by (metis nat_not_finite bij_betw_finite)
thus ?thesis using infinite_super[OF that(4)] by blast
qed
show ?thesis
proof (cases a)
case (Atom b) thus ?thesis using sub_lmm[of "PubConstAtom b" a] by force
next
case Value thus ?thesis using sub_lmm[of "λn. Val (n,True)" a] by force
next
case SetType thus ?thesis using sub_lmm[of PubConstSetType a] by fastforce
next
case AttackType thus ?thesis using sub_lmm[of PubConstAttackType a] by fastforce
next
case Bottom thus ?thesis using sub_lmm[of PubConstBottom a] by fastforce
next
case OccursSecType thus ?thesis using sub_lmm[of PubConstOccursSecType a] by fastforce
qed
qed
lemma assm9: "TComp f T ⊑ Γ t ⟹ arity f > 0"
proof (induction t rule: term.induct)
case (Var x)
hence "Γ (Var x) ≠ TAtom Bottom" by force
hence "∀t ∈ subterms (fst x). case t of
TComp f T ⇒ arity f > 0 ∧ arity f = length T
| _ ⇒ True"
using Var Γ.simps(1)[of x] unfolding Γ⇩v_def by meson
thus ?case using Var by (fastforce simp add: Γ⇩v_def)
next
case (Fun g S)
have "arity g ≠ 0" using Fun.prems Var_subtermeq assm6 by force
thus ?case using Fun by (cases "TComp f T = TComp g (map Γ S)") auto
qed
lemma assm10: "wf⇩t⇩r⇩m (Γ (Var x))"
unfolding wf⇩t⇩r⇩m_def by (auto simp add: Γ⇩v_def)
lemma assm11: "arity f > 0 ⟹ public f" using public⇩f_assm by (cases f) auto
lemma assm12: "Γ (Var (τ, n)) = Γ (Var (τ, m))" by (simp add: Γ⇩v_def)
lemma assm13: "arity c = 0 ⟹ Ana (Fun c T) = ([],[])" by (cases c) simp_all
lemma assm14:
assumes "Ana (Fun f T) = (K,M)"
shows "Ana (Fun f T ⋅ δ) = (K ⋅⇩l⇩i⇩s⇩t δ, M ⋅⇩l⇩i⇩s⇩t δ)"
proof -
show ?thesis
proof (cases "(K, M) = ([],[])")
case True
{ fix g assume f: "f = Fu g"
obtain K' M' where "Ana⇩f g = (K',M')" by moura
hence ?thesis using assms f True by auto
} thus ?thesis using True assms by (cases f) auto
next
case False
then obtain g where **: "f = Fu g" using assms by (cases f) auto
obtain K' M' where *: "Ana⇩f g = (K',M')" by moura
have ***: "K = K' ⋅⇩l⇩i⇩s⇩t (!) T" "M = map ((!) T) M'" "arity⇩f g = length T"
"∀i ∈ fv⇩s⇩e⇩t (set K') ∪ set M'. i < arity⇩f g"
using Ana_Fu_cases(1)[OF assms ** *] False Ana⇩f_assm2_alt[OF *]
by (meson prod.inject)+
have ****: "∀i∈fv⇩s⇩e⇩t (set K'). i < length T" "∀i∈set M'. i < length T" using ***(3,4) by auto
have "K ⋅⇩l⇩i⇩s⇩t δ = K' ⋅⇩l⇩i⇩s⇩t (!) (map (λt. t ⋅ δ) T)"
"M ⋅⇩l⇩i⇩s⇩t δ = map ((!) (map (λt. t ⋅ δ) T)) M'"
using subst_idx_map[OF ****(2), of δ]
subst_idx_map'[OF ****(1), of δ]
***(1,2)
by auto
thus ?thesis using assms * ** ***(3) by auto
qed
qed
sublocale labeled_stateful_typed_model' arity public Ana Γ Pair label_witness1 label_witness2
by unfold_locales
(metis assm6, metis assm7, metis assm8, metis assm9,
rule assm10, metis assm11, rule arity.simps(5), metis assm14,
metis assm12, metis assm13, metis assm14, rule label_witness_assm)
subsection ‹Minor Lemmata›
lemma Γ⇩v_TAtom[simp]: "Γ⇩v (TAtom a, n) = TAtom a"
unfolding Γ⇩v_def by simp
lemma Γ⇩v_TAtom':
assumes "a ≠ Bottom"
shows "Γ⇩v (τ, n) = TAtom a ⟷ τ = TAtom a"
proof
assume "Γ⇩v (τ, n) = TAtom a"
thus "τ = TAtom a" by (metis (no_types, lifting) assms Γ⇩v_def fst_conv term.inject(1))
qed simp
lemma Γ⇩v_TAtom_inv:
"Γ⇩v x = TAtom (Atom a) ⟹ ∃m. x = (TAtom (Atom a), m)"
"Γ⇩v x = TAtom Value ⟹ ∃m. x = (TAtom Value, m)"
"Γ⇩v x = TAtom SetType ⟹ ∃m. x = (TAtom SetType, m)"
"Γ⇩v x = TAtom AttackType ⟹ ∃m. x = (TAtom AttackType, m)"
"Γ⇩v x = TAtom OccursSecType ⟹ ∃m. x = (TAtom OccursSecType, m)"
by (metis Γ⇩v_TAtom' surj_pair prot_atom.distinct(7),
metis Γ⇩v_TAtom' surj_pair prot_atom.distinct(15),
metis Γ⇩v_TAtom' surj_pair prot_atom.distinct(21),
metis Γ⇩v_TAtom' surj_pair prot_atom.distinct(25),
metis Γ⇩v_TAtom' surj_pair prot_atom.distinct(30))
lemma Γ⇩v_TAtom'':
"(fst x = TAtom (Atom a)) = (Γ⇩v x = TAtom (Atom a))" (is "?A = ?A'")
"(fst x = TAtom Value) = (Γ⇩v x = TAtom Value)" (is "?B = ?B'")
"(fst x = TAtom SetType) = (Γ⇩v x = TAtom SetType)" (is "?C = ?C'")
"(fst x = TAtom AttackType) = (Γ⇩v x = TAtom AttackType)" (is "?D = ?D'")
"(fst x = TAtom OccursSecType) = (Γ⇩v x = TAtom OccursSecType)" (is "?E = ?E'")
proof -
have 1: "?A ⟹ ?A'" "?B ⟹ ?B'" "?C ⟹ ?C'" "?D ⟹ ?D'" "?E ⟹ ?E'"
by (metis Γ⇩v_TAtom prod.collapse)+
have 2: "?A' ⟹ ?A" "?B' ⟹ ?B" "?C' ⟹ ?C" "?D' ⟹ ?D" "?E' ⟹ ?E"
using Γ⇩v_TAtom Γ⇩v_TAtom_inv(1) apply fastforce
using Γ⇩v_TAtom Γ⇩v_TAtom_inv(2) apply fastforce
using Γ⇩v_TAtom Γ⇩v_TAtom_inv(3) apply fastforce
using Γ⇩v_TAtom Γ⇩v_TAtom_inv(4) apply fastforce
using Γ⇩v_TAtom Γ⇩v_TAtom_inv(5) by fastforce
show "?A = ?A'" "?B = ?B'" "?C = ?C'" "?D = ?D'" "?E = ?E'"
using 1 2 by metis+
qed
lemma Γ⇩v_Var_image:
"Γ⇩v ` X = Γ ` Var ` X"
by force
lemma Γ_Fu_const:
assumes "arity⇩f g = 0"
shows "∃a. Γ (Fun (Fu g) T) = TAtom (Atom a)"
proof -
have "Γ⇩f g ≠ None" using assms Γ⇩f_assm by blast
thus ?thesis using assms by force
qed
lemma Fun_Value_type_inv:
fixes T::"('fun,'atom,'sets) prot_term list"
assumes "Γ (Fun f T) = TAtom Value"
shows "(∃n. f = Val n) ∨ (∃bs. f = Abs bs)"
proof -
have *: "arity f = 0" by (metis const_type_inv assms)
show ?thesis using assms
proof (cases f)
case (Fu g)
hence "arity⇩f g = 0" using * by simp
hence False using Fu Γ_Fu_const[of g T] assms by auto
thus ?thesis by metis
next
case (Set s)
hence "arity⇩s s = 0" using * by simp
hence False using Set assms by auto
thus ?thesis by metis
qed simp_all
qed
lemma abs_Γ: "Γ t = Γ (t ⋅⇩α α)"
by (induct t α rule: abs_apply_term.induct) auto
lemma Ana⇩f_keys_not_pubval_terms:
assumes "Ana⇩f f = (K, T)"
and "k ∈ set K"
and "g ∈ funs_term k"
shows "¬is_Val g"
proof
assume "is_Val g"
then obtain n S where *: "Fun (Val n) S ∈ subterms⇩s⇩e⇩t (set K)"
using assms(2) funs_term_Fun_subterm[OF assms(3)]
by (cases g) auto
show False using Ana⇩f_assm1_alt[OF assms(1) *] by simp
qed
lemma Ana⇩f_keys_not_abs_terms:
assumes "Ana⇩f f = (K, T)"
and "k ∈ set K"
and "g ∈ funs_term k"
shows "¬is_Abs g"
proof
assume "is_Abs g"
then obtain a S where *: "Fun (Abs a) S ∈ subterms⇩s⇩e⇩t (set K)"
using assms(2) funs_term_Fun_subterm[OF assms(3)]
by (cases g) auto
show False using Ana⇩f_assm1_alt[OF assms(1) *] by simp
qed
lemma Ana⇩f_keys_not_pairs:
assumes "Ana⇩f f = (K, T)"
and "k ∈ set K"
and "g ∈ funs_term k"
shows "g ≠ Pair"
proof
assume "g = Pair"
then obtain S where *: "Fun Pair S ∈ subterms⇩s⇩e⇩t (set K)"
using assms(2) funs_term_Fun_subterm[OF assms(3)]
by (cases g) auto
show False using Ana⇩f_assm1_alt[OF assms(1) *] by simp
qed
lemma Ana_Fu_keys_funs_term_subset:
fixes K::"('fun,'atom,'sets) prot_term list"
assumes "Ana (Fun (Fu f) S) = (K, T)"
and "Ana⇩f f = (K', T')"
shows "⋃(funs_term ` set K) ⊆ ⋃(funs_term ` set K') ∪ funs_term (Fun (Fu f) S)"
proof -
{ fix k assume k: "k ∈ set K"
then obtain k' where k':
"k' ∈ set K'" "k = k' ⋅ (!) S" "arity⇩f f = length S"
"subterms k' ⊆ subterms⇩s⇩e⇩t (set K')"
using assms Ana_Fu_elim[OF assms(1) _ assms(2)] by fastforce
have 1: "funs_term k' ⊆ ⋃(funs_term ` set K')" using k'(1) by auto
have "i < length S" when "i ∈ fv k'" for i
using that Ana⇩f_assm2_alt[OF assms(2), of i] k'(1,3)
by auto
hence 2: "funs_term (S ! i) ⊆ funs_term (Fun (Fu f) S)" when "i ∈ fv k'" for i
using that by force
have "funs_term k ⊆ ⋃(funs_term ` set K') ∪ funs_term (Fun (Fu f) S)"
using funs_term_subst[of k' "(!) S"] k'(2) 1 2 by fast
} thus ?thesis by blast
qed
lemma Ana_Fu_keys_not_pubval_terms:
fixes k::"('fun,'atom,'sets) prot_term"
assumes "Ana (Fun (Fu f) S) = (K, T)"
and "Ana⇩f f = (K', T')"
and "k ∈ set K"
and "∀g ∈ funs_term (Fun (Fu f) S). is_Val g ⟶ ¬public g"
shows "∀g ∈ funs_term k. is_Val g ⟶ ¬public g"
using assms(3,4) Ana⇩f_keys_not_pubval_terms[OF assms(2)]
Ana_Fu_keys_funs_term_subset[OF assms(1,2)]
by blast
lemma Ana_Fu_keys_not_abs_terms:
fixes k::"('fun,'atom,'sets) prot_term"
assumes "Ana (Fun (Fu f) S) = (K, T)"
and "Ana⇩f f = (K', T')"
and "k ∈ set K"
and "∀g ∈ funs_term (Fun (Fu f) S). ¬is_Abs g"
shows "∀g ∈ funs_term k. ¬is_Abs g"
using assms(3,4) Ana⇩f_keys_not_abs_terms[OF assms(2)]
Ana_Fu_keys_funs_term_subset[OF assms(1,2)]
by blast
lemma Ana_Fu_keys_not_pairs:
fixes k::"('fun,'atom,'sets) prot_term"
assumes "Ana (Fun (Fu f) S) = (K, T)"
and "Ana⇩f f = (K', T')"
and "k ∈ set K"
and "∀g ∈ funs_term (Fun (Fu f) S). g ≠ Pair"
shows "∀g ∈ funs_term k. g ≠ Pair"
using assms(3,4) Ana⇩f_keys_not_pairs[OF assms(2)]
Ana_Fu_keys_funs_term_subset[OF assms(1,2)]
by blast
lemma deduct_occurs_in_ik:
fixes t::"('fun,'atom,'sets) prot_term"
assumes t: "M ⊢ occurs t"
and M: "∀s ∈ subterms⇩s⇩e⇩t M. OccursFact ∉ ⋃(funs_term ` set (snd (Ana s)))"
"∀s ∈ subterms⇩s⇩e⇩t M. OccursSec ∉ ⋃(funs_term ` set (snd (Ana s)))"
"Fun OccursSec [] ∉ M"
shows "occurs t ∈ M"
using private_fun_deduct_in_ik''[of M OccursFact "[Fun OccursSec [], t]" OccursSec] t M
by fastforce
lemma wellformed_transaction_sem_receives:
fixes T::"('fun,'atom,'sets,'lbl) prot_transaction"
assumes T_valid: "wellformed_transaction T"
and ℐ: "strand_sem_stateful IK DB (unlabel (dual⇩l⇩s⇩s⇩t (transaction_strand T ⋅⇩l⇩s⇩s⇩t θ))) ℐ"
and s: "receive⟨t⟩ ∈ set (unlabel (transaction_receive T ⋅⇩l⇩s⇩s⇩t θ))"
shows "IK ⊢ t ⋅ ℐ"
proof -
let ?R = "unlabel (dual⇩l⇩s⇩s⇩t (transaction_receive T ⋅⇩l⇩s⇩s⇩t θ))"
let ?S = "λA. unlabel (dual⇩l⇩s⇩s⇩t (A ⋅⇩l⇩s⇩s⇩t θ))"
let ?S' = "?S (transaction_receive T)"
obtain l B s where B:
"(l,send⟨t⟩) = dual⇩l⇩s⇩s⇩t⇩p ((l,s) ⋅⇩l⇩s⇩s⇩t⇩p θ)"
"prefix ((B ⋅⇩l⇩s⇩s⇩t θ)@[(l,s) ⋅⇩l⇩s⇩s⇩t⇩p θ]) (transaction_receive T ⋅⇩l⇩s⇩s⇩t θ)"
using s dual⇩l⇩s⇩s⇩t_unlabel_steps_iff(2)[of t "transaction_receive T ⋅⇩l⇩s⇩s⇩t θ"]
dual⇩l⇩s⇩s⇩t_in_set_prefix_obtain_subst[of "send⟨t⟩" "transaction_receive T" θ]
by blast
have 1: "unlabel (dual⇩l⇩s⇩s⇩t ((B ⋅⇩l⇩s⇩s⇩t θ)@[(l,s) ⋅⇩l⇩s⇩s⇩t⇩p θ])) = unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))@[send⟨t⟩]"
using B(1) unlabel_append dual⇩l⇩s⇩s⇩t⇩p_subst dual⇩l⇩s⇩s⇩t_subst singleton_lst_proj(4)
dual⇩l⇩s⇩s⇩t_subst_snoc subst_lsst_append subst_lsst_singleton
by (metis (no_types, lifting) subst_apply_labeled_stateful_strand_step.simps )
have "strand_sem_stateful IK DB ?S' ℐ"
using ℐ strand_sem_append_stateful[of IK DB _ _ ℐ] transaction_dual_subst_unfold[of T θ]
by fastforce
hence "strand_sem_stateful IK DB (unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))@[send⟨t⟩]) ℐ"
using B 1 unfolding prefix_def unlabel_def
by (metis dual⇩l⇩s⇩s⇩t_def map_append strand_sem_append_stateful)
hence t_deduct: "IK ∪ (ik⇩l⇩s⇩s⇩t (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ)) ⋅⇩s⇩e⇩t ℐ) ⊢ t ⋅ ℐ"
using strand_sem_append_stateful[of IK DB "unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))" "[send⟨t⟩]" ℐ]
by simp
have "∀s ∈ set (unlabel (transaction_receive T)). ∃t. s = receive⟨t⟩"
using T_valid wellformed_transaction_unlabel_cases(1)[OF T_valid] by auto
moreover { fix A::"('fun,'atom,'sets,'lbl) prot_strand" and θ
assume "∀s ∈ set (unlabel A). ∃t. s = receive⟨t⟩"
hence "∀s ∈ set (unlabel (A ⋅⇩l⇩s⇩s⇩t θ)). ∃t. s = receive⟨t⟩"
proof (induction A)
case (Cons a A) thus ?case using subst_lsst_cons[of a A θ] by (cases a) auto
qed simp
hence "∀s ∈ set (unlabel (A ⋅⇩l⇩s⇩s⇩t θ)). ∃t. s = receive⟨t⟩"
by (simp add: list.pred_set is_Receive_def)
hence "∀s ∈ set (unlabel (dual⇩l⇩s⇩s⇩t (A ⋅⇩l⇩s⇩s⇩t θ))). ∃t. s = send⟨t⟩"
by (metis dual⇩l⇩s⇩s⇩t_memberD dual⇩l⇩s⇩s⇩t⇩p_inv(2) unlabel_in unlabel_mem_has_label)
}
ultimately have "∀s ∈ set ?R. ∃t. s = send⟨t⟩" by simp
hence "ik⇩s⇩s⇩t ?R = {}" unfolding unlabel_def ik⇩s⇩s⇩t_def by fast
hence "ik⇩l⇩s⇩s⇩t (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ)) = {}"
using B(2) 1 ik⇩s⇩s⇩t_append dual⇩l⇩s⇩s⇩t_append
by (metis (no_types, lifting) Un_empty map_append prefix_def unlabel_def)
thus ?thesis using t_deduct by simp
qed
lemma wellformed_transaction_sem_selects:
assumes T_valid: "wellformed_transaction T"
and ℐ: "strand_sem_stateful IK DB (unlabel (dual⇩l⇩s⇩s⇩t (transaction_strand T ⋅⇩l⇩s⇩s⇩t θ))) ℐ"
and "select⟨t,u⟩ ∈ set (unlabel (transaction_selects T ⋅⇩l⇩s⇩s⇩t θ))"
shows "(t ⋅ ℐ, u ⋅ ℐ) ∈ DB"
proof -
let ?s = "select⟨t,u⟩"
let ?R = "transaction_receive T@transaction_selects T"
let ?R' = "unlabel (dual⇩l⇩s⇩s⇩t (?R ⋅⇩l⇩s⇩s⇩t θ))"
let ?S = "λA. unlabel (dual⇩l⇩s⇩s⇩t (A ⋅⇩l⇩s⇩s⇩t θ))"
let ?S' = "?S (transaction_receive T)@?S (transaction_selects T)"
let ?P = "λa. is_Receive a ∨ is_Assignment a"
let ?Q = "λa. is_Send a ∨ is_Assignment a"
have s: "?s ∈ set (unlabel (?R ⋅⇩l⇩s⇩s⇩t θ))"
using assms(3) subst_lsst_append[of "transaction_receive T"]
unlabel_append[of "transaction_receive T ⋅⇩l⇩s⇩s⇩t θ"]
by auto
obtain l B s where B:
"(l,?s) = dual⇩l⇩s⇩s⇩t⇩p ((l,s) ⋅⇩l⇩s⇩s⇩t⇩p θ)"
"prefix ((B ⋅⇩l⇩s⇩s⇩t θ)@[(l,s) ⋅⇩l⇩s⇩s⇩t⇩p θ]) (?R ⋅⇩l⇩s⇩s⇩t θ)"
using s dual⇩l⇩s⇩s⇩t_unlabel_steps_iff(6)[of assign t u]
dual⇩l⇩s⇩s⇩t_in_set_prefix_obtain_subst[of ?s ?R θ]
by blast
have 1: "unlabel (dual⇩l⇩s⇩s⇩t ((B ⋅⇩l⇩s⇩s⇩t θ)@[(l,s) ⋅⇩l⇩s⇩s⇩t⇩p θ])) = unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))@[?s]"
using B(1) unlabel_append dual⇩l⇩s⇩s⇩t⇩p_subst dual⇩l⇩s⇩s⇩t_subst singleton_lst_proj(4)
dual⇩l⇩s⇩s⇩t_subst_snoc subst_lsst_append subst_lsst_singleton
by (metis (no_types, lifting) subst_apply_labeled_stateful_strand_step.simps)
have "strand_sem_stateful IK DB ?S' ℐ"
using ℐ strand_sem_append_stateful[of IK DB _ _ ℐ] transaction_dual_subst_unfold[of T θ]
by fastforce
hence "strand_sem_stateful IK DB (unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))@[?s]) ℐ"
using B 1 strand_sem_append_stateful subst_lsst_append
unfolding prefix_def unlabel_def dual⇩l⇩s⇩s⇩t_def
by (metis (no_types) map_append)
hence in_db: "(t ⋅ ℐ, u ⋅ ℐ) ∈ dbupd⇩s⇩s⇩t (unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))) ℐ DB"
using strand_sem_append_stateful[of IK DB "unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))" "[?s]" ℐ]
by simp
have "∀a ∈ set (unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))). ?Q a"
proof
fix a assume a: "a ∈ set (unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ)))"
have "∀a ∈ set (unlabel ?R). ?P a"
using wellformed_transaction_unlabel_cases(1)[OF T_valid]
wellformed_transaction_unlabel_cases(2)[OF T_valid]
unfolding unlabel_def
by fastforce
hence "∀a ∈ set (unlabel (?R ⋅⇩l⇩s⇩s⇩t θ)). ?P a"
using stateful_strand_step_cases_subst(2,8)[of _ θ] subst_lsst_unlabel[of ?R θ]
by (simp add: subst_apply_stateful_strand_def del: unlabel_append)
hence B_P: "∀a ∈ set (unlabel (B ⋅⇩l⇩s⇩s⇩t θ)). ?P a"
using unlabel_mono[OF set_mono_prefix[OF append_prefixD[OF B(2)]]]
by blast
obtain l where "(l,a) ∈ set (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))"
using a by (meson unlabel_mem_has_label)
then obtain b where b: "(l,b) ∈ set (B ⋅⇩l⇩s⇩s⇩t θ)" "dual⇩l⇩s⇩s⇩t⇩p (l,b) = (l,a)"
using dual⇩l⇩s⇩s⇩t_memberD by blast
hence "?P b" using B_P unfolding unlabel_def by fastforce
thus "?Q a" using dual⇩l⇩s⇩s⇩t⇩p_inv[OF b(2)] by (cases b) auto
qed
hence "∀a ∈ set (unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))). ¬is_Insert a ∧ ¬is_Delete a" by fastforce
thus ?thesis using dbupd⇩s⇩s⇩t_no_upd[of "unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))" ℐ DB] in_db by simp
qed
lemma wellformed_transaction_sem_pos_checks:
assumes T_valid: "wellformed_transaction T"
and ℐ: "strand_sem_stateful IK DB (unlabel (dual⇩l⇩s⇩s⇩t (transaction_strand T ⋅⇩l⇩s⇩s⇩t θ))) ℐ"
and "⟨t in u⟩ ∈ set (unlabel (transaction_checks T ⋅⇩l⇩s⇩s⇩t θ))"
shows "(t ⋅ ℐ, u ⋅ ℐ) ∈ DB"
proof -
let ?s = "⟨t in u⟩"
let ?R = "transaction_receive T@transaction_selects T@transaction_checks T"
let ?R' = "unlabel (dual⇩l⇩s⇩s⇩t (?R ⋅⇩l⇩s⇩s⇩t θ))"
let ?S = "λA. unlabel (dual⇩l⇩s⇩s⇩t (A ⋅⇩l⇩s⇩s⇩t θ))"
let ?S' = "?S (transaction_receive T)@?S (transaction_selects T)@?S (transaction_checks T)"
let ?P = "λa. is_Receive a ∨ is_Assignment a ∨ is_Check a"
let ?Q = "λa. is_Send a ∨ is_Assignment a ∨ is_Check a"
have s: "?s ∈ set (unlabel (?R ⋅⇩l⇩s⇩s⇩t θ))"
using assms(3) subst_lsst_append[of "transaction_receive T@transaction_selects T"]
unlabel_append[of "transaction_receive T@transaction_selects T ⋅⇩l⇩s⇩s⇩t θ"]
by auto
obtain l B s where B:
"(l,?s) = dual⇩l⇩s⇩s⇩t⇩p ((l,s) ⋅⇩l⇩s⇩s⇩t⇩p θ)"
"prefix ((B ⋅⇩l⇩s⇩s⇩t θ)@[(l,s) ⋅⇩l⇩s⇩s⇩t⇩p θ]) (?R ⋅⇩l⇩s⇩s⇩t θ)"
using s dual⇩l⇩s⇩s⇩t_unlabel_steps_iff(6)[of check t u]
dual⇩l⇩s⇩s⇩t_in_set_prefix_obtain_subst[of ?s ?R θ]
by blast
have 1: "unlabel (dual⇩l⇩s⇩s⇩t ((B ⋅⇩l⇩s⇩s⇩t θ)@[(l,s) ⋅⇩l⇩s⇩s⇩t⇩p θ])) = unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))@[?s]"
using B(1) unlabel_append dual⇩l⇩s⇩s⇩t⇩p_subst dual⇩l⇩s⇩s⇩t_subst singleton_lst_proj(4)
dual⇩l⇩s⇩s⇩t_subst_snoc subst_lsst_append subst_lsst_singleton
by (metis (no_types, lifting) subst_apply_labeled_stateful_strand_step.simps )
have "strand_sem_stateful IK DB ?S' ℐ"
using ℐ strand_sem_append_stateful[of IK DB _ _ ℐ] transaction_dual_subst_unfold[of T θ]
by fastforce
hence "strand_sem_stateful IK DB (unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))@[?s]) ℐ"
using B 1 strand_sem_append_stateful subst_lsst_append
unfolding prefix_def unlabel_def dual⇩l⇩s⇩s⇩t_def
by (metis (no_types) map_append)
hence in_db: "(t ⋅ ℐ, u ⋅ ℐ) ∈ dbupd⇩s⇩s⇩t (unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))) ℐ DB"
using strand_sem_append_stateful[of IK DB "unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))" "[?s]" ℐ]
by simp
have "∀a ∈ set (unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))). ?Q a"
proof
fix a assume a: "a ∈ set (unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ)))"
have "∀a ∈ set (unlabel ?R). ?P a"
using wellformed_transaction_unlabel_cases(1,2,3)[OF T_valid]
unfolding unlabel_def
by fastforce
hence "∀a ∈ set (unlabel (?R ⋅⇩l⇩s⇩s⇩t θ)). ?P a"
using stateful_strand_step_cases_subst(2,8,9)[of _ θ] subst_lsst_unlabel[of ?R θ]
by (simp add: subst_apply_stateful_strand_def del: unlabel_append)
hence B_P: "∀a ∈ set (unlabel (B ⋅⇩l⇩s⇩s⇩t θ)). ?P a"
using unlabel_mono[OF set_mono_prefix[OF append_prefixD[OF B(2)]]]
by blast
obtain l where "(l,a) ∈ set (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))"
using a by (meson unlabel_mem_has_label)
then obtain b where b: "(l,b) ∈ set (B ⋅⇩l⇩s⇩s⇩t θ)" "dual⇩l⇩s⇩s⇩t⇩p (l,b) = (l,a)"
using dual⇩l⇩s⇩s⇩t_memberD by blast
hence "?P b" using B_P unfolding unlabel_def by fastforce
thus "?Q a" using dual⇩l⇩s⇩s⇩t⇩p_inv[OF b(2)] by (cases b) auto
qed
hence "∀a ∈ set (unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))). ¬is_Insert a ∧ ¬is_Delete a" by fastforce
thus ?thesis using dbupd⇩s⇩s⇩t_no_upd[of "unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))" ℐ DB] in_db by simp
qed
lemma wellformed_transaction_sem_neg_checks:
assumes T_valid: "wellformed_transaction T"
and ℐ: "strand_sem_stateful IK DB (unlabel (dual⇩l⇩s⇩s⇩t (transaction_strand T ⋅⇩l⇩s⇩s⇩t θ))) ℐ"
and "NegChecks X [] [(t,u)] ∈ set (unlabel (transaction_checks T ⋅⇩l⇩s⇩s⇩t θ))"
shows "∀δ. subst_domain δ = set X ∧ ground (subst_range δ) ⟶ (t ⋅ δ ⋅ ℐ, u ⋅ δ ⋅ ℐ) ∉ DB" (is ?A)
and "X = [] ⟹ (t ⋅ ℐ, u ⋅ ℐ) ∉ DB" (is "?B ⟹ ?B'")
proof -
let ?s = "NegChecks X [] [(t,u)]"
let ?R = "transaction_receive T@transaction_selects T@transaction_checks T"
let ?R' = "unlabel (dual⇩l⇩s⇩s⇩t (?R ⋅⇩l⇩s⇩s⇩t θ))"
let ?S = "λA. unlabel (dual⇩l⇩s⇩s⇩t (A ⋅⇩l⇩s⇩s⇩t θ))"
let ?S' = "?S (transaction_receive T)@?S (transaction_selects T)@?S (transaction_checks T)"
let ?P = "λa. is_Receive a ∨ is_Assignment a ∨ is_Check a"
let ?Q = "λa. is_Send a ∨ is_Assignment a ∨ is_Check a"
let ?U = "λδ. subst_domain δ = set X ∧ ground (subst_range δ)"
have s: "?s ∈ set (unlabel (?R ⋅⇩l⇩s⇩s⇩t θ))"
using assms(3) subst_lsst_append[of "transaction_receive T@transaction_selects T"]
unlabel_append[of "transaction_receive T@transaction_selects T ⋅⇩l⇩s⇩s⇩t θ"]
by auto
obtain l B s where B:
"(l,?s) = dual⇩l⇩s⇩s⇩t⇩p ((l,s) ⋅⇩l⇩s⇩s⇩t⇩p θ)"
"prefix ((B ⋅⇩l⇩s⇩s⇩t θ)@[(l,s) ⋅⇩l⇩s⇩s⇩t⇩p θ]) (?R ⋅⇩l⇩s⇩s⇩t θ)"
using s dual⇩l⇩s⇩s⇩t_unlabel_steps_iff(7)[of X "[]" "[(t,u)]"]
dual⇩l⇩s⇩s⇩t_in_set_prefix_obtain_subst[of ?s ?R θ]
by blast
have 1: "unlabel (dual⇩l⇩s⇩s⇩t ((B ⋅⇩l⇩s⇩s⇩t θ)@[(l,s) ⋅⇩l⇩s⇩s⇩t⇩p θ])) = unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))@[?s]"
using B(1) unlabel_append dual⇩l⇩s⇩s⇩t⇩p_subst dual⇩l⇩s⇩s⇩t_subst singleton_lst_proj(4)
dual⇩l⇩s⇩s⇩t_subst_snoc subst_lsst_append subst_lsst_singleton
by (metis (no_types, lifting) subst_apply_labeled_stateful_strand_step.simps)
have "strand_sem_stateful IK DB ?S' ℐ"
using ℐ strand_sem_append_stateful[of IK DB _ _ ℐ] transaction_dual_subst_unfold[of T θ]
by fastforce
hence "strand_sem_stateful IK DB (unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))@[?s]) ℐ"
using B 1 strand_sem_append_stateful subst_lsst_append
unfolding prefix_def unlabel_def dual⇩l⇩s⇩s⇩t_def
by (metis (no_types) map_append)
hence "negchecks_model ℐ (dbupd⇩s⇩s⇩t (unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))) ℐ DB) X [] [(t,u)]"
using strand_sem_append_stateful[of IK DB "unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))" "[?s]" ℐ]
by fastforce
hence in_db: "∀δ. ?U δ ⟶ (t ⋅ δ ⋅ ℐ, u ⋅ δ ⋅ ℐ) ∉ dbupd⇩s⇩s⇩t (unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))) ℐ DB"
unfolding negchecks_model_def
by simp
have "∀a ∈ set (unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))). ?Q a"
proof
fix a assume a: "a ∈ set (unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ)))"
have "∀a ∈ set (unlabel ?R). ?P a"
using wellformed_transaction_unlabel_cases(1,2,3)[OF T_valid]
unfolding unlabel_def
by fastforce
hence "∀a ∈ set (unlabel (?R ⋅⇩l⇩s⇩s⇩t θ)). ?P a"
using stateful_strand_step_cases_subst(2,8,9)[of _ θ] subst_lsst_unlabel[of ?R θ]
by (simp add: subst_apply_stateful_strand_def del: unlabel_append)
hence B_P: "∀a ∈ set (unlabel (B ⋅⇩l⇩s⇩s⇩t θ)). ?P a"
using unlabel_mono[OF set_mono_prefix[OF append_prefixD[OF B(2)]]]
by blast
obtain l where "(l,a) ∈ set (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))"
using a by (meson unlabel_mem_has_label)
then obtain b where b: "(l,b) ∈ set (B ⋅⇩l⇩s⇩s⇩t θ)" "dual⇩l⇩s⇩s⇩t⇩p (l,b) = (l,a)"
using dual⇩l⇩s⇩s⇩t_memberD by blast
hence "?P b" using B_P unfolding unlabel_def by fastforce
thus "?Q a" using dual⇩l⇩s⇩s⇩t⇩p_inv[OF b(2)] by (cases b) auto
qed
hence "∀a ∈ set (unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))). ¬is_Insert a ∧ ¬is_Delete a" by fastforce
thus ?A using dbupd⇩s⇩s⇩t_no_upd[of "unlabel (dual⇩l⇩s⇩s⇩t (B ⋅⇩l⇩s⇩s⇩t θ))" ℐ DB] in_db by simp
moreover have "δ = Var" "t ⋅ δ = t"
when "subst_domain δ = set []" for t and δ::"('fun, 'atom, 'sets) prot_subst"
using that by auto
moreover have "subst_domain Var = set []" "range_vars Var = {}"
by simp_all
ultimately show "?B ⟹ ?B'" unfolding range_vars_alt_def by metis
qed
lemma wellformed_transaction_fv_in_receives_or_selects:
assumes T: "wellformed_transaction T"
and x: "x ∈ fv_transaction T" "x ∉ set (transaction_fresh T)"
shows "x ∈ fv⇩l⇩s⇩s⇩t (transaction_receive T) ∪ fv⇩l⇩s⇩s⇩t (transaction_selects T)"
proof -
have "x ∈ fv⇩l⇩s⇩s⇩t (transaction_receive T) ∪ fv⇩l⇩s⇩s⇩t (transaction_selects T) ∪
fv⇩l⇩s⇩s⇩t (transaction_checks T) ∪ fv⇩l⇩s⇩s⇩t (transaction_updates T) ∪
fv⇩l⇩s⇩s⇩t (transaction_send T)"
using x(1) fv⇩s⇩s⇩t_append unlabel_append
by (metis transaction_strand_def append_assoc)
thus ?thesis using T x(2) unfolding wellformed_transaction_def by blast
qed
lemma dual_transaction_ik_is_transaction_send'':
fixes δ ℐ::"('a,'b,'c) prot_subst"
assumes "wellformed_transaction T"
shows "(ik⇩s⇩s⇩t (unlabel (dual⇩l⇩s⇩s⇩t (transaction_strand T ⋅⇩l⇩s⇩s⇩t δ))) ⋅⇩s⇩e⇩t ℐ) ⋅⇩α⇩s⇩e⇩t a =
(trms⇩s⇩s⇩t (unlabel (transaction_send T)) ⋅⇩s⇩e⇩t δ ⋅⇩s⇩e⇩t ℐ) ⋅⇩α⇩s⇩e⇩t a" (is "?A = ?B")
using dual_transaction_ik_is_transaction_send[OF assms]
subst_lsst_unlabel[of "dual⇩l⇩s⇩s⇩t (transaction_strand T)" δ]
ik⇩s⇩s⇩t_subst[of "unlabel (dual⇩l⇩s⇩s⇩t (transaction_strand T))" δ]
dual⇩l⇩s⇩s⇩t_subst[of "transaction_strand T" δ]
by (auto simp add: abs_apply_terms_def)
lemma while_prot_terms_fun_mono:
"mono (λM'. M ∪ ⋃(subterms ` M') ∪ ⋃((set ∘ fst ∘ Ana) ` M'))"
unfolding mono_def by fast
lemma while_prot_terms_SMP_overapprox:
fixes M::"('fun,'atom,'sets) prot_terms"
assumes N_supset: "M ∪ ⋃(subterms ` N) ∪ ⋃((set ∘ fst ∘ Ana) ` N) ⊆ N"
and Value_vars_only: "∀x ∈ fv⇩s⇩e⇩t N. Γ⇩v x = TAtom Value"
shows "SMP M ⊆ {a ⋅ δ | a δ. a ∈ N ∧ wt⇩s⇩u⇩b⇩s⇩t δ ∧ wf⇩t⇩r⇩m⇩s (subst_range δ)}"
proof -
define f where "f ≡ λM'. M ∪ ⋃(subterms ` M') ∪ ⋃((set ∘ fst ∘ Ana) ` M')"
define S where "S ≡ {a ⋅ δ | a δ. a ∈ N ∧ wt⇩s⇩u⇩b⇩s⇩t δ ∧ wf⇩t⇩r⇩m⇩s (subst_range δ)}"
note 0 = Value_vars_only
have "t ∈ S" when "t ∈ SMP M" for t
using that
proof (induction t rule: SMP.induct)
case (MP t)
hence "t ∈ N" "wt⇩s⇩u⇩b⇩s⇩t Var" "wf⇩t⇩r⇩m⇩s (subst_range Var)" using N_supset by auto
hence "t ⋅ Var ∈ S" unfolding S_def by blast
thus ?case by simp
next
case (Subterm t t')
then obtain δ a where a: "a ⋅ δ = t" "a ∈ N" "wt⇩s⇩u⇩b⇩s⇩t δ" "wf⇩t⇩r⇩m⇩s (subst_range δ)"
by (auto simp add: S_def)
hence "∀x ∈ fv a. ∃τ. Γ (Var x) = TAtom τ" using 0 by auto
hence *: "∀x ∈ fv a. (∃f. δ x = Fun f []) ∨ (∃y. δ x = Var y)"
using a(3) TAtom_term_cases[OF wf_trm_subst_rangeD[OF a(4)]]
by (metis wt⇩s⇩u⇩b⇩s⇩t_def)
obtain b where b: "b ⋅ δ = t'" "b ∈ subterms a"
using subterms_subst_subterm[OF *, of t'] Subterm.hyps(2) a(1)
by fast
hence "b ∈ N" using N_supset a(2) by blast
thus ?case using a b(1) unfolding S_def by blast
next
case (Substitution t θ)
then obtain δ a where a: "a ⋅ δ = t" "a ∈ N" "wt⇩s⇩u⇩b⇩s⇩t δ" "wf⇩t⇩r⇩m⇩s (subst_range δ)"
by (auto simp add: S_def)
have "wt⇩s⇩u⇩b⇩s⇩t (δ ∘⇩s θ)" "wf⇩t⇩r⇩m⇩s (subst_range (δ ∘⇩s θ))"
by (fact wt_subst_compose[OF a(3) Substitution.hyps(2)],
fact wf_trms_subst_compose[OF a(4) Substitution.hyps(3)])
moreover have "t ⋅ θ = a ⋅ δ ∘⇩s θ" using a(1) subst_subst_compose[of a δ θ] by simp
ultimately show ?case using a(2) unfolding S_def by blast
next
case (Ana t K T k)
then obtain δ a where a: "a ⋅ δ = t" "a ∈ N" "wt⇩s⇩u⇩b⇩s⇩t δ" "wf⇩t⇩r⇩m⇩s (subst_range δ)"
by (auto simp add: S_def)
obtain Ka Ta where a': "Ana a = (Ka,Ta)" by moura
have *: "K = Ka ⋅⇩l⇩i⇩s⇩t δ"
proof (cases a)
case (Var x)
then obtain g U where gU: "t = Fun g U"
using a(1) Ana.hyps(2,3) Ana_var
by (cases t) simp_all
have "Γ (Var x) = TAtom Value" using Var a(2) 0 by auto
hence "Γ (Fun g U) = TAtom Value"
using a(1,3) Var gU wt_subst_trm''[OF a(3), of a]
by argo
thus ?thesis using gU Fun_Value_type_inv Ana.hyps(2,3) by fastforce
next
case (Fun g U) thus ?thesis using a(1) a' Ana.hyps(2) Ana_subst'[of g U] by simp
qed
then obtain ka where ka: "k = ka ⋅ δ" "ka ∈ set Ka" using Ana.hyps(3) by auto
have "ka ∈ set ((fst ∘ Ana) a)" using ka(2) a' by simp
hence "ka ∈ N" using a(2) N_supset by auto
thus ?case using ka a(3,4) unfolding S_def by blast
qed
thus ?thesis unfolding S_def by blast
qed
subsection ‹The Protocol Transition System, Defined in Terms of the Reachable Constraints›
definition transaction_fresh_subst where
"transaction_fresh_subst σ T 𝒜 ≡
subst_domain σ = set (transaction_fresh T) ∧
(∀t ∈ subst_range σ. ∃n. t = Fun (Val (n,False)) []) ∧
(∀t ∈ subst_range σ. t ∉ subterms⇩s⇩e⇩t (trms⇩l⇩s⇩s⇩t 𝒜)) ∧
(∀t ∈ subst_range σ. t ∉ subterms⇩s⇩e⇩t (trms_transaction T)) ∧
inj_on σ (subst_domain σ)"
definition transaction_renaming_subst where
"transaction_renaming_subst α P 𝒜 ≡
∃n ≥ max_var_set (⋃(vars_transaction ` set P) ∪ vars⇩l⇩s⇩s⇩t 𝒜). α = var_rename n"
definition constraint_model where
"constraint_model ℐ 𝒜 ≡
constr_sem_stateful ℐ (unlabel 𝒜) ∧
interpretation⇩s⇩u⇩b⇩s⇩t ℐ ∧
wf⇩t⇩r⇩m⇩s (subst_range ℐ)"
definition welltyped_constraint_model where
"welltyped_constraint_model ℐ 𝒜 ≡ wt⇩s⇩u⇩b⇩s⇩t ℐ ∧ constraint_model ℐ 𝒜"
lemma constraint_model_prefix:
assumes "constraint_model I (A@B)"
shows "constraint_model I A"
by (metis assms strand_sem_append_stateful unlabel_append constraint_model_def)
lemma welltyped_constraint_model_prefix:
assumes "welltyped_constraint_model I (A@B)"
shows "welltyped_constraint_model I A"
by (metis assms constraint_model_prefix welltyped_constraint_model_def)
lemma constraint_model_Val_is_Value_term:
assumes "welltyped_constraint_model I A"
and "t ⋅ I = Fun (Val n) []"
shows "t = Fun (Val n) [] ∨ (∃m. t = Var (TAtom Value, m))"
proof -
have "wt⇩s⇩u⇩b⇩s⇩t I" using assms(1) unfolding welltyped_constraint_model_def by simp
moreover have "Γ (Fun (Val n) []) = TAtom Value" by auto
ultimately have *: "Γ t = TAtom Value" by (metis (no_types) assms(2) wt_subst_trm'')
show ?thesis
proof (cases t)
case (Var x)
obtain τ m where x: "x = (τ, m)" by (metis surj_pair)
have "Γ⇩v x = TAtom Value" using * Var by auto
hence "τ = TAtom Value" using x Γ⇩v_TAtom'[of Value τ m] by simp
thus ?thesis using x Var by metis
next
case (Fun f T) thus ?thesis using assms(2) by auto
qed
qed
text ‹
The set of symbolic constraints reachable in any symbolic run of the protocol ‹P›.
‹σ› instantiates the fresh variables of transaction ‹T› with fresh terms.
‹α› is a variable-renaming whose range consists of fresh variables.
›
inductive_set reachable_constraints::
"('fun,'atom,'sets,'lbl) prot ⇒ ('fun,'atom,'sets,'lbl) prot_constr set"
for P::"('fun,'atom,'sets,'lbl) prot"
where
init:
"[] ∈ reachable_constraints P"
| step:
"⟦𝒜 ∈ reachable_constraints P;
T ∈ set P;
transaction_fresh_subst σ T 𝒜;
transaction_renaming_subst α P 𝒜
⟧ ⟹ 𝒜@dual⇩l⇩s⇩s⇩t (transaction_strand T ⋅⇩l⇩s⇩s⇩t σ ∘⇩s α) ∈ reachable_constraints P"
subsection ‹Admissible Transactions›
definition admissible_transaction_checks where
"admissible_transaction_checks T ≡
∀x ∈ set (unlabel (transaction_checks T)).
is_Check x ∧
(is_InSet x ⟶
is_Var (the_elem_term x) ∧ is_Fun_Set (the_set_term x) ∧
fst (the_Var (the_elem_term x)) = TAtom Value) ∧
(is_NegChecks x ⟶
bvars⇩s⇩s⇩t⇩p x = [] ∧
((the_eqs x = [] ∧ length (the_ins x) = 1) ∨
(the_ins x = [] ∧ length (the_eqs x) = 1))) ∧
(is_NegChecks x ∧ the_eqs x = [] ⟶ (let h = hd (the_ins x) in
is_Var (fst h) ∧ is_Fun_Set (snd h) ∧
fst (the_Var (fst h)) = TAtom Value))"
definition admissible_transaction_selects where
"admissible_transaction_selects T ≡
∀x ∈ set (unlabel (transaction_selects T)).
is_InSet x ∧ the_check x = Assign ∧ is_Var (the_elem_term x) ∧ is_Fun_Set (the_set_term x) ∧
fst (the_Var (the_elem_term x)) = TAtom Value"
definition admissible_transaction_updates where
"admissible_transaction_updates T ≡
∀x ∈ set (unlabel (transaction_updates T)).
is_Update x ∧ is_Var (the_elem_term x) ∧ is_Fun_Set (the_set_term x) ∧
fst (the_Var (the_elem_term x)) = TAtom Value"
definition admissible_transaction_terms where
"admissible_transaction_terms T ≡
wf⇩t⇩r⇩m⇩s' arity (trms⇩l⇩s⇩s⇩t (transaction_strand T)) ∧
(∀f ∈ ⋃(funs_term ` trms_transaction T).
¬is_Val f ∧ ¬is_Abs f ∧ ¬is_PubConstSetType f ∧ f ≠ Pair ∧
¬is_PubConstAttackType f ∧ ¬is_PubConstBottom f ∧ ¬is_PubConstOccursSecType f) ∧
(∀r ∈ set (unlabel (transaction_strand T)).
(∃f ∈ ⋃(funs_term ` (trms⇩s⇩s⇩t⇩p r)). is_Attack f) ⟶
(let t = the_msg r in is_Send r ∧ is_Fun t ∧ is_Attack (the_Fun t) ∧ args t = []))"
definition admissible_transaction_occurs_checks where
"admissible_transaction_occurs_checks T ≡ (
(∀x ∈ fv_transaction T - set (transaction_fresh T). fst x = TAtom Value ⟶
receive⟨occurs (Var x)⟩ ∈ set (unlabel (transaction_receive T))) ∧
(∀x ∈ set (transaction_fresh T). fst x = TAtom Value ⟶
send⟨occurs (Var x)⟩ ∈ set (unlabel (transaction_send T))) ∧
(∀r ∈ set (unlabel (transaction_receive T)). is_Receive r ⟶
(OccursFact ∈ funs_term (the_msg r) ∨ OccursSec ∈ funs_term (the_msg r)) ⟶
(∃x ∈ fv_transaction T - set (transaction_fresh T).
fst x = TAtom Value ∧ the_msg r = occurs (Var x))) ∧
(∀r ∈ set (unlabel (transaction_send T)). is_Send r ⟶
(OccursFact ∈ funs_term (the_msg r) ∨ OccursSec ∈ funs_term (the_msg r)) ⟶
(∃x ∈ set (transaction_fresh T).
fst x = TAtom Value ∧ the_msg r = occurs (Var x)))
)"
definition admissible_transaction where
"admissible_transaction T ≡ (
wellformed_transaction T ∧
distinct (transaction_fresh T) ∧
list_all (λx. fst x = TAtom Value) (transaction_fresh T) ∧
(∀x ∈ vars⇩l⇩s⇩s⇩t (transaction_strand T). is_Var (fst x) ∧ (the_Var (fst x) = Value)) ∧
bvars⇩l⇩s⇩s⇩t (transaction_strand T) = {} ∧
(∀x ∈ fv_transaction T - set (transaction_fresh T).
∀y ∈ fv_transaction T - set (transaction_fresh T).
x ≠ y ⟶ ⟨Var x != Var y⟩ ∈ set (unlabel (transaction_checks T)) ∨
⟨Var y != Var x⟩ ∈ set (unlabel (transaction_checks T))) ∧
admissible_transaction_selects T ∧
admissible_transaction_checks T ∧
admissible_transaction_updates T ∧
admissible_transaction_terms T ∧
admissible_transaction_occurs_checks T
)"
lemma transaction_no_bvars:
assumes "admissible_transaction T"
shows "fv_transaction T = vars_transaction T"
and "bvars_transaction T = {}"
proof -
have "wellformed_transaction T" "bvars⇩l⇩s⇩s⇩t (transaction_strand T) = {}"
using assms unfolding admissible_transaction_def
by blast+
thus "bvars_transaction T = {}" "fv_transaction T = vars_transaction T"
using bvars_wellformed_transaction_unfold vars⇩s⇩s⇩t_is_fv⇩s⇩s⇩t_bvars⇩s⇩s⇩t
by fast+
qed
lemma transactions_fv_bvars_disj:
assumes "∀T ∈ set P. admissible_transaction T"
shows "(⋃T ∈ set P. fv_transaction T) ∩ (⋃T ∈ set P. bvars_transaction T) = {}"
using assms transaction_no_bvars(2) by fast
lemma transaction_bvars_no_Value_type:
assumes "admissible_transaction T"
and "x ∈ bvars_transaction T"
shows "¬TAtom Value ⊑ Γ⇩v x"
using assms transaction_no_bvars(2) by blast
lemma transaction_receive_deduct:
assumes T_adm: "admissible_transaction T"
and ℐ: "constraint_model ℐ (A@dual⇩l⇩s⇩s⇩t (transaction_strand T ⋅⇩l⇩s⇩s⇩t σ ∘⇩s α))"
and σ: "transaction_fresh_subst σ T A"
and α: "transaction_renaming_subst α P A"
and t: "receive⟨t⟩ ∈ set (unlabel (transaction_receive T ⋅⇩l⇩s⇩s⇩t σ ∘⇩s α))"
shows "ik⇩l⇩s⇩s⇩t A ⋅⇩s⇩e⇩t ℐ ⊢ t ⋅ ℐ"
proof -
define θ where "θ ≡ σ ∘⇩s α"
have t': "send⟨t⟩ ∈ set (unlabel (dual⇩l⇩s⇩s⇩t (transaction_receive T ⋅⇩l⇩s⇩s⇩t θ)))"
using t dual⇩l⇩s⇩s⇩t_unlabel_steps_iff(2) unfolding θ_def by blast
then obtain T1 T2 where T: "unlabel (dual⇩l⇩s⇩s⇩t (transaction_receive T ⋅⇩l⇩s⇩s⇩t θ)) = T1@send⟨t⟩#T2"
using t' by (meson split_list)
have "constr_sem_stateful ℐ (unlabel A@unlabel (dual⇩l⇩s⇩s⇩t (transaction_strand T ⋅⇩l⇩s⇩s⇩t θ)))"
using ℐ unlabel_append[of A] unfolding constraint_model_def θ_def by simp
hence "constr_sem_stateful ℐ (unlabel A@T1@[send⟨t⟩])"
using strand_sem_append_stateful[of "{}" "{}" "unlabel A@T1@[send⟨t⟩]" _ ℐ]
transaction_dual_subst_unfold[of T θ] T
by (metis append.assoc append_Cons append_Nil)
hence "ik⇩s⇩s⇩t (unlabel A@T1) ⋅⇩s⇩e⇩t ℐ ⊢ t ⋅ ℐ"
using strand_sem_append_stateful[of "{}" "{}" "unlabel A@T1" "[send⟨t⟩]" ℐ] T
by force
moreover have "¬is_Receive x"
when x: "x ∈ set (unlabel (dual⇩l⇩s⇩s⇩t (transaction_receive T ⋅⇩l⇩s⇩s⇩t θ)))" for x
proof -
have *: "is_Receive a" when "a ∈ set (unlabel (transaction_receive T))" for a
using T_adm Ball_set[of "unlabel (transaction_receive T)" is_Receive] that
unfolding admissible_transaction_def wellformed_transaction_def
by blast
obtain l where l: "(l,x) ∈ set (dual⇩l⇩s⇩s⇩t (transaction_receive T ⋅⇩l⇩s⇩s⇩t θ))"
using x unfolding unlabel_def by fastforce
then obtain ly where ly: "ly ∈ set (transaction_receive T ⋅⇩l⇩s⇩s⇩t θ)" "(l,x) = dual⇩l⇩s⇩s⇩t⇩p ly"
unfolding dual⇩l⇩s⇩s⇩t_def by auto
obtain j y where j: "ly = (j,y)" by (metis surj_pair)
hence "j = l" using ly(2) by (cases y) auto
hence y: "(l,y) ∈ set (transaction_receive T ⋅⇩l⇩s⇩s⇩t θ)" "(l,x) = dual⇩l⇩s⇩s⇩t⇩p (l,y)"
by (metis j ly(1), metis j ly(2))
obtain z where z:
"z ∈ set (unlabel (transaction_receive T))"
"(l,z) ∈ set (transaction_receive T)"
"(l,y) = (l,z) ⋅⇩l⇩s⇩s⇩t⇩p θ"
using y(1) unfolding subst_apply_labeled_stateful_strand_def unlabel_def by force
have "is_Receive y" using *[OF z(1)] z(3) by (cases z) auto
thus "¬is_Receive x" using l y by (cases y) auto
qed
hence "¬is_Receive x" when "x ∈ set T1" for x using T that by simp
hence "ik⇩s⇩s⇩t T1 = {}" unfolding ik⇩s⇩s⇩t_def is_Receive_def by fast
hence "ik⇩s⇩s⇩t (unlabel A@T1) = ik⇩l⇩s⇩s⇩t A" using ik⇩s⇩s⇩t_append[of "unlabel A" T1] by simp
ultimately show ?thesis by (simp add: θ_def)
qed
lemma transaction_checks_db:
assumes T: "admissible_transaction T"
and ℐ: "constraint_model ℐ (A@dual⇩l⇩s⇩s⇩t (transaction_strand T ⋅⇩l⇩s⇩s⇩t σ ∘⇩s α))"
and σ: "transaction_fresh_subst σ T A"
and α: "transaction_renaming_subst α P A"
shows "⟨Var (TAtom Value, n) in Fun (Set s) []⟩ ∈ set (unlabel (transaction_checks T))
⟹ (α (TAtom Value, n) ⋅ ℐ, Fun (Set s) []) ∈ set (db⇩l⇩s⇩s⇩t A ℐ)"
(is "?A ⟹ ?B")
and "⟨Var (TAtom Value, n) not in Fun (Set s) []⟩ ∈ set (unlabel (transaction_checks T))
⟹ (α (TAtom Value, n) ⋅ ℐ, Fun (Set s) []) ∉ set (db⇩l⇩s⇩s⇩t A ℐ)"
(is "?C ⟹ ?D")
proof -
let ?x = "λn. (TAtom Value, n)"
let ?s = "Fun (Set s) []"
let ?T = "transaction_receive T@transaction_selects T@transaction_checks T"
let ?T' = "?T ⋅⇩l⇩s⇩s⇩t σ ∘⇩s α"
let ?S = "λS. transaction_receive T@transaction_selects T@S"
let ?S' = "λS. ?S S ⋅⇩l⇩s⇩s⇩t σ ∘⇩s α"
have T_valid: "wellformed_transaction T" using T by (simp add: admissible_transaction_def)
have "constr_sem_stateful ℐ (unlabel (A@dual⇩l⇩s⇩s⇩t (transaction_strand T ⋅⇩l⇩s⇩s⇩t σ ∘⇩s α)))"
using ℐ unfolding constraint_model_def by simp
moreover have
"dual⇩l⇩s⇩s⇩t (transaction_strand T ⋅⇩l⇩s⇩s⇩t δ) =
dual⇩l⇩s⇩s⇩t (?S (T1@[c]) ⋅⇩l⇩s⇩s⇩t δ)@
dual⇩l⇩s⇩s⇩t (T2@transaction_updates T@transaction_send T ⋅⇩l⇩s⇩s⇩t δ)"
when "transaction_checks T = T1@c#T2" for T1 T2 c δ
using that dual⇩l⇩s⇩s⇩t_append subst_lsst_append
unfolding transaction_strand_def
by (metis append.assoc append_Cons append_Nil)
ultimately have T'_model: "constr_sem_stateful ℐ (unlabel (A@dual⇩l⇩s⇩s⇩t (?S' (T1@[(l,c)]))))"
when "transaction_checks T = T1@(l,c)#T2" for T1 T2 l c
using strand_sem_append_stateful[of _ _ _ _ ℐ]
by (simp add: that transaction_strand_def)
show "?A ⟹ ?B"
proof -
assume a: ?A
hence *: "⟨Var (?x n) in ?s⟩ ∈ set (unlabel ?T)"
unfolding transaction_strand_def unlabel_def by simp
then obtain l T1 T2 where T1: "transaction_checks T = T1@(l,⟨Var (?x n) in ?s⟩)#T2"
by (metis a split_list unlabel_mem_has_label)
have "?x n ∈ fv⇩l⇩s⇩s⇩t (transaction_checks T)"
using a by force
hence "?x n ∉ set (transaction_fresh T)"
using a transaction_fresh_vars_notin[OF T_valid] by fast
hence "unlabel (A@dual⇩l⇩s⇩s⇩t (?S' (T1@[(l,⟨Var (?x n) in ?s⟩)]))) =
unlabel (A@dual⇩l⇩s⇩s⇩t (?S' T1))@[⟨α (?x n) in ?s⟩]"
using T a σ dual⇩l⇩s⇩s⇩t_append subst_lsst_append unlabel_append
by (fastforce simp add: transaction_fresh_subst_def unlabel_def dual⇩l⇩s⇩s⇩t_def
subst_apply_labeled_stateful_strand_def)
moreover have "db⇩s⇩s⇩t (unlabel A) = db⇩s⇩s⇩t (unlabel (A@dual⇩l⇩s⇩s⇩t (?S' T1)))"
by (simp add: T1 db⇩s⇩s⇩t_transaction_prefix_eq[OF T_valid] del: unlabel_append)
ultimately have "∃M. strand_sem_stateful M (set (db⇩s⇩s⇩t (unlabel A) ℐ)) [⟨α (?x n) in ?s⟩] ℐ"
using T'_model[OF T1] db⇩s⇩s⇩t_set_is_dbupd⇩s⇩s⇩t[of _ ℐ] strand_sem_append_stateful[of _ _ _ _ ℐ]
by (simp add: db⇩s⇩s⇩t_def del: unlabel_append)
thus ?B by simp
qed
show "?C ⟹ ?D"
proof -
assume a: ?C
hence *: "⟨Var (?x n) not in ?s⟩ ∈ set (unlabel ?T)"
unfolding transaction_strand_def unlabel_def by simp
then obtain l T1 T2 where T1: "transaction_checks T = T1@(l,⟨Var (?x n) not in ?s⟩)#T2"
by (metis a split_list unlabel_mem_has_label)
have "?x n ∈ vars⇩s⇩s⇩t⇩p ⟨Var (?x n) not in ?s⟩"
using vars⇩s⇩s⇩t⇩p_cases(9)[of "[]" "Var (?x n)" ?s] by auto
hence "?x n ∈ vars⇩l⇩s⇩s⇩t (transaction_checks T)"
using a unfolding vars⇩s⇩s⇩t_def by force
hence "?x n ∉ set (transaction_fresh T)"
using a transaction_fresh_vars_notin[OF T_valid] by fast
hence "unlabel (A@dual⇩l⇩s⇩s⇩t (?S' (T1@[(l,⟨Var (?x n) not in ?s⟩)]))) =
unlabel (A@dual⇩l⇩s⇩s⇩t (?S' T1))@[⟨α (?x n) not in ?s⟩]"
using T a σ dual⇩l⇩s⇩s⇩t_append subst_lsst_append unlabel_append
by (fastforce simp add: transaction_fresh_subst_def unlabel_def dual⇩l⇩s⇩s⇩t_def
subst_apply_labeled_stateful_strand_def)
moreover have "db⇩s⇩s⇩t (unlabel A) = db⇩s⇩s⇩t (unlabel (A@dual⇩l⇩s⇩s⇩t (?S' T1)))"
by (simp add: T1 db⇩s⇩s⇩t_transaction_prefix_eq[OF T_valid] del: unlabel_append)
ultimately have "∃M. strand_sem_stateful M (set (db⇩s⇩s⇩t (unlabel A) ℐ)) [⟨α (?x n) not in ?s⟩] ℐ"
using T'_model[OF T1] db⇩s⇩s⇩t_set_is_dbupd⇩s⇩s⇩t[of _ ℐ] strand_sem_append_stateful[of _ _ _ _ ℐ]
by (simp add: db⇩s⇩s⇩t_def del: unlabel_append)
thus ?D using stateful_strand_sem_NegChecks_no_bvars(1)[of _ _ _ ?s ℐ] by simp
qed
qed
lemma transaction_selects_db:
assumes T: "admissible_transaction T"
and ℐ: "constraint_model ℐ (A@dual⇩l⇩s⇩s⇩t (transaction_strand T ⋅⇩l⇩s⇩s⇩t σ ∘⇩s α))"
and σ: "transaction_fresh_subst σ T A"
and α: "transaction_renaming_subst α P A"
shows "select⟨Var (TAtom Value, n), Fun (Set s) []⟩ ∈ set (unlabel (transaction_selects T))
⟹ (α (TAtom Value, n) ⋅ ℐ, Fun (Set s) []) ∈ set (db⇩l⇩s⇩s⇩t A ℐ)"
(is "?A ⟹ ?B")
proof -
let ?x = "λn. (TAtom Value, n)"
let ?s = "Fun (Set s) []"
let ?T = "transaction_receive T@transaction_selects T@transaction_checks T"
let ?T' = "?T ⋅⇩l⇩s⇩s⇩t σ ∘⇩s α"
let ?S = "λS. transaction_receive T@S"
let ?S' = "λS. ?S S ⋅⇩l⇩s⇩s⇩t σ ∘⇩s α"
have T_valid: "wellformed_transaction T" using T by (simp add: admissible_transaction_def)
have "constr_sem_stateful ℐ (unlabel (A@dual⇩l⇩s⇩s⇩t (transaction_strand T ⋅⇩l⇩s⇩s⇩t σ ∘⇩s α)))"
using ℐ unfolding constraint_model_def by simp
moreover have
"dual⇩l⇩s⇩s⇩t (transaction_strand T ⋅⇩l⇩s⇩s⇩t δ) =
dual⇩l⇩s⇩s⇩t (?S (T1@[c]) ⋅⇩l⇩s⇩s⇩t δ)@
dual⇩l⇩s⇩s⇩t (T2@transaction_checks T @ transaction_updates T@transaction_send T ⋅⇩l⇩s⇩s⇩t δ)"
when "transaction_selects T = T1@c#T2" for T1 T2 c δ
using that dual⇩l⇩s⇩s⇩t_append subst_lsst_append
unfolding transaction_strand_def by (metis append.assoc append_Cons append_Nil)
ultimately have T'_model: "constr_sem_stateful ℐ (unlabel (A@dual⇩l⇩s⇩s⇩t (?S' (T1@[(l,c)]))))"
when "transaction_selects T = T1@(l,c)#T2" for T1 T2 l c
using strand_sem_append_stateful[of _ _ _ _ ℐ]
by (simp add: that transaction_strand_def)
show "?A ⟹ ?B"
proof -
assume a: ?A
hence *: "select⟨Var (?x n), ?s⟩ ∈ set (unlabel ?T)"
unfolding transaction_strand_def unlabel_def by simp
then obtain l T1 T2 where T1: "transaction_selects T = T1@(l,select⟨Var (?x n), ?s⟩)#T2"
by (metis a split_list unlabel_mem_has_label)
have "?x n ∈ fv⇩l⇩s⇩s⇩t (transaction_selects T)"
using a by force
hence "?x n ∉ set (transaction_fresh T)"
using a transaction_fresh_vars_notin[OF T_valid] by fast
hence "unlabel (A@dual⇩l⇩s⇩s⇩t (?S' (T1@[(l,select⟨Var (?x n), ?s⟩)]))) =
unlabel (A@dual⇩l⇩s⇩s⇩t (?S' T1))@[select⟨α (?x n), ?s⟩]"
using T a σ dual⇩l⇩s⇩s⇩t_append subst_lsst_append unlabel_append
by (fastforce simp add: transaction_fresh_subst_def unlabel_def dual⇩l⇩s⇩s⇩t_def
subst_apply_labeled_stateful_strand_def)
moreover have "db⇩s⇩s⇩t (unlabel A) = db⇩s⇩s⇩t (unlabel (A@dual⇩l⇩s⇩s⇩t (?S' T1)))"
by (simp add: T1 db⇩s⇩s⇩t_transaction_prefix_eq[OF T_valid] del: unlabel_append)
ultimately have "∃M. strand_sem_stateful M (set (db⇩s⇩s⇩t (unlabel A) ℐ)) [⟨α (?x n) in ?s⟩] ℐ"
using T'_model[OF T1] db⇩s⇩s⇩t_set_is_dbupd⇩s⇩s⇩t[of _ ℐ] strand_sem_append_stateful[of _ _ _ _ ℐ]
by (simp add: db⇩s⇩s⇩t_def del: unlabel_append)
thus ?B by simp
qed
qed
lemma transactions_have_no_Value_consts:
assumes "admissible_transaction T"
and "t ∈ subterms⇩s⇩e⇩t (trms⇩l⇩s⇩s⇩t (transaction_strand T))"
shows "∄a T. t = Fun (Val a) T" (is ?A)
and "∄a T. t = Fun (Abs a) T" (is ?B)
proof -
have "admissible_transaction_terms T" using assms(1) unfolding admissible_transaction_def by blast
hence "¬is_Val f" "¬is_Abs f"
when "f ∈ ⋃(funs_term ` (trms_transaction T))" for f
using that unfolding admissible_transaction_terms_def by blast+
moreover have "f ∈ ⋃(funs_term ` (trms_transaction T))"
when "f ∈ funs_term t" for f
using that assms(2) funs_term_subterms_eq(2)[of "trms_transaction T"] by blast+
ultimately have *: "¬is_Val f" "¬is_Abs f"
when "f ∈ funs_term t" for f
using that by presburger+
show ?A using *(1) by force
show ?B using *(2) by force
qed
lemma transactions_have_no_Value_consts':
assumes "admissible_transaction T"
and "t ∈ trms⇩l⇩s⇩s⇩t (transaction_strand T)"
shows "∄a T. Fun (Val a) T ∈ subterms t"
and "∄a T. Fun (Abs a) T ∈ subterms t"
using transactions_have_no_Value_consts[OF assms(1)] assms(2) by fast+
lemma transactions_have_no_PubConsts:
assumes "admissible_transaction T"
and "t ∈ subterms⇩s⇩e⇩t (trms⇩l⇩s⇩s⇩t (transaction_strand T))"
shows "∄a T. t = Fun (PubConstSetType a) T" (is ?A)
and "∄a T. t = Fun (PubConstAttackType a) T" (is ?B)
and "∄a T. t = Fun (PubConstBottom a) T" (is ?C)
and "∄a T. t = Fun (PubConstOccursSecType a) T" (is ?D)
proof -
have "admissible_transaction_terms T" using assms(1) unfolding admissible_transaction_def by blast
hence "¬is_PubConstSetType f" "¬is_PubConstAttackType f"
"¬is_PubConstBottom f" "¬is_PubConstOccursSecType f"
when "f ∈ ⋃(funs_term ` (trms_transaction T))" for f
using that unfolding admissible_transaction_terms_def by blast+
moreover have "f ∈ ⋃(funs_term ` (trms_transaction T))"
when "f ∈ funs_term t" for f
using that assms(2) funs_term_subterms_eq(2)[of "trms_transaction T"] by blast+
ultimately have *:
"¬is_PubConstSetType f" "¬is_PubConstAttackType f"
"¬is_PubConstBottom f" "¬is_PubConstOccursSecType f"
when "f ∈ funs_term t" for f
using that by presburger+
show ?A using *(1) by force
show ?B using *(2) by force
show ?C using *(3) by force
show ?D using *(4) by force
qed
lemma transactions_have_no_PubConsts':
assumes "admissible_transaction T"
and "t ∈ trms⇩l⇩s⇩s⇩t (transaction_strand T)"
shows "∄a T. Fun (PubConstSetType a) T ∈ subterms t"
and "∄a T. Fun (PubConstAttackType a) T ∈ subterms t"
and "∄a T. Fun (PubConstBottom a) T ∈ subterms t"
and "∄a T. Fun (PubConstOccursSecType a) T ∈ subterms t"
using transactions_have_no_PubConsts[OF assms(1)] assms(2) by fast+
lemma transaction_inserts_are_Value_vars:
assumes T_valid: "wellformed_transaction T"
and "admissible_transaction_updates T"
and "insert⟨t,s⟩ ∈ set (unlabel (transaction_strand T))"
shows "∃n. t = Var (TAtom Value, n)"
and "∃u. s = Fun (Set u) []"
proof -
let ?x = "insert⟨t,s⟩"
have "?x ∈ set (unlabel (transaction_updates T))"
using assms(3) wellformed_transaction_unlabel_cases[OF T_valid, of ?x]
by (auto simp add: transaction_strand_def unlabel_def)
hence *: "is_Var (the_elem_term ?x)" "fst (the_Var (the_elem_term ?x)) = TAtom Value"
"is_Fun (the_set_term ?x)" "args (the_set_term ?x) = []"
"is_Set (the_Fun (the_set_term ?x))"
using assms(2) unfolding admissible_transaction_updates_def is_Fun_Set_def by fastforce+
show "∃n. t = Var (TAtom Value, n)" using *(1,2) by (cases t) auto
show "∃u. s = Fun (Set u) []" using *(3,4,5) unfolding is_Set_def by (cases s) auto
qed
lemma transaction_deletes_are_Value_vars:
assumes T_valid: "wellformed_transaction T"
and "admissible_transaction_updates T"
and "delete⟨t,s⟩ ∈ set (unlabel (transaction_strand T))"
shows "∃n. t = Var (TAtom Value, n)"
and "∃u. s = Fun (Set u) []"
proof -
let ?x = "delete⟨t,s⟩"
have "?x ∈ set (unlabel (transaction_updates T))"
using assms(3) wellformed_transaction_unlabel_cases[OF T_valid, of ?x]
by (auto simp add: transaction_strand_def unlabel_def)
hence *: "is_Var (the_elem_term ?x)" "fst (the_Var (the_elem_term ?x)) = TAtom Value"
"is_Fun (the_set_term ?x)" "args (the_set_term ?x) = []"
"is_Set (the_Fun (the_set_term ?x))"
using assms(2) unfolding admissible_transaction_updates_def is_Fun_Set_def by fastforce+
show "∃n. t = Var (TAtom Value, n)" using *(1,2) by (cases t) auto
show "∃u. s = Fun (Set u) []" using *(3,4,5) unfolding is_Set_def by (cases s) auto
qed
lemma transaction_selects_are_Value_vars:
assumes T_valid: "wellformed_transaction T"
and "admissible_transaction_selects T"
and "select⟨t,s⟩ ∈ set (unlabel (transaction_strand T))"
shows "∃n. t = Var (TAtom Value, n) ∧ (TAtom Value, n) ∉ set (transaction_fresh T)" (is ?A)
and "∃u. s = Fun (Set u) []" (is ?B)
proof -
let ?x = "select⟨t,s⟩"
have *: "?x ∈ set (unlabel (transaction_selects T))"
using assms(3) wellformed_transaction_unlabel_cases[OF T_valid, of ?x]
by (auto simp add: transaction_strand_def unlabel_def)
have **: "is_Var (the_elem_term ?x)" "fst (the_Var (the_elem_term ?x)) = TAtom Value"
"is_Fun (the_set_term ?x)" "args (the_set_term ?x) = []"
"is_Set (the_Fun (the_set_term ?x))"
using * assms(2) unfolding admissible_transaction_selects_def is_Fun_Set_def by fastforce+
have "fv⇩s⇩s⇩t⇩p ?x ⊆ fv⇩l⇩s⇩s⇩t (transaction_selects T)"
using * by force
hence ***: "fv⇩s⇩s⇩t⇩p ?x ∩ set (transaction_fresh T) = {}"
using T_valid unfolding wellformed_transaction_def by fast
show ?A using **(1,2) *** by (cases t) auto
show ?B using **(3,4,5) unfolding is_Set_def by (cases s) auto
qed
lemma transaction_inset_checks_are_Value_vars:
assumes T_valid: "wellformed_transaction T"
and "admissible_transaction_checks T"
and "⟨t in s⟩ ∈ set (unlabel (transaction_strand T))"
shows "∃n. t = Var (TAtom Value, n) ∧ (TAtom Value, n) ∉ set (transaction_fresh T)" (is ?A)
and "∃u. s = Fun (Set u) []" (is ?B)
proof -
let ?x = "⟨t in s⟩"
have *: "?x ∈ set (unlabel (transaction_checks T))"
using assms(3) wellformed_transaction_unlabel_cases[OF T_valid, of ?x]
by (auto simp add: transaction_strand_def unlabel_def)
have **: "is_Var (the_elem_term ?x)" "fst (the_Var (the_elem_term ?x)) = TAtom Value"
"is_Fun (the_set_term ?x)" "args (the_set_term ?x) = []"
"is_Set (the_Fun (the_set_term ?x))"
using * assms(2) unfolding admissible_transaction_checks_def is_Fun_Set_def by fastforce+
have "fv⇩s⇩s⇩t⇩p ?x ⊆ fv⇩l⇩s⇩s⇩t (transaction_checks T)"
using * by force
hence ***: "fv⇩s⇩s⇩t⇩p ?x ∩ set (transaction_fresh T) = {}"
using T_valid unfolding wellformed_transaction_def by fast
show ?A using **(1,2) *** by (cases t) auto
show ?B using **(3,4,5) unfolding is_Set_def by (cases s) auto
qed
lemma transaction_notinset_checks_are_Value_vars:
assumes T_valid: "wellformed_transaction T"
and "admissible_transaction_checks T"
and "∀X⟨∨≠: F ∨∉: G⟩ ∈ set (unlabel (transaction_strand T))"
and "(t,s) ∈ set G"
shows "∃n. t = Var (TAtom Value, n) ∧ (TAtom Value, n) ∉ set (transaction_fresh T)" (is ?A)
and "∃u. s = Fun (Set u) []" (is ?B)
proof -
let ?x = "∀X⟨∨≠: F ∨∉: G⟩"
have 0: "?x ∈ set (unlabel (transaction_checks T))"
using assms(3) wellformed_transaction_unlabel_cases[OF T_valid, of ?x]
by (auto simp add: transaction_strand_def unlabel_def)
hence 1: "F = [] ∧ length G = 1"
using assms(2,4) unfolding admissible_transaction_checks_def by fastforce
hence "hd G = (t,s)" using assms(4) by (cases "the_ins ?x") auto
hence **: "is_Var t" "fst (the_Var t) = TAtom Value" "is_Fun s" "args s = []" "is_Set (the_Fun s)"
using 0 1 assms(2) unfolding admissible_transaction_checks_def Let_def is_Fun_Set_def
by fastforce+
have "fv⇩s⇩s⇩t⇩p ?x ⊆ fv⇩l⇩s⇩s⇩t (transaction_checks T)"
"set (bvars⇩s⇩s⇩t⇩p ?x) ⊆ bvars⇩l⇩s⇩s⇩t (transaction_checks T)"
using 0 by force+
moreover have
"fv⇩l⇩s⇩s⇩t (transaction_checks T) ⊆ fv⇩l⇩s⇩s⇩t (transaction_receive T) ∪ fv⇩l⇩s⇩s⇩t (transaction_selects T)"
"set (transaction_fresh T) ∩ fv⇩l⇩s⇩s⇩t (transaction_receive T) = {}"
"set (transaction_fresh T) ∩ fv⇩l⇩s⇩s⇩t (transaction_selects T) = {}"
using T_valid unfolding wellformed_transaction_def by fast+
ultimately have
"fv⇩s⇩s⇩t⇩p ?x ∩ set (transaction_fresh T) = {}"
"set (bvars⇩s⇩s⇩t⇩p ?x) ∩ set (transaction_fresh T) = {}"
using wellformed_transaction_wf⇩s⇩s⇩t(2,3)[OF T_valid]
fv_transaction_unfold[of T] bvars_transaction_unfold[of T]
by blast+
hence ***: "fv t ∩ set (transaction_fresh T) = {}"
using assms(4) by auto
show ?A using **(1,2) *** by (cases t) auto
show ?B using **(3,4,5) unfolding is_Set_def by (cases s) auto
qed
lemma admissible_transaction_strand_step_cases:
assumes T_adm: "admissible_transaction T"
shows "r ∈ set (unlabel (transaction_receive T)) ⟹ ∃t. r = receive⟨t⟩"
(is "?A ⟹ ?A'")
and "r ∈ set (unlabel (transaction_selects T)) ⟹
∃x s. r = select⟨Var x, Fun (Set s) []⟩ ∧
fst x = TAtom Value ∧ x ∈ fv_transaction T - set (transaction_fresh T)"
(is "?B ⟹ ?B'")
and "r ∈ set (unlabel (transaction_checks T)) ⟹
(∃x s. (r = ⟨Var x in Fun (Set s) []⟩ ∨ r = ⟨Var x not in Fun (Set s) []⟩) ∧
fst x = TAtom Value ∧ x ∈ fv_transaction T - set (transaction_fresh T)) ∨
(∃s t. r = ⟨s == t⟩ ∨ r = ⟨s != t⟩)"
(is "?C ⟹ ?C'")
and "r ∈ set (unlabel (transaction_updates T)) ⟹
∃x s. (r = insert⟨Var x, Fun (Set s) []⟩ ∨ r = delete⟨Var x, Fun (Set s) []⟩) ∧
fst x = TAtom Value"
(is "?D ⟹ ?D'")
and "r ∈ set (unlabel (transaction_send T)) ⟹ ∃t. r = send⟨t⟩"
(is "?E ⟹ ?E'")
proof -
have T_valid: "wellformed_transaction T"
using T_adm unfolding admissible_transaction_def by metis
show "?A ⟹ ?A'"
using T_valid Ball_set[of "unlabel (transaction_receive T)" is_Receive]
unfolding wellformed_transaction_def is_Receive_def
by blast
show "?E ⟹ ?E'"
using T_valid Ball_set[of "unlabel (transaction_send T)" is_Send]
unfolding wellformed_transaction_def is_Send_def
by blast
show "?B ⟹ ?B'"
proof -
assume r: ?B
have "admissible_transaction_selects T"
using T_adm unfolding admissible_transaction_def by simp
hence *: "is_InSet r" "the_check r = Assign" "is_Var (the_elem_term r)"
"is_Fun (the_set_term r)" "is_Set (the_Fun (the_set_term r))"
"args (the_set_term r) = []" "fst (the_Var (the_elem_term r)) = TAtom Value"
using r unfolding admissible_transaction_selects_def is_Fun_Set_def
by fast+
obtain rt rs where r': "r = select⟨rt,rs⟩" using *(1,2) by (cases r) auto
obtain x where x: "rt = Var x" "fst x = TAtom Value" using *(3,7) r' by auto
obtain f S where fS: "rs = Fun f S" using *(4) r' by auto
obtain s where s: "f = Set s" using *(5) fS r' by (cases f) auto
hence S: "S = []" using *(6) fS r' by (cases S) auto
have fv_r1: "fv⇩s⇩s⇩t⇩p r ⊆ fv_transaction T"
using r fv_transaction_unfold[of T] by auto
have fv_r2: "fv⇩s⇩s⇩t⇩p r ∩ set (transaction_fresh T) = {}"
using r T_valid unfolding wellformed_transaction_def by fastforce
show ?B' using r' x fS s S fv_r1 fv_r2 by simp
qed
show "?C ⟹ ?C'"
proof -
assume r: ?C
have adm_checks: "admissible_transaction_checks T"
using assms unfolding admissible_transaction_def by simp
have fv_r1: "fv⇩s⇩s⇩t⇩p r ⊆ fv_transaction T"
using r fv_transaction_unfold[of T] by auto
have fv_r2: "fv⇩s⇩s⇩t⇩p r ∩ set (transaction_fresh T) = {}"
using r T_valid unfolding wellformed_transaction_def by fastforce
have "(is_InSet r ∧ the_check r = Check) ∨
(is_Equality r ∧ the_check r = Check) ∨
is_NegChecks r"
using r adm_checks unfolding admissible_transaction_checks_def by fast
thus ?C'
proof (elim disjE conjE)
assume *: "is_InSet r" "the_check r = Check"
hence **: "is_Var (the_elem_term r)" "is_Fun (the_set_term r)"
"is_Set (the_Fun (the_set_term r))" "args (the_set_term r) = []"
"fst (the_Var (the_elem_term r)) = TAtom Value"
using r adm_checks unfolding admissible_transaction_checks_def is_Fun_Set_def
by fast+
obtain rt rs where r': "r = ⟨rt in rs⟩" using * by (cases r) auto
obtain x where x: "rt = Var x" "fst x = TAtom Value" using **(1,5) r' by auto
obtain f S where fS: "rs = Fun f S" using **(2) r' by auto
obtain s where s: "f = Set s" using **(3) fS r' by (cases f) auto
hence S: "S = []" using **(4) fS r' by auto
show ?C' using r' x fS s S fv_r1 fv_r2 by simp
next
assume *: "is_NegChecks r"
hence **: "bvars⇩s⇩s⇩t⇩p r = []"
"(the_eqs r = [] ∧ length (the_ins r) = 1) ∨
(the_ins r = [] ∧ length (the_eqs r) = 1)"
using r adm_checks unfolding admissible_transaction_checks_def by fast+
show ?C' using **(2)
proof (elim disjE conjE)
assume ***: "the_eqs r = []" "length (the_ins r) = 1"
then obtain t s where ts: "the_ins r = [(t,s)]" by (cases "the_ins r") auto
hence "hd (the_ins r) = (t,s)" by simp
hence ****: "is_Var (fst (t,s))" "is_Fun (snd (t,s))"
"is_Set (the_Fun (snd (t,s)))" "args (snd (t,s)) = []"
"fst (the_Var (fst (t,s))) = TAtom Value"
using r adm_checks * ***(1) unfolding admissible_transaction_checks_def is_Fun_Set_def
by metis+
obtain x where x: "t = Var x" "fst x = TAtom Value" using ts ****(1,5) by (cases t) simp_all
obtain f S where fS: "s = Fun f S" using ts ****(2) by (cases s) simp_all
obtain ss where ss: "f = Set ss" using fS ****(3) by (cases f) simp_all
have S: "S = []" using ts fS ss ****(4) by simp
show ?C' using ts x fS ss S *** **(1) * fv_r1 fv_r2 by (cases r) auto
next
assume ***: "the_ins r = []" "length (the_eqs r) = 1"
then obtain t s where "the_eqs r = [(t,s)]" by (cases "the_eqs r") auto
thus ?C' using *** **(1) * by (cases r) auto
qed
qed (auto simp add: is_Equality_def the_check_def)
qed
show "?D ⟹ ?D'"
proof -
assume r: ?D
have adm_upds: "admissible_transaction_updates T"
using assms unfolding admissible_transaction_def by simp
have *: "is_Update r" "is_Var (the_elem_term r)" "is_Fun (the_set_term r)"
"is_Set (the_Fun (the_set_term r))" "args (the_set_term r) = []"
"fst (the_Var (the_elem_term r)) = TAtom Value"
using r adm_upds unfolding admissible_transaction_updates_def is_Fun_Set_def by fast+
obtain t s where ts: "r = insert⟨t,s⟩ ∨ r = delete⟨t,s⟩" using *(1) by (cases r) auto
obtain x where x: "t = Var x" "fst x = TAtom Value" using ts *(2,6) by (cases t) auto
obtain f T where fT: "s = Fun f T" using ts *(3) by (cases s) auto
obtain ss where ss: "f = Set ss" using ts fT *(4) by (cases f) fastforce+
have T: "T = []" using ts fT *(5) ss by (cases T) auto
show ?D'
using ts x fT ss T by blast
qed
qed
lemma transaction_Value_vars_are_fv:
assumes "admissible_transaction T"
and "x ∈ vars_transaction T"
and "Γ⇩v x = TAtom Value"
shows "x ∈ fv_transaction T"
using assms Γ⇩v_TAtom''(2)[of x] vars⇩s⇩s⇩t_is_fv⇩s⇩s⇩t_bvars⇩s⇩s⇩t[of "unlabel (transaction_strand T)"]
unfolding admissible_transaction_def by fast
lemma protocol_transaction_vars_TAtom_typed:
assumes P: "admissible_transaction T"
shows "∀x ∈ vars_transaction T. Γ⇩v x = TAtom Value ∨ (∃a. Γ⇩v x = TAtom (Atom a))"
and "∀x ∈ fv_transaction T. Γ⇩v x = TAtom Value ∨ (∃a. Γ⇩v x = TAtom (Atom a))"
and "∀x ∈ set (transaction_fresh T). Γ⇩v x = TAtom Value"
proof -
have P': "wellformed_transaction T"
using P unfolding admissible_transaction_def by fast
show "∀x ∈ vars_transaction T. Γ⇩v x = TAtom Value ∨ (∃a. Γ⇩v x = TAtom (Atom a))"
using P Γ⇩v_TAtom''
unfolding admissible_transaction_def is_Var_def prot_atom.is_Atom_def the_Var_def
by fastforce
thus "∀x ∈ fv_transaction T. Γ⇩v x = TAtom Value ∨ (∃a. Γ⇩v x = TAtom (Atom a))"
using vars⇩s⇩s⇩t_is_fv⇩s⇩s⇩t_bvars⇩s⇩s⇩t by fast
have "list_all (λx. fst x = Var Value) (transaction_fresh T)"
using P Γ⇩v_TAtom'' unfolding admissible_transaction_def by fast
thus "∀x ∈ set (transaction_fresh T). Γ⇩v x = TAtom Value"
using Γ⇩v_TAtom''(2) unfolding list_all_iff by fast
qed
lemma protocol_transactions_no_pubconsts:
assumes "admissible_transaction T"
shows "Fun (Val (n,True)) S ∉ subterms⇩s⇩e⇩t (trms_transaction T)"
using assms transactions_have_no_Value_consts(1)
by fast
lemma protocol_transactions_no_abss:
assumes "admissible_transaction T"
shows "Fun (Abs n) S ∉ subterms⇩s⇩e⇩t (trms_transaction T)"
using assms transactions_have_no_Value_consts(2)
by fast
lemma admissible_transaction_strand_sem_fv_ineq:
assumes T_adm: "admissible_transaction T"
and ℐ: "strand_sem_stateful IK DB (unlabel (dual⇩l⇩s⇩s⇩t (transaction_strand T ⋅⇩l⇩s⇩s⇩t θ))) ℐ"
and x: "x ∈ fv_transaction T - set (transaction_fresh T)"
and y: "y ∈ fv_transaction T - set (transaction_fresh T)"
and x_not_y: "x ≠ y"
shows "θ x ⋅ ℐ ≠