Theory CompositionSupport

theory CompositionSupport
imports CompositionBase
begin

locale CompositionSupport =
fixes ESi :: "'e ES_rec"
and 𝒱 :: "'e V_rec"
and 𝒱i :: "'e V_rec"

(* assumption about the component event system *)
assumes validESi: "ES_valid ESi"

(* assumption about the views (part of proper separation) *)
and validVi: "isViewOn 𝒱i E⇘ESi⇙"
and Vv_inter_Ei_is_Vvi: "V⇘𝒱⇙ ∩ E⇘ESi⇙ = V⇘𝒱i⇙"
and Cv_inter_Ei_subsetof_Cvi: "C⇘𝒱⇙ ∩ E⇘ESi⇙ ⊆ C⇘𝒱i⇙"

(* sublocale relations for CompositionSupport *)

(* body of CompositionSupport *)
context CompositionSupport
begin

(* This lemma is used in the compositionality proof for BSD.
  Assuming that BSD holds for a subsystem ESi and given a trace β @ [c] @ α of the composed system,
  we can obtain a trace (β ↿ EESi) @ α_i' of ESi where α_i' contains no 
  events that are confidential in ESi and (α_i' ↿ V𝒱i) = (α ↿ V𝒱i) holds.
  
 𝒱 and 𝒱i denote views on the composition and subsystem respectively.
  We assume that 𝒱 and 𝒱i are properly separated. *)
lemma BSD_in_subsystem:
"⟦ c ∈ C⇘𝒱⇙; ((β @ [c] @ α) ↿ E⇘ESi⇙) ∈ Tr⇘ESi⇙ ; BSD 𝒱i Tr⇘ESi⇙ ⟧ 
  ⟹ ∃α_i'. ( ((β ↿ E⇘ESi⇙) @ α_i') ∈ Tr⇘ESi⇙ 
  ∧ (α_i' ↿ V⇘𝒱i⇙) = (α ↿ V⇘𝒱i⇙) ∧ α_i' ↿ C⇘𝒱i⇙ = [] )"
proof (induct "length (([c] @ α) ↿ C⇘𝒱i⇙)" arbitrary: β c α)
  case 0
  (* show that ([c] @ α) ↿ EESi is a suitable choice for α_i' *)
  let ?L = "([c] @ α) ↿ E⇘ESi⇙"
  
  from 0(3) have β_E1_cα_E1_in_Tr1: "((β ↿ E⇘ESi⇙) @ (([c] @ α) ↿ E⇘ESi⇙)) ∈ Tr⇘ESi⇙"
    by (simp only: projection_concatenation_commute)
  moreover
  have "(?L ↿ V⇘𝒱i⇙) = (α ↿ V⇘𝒱i⇙)"
  proof -
    have "(?L ↿ V⇘𝒱i⇙) = ([c] @ α) ↿ V⇘𝒱i⇙"
    proof -
      from validVi have "E⇘ESi⇙ ∩ V⇘𝒱i⇙ = V⇘𝒱i⇙"
        by (simp add: isViewOn_def V_valid_def VN_disjoint_def VC_disjoint_def NC_disjoint_def 
          , auto)
      moreover
      have "(?L ↿ V⇘𝒱i⇙) = ([c] @ α) ↿ (E⇘ESi⇙ ∩ V⇘𝒱i⇙)"
        by (simp add: projection_def)
      ultimately show ?thesis
        by auto
    qed
    moreover
    have "([c] @ α) ↿ V⇘𝒱i⇙ = α ↿ V⇘𝒱i⇙"
    proof -
      have "([c] @ α) ↿ V⇘𝒱i⇙ = ([c] ↿ V⇘𝒱i⇙) @ (α ↿ V⇘𝒱i⇙)"
        by (rule projection_concatenation_commute)
      moreover
      have "([c] ↿ V⇘𝒱i⇙) = []"
      proof -
        from 0(2) have "[c] ↿ C⇘𝒱⇙ = [c]"
          by (simp add: projection_def)
        moreover
        have "[c] ↿ C⇘𝒱⇙ ↿ V⇘𝒱i⇙ = []"
        proof -
          from validVi Cv_inter_Ei_subsetof_Cvi have "C⇘𝒱⇙ ∩ V⇘𝒱i⇙ ⊆ C⇘𝒱i⇙"
            by (simp add: isViewOn_def  V_valid_def VC_disjoint_def, auto)
          moreover
          from 0(1) have "[c] ↿ C⇘𝒱i⇙ = []"
            by (simp only: projection_concatenation_commute, auto)
          ultimately have "[c] ↿ (C⇘𝒱⇙ ∩ V⇘𝒱i⇙) = []"
            by (rule projection_on_subset)
          thus ?thesis
            by (simp only: projection_def, auto)
        qed
        ultimately show ?thesis
          by auto
      qed
      ultimately show ?thesis
        by auto
    qed
    ultimately show ?thesis
      by auto
  qed
  moreover
  have "?L ↿ C⇘𝒱i⇙ = []"
  proof -
    from 0(1) have "([c] @ α) ↿ C⇘𝒱i⇙ = []"
      by auto
    hence "([c] @ α) ↿ (C⇘𝒱i⇙ ∩ E⇘ESi⇙) = []"
      by (rule projection_on_intersection)
    hence "([c] @ α) ↿ (E⇘ESi⇙ ∩ C⇘𝒱i⇙) = []"
      by (simp only: Int_commute)
    thus ?thesis
      by (simp only: projection_def, auto)                
  qed
  ultimately show ?case
    by auto
  
next
  case (Suc n)
  
  from projection_split_last[OF Suc(2)] obtain γ c_i δ
    where c_i_in_C𝒱i: "c_i ∈ C⇘𝒱i⇙"
    and   cα_is_γc_iδ: "[c] @ α = γ @ [c_i] @ δ"
    and   δ_no_C𝒱i:  "δ ↿ C⇘𝒱i⇙ = []"
    and   n_is_len_γδ_C𝒱i: "n = length ((γ @ δ) ↿ C⇘𝒱i⇙)"
    by auto
  
  let ?L1 = "((β @ γ) ↿ E⇘ESi⇙)"
  let ?L2 = "(δ ↿ E⇘ESi⇙)"

  note c_i_in_C𝒱i
  moreover
  have list_with_c_i_in_Tr1: "(?L1 @ [c_i] @ ?L2) ∈ Tr⇘ESi⇙"
  proof -
    from c_i_in_C𝒱i validVi have "[c_i] ↿ E⇘ESi⇙ = [c_i]"
      by (simp only: isViewOn_def V_valid_def VC_disjoint_def
        VN_disjoint_def NC_disjoint_def projection_def, auto)
    moreover
    from Suc(4) cα_is_γc_iδ have "((β @ γ @ [c_i] @ δ) ↿ E⇘ESi⇙) ∈ Tr⇘ESi⇙"
      by auto
    hence "(?L1 @ ([c_i] ↿ E⇘ESi⇙) @ ?L2) ∈ Tr⇘ESi⇙"
      by (simp only: projection_def, auto)
    ultimately show ?thesis
      by auto
  qed
  moreover 
  have "?L2 ↿ C⇘𝒱i⇙ = []"
  proof -
    from validVi have "⋀x. (x ∈ E⇘ESi⇙ ∧ x ∈ C⇘𝒱i⇙) = (x ∈ C⇘𝒱i⇙)"
      by (simp add: isViewOn_def V_valid_def VC_disjoint_def
        VN_disjoint_def NC_disjoint_def, auto)
    with δ_no_C𝒱i show ?thesis
      by (simp add: projection_def)
  qed            
  moreover note Suc(5)
  ultimately obtain δ'
    where δ'_1: "(?L1 @ δ') ∈ Tr⇘ESi⇙"
    and δ'_2: "δ' ↿ V⇘𝒱i⇙ = ?L2 ↿ V⇘𝒱i⇙"
    and δ'_3: "δ' ↿ C⇘𝒱i⇙ = []"
    unfolding BSD_def
    by blast
  hence δ'_2': "δ' ↿ V⇘𝒱i⇙ = δ ↿ V⇘𝒱i⇙"
  proof -
    have "?L2 ↿ V⇘𝒱i⇙ = δ ↿ V⇘𝒱i⇙"
    proof -
      from validVi have "⋀x. (x ∈ E⇘ESi⇙ ∧ x ∈ V⇘𝒱i⇙) = (x ∈ V⇘𝒱i⇙)"
        by (simp add: isViewOn_def V_valid_def VC_disjoint_def
        VN_disjoint_def NC_disjoint_def, auto)
      thus ?thesis
        by (simp add: projection_def)
    qed
    with δ'_2 show ?thesis
      by auto
  qed
  
  show ?case
  proof (cases γ) (* need to distinguish between these cases as the inductive 
      hypothesis can only be applied to one case. *)
    case Nil
    with cα_is_γc_iδ have "[c] @ α = [c_i] @ δ"
      by auto
    hence δ_is_α: "δ = α"
      by auto
    
    from δ'_1 have δ'_1': "((β ↿ E⇘ESi⇙) @ δ') ∈ Tr⇘ESi⇙"
      by (simp only: Nil, auto)
    moreover
    note δ'_2'
    moreover note δ'_3
    ultimately show ?thesis
      by (simp only: δ_is_α, auto)
  next
    case (Cons x γ')
    with cα_is_γc_iδ have γ_is_cγ': "γ = [c] @ γ'"
      by simp
    with n_is_len_γδ_C𝒱i have "n = length (([c] @ γ' @ δ) ↿ C⇘𝒱i⇙)"
      by auto
    with δ_no_C𝒱i δ'_3 have "n = length (([c] @ γ' @ δ') ↿ C⇘𝒱i⇙)"
      by (simp only: projection_concatenation_commute)
    moreover
    note Suc(3)
    moreover
    have "((β @ [c] @ (γ' @ δ')) ↿ E⇘ESi⇙) ∈ Tr⇘ESi⇙"
    proof -
      from δ'_1 validESi have "δ' = δ' ↿ E⇘ESi⇙"
      proof -
        let ?L = "(β @ γ) ↿ E⇘ESi⇙ @ δ'"
        
        from δ'_1 validESi have "∀e ∈ set ?L. e ∈ E⇘ESi⇙"
          by (simp add: ES_valid_def traces_contain_events_def)
        hence "set δ' ⊆ E⇘ESi⇙"
          by auto
        thus ?thesis
          by (simp add: list_subset_iff_projection_neutral)
      qed
      with δ'_1  have "?L1 @ δ' = (β @ γ @ δ') ↿ E⇘ESi⇙"
        by (simp only: projection_concatenation_commute, auto)
      with γ_is_cγ' δ'_1  show ?thesis
        by auto
    qed
    moreover
    note Suc(5)
    moreover note Suc(1)[of c "γ' @ δ'" β]
    ultimately obtain α_i'
      where α_i'_1: "β ↿ E⇘ESi⇙ @ α_i' ∈ Tr⇘ESi⇙"
      and α_i'_2: "α_i' ↿ V⇘𝒱i⇙ = (γ' @ δ') ↿ V⇘𝒱i⇙"
      and α_i'_3: "α_i' ↿ C⇘𝒱i⇙ = []"
      by auto
    moreover
    have "α_i' ↿ V⇘𝒱i⇙ = α ↿ V⇘𝒱i⇙"
    proof -
      have "α ↿ V⇘𝒱i⇙ = (γ' @ δ) ↿ V⇘𝒱i⇙"
      proof -
        from cα_is_γc_iδ γ_is_cγ' have "α ↿ V⇘𝒱i⇙ = (γ' @ [c_i] @ δ) ↿ V⇘𝒱i⇙"
          by simp
        with validVi c_i_in_C𝒱i show ?thesis
          by (simp only: isViewOn_def V_valid_def  VC_disjoint_def
            VN_disjoint_def NC_disjoint_def projection_concatenation_commute 
            projection_def, auto)
      qed
      moreover
      from α_i'_2 δ'_2' have "α_i' ↿ V⇘𝒱i⇙ = (γ' @ δ) ↿ V⇘𝒱i⇙"
        by (simp only: projection_concatenation_commute)
      ultimately show ?thesis
        by auto
    qed
    ultimately show ?thesis
      by auto
  qed
qed

(*
    Variant of the previous lemma with different propositions (note the lack of a confidential event c).
*)
lemma BSD_in_subsystem2:
"⟦ ((β @ α) ↿ E⇘ESi⇙) ∈ Tr⇘ESi⇙ ; BSD 𝒱i Tr⇘ESi⇙ ⟧ 
  ⟹ ∃ α_i'. ( ((β ↿ E⇘ESi⇙) @ α_i') ∈ Tr⇘ESi⇙ ∧ (α_i' ↿ V⇘𝒱i⇙) = (α ↿ V⇘𝒱i⇙) ∧ α_i' ↿ C⇘𝒱i⇙ = [] )"
proof (induct "length (α ↿ C⇘𝒱i⇙)" arbitrary: β α)
  case 0
  (* show that α ↿ EESi  is a suitable choice for α_i' *)
  let ?L = "α ↿ E⇘ESi⇙"
  
  from 0(2) have β_E1_α_E1_in_Tr1: "((β ↿ E⇘ESi⇙) @ ?L) ∈ Tr⇘ESi⇙"
    by (simp only: projection_concatenation_commute)
  moreover
  have "(?L ↿ V⇘𝒱i⇙) = (α ↿ V⇘𝒱i⇙)"
    proof -
      from validVi have "E⇘ESi⇙ ∩ V⇘𝒱i⇙ = V⇘𝒱i⇙"
        by (simp add: isViewOn_def V_valid_def  VC_disjoint_def
        VN_disjoint_def NC_disjoint_def, auto)
      moreover
      have "(?L ↿ V⇘𝒱i⇙) = α ↿ (E⇘ESi⇙ ∩ V⇘𝒱i⇙)"
        by (simp add: projection_def)
      ultimately show ?thesis
        by auto
    qed
  moreover
  have "?L ↿ C⇘𝒱i⇙ = []"
  proof -
    from 0(1) have "α ↿ C⇘𝒱i⇙ = []"
      by auto
    hence "α ↿ (C⇘𝒱i⇙ ∩ E⇘ESi⇙) = []"
      by (rule projection_on_intersection)
    hence "α ↿ (E⇘ESi⇙ ∩ C⇘𝒱i⇙) = []"
      by (simp only: Int_commute)
    thus ?thesis
      by (simp only: projection_def, auto)                
  qed
  ultimately show ?case
    by auto
  
next
  case (Suc n)
  
  from projection_split_last[OF Suc(2)] obtain γ c_i δ
    where c_i_in_C𝒱i: "c_i ∈ C⇘𝒱i⇙"
    and   α_is_γc_iδ: "α = γ @ [c_i] @ δ"
    and   δ_no_C𝒱i:  "δ ↿ C⇘𝒱i⇙ = []"
    and   n_is_len_γδ_C𝒱i: "n = length ((γ @ δ) ↿ C⇘𝒱i⇙)"
    by auto
  
  let ?L1 = "((β @ γ) ↿ E⇘ESi⇙)"
  let ?L2 = "(δ ↿ E⇘ESi⇙)"


  (* first apply BSD to get rid of c_i in α *)
  note c_i_in_C𝒱i
  moreover
  have list_with_c_i_in_Tr1: "(?L1 @ [c_i] @ ?L2) ∈ Tr⇘ESi⇙"
  proof -
    from c_i_in_C𝒱i validVi have "[c_i] ↿ E⇘ESi⇙ = [c_i]"
      by (simp only: isViewOn_def V_valid_def  VC_disjoint_def
        VN_disjoint_def NC_disjoint_def projection_def, auto)
    moreover
    from Suc(3) α_is_γc_iδ have "((β @ γ @ [c_i] @ δ) ↿ E⇘ESi⇙) ∈ Tr⇘ESi⇙"
      by auto
    hence "(?L1 @ ([c_i] ↿ E⇘ESi⇙) @ ?L2) ∈ Tr⇘ESi⇙"
      by (simp only: projection_def, auto)
    ultimately show ?thesis
      by auto
  qed
  moreover 
  have "?L2 ↿ C⇘𝒱i⇙ = []"
  proof -
    from validVi have "⋀x. (x ∈ E⇘ESi⇙ ∧ x ∈ C⇘𝒱i⇙) = (x ∈ C⇘𝒱i⇙)"
      by (simp add: isViewOn_def V_valid_def  VC_disjoint_def
        VN_disjoint_def NC_disjoint_def, auto)
    with δ_no_C𝒱i show ?thesis
      by (simp add: projection_def)
  qed            
  moreover note Suc(4)
  ultimately obtain δ'
    where δ'_1: "(?L1 @ δ') ∈ Tr⇘ESi⇙"
    and δ'_2: "δ' ↿ V⇘𝒱i⇙ = ?L2 ↿ V⇘𝒱i⇙"
    and δ'_3: "δ' ↿ C⇘𝒱i⇙ = []"
    unfolding BSD_def
    by blast
  hence δ'_2': "δ' ↿ V⇘𝒱i⇙ = δ ↿ V⇘𝒱i⇙"
  proof -
    have "?L2 ↿ V⇘𝒱i⇙ = δ ↿ V⇘𝒱i⇙"
    proof -
      from validVi have "⋀x. (x ∈ E⇘ESi⇙ ∧ x ∈ V⇘𝒱i⇙) = (x ∈ V⇘𝒱i⇙)"
        by (simp add: isViewOn_def V_valid_def  VC_disjoint_def
        VN_disjoint_def NC_disjoint_def, auto)
      thus ?thesis
        by (simp add: projection_def)
    qed
    with δ'_2 show ?thesis
      by auto
  qed

  (* now that we eliminated c_i, we can apply the inductive hypothesis for ?β = β and ?α = γ @ δ' *)
  from n_is_len_γδ_C𝒱i δ_no_C𝒱i δ'_3 have "n = length ((γ @ δ') ↿ C⇘𝒱i⇙)"
    by (simp add: projection_concatenation_commute)
  moreover
  have "(β @ (γ @ δ')) ↿ E⇘ESi⇙ ∈ Tr⇘ESi⇙"
    proof -
      have "δ' = δ' ↿ E⇘ESi⇙"
        proof -
          let ?L = "(β @ γ) ↿ E⇘ESi⇙ @ δ'"
        
          from δ'_1 validESi have "∀e ∈ set ?L. e ∈ E⇘ESi⇙"
            by (simp add: ES_valid_def traces_contain_events_def)
          hence "set δ' ⊆ E⇘ESi⇙"
            by auto
          thus ?thesis
            by (simp add: list_subset_iff_projection_neutral)
        qed
      with δ'_1  have "?L1 @ δ' = (β @ γ @ δ') ↿ E⇘ESi⇙"
        by (simp only: projection_concatenation_commute, auto)
      with δ'_1  show ?thesis
        by auto
    qed
  moreover
  note Suc(4) Suc(1)[of "γ @ δ'" β] 
  ultimately obtain α_i' 
    where res1: "β ↿ E⇘ESi⇙ @ α_i' ∈ Tr⇘ESi⇙" 
    and res2: "α_i' ↿ V⇘𝒱i⇙ = (γ @ δ') ↿ V⇘𝒱i⇙"
    and res3: "α_i' ↿ C⇘𝒱i⇙ = []"
    by auto

  (* Show that the resulting α_i' is suitable *)
  have "α_i' ↿ V⇘𝒱i⇙ = α ↿ V⇘𝒱i⇙"
    proof -
      from c_i_in_C𝒱i validVi have "[c_i] ↿ V⇘𝒱i⇙ = []"
        by (simp add: isViewOn_def V_valid_def  VC_disjoint_def
        VN_disjoint_def NC_disjoint_def projection_def, auto)
      with α_is_γc_iδ δ'_2' have "α ↿ V⇘𝒱i⇙ = (γ @ δ') ↿ V⇘𝒱i⇙"
        by (simp only: projection_concatenation_commute, auto)
      with res2 show ?thesis
        by auto
    qed
  with res1 res3 show ?case
    by auto
qed

end

end