Theory Combining_Synchronization_Product_Generalized

(***********************************************************************************
 * Copyright (c) 2025 Université Paris-Saclay
 *
 * Author: Benoît Ballenghien, Université Paris-Saclay,
 *         CNRS, ENS Paris-Saclay, LMF
 * Author: Burkhart Wolff, Université Paris-Saclay,
 *         CNRS, ENS Paris-Saclay, LMF
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice, this
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * SPDX-License-Identifier: BSD-2-Clause
 ***********************************************************************************)


chapter ‹Combining Automata for Generalized Synchronization Product›

(*<*)
theory Combining_Synchronization_Product_Generalized
  imports Combining_Synchronization_Product
begin
  (*>*)


section ‹Definitions›

subsection ‹Specializations›

definition combinedPairlist_Syncptick ::
  [(, 'e, 'r, ) Ad_scheme, 'e set, (, 'e, 'r, ) Ad_scheme]  ( list, 'e, 'r list) Ad
  where combinedPairlist_Syncptick A0 E A1 
         combined_Sync A0 E A1 hd (λσs. hd (tl σs)) (λs t. [s, t]) (λs t. [s, t])
definition combinendPairlist_Syncptick ::
  [(, 'e, 'r, ) And_scheme, 'e set, (, 'e, 'r, ) And_scheme]  ( list, 'e, 'r list) And
  where combinendPairlist_Syncptick A0 E A1  combinend_Sync A0 E A1 hd (λσs. hd (tl σs)) (λs t. [s, t]) (λs t. [s, t])

definition combinedPair_Syncptick ::
  [(0, 'e, 'r0, ) Ad_scheme, 'e set, (1, 'e, 'r1, ) Ad_scheme]  (0 × 1, 'e, 'r0 × 'r1) Ad
  where combinedPair_Syncptick A0 E A1  combined_Sync A0 E A1 fst snd Pair (λs r. (s, r))
definition combinendPair_Syncptick ::
  [(0, 'e, 'r0, ) And_scheme, 'e set, (1, 'e, 'r1, ) And_scheme]  (0 × 1, 'e, 'r0 × 'r1) And
  where combinendPair_Syncptick A0 E A1  combinend_Sync A0 E A1 fst snd Pair (λs r. (s, r))

definition combinedListslenL_Syncptick ::
  [( list, 'e, 'r list, ) Ad_scheme, nat, 'e set, ( list, 'e, 'r list, ) Ad_scheme]  ( list, 'e, 'r list) Ad
  where combinedListslenL_Syncptick A0 len0 E A1  combined_Sync A0 E A1 (take len0) (drop len0) (@) (λs r. s @ r)
definition combinendListslenL_Syncptick ::
  [( list, 'e, 'r list, ) And_scheme, nat, 'e set, ( list, 'e, 'r list, ) And_scheme]  ( list, 'e, 'r list) And
  where combinendListslenL_Syncptick A0 len0 E A1  combinend_Sync A0 E A1 (take len0) (drop len0) (@) (λs r. s @ r)

definition combinedRlist_Syncptick ::
  [(, 'e, 'r, ) Ad_scheme, 'e set, ( list, 'e, 'r list, ) Ad_scheme]  ( list, 'e, 'r list) Ad
  where combinedRlist_Syncptick A0 E A1  combined_Sync A0 E A1 hd tl (#) (λs r. s # r)
definition combinendRlist_Syncptick ::
  [(, 'e, 'r, ) And_scheme, 'e set, ( list, 'e, 'r list, ) And_scheme]  ( list, 'e, 'r list) And
  where combinendRlist_Syncptick A0 E A1  combinend_Sync A0 E A1 hd tl (#) (λs r. s # r)

lemmas combinePairlist_Syncptick_defs = combinedPairlist_Syncptick_def combinendPairlist_Syncptick_def
  and combinePair_Syncptick_defs = combinedPair_Syncptick_def combinendPair_Syncptick_def
  and combineListslenL_Syncptick_defs = combinedListslenL_Syncptick_def combinendListslenL_Syncptick_def
  and combineRlist_Syncptick_defs = combinedRlist_Syncptick_def combinendRlist_Syncptick_def

lemmas combine_Syncptick_defs =
  combinePairlist_Syncptick_defs combinePair_Syncptick_defs combineListslenL_Syncptick_defs combineRlist_Syncptick_defs


bundle combinend_Syncptick_syntax begin

notation combinedPairlist_Syncptick (_ d⊗⟦_Pairlist _ [0, 0, 0])
notation combinendPairlist_Syncptick (_ nd⊗⟦_Pairlist _ [0, 0, 0])
notation combinedPair_Syncptick (_ d⊗⟦_Pair _ [0, 0, 0])
notation combinendPair_Syncptick (_ nd⊗⟦_Pair _ [0, 0, 0])
notation combinedListslenL_Syncptick (_ d⊗⟦_, _ListslenL _ [0, 0, 0, 0])
notation combinendListslenL_Syncptick (_ nd⊗⟦_, _ListslenL _ [0, 0, 0, 0])
notation combinedRlist_Syncptick (_ d⊗⟦_Rlist _ [0, 0, 0])
notation combinendRlist_Syncptick (_ nd⊗⟦_Rlist _ [0, 0, 0])

end

unbundle combinend_Syncptick_syntax



section ‹First Properties›

lemma finite_trans_combinend_Syncptick_simps [simp] : 
  finite_trans A0  finite_trans A1  finite_trans A0 nd⊗⟦EPairlist A1
  finite_trans B0  finite_trans B1  finite_trans B0 nd⊗⟦EPair B1
  finite_trans C0  finite_trans C1  finite_trans C0 nd⊗⟦len0, EListslenL C1
  finite_trans D0  finite_trans D1  finite_trans D0 nd⊗⟦ERlist D1
  unfolding combinendPairlist_Syncptick_def combinendPair_Syncptick_def combinendListslenL_Syncptick_def combinendRlist_Syncptick_def 
  by (simp_all add: finite_trans_def finite_image_set2)

lemma ε_combinePairlist_Syncptick:
  ε A0 d⊗⟦EPairlist A1 σs = combine_Sync_ε A0 E A1 hd (hd  tl) σs
  ε B0 nd⊗⟦EPairlist B1 σs = combine_Sync_ε B0 E B1 hd (hd  tl) σs
  by (auto simp add: combine_Sync_ε_def_bis combinePairlist_Syncptick_defs ε_simps)

lemma ε_combinePair_Syncptick:
  ε A0 d⊗⟦EPair A1 σs = combine_Sync_ε A0 E A1 fst snd σs
  ε B0 nd⊗⟦EPair B1 σs = combine_Sync_ε B0 E B1 fst snd σs
  by (auto simp add: combine_Sync_ε_def_bis combinePair_Syncptick_defs ε_simps)

lemma ε_combineListslenL_Syncptick: 
  ε A0 d⊗⟦len0, EListslenL A1 σs = combine_Sync_ε A0 E A1 (take len0) (drop len0) σs
  ε B0 nd⊗⟦len0, EListslenL B1 σs = combine_Sync_ε B0 E B1 (take len0) (drop len0) σs
  by (auto simp add: combine_Sync_ε_def_bis combineListslenL_Syncptick_defs ε_simps)

lemma ε_combineRlist_Syncptick:
  ε A0 d⊗⟦ERlist A1 σs = combine_Sync_ε A0 E A1 hd tl σs
  ε B0 nd⊗⟦ERlist B1 σs = combine_Sync_ε B0 E B1 hd tl σs
  by (auto simp add: combine_Sync_ε_def_bis combineRlist_Syncptick_defs ε_simps)


lemma ρ_combinePairlist_Syncptick:
  ρ A0 d⊗⟦EPairlist A1 = {σs. hd σs  ρ A0  hd (tl σs)  ρ A1}
  ρ B0 nd⊗⟦EPairlist B1 = {σs. hd σs  ρ B0  hd (tl σs)  ρ B1}
  by (auto simp add: combinePairlist_Syncptick_defs ρ_simps split: option.split)

lemma ρ_combinePair_Syncptick:
  ρ A0 d⊗⟦EPair A1 = {(σ0, σ1). σ0  ρ A0  σ1  ρ A1}
  ρ B0 nd⊗⟦EPair B1 = {(σ0, σ1). σ0  ρ B0  σ1  ρ B1}
  by (auto simp add: combinePair_Syncptick_defs ρ_simps split: option.split)

lemma ρ_combineListslenL_Syncptick: 
  ρ A0 d⊗⟦len0, EListslenL A1 = {σs. take len0 σs  ρ A0  drop len0 σs  ρ A1}
  ρ B0 nd⊗⟦len0, EListslenL B1 = {σs. take len0 σs  ρ B0  drop len0 σs  ρ B1}
  by (auto simp add: combineListslenL_Syncptick_defs ρ_simps split: option.split)

lemma ρ_combineRlist_Syncptick:
  ρ A0 d⊗⟦ERlist A1 = {σs. hd σs  ρ A0  tl σs  ρ A1}
  ρ B0 nd⊗⟦ERlist B1 = {σs. hd σs  ρ B0  tl σs  ρ B1}
  by (auto simp add: combineRlist_Syncptick_defs ρ_simps split: option.split)



section ‹Transitions are unchanged in the Generalization›

text ‹
In the generalization, only the constω function is modified.
›

lemma τ_combinePairlist_Syncptick :
  τ A0 d⊗⟦EPairlist A1 = τ A0 d⊗⟦EPairlist A1
  τ B0 nd⊗⟦EPairlist B1 = τ B0 nd⊗⟦EPairlist B1
  by (simp_all add: combine_Sync_defs combine_Syncptick_defs)

lemma τ_combinePair_Syncptick :
  τ A0 d⊗⟦EPair A1 = τ A0 d⊗⟦EPair A1
  τ B0 nd⊗⟦EPair B1 = τ B0 nd⊗⟦EPair B1
  by (simp_all add: combine_Sync_defs combine_Syncptick_defs)

lemma τ_combineListslenL_Syncptick :
  τ A0 d⊗⟦len0, EListslenL A1 = τ A0 d⊗⟦len0, EListslenL A1
  τ B0 nd⊗⟦len0, EListslenL B1 = τ B0 nd⊗⟦len0, EListslenL B1
  by (simp_all add: combine_Sync_defs combine_Syncptick_defs)

text termτ A0 d⊗⟦ERlist A1 and termτ B0 nd⊗⟦ERlist B1
cannot be obtained that easily because of the types of terminations.›



section ‹Reachability›

lemma d_combinedListslenL_Syncptick_subset: 
  d A0 d⊗⟦len0, EListslenL A1 (s0 @ s1)  {t0 @ t1| t0 t1. t0  d A0 s0  t1  d A1 s1} (is ?SA  _)
  if t0. t0  d A0 s0  length t0 = len0
  by (subst same_τ_implies_same_ℛd[of _ _ A0 d⊗⟦len0, EListslenL A1])
    (simp_all add: τ_combineListslenL_Syncptick d_combinedListslenL_Sync_subset that)

lemma nd_combinendListslenL_Syncptick_subset: 
  nd B0 nd⊗⟦len0, EListslenL B1 (s0 @ s1)  {t0 @ t1| t0 t1. t0  nd B0 s0  t1  nd B1 s1} (is ?SB  _)
  if t0. t0  nd B0 s0  length t0 = len0
  by (subst same_τ_implies_same_ℛnd[of _ _ B0 nd⊗⟦len0, EListslenL B1])
    (simp_all add: τ_combineListslenL_Syncptick nd_combinendListslenL_Sync_subset that)


lemma d_combinedPairlist_Syncptick_subset:
  d A0 d⊗⟦EPairlist A1 [s0, s1]  {[t0, t1]| t0 t1. t0  d A0 s0  t1  d A1 s1} (is ?SA  _)
  and nd_combinendPairlist_Syncptick_subset:
  nd B0 nd⊗⟦EPairlist B1 [s0, s1]  {[t0, t1]| t0 t1. t0  nd B0 s0  t1  nd B1 s1} (is ?SB  _)
proof safe
  show t  ?SA  t0 t1. t = [t0, t1]  t0  d A0 s0  t1  d A1 s1 for t
    by (d_subset_method defs: combinePairlist_Syncptick_defs)
  show t  ?SB  t0 t1. t = [t0, t1]  t0  nd B0 s0  t1  nd B1 s1 for t
    by (nd_subset_method defs: combinePairlist_Syncptick_defs)
qed

lemma d_combinedPair_Syncptick_subset:
  d A0 d⊗⟦EPair A1 (s0, s1)  d A0 s0 × d A1 s1 (is ?SA  _)
  and nd_combinendPair_Syncptick_subset:
  nd B0 nd⊗⟦EPair B1 (s0, s1)  nd B0 s0 × nd B1 s1 (is ?SB  _)
proof -
  have t  ?SA  fst t  d A0 s0  snd t  d A1 s1 for t 
    by (d_subset_method defs: combinePair_Syncptick_defs)
  thus ?SA  d A0 s0 × d A1 s1 by force
next
  have t  ?SB  fst t  nd B0 s0  snd t  nd B1 s1 for t
    by (nd_subset_method defs: combinePair_Syncptick_defs)
  thus ?SB  nd B0 s0 × nd B1 s1 by force
qed


lemma d_combinedRlist_Syncptick_subset:
  d A0 d⊗⟦ERlist A1 (s0 # σs)  {t0 # σt| t0 σt. t0  d A0 s0  σt  d A1 σs} (is ?SA  _)
  and nd_combinendRlist_Syncptick_subset: 
  nd B0 nd⊗⟦ERlist B1 (s0 # σs)  {t0 # σt| t0 σt. t0  nd B0 s0  σt  nd B1 σs} (is ?SB  _)
proof safe
  show t  ?SA  t0 σt. t = t0 # σt  t0  d A0 s0  σt  d A1 σs for t
    by (d_subset_method defs: combineRlist_Syncptick_defs)
next
  show t  ?SB  t0 σt. t = t0 # σt  t0  nd B0 s0  σt  nd B1 σs for t
    by (nd_subset_method defs: combineRlist_Syncptick_defs)
qed



section ‹Normalization› 


lemma ω_combinePairlist_Syncptick_behaviour:
  ω A0 d⊗⟦EPairlist A1dnd [s0, s1] = ω A0dnd nd⊗⟦EPairlist A1dnd [s0, s1]
  by (simp add: combinePairlist_Syncptick_defs det_ndet_conv_defs option.case_eq_if)

lemma ω_combinePair_Syncptick_behaviour:
  ω A0 d⊗⟦EPair A1dnd (s0, s1) = ω A0dnd nd⊗⟦EPair A1dnd (s0, s1)
  by (simp add: combinePair_Syncptick_defs det_ndet_conv_defs option.case_eq_if)

lemma ω_combineListslenL_Syncptick_behaviour:
  ω A0 d⊗⟦len0, EListslenL A1dnd (σs0 @ σs1) = ω A0dnd nd⊗⟦len0, EListslenL A1dnd (σs0 @ σs1)
  by (simp add: combineListslenL_Syncptick_defs det_ndet_conv_defs option.case_eq_if)

lemma ω_combineRlist_Syncptick_behaviour:
  ω A0 d⊗⟦ERlist A1dnd (s0 # σs1) = ω A0dnd nd⊗⟦ERlist A1dnd (s0 # σs1)
  by (simp add: combineRlist_Syncptick_defs det_ndet_conv_defs option.case_eq_if)


lemma τ_combinePairlist_Syncptick_behaviour_when_indep:
  ε A0 s0  ε A1 s1  E 
   τ A0 d⊗⟦EPairlist A1dnd [s0, s1] e = τ A0dnd nd⊗⟦EPairlist A1dnd [s0, s1] e
  by (auto simp add: combinePairlist_Syncptick_defs det_ndet_conv_defs option.case_eq_if ε_simps)

lemma τ_combinePair_Syncptick_behaviour_when_indep:
  ε A0 s0  ε A1 s1  E  
   τ A0 d⊗⟦EPair A1dnd (s0, s1) e = τ A0dnd nd⊗⟦EPair A1dnd (s0, s1) e
  by (auto simp add: combinePair_Syncptick_defs det_ndet_conv_defs option.case_eq_if ε_simps)

lemma τ_combineListslenL_Syncptick_behaviour_when_indep:
  ε A0 σs0  ε A1 σs1  E  length σs0 = len0  
   τ A0 d⊗⟦len0, EListslenL A1dnd (σs0 @ σs1) e = τ A0dnd nd⊗⟦len0, EListslenL A1dnd (σs0 @ σs1) e
  by (auto simp add: combineListslenL_Syncptick_defs det_ndet_conv_defs option.case_eq_if ε_simps)

lemma τ_combineRlist_Syncptick_behaviour_when_indep:
  ε A0 s0  ε A1 σs1  E 
   τ A0 d⊗⟦ERlist A1dnd (s0 # σs1) e = τ A0dnd nd⊗⟦ERlist A1dnd (s0 # σs1) e
  by (auto simp add: combineRlist_Syncptick_defs det_ndet_conv_defs option.case_eq_if ε_simps)



lemma PSKIPS_combinePairlist_Syncptick_behaviour_when_indep:
  PSKIPSA0 d⊗⟦EPairlist A1d [s0, s1] = PSKIPSA0dnd nd⊗⟦EPairlist A1dndnd [s0, s1]
  if indep_enabl A0 s0 E A1 s1
  by (PSKIPS_when_indep_method R_d_subset: d_combinedPairlist_Syncptick_subset, simp_all)
    (metis τ_combinePairlist_Syncptick_behaviour_when_indep indep_enablD that,
      metis ω_combinePairlist_Syncptick_behaviour)

lemma P_combinePairlist_Syncptick_behaviour_when_indep:
  P⟪A0 d⊗⟦EPairlist A1d [s0, s1] = P⟪A0dnd nd⊗⟦EPairlist A1dndnd [s0, s1]
  if indep_enabl A0 s0 E A1 s1
  by (P_when_indep_method R_d_subset: d_combinedPairlist_Syncptick_subset, simp_all)
    (metis τ_combinePairlist_Syncptick_behaviour_when_indep indep_enablD that)


lemma PSKIPS_combinePair_Syncptick_behaviour_when_indep:
  PSKIPSA0 d⊗⟦EPair A1d (s0, s1) = PSKIPSA0dnd nd⊗⟦EPair A1dndnd (s0, s1)
  if indep_enabl A0 s0 E A1 s1
  by (PSKIPS_when_indep_method R_d_subset: d_combinedPair_Syncptick_subset, all elim SigmaE)
    (metis τ_combinePair_Syncptick_behaviour_when_indep indep_enablD that,
      auto simp add: ω_combinePair_Syncptick_behaviour option.case_eq_if)

lemma P_combinePair_Syncptick_behaviour_when_indep:
  P⟪A0 d⊗⟦EPair A1d (s0, s1) = P⟪A0dnd nd⊗⟦EPair A1dndnd (s0, s1)
  if indep_enabl A0 s0 E A1 s1
  by (P_when_indep_method R_d_subset: d_combinedPair_Syncptick_subset, elim SigmaE)
    (metis τ_combinePair_Syncptick_behaviour_when_indep indep_enablD that)


lemma PSKIPS_combineListslenL_Syncptick_behaviour_when_indep:
  PSKIPSA0 d⊗⟦len0, EListslenL A1d (σs0 @ σs1) = PSKIPSA0dnd nd⊗⟦len0, EListslenL A1dndnd (σs0 @ σs1) 
  if indep_enabl A0 σs0 E A1 σs1 and σt0. σt0  d A0 σs0  length σt0 = len0
  by (PSKIPS_when_indep_method R_d_subset: d_combinedListslenL_Syncptick_subset, simp_all add: that(2))
    (metis τ_combineListslenL_Syncptick_behaviour_when_indep indep_enablD that,
      metis ω_combineListslenL_Syncptick_behaviour)

lemma P_combineListslenL_Syncptick_behaviour_when_indep:
  P⟪A0 d⊗⟦len0, EListslenL A1d (σs0 @ σs1) = P⟪A0dnd nd⊗⟦len0, EListslenL A1dndnd (σs0 @ σs1)
  if indep_enabl A0 σs0 E A1 σs1 and σt0. σt0  d A0 σs0  length σt0 = len0
  by (P_when_indep_method R_d_subset: d_combinedListslenL_Syncptick_subset, simp_all add: that(2))
    (metis τ_combineListslenL_Syncptick_behaviour_when_indep indep_enablD that)


lemma PSKIPS_combineRlist_Syncptick_behaviour_when_indep:
  PSKIPSA0 d⊗⟦ERlist A1d (s0 # σs1) = PSKIPSA0dnd nd⊗⟦ERlist A1dndnd (s0 # σs1)
  if indep_enabl A0 s0 E A1 σs1
  by (PSKIPS_when_indep_method R_d_subset: d_combinedRlist_Syncptick_subset, simp_all)
    (metis τ_combineRlist_Syncptick_behaviour_when_indep indep_enablD that,
      metis ω_combineRlist_Syncptick_behaviour)

lemma P_combineRlist_Syncptick_behaviour_when_indep:
  P⟪A0 d⊗⟦ERlist A1d (s0 # σs1) = P⟪A0dnd nd⊗⟦ERlist A1dndnd (s0 # σs1)
  if indep_enabl A0 s0 E A1 σs1
  by (P_when_indep_method R_d_subset: d_combinedRlist_Syncptick_subset, simp)
    (metis τ_combineRlist_Syncptick_behaviour_when_indep indep_enablD that)


(*<*)
end
  (*>*)