Theory UnwindingResults

theory UnwindingResults
imports AuxiliaryLemmas
begin

context Unwinding
begin
theorem unwinding_theorem_BSD:
"⟦ lrf ur; osc ur ⟧ ⟹ BSD 𝒱 Trβ‡˜(induceES SES)⇙"
proof -
  assume lrf_true: "lrf ur"
  assume osc_true: "osc ur"

  { (* show that the conclusion of the BSP follows from the assumptions *)
    fix Ξ± Ξ² c
    assume c_in_C: "c ∈ Cβ‡˜π’±β‡™"
    assume Ξ²cΞ±_in_Tr: "((Ξ² @ [c]) @ Ξ±) ∈ Trβ‡˜(induceES SES)⇙"
    assume Ξ±_contains_no_c: "Ξ± β†Ώ Cβ‡˜π’±β‡™ = []"
 
    from state_from_induceES_trace[OF Ξ²cΞ±_in_Tr] obtain s1'
      where s1'_in_S: "s1' ∈ Sβ‡˜SES⇙" 
      and enabled_s1'_Ξ±: "enabled SES s1' Ξ±" 
      and s0_Ξ²c_s1': "s0β‡˜SES⇙ (Ξ² @ [c])βŸΉβ‡˜SES⇙ s1'"
      and reachable_s1': "reachable SES s1'"
      by auto
    
    from path_split_single2[OF s0_Ξ²c_s1'] obtain s1
      where s1_in_S: "s1 ∈ Sβ‡˜SES⇙" 
      and s0_Ξ²_s1: "s0β‡˜SES⇙ Ξ²βŸΉβ‡˜SES⇙ s1" 
      and s1_c_s1': "s1 cβŸΆβ‡˜SES⇙ s1'"
      and reachable_s1: "reachable SES s1"
      by auto

    from s1_in_S s1'_in_S c_in_C reachable_s1 s1_c_s1' lrf_true 
    have s1'_ur_s1: "((s1', s1) ∈ ur)"
      by (simp add: lrf_def, auto)

    from osc_property[OF osc_true s1_in_S s1'_in_S Ξ±_contains_no_c reachable_s1
      reachable_s1' enabled_s1'_Ξ± s1'_ur_s1]
    obtain Ξ±' 
      where Ξ±'_contains_no_c: "Ξ±' β†Ώ Cβ‡˜π’±β‡™ = []"
      and Ξ±'_V_is_Ξ±_V: "Ξ±' β†Ώ Vβ‡˜π’±β‡™ = Ξ± β†Ώ Vβ‡˜π’±β‡™"
      and enabled_s1_Ξ±': "enabled SES s1 Ξ±'" 
      by auto
  
    have Ξ²Ξ±'_in_Tr: "Ξ² @ Ξ±' ∈ Trβ‡˜(induceES SES)⇙"
    proof -
      note s0_Ξ²_s1
      moreover
      from enabled_s1_Ξ±' obtain s2
        where "s1 Ξ±'βŸΉβ‡˜SES⇙ s2"
        by (simp add: enabled_def, auto)
      ultimately have "s0β‡˜SES⇙ (Ξ² @ Ξ±') βŸΉβ‡˜SES⇙ s2"
        by (rule path_trans)
      thus ?thesis
        by (simp add: induceES_def possible_traces_def enabled_def)
    qed
    
    from Ξ²Ξ±'_in_Tr Ξ±'_V_is_Ξ±_V Ξ±'_contains_no_c have 
      "βˆƒΞ±'. ((Ξ² @ Ξ±') ∈ (Trβ‡˜(induceES SES)⇙) ∧ (Ξ±' β†Ώ (Vβ‡˜π’±β‡™)) = (Ξ± β†Ώ Vβ‡˜π’±β‡™) ∧ Ξ±' β†Ώ Cβ‡˜π’±β‡™ = [])"
      by auto
  }
  thus ?thesis 
    by (simp add: BSD_def) 
qed

theorem unwinding_theorem_BSI:
"⟦ lrb ur; osc ur ⟧ ⟹ BSI 𝒱 Trβ‡˜(induceES SES)⇙"
proof -
  assume lrb_true: "lrb ur"
  assume osc_true: "osc ur"
  
  {   (* show that the conclusion of the BSP follows from the assumptions *)
    fix Ξ± Ξ² c
    assume c_in_C: "c ∈ Cβ‡˜π’±β‡™"
    assume Ξ²Ξ±_in_ind_Tr: "(Ξ² @ Ξ±) ∈ Trβ‡˜(induceES SES)⇙"
    assume Ξ±_contains_no_c: "Ξ± β†Ώ Cβ‡˜π’±β‡™ = []"
    
    from state_from_induceES_trace[OF Ξ²Ξ±_in_ind_Tr] obtain s1
      where s1_in_S : "s1 ∈ Sβ‡˜SES⇙"
      and path_Ξ²_yields_s1:  "s0β‡˜SES⇙ Ξ²βŸΉβ‡˜SES⇙ s1" 
      and enabled_s1_Ξ±: "enabled SES s1 Ξ±"
      and reachable_s1: "reachable SES s1"
      by auto

    from reachable_s1 s1_in_S c_in_C  lrb_true 
    have "βˆƒs1'∈ Sβ‡˜SES⇙. s1 cβŸΆβ‡˜SES⇙ s1' ∧ (s1, s1') ∈ ur"
      by(simp add: lrb_def) 
    then obtain s1' 
      where s1'_in_S: "s1' ∈ Sβ‡˜SES⇙"
      and s1_trans_c_s1': "s1 cβŸΆβ‡˜SES⇙ s1'"
      and s1_s1'_in_ur: "(s1, s1') ∈ ur" 
      by auto

    have reachable_s1': "reachable SES s1'" 
    proof -
      from path_Ξ²_yields_s1 s1_trans_c_s1' have "s0β‡˜SES⇙ (Ξ² @ [c])βŸΉβ‡˜SES⇙ s1'"
        by (rule path_trans_single)
      thus ?thesis by (simp add: reachable_def, auto)
    qed
    
    from osc_property[OF osc_true s1'_in_S s1_in_S Ξ±_contains_no_c 
      reachable_s1' reachable_s1 enabled_s1_Ξ± s1_s1'_in_ur]
    obtain Ξ±' 
      where Ξ±'_contains_no_c: "Ξ±' β†Ώ Cβ‡˜π’±β‡™ = []"
      and Ξ±'_V_is_Ξ±_V: "Ξ±' β†Ώ Vβ‡˜π’±β‡™ = Ξ± β†Ώ Vβ‡˜π’±β‡™"
      and enabled_s1'_Ξ±': "enabled SES s1' Ξ±'" 
      by auto

    have Ξ²cΞ±'_in_ind_Tr: "Ξ² @ [c] @ Ξ±' ∈ Trβ‡˜(induceES SES)⇙"
    proof -
      from path_Ξ²_yields_s1 s1_trans_c_s1' have "s0β‡˜SES⇙ (Ξ² @ [c])βŸΉβ‡˜SES⇙ s1'"
        by (rule path_trans_single)
      moreover
      from enabled_s1'_Ξ±' obtain s2
        where "s1' Ξ±'βŸΉβ‡˜SES⇙ s2"
        by (simp add: enabled_def, auto)
      ultimately have "s0β‡˜SES⇙ ((Ξ² @ [c]) @ Ξ±')βŸΉβ‡˜SES⇙ s2"
        by (rule path_trans)
      thus ?thesis
        by (simp add: induceES_def possible_traces_def enabled_def)
    qed
    
    from Ξ²cΞ±'_in_ind_Tr Ξ±'_V_is_Ξ±_V Ξ±'_contains_no_c 
    have "βˆƒΞ±'. Ξ² @ c # Ξ±' ∈ Trβ‡˜(induceES SES)⇙ ∧ Ξ±' β†Ώ Vβ‡˜π’±β‡™ = Ξ± β†Ώ Vβ‡˜π’±β‡™ ∧ Ξ±' β†Ώ Cβ‡˜π’±β‡™ = []"
      by auto
  }
  thus ?thesis
    by(simp add: BSI_def)
qed

(* unwinding theorem for BSP BSIA *)
theorem unwinding_theorem_BSIA:
"⟦ lrbe ρ ur; osc ur ⟧ ⟹ BSIA ρ 𝒱 Trβ‡˜(induceES SES)⇙"
proof -
  assume lrbe_true: "lrbe ρ ur"
  assume osc_true: "osc ur"
  
  { (* show that the conclusion of the BSP follows from the assumptions *)
    fix Ξ± Ξ² c
    assume c_in_C: "c ∈ Cβ‡˜π’±β‡™"
    assume Ξ²Ξ±_in_ind_Tr: "(Ξ² @ Ξ±) ∈ Trβ‡˜(induceES SES)⇙"
    assume Ξ±_contains_no_c: "Ξ± β†Ώ Cβ‡˜π’±β‡™ = []"
    
    assume adm: "Adm 𝒱 ρ Trβ‡˜(induceES SES)⇙ Ξ² c"
    
    from state_from_induceES_trace[OF Ξ²Ξ±_in_ind_Tr] 
    obtain s1 
      where s1_in_S : "s1 ∈ Sβ‡˜SES⇙"
      and s0_Ξ²_s1:  "s0β‡˜SES⇙ Ξ²βŸΉβ‡˜SES⇙ s1" 
      and enabled_s1_Ξ±: "enabled SES s1 Ξ±"  
      and reachable_s1: "reachable SES s1"
      by auto

        (* case distinction whether En is true or not *)
    have "βˆƒΞ±'. Ξ² @ [c] @ Ξ±' ∈ Trβ‡˜(induceES SES)⇙ ∧ Ξ±' β†Ώ Vβ‡˜π’±β‡™ = Ξ± β†Ώ Vβ‡˜π’±β‡™ ∧ Ξ±' β†Ώ Cβ‡˜π’±β‡™ = []"
    proof cases
      assume en: "En ρ s1 c" (*first case, en is true *)

      from reachable_s1 s1_in_S c_in_C en lrbe_true 
      have "βˆƒs1'∈ Sβ‡˜SES⇙. s1 cβŸΆβ‡˜SES⇙ s1' ∧ (s1, s1') ∈ ur"
        by(simp add: lrbe_def) 
      then obtain s1' 
        where s1'_in_S: "s1' ∈ Sβ‡˜SES⇙"
        and s1_trans_c_s1': "s1 cβŸΆβ‡˜SES⇙ s1'"
        and s1_s1'_in_ur: "(s1, s1') ∈ ur" 
        by auto

      have reachable_s1': "reachable SES s1'" 
      proof -
        from s0_Ξ²_s1 s1_trans_c_s1' have "s0β‡˜SES⇙ (Ξ² @ [c])βŸΉβ‡˜SES⇙ s1'"
          by (rule path_trans_single)
        thus ?thesis by (simp add: reachable_def, auto)
      qed 

      from osc_property[OF osc_true s1'_in_S s1_in_S Ξ±_contains_no_c 
        reachable_s1' reachable_s1 enabled_s1_Ξ± s1_s1'_in_ur] 
      obtain Ξ±' 
        where Ξ±'_contains_no_c: "Ξ±' β†Ώ Cβ‡˜π’±β‡™ = []"
        and Ξ±'_V_is_Ξ±_V: "Ξ±' β†Ώ Vβ‡˜π’±β‡™ = Ξ± β†Ώ Vβ‡˜π’±β‡™"
        and enabled_s1'_Ξ±': "enabled SES s1' Ξ±'" 
        by auto
      
      have Ξ²cΞ±'_in_ind_Tr: "Ξ² @ [c] @ Ξ±' ∈ Trβ‡˜(induceES SES)⇙"
      proof -
        from s0_Ξ²_s1 s1_trans_c_s1' have "s0β‡˜SES⇙ (Ξ² @ [c])βŸΉβ‡˜SES⇙ s1'"
          by (rule path_trans_single)
        moreover
        from enabled_s1'_Ξ±' obtain s2
          where "s1' Ξ±'βŸΉβ‡˜SES⇙ s2"
          by (simp add: enabled_def, auto)
        ultimately have "s0β‡˜SES⇙ ((Ξ² @ [c]) @ Ξ±')βŸΉβ‡˜SES⇙ s2"
          by (rule path_trans)
        thus ?thesis
          by (simp add: induceES_def possible_traces_def enabled_def)
      qed
      
      from Ξ²cΞ±'_in_ind_Tr Ξ±'_V_is_Ξ±_V Ξ±'_contains_no_c show ?thesis
        by auto
    next (* second case, en is false *)
      assume not_en: "¬ En ρ s1 c"
      
      let ?A = "(Adm 𝒱 ρ (Trβ‡˜(induceES SES)⇙) Ξ² c)"
      let ?E = "βˆƒs ∈ Sβ‡˜SES⇙. (s0β‡˜SES⇙ Ξ²βŸΉβ‡˜SES⇙ s ∧ En ρ s c)"

      { (* show the contraposition of Adm_to_En *)
        assume adm: "?A" 
        
        from s0_Ξ²_s1 have Ξ²_in_Tr: "Ξ² ∈ Trβ‡˜(induceES SES)⇙"
          by (simp add: induceES_def possible_traces_def enabled_def)
        
        from  Ξ²_in_Tr adm have "?E"
          by (rule Adm_to_En)
      }
      hence Adm_to_En_contr: "¬ ?E ⟹ ¬ ?A"
        by blast
      with s1_in_S s0_Ξ²_s1 not_en have not_adm: "Β¬ ?A"
        by auto
      with adm show ?thesis
        by auto
    qed
  }
  thus ?thesis 
    by (simp add: BSIA_def)
qed

theorem unwinding_theorem_FCD:
"⟦ fcrf Ξ“ ur; osc ur ⟧ ⟹ FCD Ξ“ 𝒱 Trβ‡˜(induceES SES)⇙"
proof - 
  assume fcrf: "fcrf Ξ“ ur"
  assume osc: "osc ur"

  { (* show that the conclusion of the BSP follows from the assumptions *)
    fix Ξ± Ξ² c v

    assume c_in_C_inter_Y: "c ∈ (Cβ‡˜π’±β‡™ ∩ Ξ₯β‡˜Ξ“β‡™)"
    assume v_in_V_inter_Nabla: "v ∈ (Vβ‡˜π’±β‡™ ∩ βˆ‡β‡˜Ξ“β‡™)"
    assume Ξ²cvΞ±_in_Tr: "((Ξ² @ [c] @ [v]) @ Ξ±) ∈ Trβ‡˜(induceES SES)⇙"
    assume Ξ±_contains_no_c: "Ξ± β†Ώ Cβ‡˜π’±β‡™ = []"

    from state_from_induceES_trace[OF Ξ²cvΞ±_in_Tr] obtain s1'
      where s1'_in_S: "s1' ∈ Sβ‡˜SES⇙"
      and s0_Ξ²cv_s1': "s0β‡˜SES⇙ (Ξ² @ ([c] @ [v]))βŸΉβ‡˜SES⇙ s1'"
      and enabled_s1'_Ξ±: "enabled SES s1' Ξ±"
      and reachable_s1': "reachable SES s1'"
      by auto
    
    from path_split2[OF s0_Ξ²cv_s1'] obtain s1 
      where s1_in_S: "s1 ∈ Sβ‡˜SES⇙"
      and s0_Ξ²_s1: "s0β‡˜SES⇙ Ξ²βŸΉβ‡˜SES⇙ s1"
      and s1_cv_s1': "s1 ([c] @ [v])βŸΉβ‡˜SES⇙ s1'"
      and reachable_s1: "reachable SES s1"
      by (auto)

    from c_in_C_inter_Y v_in_V_inter_Nabla s1_in_S s1'_in_S reachable_s1 s1_cv_s1' fcrf
    have "βˆƒs1'' ∈ Sβ‡˜SES⇙. βˆƒΞ΄. (βˆ€d ∈ (set Ξ΄). d ∈ (Nβ‡˜π’±β‡™ ∩ Ξ”β‡˜Ξ“β‡™)) ∧
      s1 (Ξ΄ @ [v])βŸΉβ‡˜SES⇙ s1'' ∧ (s1', s1'') ∈ ur"
      by (simp add: fcrf_def)
    then obtain s1'' Ξ΄
      where s1''_in_S: "s1'' ∈ Sβ‡˜SES⇙"
      and Ξ΄_in_N_inter_Delta_star: "(βˆ€d ∈ (set Ξ΄). d ∈ (Nβ‡˜π’±β‡™ ∩ Ξ”β‡˜Ξ“β‡™))"
      and s1_Ξ΄v_s1'': "s1 (Ξ΄ @ [v])βŸΉβ‡˜SES⇙ s1''"
      and s1'_ur_s1'': "(s1', s1'') ∈ ur" 
      by auto
      
    have reachable_s1'': "reachable SES s1''"
    proof -
      from s0_Ξ²_s1 s1_Ξ΄v_s1'' have "s0β‡˜SES⇙ (Ξ² @ (Ξ΄ @ [v]))βŸΉβ‡˜SES⇙ s1''"
        by (rule path_trans)
      thus ?thesis
        by (simp add: reachable_def, auto)
    qed

    from osc_property[OF  osc s1''_in_S s1'_in_S Ξ±_contains_no_c 
      reachable_s1'' reachable_s1' enabled_s1'_Ξ± s1'_ur_s1'']
    obtain Ξ±' 
      where  Ξ±'_contains_no_c: "Ξ±' β†Ώ Cβ‡˜π’±β‡™ = []"
      and Ξ±'_V_is_Ξ±_V: "Ξ±' β†Ώ Vβ‡˜π’±β‡™ = Ξ± β†Ώ Vβ‡˜π’±β‡™"
      and enabled_s1''_Ξ±': "enabled SES s1'' Ξ±'" 
      by auto

    have Ξ²Ξ΄vΞ±'_in_Tr: "Ξ² @ Ξ΄ @ [v] @ Ξ±' ∈ Trβ‡˜(induceES SES)⇙"
      proof -
        from s0_Ξ²_s1 s1_Ξ΄v_s1'' have "s0β‡˜SES⇙ (Ξ² @ Ξ΄ @ [v])βŸΉβ‡˜SES⇙ s1''"
          by (rule path_trans)
        moreover
        from enabled_s1''_Ξ±' obtain s2
          where "s1'' Ξ±'βŸΉβ‡˜SES⇙ s2"
          by (simp add: enabled_def, auto)
        ultimately have "s0β‡˜SES⇙ ((Ξ² @ Ξ΄ @ [v]) @ Ξ±')βŸΉβ‡˜SES⇙ s2"
          by (rule path_trans)
        thus ?thesis
          by (simp add: induceES_def possible_traces_def enabled_def)
      qed

      from Ξ΄_in_N_inter_Delta_star Ξ²Ξ΄vΞ±'_in_Tr Ξ±'_V_is_Ξ±_V Ξ±'_contains_no_c
      have "βˆƒΞ±'. βˆƒΞ΄'. set Ξ΄' βŠ† (Nβ‡˜π’±β‡™ ∩ Ξ”β‡˜Ξ“β‡™) ∧ Ξ² @ Ξ΄' @ [v] @ Ξ±' ∈ Trβ‡˜(induceES SES)⇙ 
        ∧ Ξ±' β†Ώ Vβ‡˜π’±β‡™ = Ξ± β†Ώ Vβ‡˜π’±β‡™ ∧ Ξ±' β†Ώ Cβ‡˜π’±β‡™ = []"
        by auto
  }
  thus ?thesis
    by (simp add: FCD_def)
qed

theorem unwinding_theorem_FCI:
"⟦ fcrb Ξ“ ur; osc ur ⟧ ⟹ FCI Ξ“ 𝒱 Trβ‡˜(induceES SES)⇙"
proof -
  assume fcrb: "fcrb Ξ“ ur"
  assume osc: "osc ur"

  { (* show that the conclusion of the BSP follows from the assumptions *)
    fix Ξ± Ξ² c v

    assume c_in_C_inter_Y: "c ∈ (Cβ‡˜π’±β‡™ ∩ Ξ₯β‡˜Ξ“β‡™)"
    assume v_in_V_inter_Nabla: "v ∈ (Vβ‡˜π’±β‡™ ∩ βˆ‡β‡˜Ξ“β‡™)"
    assume Ξ²vΞ±_in_Tr: "((Ξ² @ [v]) @ Ξ±) ∈ Trβ‡˜(induceES SES)⇙"
    assume Ξ±_contains_no_c: "Ξ± β†Ώ Cβ‡˜π’±β‡™ = []"
  
    from state_from_induceES_trace[OF Ξ²vΞ±_in_Tr] obtain s1''
      where s1''_in_S: "s1'' ∈ Sβ‡˜SES⇙"
      and s0_Ξ²v_s1'': "s0β‡˜SES⇙ (Ξ² @ [v]) βŸΉβ‡˜SES⇙ s1''"
      and enabled_s1''_Ξ±: "enabled SES s1'' Ξ±"
      and reachable_s1'': "reachable SES s1''"
      by auto

    from path_split_single2[OF s0_Ξ²v_s1''] obtain s1 
      where s1_in_S: "s1 ∈ Sβ‡˜SES⇙"
      and s0_Ξ²_s1: "s0β‡˜SES⇙ Ξ²βŸΉβ‡˜SES⇙ s1"
      and s1_v_s1'': "s1 vβŸΆβ‡˜SES⇙ s1''"
      and reachable_s1: "reachable SES s1"
      by (auto)

    from c_in_C_inter_Y v_in_V_inter_Nabla s1_in_S 
      s1''_in_S reachable_s1 s1_v_s1'' fcrb 
    have "βˆƒs1' ∈ Sβ‡˜SES⇙. βˆƒΞ΄. (βˆ€d ∈ (set Ξ΄). d ∈ (Nβ‡˜π’±β‡™ ∩ Ξ”β‡˜Ξ“β‡™))
      ∧ s1 ([c] @ Ξ΄ @ [v])βŸΉβ‡˜SES⇙ s1'
      ∧ (s1'', s1') ∈ ur"
      by (simp add: fcrb_def)
    then obtain s1' Ξ΄
      where s1'_in_S: "s1' ∈ Sβ‡˜SES⇙"
      and Ξ΄_in_N_inter_Delta_star: "(βˆ€d ∈ (set Ξ΄). d ∈ (Nβ‡˜π’±β‡™ ∩ Ξ”β‡˜Ξ“β‡™))"
      and s1_cΞ΄v_s1': "s1 ([c] @ Ξ΄ @ [v])βŸΉβ‡˜SES⇙ s1'"
      and s1''_ur_s1': "(s1'', s1') ∈ ur" 
      by auto

    have reachable_s1': "reachable SES s1'"
    proof -
      from s0_Ξ²_s1 s1_cΞ΄v_s1' have "s0β‡˜SES⇙ (Ξ² @ ([c] @ Ξ΄ @ [v]))βŸΉβ‡˜SES⇙ s1'"
        by (rule path_trans)
      thus ?thesis
        by (simp add: reachable_def, auto)
    qed
    
    from osc_property[OF osc s1'_in_S s1''_in_S Ξ±_contains_no_c 
      reachable_s1' reachable_s1'' enabled_s1''_Ξ± s1''_ur_s1']
    obtain Ξ±' 
      where  Ξ±'_contains_no_c: "Ξ±' β†Ώ Cβ‡˜π’±β‡™ = []"
      and Ξ±'_V_is_Ξ±_V: "Ξ±' β†Ώ Vβ‡˜π’±β‡™ = Ξ± β†Ώ Vβ‡˜π’±β‡™"
      and enabled_s1'_Ξ±': "enabled SES s1' Ξ±'" 
      by auto

    have Ξ²cΞ΄vΞ±'_in_Tr: "Ξ² @ [c] @ Ξ΄ @ [v] @ Ξ±' ∈ Trβ‡˜(induceES SES)⇙"
    proof -
      let ?l1 = "Ξ² @ [c] @ Ξ΄ @ [v]"
      let ?l2 = "Ξ±'"
      from s0_Ξ²_s1 s1_cΞ΄v_s1' have "s0β‡˜SES⇙ (?l1)βŸΉβ‡˜SES⇙ s1'"
        by (rule path_trans)
      moreover
      from enabled_s1'_Ξ±' obtain s1337 where "s1' ?l2 βŸΉβ‡˜SES⇙ s1337"
        by (simp add: enabled_def, auto)
      ultimately have "s0β‡˜SES⇙ (?l1 @ ?l2)βŸΉβ‡˜SES⇙ s1337"
        by (rule path_trans)
      thus ?thesis
        by (simp add: induceES_def possible_traces_def enabled_def) 
    qed

from Ξ΄_in_N_inter_Delta_star Ξ²cΞ΄vΞ±'_in_Tr Ξ±'_V_is_Ξ±_V Ξ±'_contains_no_c
    have "βˆƒΞ±' Ξ΄'.
      set Ξ΄' βŠ† (Nβ‡˜π’±β‡™ ∩ Ξ”β‡˜Ξ“β‡™) ∧ Ξ² @ [c] @ Ξ΄' @ [v] @ Ξ±' ∈ Trβ‡˜(induceES SES)⇙ 
      ∧ Ξ±' β†Ώ Vβ‡˜π’±β‡™ = Ξ± β†Ώ Vβ‡˜π’±β‡™ ∧ Ξ±' β†Ώ Cβ‡˜π’±β‡™ = []"
      by auto
  }
  thus ?thesis
    by(simp add: FCI_def)     
qed

theorem unwinding_theorem_FCIA:
"⟦ fcrbe Ξ“ ρ ur; osc ur ⟧ ⟹ FCIA ρ Ξ“ 𝒱 Trβ‡˜(induceES SES)⇙"
proof -
  assume fcrbe: "fcrbe Ξ“ ρ ur"
  assume osc: "osc ur"

  { (* show that the conclusion of the BSP follows from the assumptions *)
    fix Ξ± Ξ² c v

    assume c_in_C_inter_Y: "c ∈ (Cβ‡˜π’±β‡™ ∩ Ξ₯β‡˜Ξ“β‡™)"
    assume v_in_V_inter_Nabla: "v ∈ (Vβ‡˜π’±β‡™ ∩ βˆ‡β‡˜Ξ“β‡™)"
    assume Ξ²vΞ±_in_Tr: "((Ξ² @ [v]) @ Ξ±) ∈ Trβ‡˜(induceES SES)⇙"
    assume Ξ±_contains_no_c: "Ξ± β†Ώ Cβ‡˜π’±β‡™ = []"
    assume adm: "Adm 𝒱 ρ Trβ‡˜(induceES SES)⇙ Ξ² c"

    from state_from_induceES_trace[OF Ξ²vΞ±_in_Tr] obtain s1''
      where s1''_in_S: "s1'' ∈ Sβ‡˜SES⇙"
      and s0_Ξ²v_s1'': "s0β‡˜SES⇙ (Ξ² @ [v])βŸΉβ‡˜SES⇙ s1''"
      and enabled_s1''_Ξ±: "enabled SES s1'' Ξ±"
      and reachable_s1'': "reachable SES s1''"
      by auto

    from path_split_single2[OF s0_Ξ²v_s1''] obtain s1 
      where s1_in_S: "s1 ∈ Sβ‡˜SES⇙"
      and s0_Ξ²_s1: "s0β‡˜SES⇙ Ξ²βŸΉβ‡˜SES⇙ s1"
      and s1_v_s1'': "s1 vβŸΆβ‡˜SES⇙ s1''"
      and reachable_s1: "reachable SES s1"
      by (auto)
    
    have "βˆƒΞ±' Ξ΄'.(set Ξ΄' βŠ† (Nβ‡˜π’±β‡™ ∩ Ξ”β‡˜Ξ“β‡™) ∧ Ξ² @ [c] @ Ξ΄' @ [v] @ Ξ±' ∈ Trβ‡˜(induceES SES)⇙ 
      ∧ Ξ±' β†Ώ Vβ‡˜π’±β‡™ = Ξ± β†Ώ Vβ‡˜π’±β‡™ ∧ Ξ±' β†Ώ Cβ‡˜π’±β‡™ = [])"
    proof (cases)
      assume en: "En ρ s1 c"

      from c_in_C_inter_Y v_in_V_inter_Nabla s1_in_S s1''_in_S reachable_s1 s1_v_s1'' en fcrbe
      have "βˆƒs1' ∈ Sβ‡˜SES⇙. βˆƒΞ΄. (βˆ€d ∈ (set Ξ΄). d ∈ (Nβ‡˜π’±β‡™ ∩ Ξ”β‡˜Ξ“β‡™))
        ∧ s1 ([c] @ Ξ΄ @ [v]) βŸΉβ‡˜SES⇙ s1'
        ∧ (s1'', s1') ∈ ur"
        by (simp add: fcrbe_def)
      then  obtain s1' Ξ΄
        where s1'_in_S: "s1' ∈ Sβ‡˜SES⇙"
        and Ξ΄_in_N_inter_Delta_star: "(βˆ€d ∈ (set Ξ΄). d ∈ (Nβ‡˜π’±β‡™ ∩ Ξ”β‡˜Ξ“β‡™))"
        and s1_cΞ΄v_s1': "s1 ([c] @ Ξ΄ @ [v]) βŸΉβ‡˜SES⇙ s1'"
        and s1''_ur_s1': "(s1'', s1') ∈ ur"
        by (auto)

      have reachable_s1': "reachable SES s1'"
      proof -
        from s0_Ξ²_s1 s1_cΞ΄v_s1' have "s0β‡˜SES⇙ (Ξ² @ ([c] @ Ξ΄ @ [v]))βŸΉβ‡˜SES⇙ s1'"
          by (rule path_trans)
        thus ?thesis
          by (simp add: reachable_def, auto)
      qed
      
      from osc_property[OF osc s1'_in_S s1''_in_S Ξ±_contains_no_c reachable_s1' 
        reachable_s1'' enabled_s1''_Ξ± s1''_ur_s1']
      obtain Ξ±' 
        where  Ξ±'_contains_no_c: "Ξ±' β†Ώ Cβ‡˜π’±β‡™ = []"
        and Ξ±'_V_is_Ξ±_V: "Ξ±' β†Ώ Vβ‡˜π’±β‡™ = Ξ± β†Ώ Vβ‡˜π’±β‡™"
        and enabled_s1'_Ξ±': "enabled SES s1' Ξ±'" 
        by auto

      have Ξ²cΞ΄vΞ±'_in_Tr: "Ξ² @ [c] @ Ξ΄ @ [v] @ Ξ±' ∈ Trβ‡˜(induceES SES)⇙"
      proof -
        let ?l1 = "Ξ² @ [c] @ Ξ΄ @ [v]"
        let ?l2 = "Ξ±'"
        from s0_Ξ²_s1 s1_cΞ΄v_s1' have "s0β‡˜SES⇙ (?l1)βŸΉβ‡˜SES⇙ s1'"
          by (rule path_trans)
        moreover
        from enabled_s1'_Ξ±' obtain s1337 where "s1' ?l2βŸΉβ‡˜SES⇙ s1337"
          by (simp add: enabled_def, auto)
        ultimately have "s0β‡˜SES⇙ (?l1 @ ?l2)βŸΉβ‡˜SES⇙ s1337"
          by (rule path_trans)
        thus ?thesis
          by (simp add: induceES_def possible_traces_def enabled_def) 
      qed

      from Ξ΄_in_N_inter_Delta_star Ξ²cΞ΄vΞ±'_in_Tr Ξ±'_V_is_Ξ±_V Ξ±'_contains_no_c
      show ?thesis
        by auto
    next
      assume not_en: "¬ En ρ s1 c"
      
      let ?A = "(Adm 𝒱 ρ Trβ‡˜(induceES SES)⇙ Ξ² c)"
      let ?E = "βˆƒs ∈ Sβ‡˜SES⇙. (s0β‡˜SES⇙ Ξ²βŸΉβ‡˜SES⇙ s ∧ En ρ s c)"

      { (* show the contraposition of Adm_to_En *)
        assume adm: "?A" 
        
        from s0_Ξ²_s1 have Ξ²_in_Tr: "Ξ² ∈ Trβ‡˜(induceES SES)⇙"
          by (simp add: induceES_def possible_traces_def enabled_def)
        
        from  Ξ²_in_Tr adm have "?E"
          by (rule Adm_to_En)
      }
      hence Adm_to_En_contr: "¬ ?E ⟹ ¬ ?A"
        by blast
      with s1_in_S s0_Ξ²_s1 not_en have not_adm: "Β¬ ?A"
        by auto
      with adm show ?thesis
        by auto
    qed  
  }
  thus ?thesis
    by (simp add: FCIA_def)
qed

theorem unwinding_theorem_SD:
"⟦ 𝒱' = ⦇ V = (Vβ‡˜π’±β‡™ βˆͺ Nβ‡˜π’±β‡™), N = {}, C = Cβ‡˜π’±β‡™ ⦈; 
  Unwinding.lrf SES 𝒱' ur; Unwinding.osc SES 𝒱' ur ⟧ 
  ⟹ SD 𝒱 Trβ‡˜(induceES SES)⇙"
proof -
  assume view'_def : "𝒱' = ⦇V = (Vβ‡˜π’±β‡™ βˆͺ Nβ‡˜π’±β‡™), N = {}, C = Cβ‡˜π’±β‡™β¦ˆ"
  assume lrf_view' : "Unwinding.lrf SES 𝒱' ur"
  assume osc_view' : "Unwinding.osc SES 𝒱' ur"

  interpret modified_view: Unwinding "SES" "𝒱'"
    by (unfold_locales, rule validSES, simp add: view'_def modified_view_valid)
      
  from lrf_view' osc_view' have BSD_view' : "BSD 𝒱' Trβ‡˜(induceES SES)⇙"
     by (rule_tac ur="ur" in modified_view.unwinding_theorem_BSD)
  with view'_def BSD_implies_SD_for_modified_view show ?thesis 
    by auto
qed

theorem unwinding_theorem_SI:
"⟦ 𝒱' = ⦇ V = (Vβ‡˜π’±β‡™ βˆͺ Nβ‡˜π’±β‡™), N = {}, C = Cβ‡˜π’±β‡™ ⦈; 
  Unwinding.lrb SES 𝒱' ur; Unwinding.osc SES 𝒱' ur ⟧ 
  ⟹ SI 𝒱 Trβ‡˜(induceES SES)⇙"
proof -
  assume view'_def : "𝒱' = ⦇V = Vβ‡˜π’±β‡™ βˆͺ Nβ‡˜π’±β‡™, N = {}, C = Cβ‡˜π’±β‡™β¦ˆ"
  assume lrb_view' : "Unwinding.lrb SES 𝒱' ur"
  assume osc_view' : "Unwinding.osc SES 𝒱' ur"

  interpret modified_view: Unwinding "SES" "𝒱'"
    by (unfold_locales, rule validSES, simp add: view'_def modified_view_valid)

  from lrb_view' osc_view' have BSI_view' : "BSI 𝒱' Trβ‡˜(induceES SES)⇙"
     by (rule_tac ur="ur" in modified_view.unwinding_theorem_BSI)
  with view'_def BSI_implies_SI_for_modified_view show ?thesis 
    by auto
qed

theorem unwinding_theorem_SIA: 
"⟦ 𝒱' = ⦇ V = (Vβ‡˜π’±β‡™ βˆͺ Nβ‡˜π’±β‡™), N = {}, C = Cβ‡˜π’±β‡™ ⦈; ρ 𝒱 = ρ 𝒱'; 
  Unwinding.lrbe SES 𝒱' ρ ur; Unwinding.osc SES 𝒱' ur ⟧ 
  ⟹ SIA ρ 𝒱 Trβ‡˜(induceES SES)⇙"
proof -
  assume view'_def : "𝒱' = ⦇V = Vβ‡˜π’±β‡™ βˆͺ Nβ‡˜π’±β‡™, N = {}, C = Cβ‡˜π’±β‡™β¦ˆ"
  assume ρ_eq : "ρ 𝒱 = ρ 𝒱'"
  assume lrbe_view' : "Unwinding.lrbe SES 𝒱' ρ ur"
  assume osc_view' : "Unwinding.osc SES 𝒱' ur"

  interpret modified_view: Unwinding "SES" "𝒱'"
    by (unfold_locales, rule validSES, simp add: view'_def modified_view_valid)

  from lrbe_view' osc_view' have BSIA_view' : "BSIA ρ 𝒱' Trβ‡˜(induceES SES)⇙"
     by (rule_tac ur="ur" in modified_view.unwinding_theorem_BSIA)
  with view'_def BSIA_implies_SIA_for_modified_view ρ_eq show ?thesis 
    by auto
qed 

theorem unwinding_theorem_SR:
"⟦ 𝒱' = ⦇ V = (Vβ‡˜π’±β‡™ βˆͺ Nβ‡˜π’±β‡™), N = {}, C = Cβ‡˜π’±β‡™ ⦈; 
  Unwinding.lrf SES 𝒱' ur; Unwinding.osc SES 𝒱' ur ⟧ 
  ⟹ SR 𝒱 Trβ‡˜(induceES SES)⇙"
proof -
  assume view'_def : "𝒱' = ⦇V = Vβ‡˜π’±β‡™ βˆͺ Nβ‡˜π’±β‡™, N = {}, C = Cβ‡˜π’±β‡™β¦ˆ"
  assume lrf_view' : "Unwinding.lrf SES 𝒱' ur"
  assume osc_view' : "Unwinding.osc SES 𝒱' ur"

  from lrf_view' osc_view' view'_def have S_view : "SD 𝒱 Trβ‡˜(induceES SES)⇙"
     by (rule_tac ur="ur" in  unwinding_theorem_SD, auto)
  with SD_implies_SR show ?thesis
    by auto
qed

theorem unwinding_theorem_D:
"⟦ lrf ur; osc ur ⟧ ⟹ D 𝒱 Trβ‡˜(induceES SES)⇙"
proof -
  assume "lrf ur"
  and "osc ur"
  hence "BSD 𝒱 Trβ‡˜(induceES SES)⇙"
    by (rule unwinding_theorem_BSD)
  thus ?thesis
    by (rule BSD_implies_D)
qed

theorem unwinding_theorem_I:
"⟦ lrb ur; osc ur ⟧ ⟹ I 𝒱 Trβ‡˜(induceES SES)⇙"
proof -
  assume "lrb ur"
  and "osc ur"
  hence "BSI 𝒱 Trβ‡˜(induceES SES)⇙"
    by (rule unwinding_theorem_BSI)
  thus ?thesis
    by (rule BSI_implies_I)
qed

theorem unwinding_theorem_IA:
"⟦ lrbe ρ ur; osc ur ⟧ ⟹ IA ρ 𝒱 Trβ‡˜(induceES SES)⇙"
proof -
  assume "lrbe ρ ur"
  and "osc ur"
  hence "BSIA ρ 𝒱 Trβ‡˜(induceES SES)⇙"
    by (rule unwinding_theorem_BSIA)
  thus ?thesis
    by (rule BSIA_implies_IA)
qed

theorem unwinding_theorem_R:
"⟦ lrf ur; osc ur ⟧ ⟹ R 𝒱 (Trβ‡˜(induceES SES)⇙)"
proof -
  assume "lrf ur"
  and "osc ur"
  hence "BSD 𝒱 Trβ‡˜(induceES SES)⇙"
    by (rule unwinding_theorem_BSD)
  hence "D 𝒱 Trβ‡˜(induceES SES)⇙"
    by (rule BSD_implies_D)
  thus ?thesis
    by (rule D_implies_R)
qed

end

end