From mathcomp.ssreflect
Require Import ssreflect ssrbool ssrnat eqtype ssrfun seq.
From mathcomp
Require Import path.
Require Import Eqdep.
Require Import Relation_Operators.
From fcsl
Require Import axioms pred prelude ordtype finmap pcm unionmap heap.
From DiSeL
Require Import Freshness State EqTypeX Protocols Worlds NetworkSem Actions.
Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.

(* Framing with respect to the world *)

Module Injection.
Section Injection.

Variable W : world.

Structure injects (U V : world) (K : hooks) := Inject {
  (* The "delta world" *)
  E : world;
                                       
  _ : hook_complete U /\ hook_complete E;

  (* Additional hooks are included with an empty world *)
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  _ : V = U \+ E \+ (Unit, K);

(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  (* Additional hooks are well-formed with respect to the world *)
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  _ : hooks_consistent (getc (U \+ E)) K;
  
  (* These all should be easy to prove given a standard world disentanglement *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  _ : forall s, Coh V s <-> exists s1 s2,
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
        [/\ s = s1 \+ s2, Coh U s1 & Coh E s2];

  (* Framing wrt. worlds and hooks *)
  _ : forall s1 s2 s this,
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
      s1 \+ s \In Coh V -> network_step U this s1 s2 ->
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
      network_step V this (s1 \+ s) (s2 \+ s);

  _ : forall s1 s2 s1' s2' this,
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
      s1 \In Coh U -> s2 \In Coh U ->
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
      network_step V this (s1 \+ s1') (s2 \+ s2') ->
      (network_step U this s1 s2   /\ s1' = s2') \/
      (network_step E this s1' s2' /\ s1 = s2); }.

End Injection.

Module Exports.
Section Exports.

Definition inj_ext := E.
Definition injects := injects. 
Definition Inject := Inject.

Lemma cohK (U V : world) (K : hooks) (w : injects U V K) :
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  V = U \+ inj_ext w \+ (Unit, K).
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
Proof. by case: w=>E/=. Qed.

Lemma cohE (U V : world) (K : hooks) (w : injects U V K) s :
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  Coh V s <-> exists s1 s2,
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
      [/\ s = s1 \+ s2, Coh U s1 & Coh (inj_ext w) s2].
Proof. by case: w=>W ??? cohE sL sR; apply: cohE. Qed.

Lemma sem_extend (U V : world) (K : hooks) (w : injects U V K) s1 s2 s this: 
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
      s1 \+ s \In Coh V -> s2 \+ s \In Coh V ->
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
      network_step U this s1 s2 -> network_step V this (s1 \+ s) (s2 \+ s).
Proof.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
by case: w=>W _ _ _ cohE sL sR C G; apply: sL=>//.
Qed.

Lemma sem_split (U V : world) (K : hooks) (w : injects U V K) s1 s1' s2 s2' this: 
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
      s1 \In Coh U -> s2 \In Coh U ->
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
      network_step V this (s1 \+ s1') (s2 \+ s2') ->
      (network_step U this s1 s2   /\ s1' = s2') \/
      (network_step (inj_ext w) this s1' s2' /\ s1 = s2).
Proof. by case: w=>W ??? cohE sl sR; apply: sR. Qed.

Definition extends (U V : world) (K : hooks) (w : injects U V K) s s1 := 
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  exists s2, [/\ s = s1 \+ s2, s1 \In Coh U & s \In Coh V].

Notation dom_filt W := (fun k => k \in dom W).

(* TODO: prove something about hooks K being irrelevant for coherence *)

(* TODO: remove all irrelevant hooks *)

Definition projectS (W : world) (s : state) :=
  um_filter (dom_filt (getc W)) s.

Lemma projectS_cohL W1 W2 s :
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  s \In Coh (W1 \+ W2) -> hook_complete W1 -> projectS W1 s \In Coh W1.
Proof.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
case=>V1 V2 G1 D H G2; split=>//; first by move/validL: V1.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
- by rewrite valid_umfilt.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
- move=>z; case B: (z \in dom (getc W1)).
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  + by rewrite dom_umfilt !inE B/= -D/=domUn !inE B/=; case/andP:V1=>->.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
  by rewrite dom_umfilt !inE B.
(* Goal: forall (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (@fst (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label dstatelet (union_mapUMC Label dstatelet) s)))) (_ : @InMem (@UMC.sort Label dstatelet (union_mapUMC Label dstatelet)) s (@Mem state (PredPredType state) (Coh U))) (_ : @InMem (PCM.sort (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet))) (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) hooks (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : not_hooked_by K l) (_ : all_hooks_fire (geth U) l st s n msg to), all_hooks_fire (geth (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) hooks (@PCM.unit (union_mapPCM Label protocol)) K))) l st (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') n msg to *)
move=>l; move: (H l)=>{H}H.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
case B: (l \in dom (getc W1)); last first.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
- rewrite /getProtocol /getStatelet; move: (B).
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  case: dom_find=>//-> _.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  suff X: ~~(l \in dom (projectS W1 s)) by case: dom_find X=>//-> _. 
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
  by rewrite /projectS dom_umfilt inE/= B.
(* Goal: Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
have E1: find l s = find l (projectS W1 s).
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
- by rewrite /projectS/= find_umfilt B.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
have E2: getProtocol (W1 \+ W2) l = getProtocol W1 l.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  - rewrite /getProtocol findUnL//?B//.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
    by rewrite /valid/= in V1; case/andP: V1.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
by rewrite -E2 /getStatelet -E1 in H *.  
Qed.

Lemma projectS_cohR W1 W2 s :
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  s \In Coh (W1 \+ W2) -> hook_complete W2 -> projectS W2 s \In Coh W2.
Proof. by rewrite joinC; apply: projectS_cohL. Qed.

Lemma projectSE W1 W2 s :
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  s \In Coh (W1 \+ W2) ->
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  s = projectS W1 s \+ projectS W2 s.
Proof.
(* Goal: is_true (@PCM.valid (union_mapPCM Label dstatelet) (@PCM.join (union_mapPCM Label dstatelet) s1 s2)) *)
(* Goal: Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
case=>Vw Vs G D H; rewrite /projectS.
(* Goal: Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
have X: {in dom s, dom_filt (getc W2) =1 predD (dom_filt (getc W2)) (dom_filt (getc W1))}.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
- move=>z _/=; case I : (z \in dom (W1.1 \+ W2.1)).
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  + move: I; rewrite domUn !inE/==>/andP[V']/orP[]Z; rewrite Z/=.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
    - by case: validUn V'=>//_ _/(_ z Z)/=G' _;apply/negbTE. 
(* Goal: forall _ : @eq (option hook_type) (@Some hook_type hk) (@UMC.find (prod_ordType (prod_ordType nat_ordType Label) (prod_ordType Label nat_ordType)) hook_type (union_mapUMC (prod_ordType (prod_ordType nat_ordType Label) (prod_ordType Label nat_ordType)) hook_type) (@pair (prod nat nat) (prod nat nat) (@pair nat nat z lc) (@pair nat nat l st)) (@PCM.join (union_mapPCM hook_domain hook_type) (@snd (UMDef.tp Label protocol) (UMDef.tp hook_domain hook_type) U) (@snd (UMDef.tp Label protocol) (UMDef.tp hook_domain hook_type) W))), hk (getLocal n (getStatelet (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') lc)) (getLocal n (getStatelet (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') l)) msg to *)
    rewrite joinC in V'; case: validUn V'=>//_ _/(_ z Z)G' _.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
    by rewrite andbC.
(* Goal: @eq bool (@in_mem nat z (@mem nat (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (getc W2)))) (andb (negb (@in_mem nat z (@mem nat (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (getc W1))))) (@in_mem nat z (@mem nat (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (getc W2))))) *)
(* Goal: @eq state s (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) (@UMC.um_filter Label dstatelet (union_mapUMC Label dstatelet) (fun k : Ordered.sort Label => @in_mem (Ordered.sort Label) k (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (getc W1)))) s) (@UMC.um_filter Label dstatelet (union_mapUMC Label dstatelet) (fun k : Ordered.sort Label => @in_mem (Ordered.sort Label) k (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (getc W2)))) s)) *)
  move: I; rewrite domUn inE/==>/negbT; rewrite negb_and negb_or/=.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  have X: valid (W1 \+ W2) by [].
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  by case/andP: X=>->/=_/andP[]->.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
rewrite (eq_in_umfilt X) -umfilt_predU/=; clear X.
(* Goal: @eq (PCM.sort (union_mapPCM Label dstatelet)) s (@UMC.um_filter Label dstatelet (union_mapUMC Label dstatelet) (fun k : Ordered.sort Label => @in_mem (Ordered.sort Label) k (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (getc U)))) (@PCM.join (union_mapPCM Label dstatelet) s s')) *)
suff X: {in dom s, predU (dom_filt (getc W1)) (dom_filt (getc W2)) =1 predT}.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
- by rewrite (eq_in_umfilt X) umfilt_predT. 
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
by move=>z; rewrite/= -D domUn inE=>/andP[].
Qed.

Lemma coh_split W1 W2 s :
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  s \In Coh (W1 \+ W2) ->
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  hook_complete W1 -> hook_complete W2 ->
  exists s1 s2 : state,
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
    [/\ s1 \In Coh W1, s2 \In Coh W2 & s = s1 \+ s2].
Proof.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
move=>C G1 G2; move/projectSE: (C)->.
(* Goal: @ex state (fun s1 : state => @ex state (fun s2 : state => and3 (@InMem state s1 (@Mem state (PredPredType state) (Coh W1))) (@InMem state s2 (@Mem state (PredPredType state) (Coh W2))) (@eq state (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) (projectS W1 s) (projectS W2 s)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2)))) *)
exists (projectS W1 s), (projectS W2 s).
(* Goal: and3 (@InMem state (projectS W1 s) (@Mem state (PredPredType state) (Coh W1))) (@InMem state (projectS W2 s) (@Mem state (PredPredType state) (Coh W2))) (@eq state (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) (projectS W1 s) (projectS W2 s)) (@PCM.join (union_mapPCM Label dstatelet) (projectS W1 s) (projectS W2 s))) *)
split=>//; [by apply: projectS_cohL C G1| by apply: projectS_cohR C G2].
Qed.

(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
Lemma injExtL' (W1 W2 : world) K (pf : injects W1 (W1 \+ W2) K) :
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  valid (W1 \+ W2) -> inj_ext pf \+ (Unit, K) = W2.
Proof.
(* Goal: forall _ : is_true (@PCM.valid (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)), @eq (PCM.sort (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type))) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@inj_ext W2 (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2) K pf) (@pair (PCM.sort (union_mapPCM Label protocol)) hooks (@PCM.unit (union_mapPCM Label protocol)) K)) W1 *)
move=>H; case: pf=>W2' _ E/=_ _ _ _.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
rewrite -joinA in E.
(* Goal: forall _ : @eq (option hook_type) (@Some hook_type hk) (@UMC.find (prod_ordType (prod_ordType nat_ordType Label) (prod_ordType Label nat_ordType)) hook_type (union_mapUMC (prod_ordType (prod_ordType nat_ordType Label) (prod_ordType Label nat_ordType)) hook_type) (@pair (prod (Ordered.sort nat_ordType) (Ordered.sort Label)) (prod (Ordered.sort Label) (Ordered.sort nat_ordType)) (@pair (Ordered.sort nat_ordType) (Ordered.sort Label) z lc) (@pair (Ordered.sort Label) (Ordered.sort nat_ordType) l st)) (geth (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) hooks (@PCM.unit (union_mapPCM Label protocol)) K)))), hk (getLocal n (getStatelet (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') lc)) (getLocal n (getStatelet (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') l)) msg to *)
case/andP: H=>H1 H2.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
rewrite /PCM.join/= in H1 H2 E *.
(* Goal: forall _ : @eq (option hook_type) (@Some hook_type hk) (@UMC.find (prod_ordType (prod_ordType nat_ordType Label) (prod_ordType Label nat_ordType)) hook_type (union_mapUMC (prod_ordType (prod_ordType nat_ordType Label) (prod_ordType Label nat_ordType)) hook_type) (@pair (prod (Ordered.sort nat_ordType) (Ordered.sort Label)) (prod (Ordered.sort Label) (Ordered.sort nat_ordType)) (@pair (Ordered.sort nat_ordType) (Ordered.sort Label) z lc) (@pair (Ordered.sort Label) (Ordered.sort nat_ordType) l st)) (geth (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) hooks (@PCM.unit (union_mapPCM Label protocol)) K)))), hk (getLocal n (getStatelet (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') lc)) (getLocal n (getStatelet (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') l)) msg to *)
case: W2 H1 H2 E=>/=c2 h2 H1 H2 [E1 E2].
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
by rewrite (joinxK H1 E1) (joinxK H2 E2).
Qed.

(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
Lemma injExtR' W1 W2 K (pf : injects W2 (W1 \+ W2) K) :
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  valid (W1 \+ W2) -> inj_ext pf \+ (Unit, K) = W1.
Proof.
(* Goal: forall _ : is_true (@PCM.valid (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)), @eq (PCM.sort (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type))) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@inj_ext W2 (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2) K pf) (@pair (PCM.sort (union_mapPCM Label protocol)) hooks (@PCM.unit (union_mapPCM Label protocol)) K)) W1 *)
move=>H; case: pf=>W2' _ E/= _ _ _ _.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
rewrite -(joinC W2) in E H.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
case/andP: H=>H1 H2; rewrite -joinA in E.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
rewrite /PCM.join/= in H1 H2 E *.
(* Goal: forall _ : @eq (option hook_type) (@Some hook_type hk) (@UMC.find (prod_ordType (prod_ordType nat_ordType Label) (prod_ordType Label nat_ordType)) hook_type (union_mapUMC (prod_ordType (prod_ordType nat_ordType Label) (prod_ordType Label nat_ordType)) hook_type) (@pair (prod (Ordered.sort nat_ordType) (Ordered.sort Label)) (prod (Ordered.sort Label) (Ordered.sort nat_ordType)) (@pair (Ordered.sort nat_ordType) (Ordered.sort Label) z lc) (@pair (Ordered.sort Label) (Ordered.sort nat_ordType) l st)) (geth (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) hooks (@PCM.unit (union_mapPCM Label protocol)) K)))), hk (getLocal n (getStatelet (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') lc)) (getLocal n (getStatelet (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') l)) msg to *)
case: W1 H1 H2 E=>/=c1 h1 H1 H2 [E1 E2].
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
by rewrite (joinxK H1 E1) (joinxK H2 E2).
Qed.

(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
Lemma injExtL W1 W2 (pf : injects W1 (W1 \+ W2) Unit) :
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  valid (W1 \+ W2) -> inj_ext pf = W2.
Proof. by move/(injExtL' pf); rewrite unitR. Qed.

(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
Lemma injExtR W1 W2 (pf : injects W2 (W1 \+ W2) Unit) :
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  valid (W1 \+ W2) -> inj_ext pf  = W1.
Proof. by move/(injExtR' pf); rewrite unitR. Qed.

End Exports.
End Exports.

End Injection.

Export Injection.Exports.

Module InjectExtra.

Lemma cohUnKR U W s s':
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  s \+ s' \In Coh (U \+ W) -> s \In Coh U ->
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  hook_complete W -> s' \In Coh W.
Proof.
(* Goal: forall (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (@fst (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label dstatelet (union_mapUMC Label dstatelet) s)))) (_ : @InMem (@UMC.sort Label dstatelet (union_mapUMC Label dstatelet)) s (@Mem state (PredPredType state) (Coh U))) (_ : @InMem (PCM.sort (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet))) (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) hooks (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : not_hooked_by K l) (_ : all_hooks_fire (geth U) l st s n msg to), all_hooks_fire (geth (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) hooks (@PCM.unit (union_mapPCM Label protocol)) K))) l st (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') n msg to *)
move=>H C G2; move: (cohH C) => G1.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
suff X: s' = projectS W (s \+ s').
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
- by rewrite X; apply: (projectS_cohR H).
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
suff X: s = projectS U (s \+ s').
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
- move: (cohS H)=>V; move/projectSE: (H)=>E.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  rewrite E in V.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  rewrite {1}X in E.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
  by rewrite (joinxK V (sym_eq E)).
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
rewrite /projectS.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
suff X: {in dom (s \+ s'), dom U.1 =i dom s}.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
- by rewrite (eq_in_umfilt X) umfilt_dom ?(cohS H)//.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
by move=>z _; move: (cohD C z); rewrite /in_mem.
Qed.

Lemma cohUnKL U W s s':
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  s \+ s' \In Coh (U \+ W) -> s' \In Coh W ->
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  hook_complete U -> s \In Coh U .
Proof.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
by move=>H C G1; rewrite [U \+ W]joinC [s\+_]joinC in H; apply: (cohUnKR H).
Qed.

Lemma getPUn (U W : world) l :
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  valid (U \+ W) -> l \in dom U.1 ->
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  getProtocol U l = getProtocol (U \+ W) l.
Proof.
(* Goal: forall (_ : is_true (@PCM.valid (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s1 s2))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label dstatelet (union_mapUMC Label dstatelet) s1)))), @eq dstatelet (getStatelet s1 l) (getStatelet (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s1 s2) l) *)
move=>V; rewrite /getProtocol=>D.
(* Goal: forall _ : @eq (option hook_type) (@Some hook_type hk) (@UMC.find (prod_ordType (prod_ordType nat_ordType Label) (prod_ordType Label nat_ordType)) hook_type (union_mapUMC (prod_ordType (prod_ordType nat_ordType Label) (prod_ordType Label nat_ordType)) hook_type) (@pair (prod (Ordered.sort nat_ordType) (Ordered.sort Label)) (prod (Ordered.sort Label) (Ordered.sort nat_ordType)) (@pair (Ordered.sort nat_ordType) (Ordered.sort Label) z lc) (@pair (Ordered.sort Label) (Ordered.sort nat_ordType) l st)) (geth (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) hooks (@PCM.unit (union_mapPCM Label protocol)) K)))), hk (getLocal n (getStatelet (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') lc)) (getLocal n (getStatelet (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') l)) msg to *)
case/andP: (V)=>V1 V2.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
by rewrite findUnL ?V1// D.
Qed.

Lemma getSUn s1 s2 l :
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  valid (s1 \+ s2) -> l \in dom s1 ->
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  getStatelet s1 l = getStatelet (s1 \+ s2) l.
Proof.
(* Goal: forall (_ : is_true (@PCM.valid (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s1 s2))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label dstatelet (union_mapUMC Label dstatelet) s1)))), @eq dstatelet (getStatelet s1 l) (getStatelet (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s1 s2) l) *)
move=>V; rewrite /getStatelet=>D.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
by rewrite findUnL ?V// D.
Qed.

Lemma hook_completeL (U : world) K :
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  valid (U \+ (Unit, K)) ->
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  hook_complete (U \+ (Unit, K)) -> hook_complete U.
Proof.
(* Goal: Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
case: U=>c h=> V H z lc ls st D.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W1))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s1 (@Mem state (PredPredType state) (Coh W1))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s1 l) *)
move: (H z lc ls st); rewrite domUn inE/= D/=.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
case/andP: V=>_->/==>/(_ is_true_true)=>/andP[].
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
by rewrite !unitR=>->->.
Qed.

Lemma get_protocol_hooks (U: world) K l:
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  valid U -> getProtocol (U \+ (Unit, K)) l = getProtocol U l.
Proof.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W1))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s1 (@Mem state (PredPredType state) (Coh W1))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s1 l) *)
move=>V; rewrite /getProtocol.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
by rewrite findUnR ?dom0 ?inE//; rewrite unitR; case/andP: V.
Qed.

Lemma coh_hooks (U : world) K s :
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  s \In (Coh (U \+ (Unit, K))) -> s \In (Coh U).
Proof.
(* Goal: forall _ : @eq (option hook_type) (@Some hook_type hk) (@UMC.find (prod_ordType (prod_ordType nat_ordType Label) (prod_ordType Label nat_ordType)) hook_type (union_mapUMC (prod_ordType (prod_ordType nat_ordType Label) (prod_ordType Label nat_ordType)) hook_type) (@pair (prod (Ordered.sort nat_ordType) (Ordered.sort Label)) (prod (Ordered.sort Label) (Ordered.sort nat_ordType)) (@pair (Ordered.sort nat_ordType) (Ordered.sort Label) z lc) (@pair (Ordered.sort Label) (Ordered.sort nat_ordType) l st)) (geth (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) hooks (@PCM.unit (union_mapPCM Label protocol)) K)))), hk (getLocal n (getStatelet (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') lc)) (getLocal n (getStatelet (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') l)) msg to *)
case=>V Vs Hk D L.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
split=>//; first by move/validL: V.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
- by apply: hook_completeL V Hk.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
- move=>z; rewrite -D domUn !inE/= unitR dom0 orbC/=.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  by move/validL:V=>/andP[]->_.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
by move=>l; move: (L l); rewrite (get_protocol_hooks K l (validL V)).
Qed.

Lemma inj_hooks_complete (U W : world) K:
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  valid (U \+ W \+ (Unit, K)) ->
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  hook_complete U -> hook_complete W ->
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  hooks_consistent (U \+ W).1 K ->
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  hook_complete (U \+ W \+ (Unit, K)).
Proof.
(* Goal: forall (_ : is_true (@PCM.valid (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)))) (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (getc (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : world_not_hooked U K), injects U (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) K *)
move=>V G1 G2 G.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W1))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s1 (@Mem state (PredPredType state) (Coh W1))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s1 l) *)
move=>z lc ls st; rewrite domUn !inE/= !unitR.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
move/andP: (V)=>[_]->/=; case/orP; last by move/G.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
rewrite !domUn !inE; case/validL/andP:V=>->->/=.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
case/orP; first by case/G1/andP=>->->.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
by case/G2/andP=>->->; rewrite -!(orbC true).
Qed.

Lemma inject_step U W K this s1 s2 s1' s2' :
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  valid (U \+ W) ->
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  s1 \In Coh U -> s2 \In Coh U ->
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  hook_complete U -> hook_complete W ->
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  network_step (U \+ W \+ (Unit, K)) this (s1 \+ s1') (s2 \+ s2') ->
  network_step U this s1 s2 /\ s1' = s2' \/
  network_step W this s1' s2' /\ s1 = s2.
Proof.
(* Goal: forall (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (@fst (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label dstatelet (union_mapUMC Label dstatelet) s)))) (_ : @InMem (@UMC.sort Label dstatelet (union_mapUMC Label dstatelet)) s (@Mem state (PredPredType state) (Coh U))) (_ : @InMem (PCM.sort (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet))) (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) hooks (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : not_hooked_by K l) (_ : all_hooks_fire (geth U) l st s n msg to), all_hooks_fire (geth (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) hooks (@PCM.unit (union_mapPCM Label protocol)) K))) l st (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') n msg to *)
move=>V C1 C2 Hu Hw S; move/step_coh: (S)=>[C1' C2'].
(* Goal: forall (_ : is_true (@PCM.valid (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)))) (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (getc (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : world_not_hooked U K), injects U (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) K *)
move: (cohW C1')=>V1.
(* Goal: forall (_ : is_true (@PCM.valid (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)))) (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (getc (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : world_not_hooked U K), injects U (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) K *)
move: (coh_hooks C1')(coh_hooks C2')=>{C1'}C1'{C2'}C2'.
(* Goal: forall (_ : is_true (@PCM.valid (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)))) (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (getc (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : world_not_hooked U K), injects U (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) K *)
move: (cohUnKR C1' C1 Hw) (cohUnKR C2' C2 Hw)=>D1 D2.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
case: S; first 2 last.

(* Receive Step *)
(* Goal: forall (_ : is_true (@PCM.valid (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)))) (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (getc (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : world_not_hooked U K), injects U (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) K *)
move=>l rt R i from H1.
rewrite domUn inE=>/andP[Vs]/=/orP; case=>D C msg H2 [H3 H4]/=;
[rewrite updUnL D|rewrite updUnR D]=>G;[left|right].
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
- have X: s1' = s2'.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  + move: (C2'); rewrite (joinC U) G -[upd _ _ _ \+ s1'](joinC s1'). 
(* Goal: forall (_ : is_true (@PCM.valid (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)))) (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (getc (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : world_not_hooked U K), injects U (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) K *)
    move/cohUnKR/(_ D1)/(_ Hu)=>C1''.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
    move: (coh_prec (cohS C2') C2 C1'' G)=>Z; rewrite -Z in G; clear Z.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
    by rewrite (joinxK (cohS C2') G).
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  split=>//; subst s2'; rewrite -![_ \+ s1'](joinC s1') in G C2'.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  rewrite -[upd _ _ _ \+ s1'](joinC s1') in G; rewrite (joinC U) in C2'.
(* Goal: forall (_ : is_true (@PCM.valid (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)))) (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (getc (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : world_not_hooked U K), injects U (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) K *)
  move: (joinxK (cohS C2') G)=>{G}G. 
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  have E: getProtocol U l = getProtocol (U \+ W) l.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
    by rewrite (getPUn V)// (cohD C1).
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  have E': getStatelet s1 l = getStatelet (s1 \+ s1') l.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
    by rewrite (getSUn (cohS C1')). 
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  rewrite /get_rt /InMem/= in R. 
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  move: (getStatelet (s1 \+ s1') l) E' C (coh_s l C) H1 G H3 H4=>_<-_.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  move: (getProtocol (U \+ W \+ (Unit, K)) l)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
        (get_protocol_hooks K l V) E rt R H2=>_-><-rt R H2 coh_s H1 G H3 H4.
  apply: (ReceiveMsg R D H2 (i := i) (from := from) (s2 := s2) (C := C1)). 
  split=>//=; move: (NetworkSem.coh_s l C1)=>coh_s';
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  by rewrite -(pf_irr coh_s coh_s').

(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
(* Second part or receive-step *)
(* Goal: forall (_ : is_true (@PCM.valid (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)))) (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (getc (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : world_not_hooked U K), injects U (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) K *)
move: U W V {V1} Hw Hu s1 s2 s1' s2' C1 C2 C1' C2' D1 D2 rt H1 H2 Vs D C R H3 H4 G.
(* Goal: forall (_ : is_true (@PCM.valid (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)))) (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (getc (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : world_not_hooked U K), injects U (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) K *)
move=>W U V Hw Hu s1' s2' s1 s2 D1 D2.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
rewrite !(joinC W) -!(joinC s1) -!(joinC s2)=> C1' C2' C1 C2.
(* Goal: forall (_ : is_true (@PCM.valid (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)))) (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (getc (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : world_not_hooked U K), injects U (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) K *)
move=>rt H1 H2 Vs D C R H3 H4 G.
(* Goal: Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
have X: s1' = s2'.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
- move: (C2'); rewrite (joinC U) G. 
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W1))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s1 (@Mem state (PredPredType state) (Coh W1))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s1 l) *)
  move/cohUnKR/(_ D1)/(_ Hw)=>C1''; rewrite (joinC s1') in G.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  move: (coh_prec (cohS C2') C2 C1'' G)=>Z; rewrite -Z in G; clear Z.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
  by rewrite (joinxK (cohS C2') G).
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
split=>//; subst s2'; rewrite -!(joinC s1') in G C2'.
(* Goal: forall (_ : is_true (@PCM.valid (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)))) (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (getc (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : world_not_hooked U K), injects U (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) K *)
rewrite (joinC U) in C2'; move: (joinxK (cohS C2') G)=>{G}G.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
rewrite joinC in V.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
have E: getProtocol U l = getProtocol (U \+ W) l.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
  by rewrite (getPUn V)// (cohD C1).
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
have E': getStatelet s1 l = getStatelet (s1 \+ s1') l.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
  by rewrite (getSUn (cohS C1')). 
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
rewrite /get_rt /InMem/= in R. 
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
move: (getStatelet (s1 \+ s1') l) E' C (coh_s l C) H1 G H3 H4=>_<-_.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
move: (getProtocol (U \+ W \+ (Unit, K)) l)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
      (get_protocol_hooks K l V) E rt R H2=>_-><-rt R H2 coh_s H1 G H3 H4.
apply: (ReceiveMsg R D H2 (i := i) (from := from) (s2 := s2) (C := C1)). 
split=>//=; move: (NetworkSem.coh_s l C1)=>coh_s';
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
by rewrite -(pf_irr coh_s coh_s').

(* Idle Step *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
- case=>_ E; move: (coh_prec (cohS C1') C1 C2 E)=>Z; subst s2.
  rewrite (joinC U) (joinC s1) in C1'; rewrite !(joinC s1) in E.
  move: (coh_prec (cohS C1') D1 D2 E)=>Z; subst s2'.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
  by left; split=>//; apply: Idle.

(* Send Step *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
- move=>l st H1 to msg h H2.
  rewrite domUn inE=>/andP[Vs]/orP; case=> D _ S Hk H3;
  [rewrite updUnL D|rewrite updUnR D]=>G;[left|right];
  [| move: U W V1 Hu Hw V s1 s2 s1' s2' C1 C2 C1' C2' D1 D2 st Hk H1 H2 Vs D S H3 G;
    move=> W U V1 Hw Hu V s1' s2' s1 s2 D1 D2 C1' C2' C1 C2 st Hk H1 H2 Vs D S H3 G;
     rewrite (joinC W) in V C1' C2' st H1 S H3 G H2 Hk;
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
     rewrite -?(joinC s1) -?(joinC s2) in C1' C2' S G H3 Vs].
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  + have X: s1' = s2'.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
    - move: (C2'); rewrite (joinC U) G -[upd _ _ _ \+ s1'](joinC s1'). 
(* Goal: forall (_ : is_true (@PCM.valid (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)))) (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (getc (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : world_not_hooked U K), injects U (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) K *)
      move/cohUnKR/(_ D1)/(_ Hu)=>C1''.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
      move: (coh_prec (cohS C2') C2 C1'' G)=>Z; rewrite -Z in G; clear Z.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
      by rewrite (joinxK (cohS C2') G).
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
    split=>//; subst s2'; rewrite -!(joinC s1') in G C2'.
(* Goal: forall (_ : is_true (@PCM.valid (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)))) (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (getc (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : world_not_hooked U K), injects U (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) K *)
    rewrite (joinC U) in C2'; move: (joinxK (cohS C2') G)=>{G}G.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
    rewrite (joinC s1') in G.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
    have E: getProtocol U l = getProtocol (U \+ W) l.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
      by rewrite (getPUn V)// (cohD C1).
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
    have E': getStatelet s1 l = getStatelet (s1 \+ s1') l.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
      by rewrite (getSUn Vs). 
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
    rewrite /get_st /InMem in H1.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
    move: (getStatelet (s1 \+ s1') l) (E') H2 S H3 G=>_<- H2 S H3 G.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
    move: (getProtocol (U \+ W \+ (Unit, K)) l)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
     (get_protocol_hooks K l V) E st H1 S H2 H3 G Hk=>_-><- st H1 S H2 H3 G Hk.
    apply: (SendMsg H1 H2 D C1 _ H3 G).

    (* Now proving the obligation about all_hooks_fire *)
(* Goal: forall (_ : is_true (@PCM.valid (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)))) (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (getc (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : world_not_hooked U K), injects U (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) K *)
    move=>z lc hk F A1 A2.
(* Goal: hk (getLocal n (getStatelet (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') lc)) (getLocal n (getStatelet (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') l)) msg to *)
    apply sym_eq in F.
(* Goal: forall (_ : is_true (@PCM.valid (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)))) (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (getc (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : world_not_hooked U K), injects U (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) K *)
    move: (Hk z lc hk).
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
    rewrite -F -joinA !domUn !inE !Vs A1 A2 findUnL ?E' ?(find_some F)/=;
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
      last by case/andP:V1; rewrite-joinA =>_->.
(* Goal: forall (_ : is_true (@PCM.valid (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)))) (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (getc (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : world_not_hooked U K), injects U (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) K *)
    move/(_ erefl is_true_true is_true_true).
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
    by rewrite {1 3}/getStatelet findUnL// A1.

(* Goal: Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  have X: s1' = s2'.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  - move: (C2'); rewrite (joinC U) G. 
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
    move/cohUnKR/(_ D1)/(_ Hu)=>C1''; rewrite (joinC s1') in G.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
    move: (coh_prec (cohS C2') C2 C1'' G)=>Z; rewrite -Z in G; clear Z.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
    by rewrite (joinxK (cohS C2') G).
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  split=>//; subst s2'; rewrite -!(joinC s1') in G C2'.
(* Goal: forall (_ : is_true (@PCM.valid (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)))) (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (getc (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : world_not_hooked U K), injects U (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) K *)
  rewrite (joinC U) in C2'; move: (joinxK (cohS C2') G)=>{G}G.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  rewrite (joinC s1') in G.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  have E: getProtocol U l = getProtocol (U \+ W) l.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
    by rewrite (getPUn V)// (cohD C1).
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  have E': getStatelet s1 l = getStatelet (s1 \+ s1') l.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
    by rewrite (getSUn Vs). 
  rewrite /get_st /InMem in H1; rewrite (joinC s1') in H2.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
    move: (getStatelet (s1 \+ s1') l) (E') H2 S H3 G=>_<- H2 S H3 G.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
    move: (getProtocol (U \+ W \+ (Unit, K)) l)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
     (get_protocol_hooks K l V) E st H1 S H2 H3 G Hk=>_-><- st H1 S H2 H3 G Hk.
    apply: (SendMsg H1 H2 D C1 _ H3 G).

    (* Now proving the obligation about all_hooks_fire *)
(* Goal: forall (_ : is_true (@PCM.valid (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)))) (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (getc (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : world_not_hooked U K), injects U (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) K *)
    move=>z lc hk F A1 A2.
(* Goal: hk (getLocal n (getStatelet (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') lc)) (getLocal n (getStatelet (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') l)) msg to *)
    apply sym_eq in F.
(* Goal: forall (_ : is_true (@PCM.valid (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)))) (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (getc (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : world_not_hooked U K), injects U (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) K *)
    move: (Hk z lc hk).
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
    rewrite -F -joinA !domUn !inE A1 A2 findUnL ?E' ?(find_some F)/=;
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
      last by rewrite joinA (joinC U.2); case/andP:V1=>_->.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
    rewrite !(joinC s1') !Vs/= -!(orbC true).
(* Goal: forall (_ : is_true (@PCM.valid (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)))) (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (getc (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : world_not_hooked U K), injects U (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) K *)
    move/(_ erefl is_true_true is_true_true).
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
    by rewrite {1 3}/getStatelet findUnL// A1.
Qed.

(* The following two definitions are central for framing with respect
to the hooks. In essence. we can add more hooks via the frame rule, if
none of the protocols in the "core" world (i.e., the world, to which
we attach the frame with more hooks) are going to become constrained
by the newly added hooks.

In other words, the new hooks only constrain the world "to be
attached" but not our "core" world. *)

Definition not_hooked_by (K : hooks) l :=
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  forall z lc l' st, (z, lc, (l', st)) \in dom K -> l != l'.

Definition world_not_hooked (W: world) K :=
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  forall l, l \in dom W.1 -> not_hooked_by K l.

Lemma hooks_frame (U W : world) (K : hooks) l st s s' n msg to :
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  hook_complete U -> hook_complete W ->
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  hooks_consistent (U \+ W).1 K ->
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  l \in dom s -> s \In Coh U -> s \+ s' \In Coh (U \+ W \+ (Unit, K)) ->
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  not_hooked_by K l ->        
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  all_hooks_fire (geth U) l st s n msg to ->
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  all_hooks_fire (geth (U \+ W \+ (Unit, K))) l st (s \+ s') n msg to.
Proof.
(* Goal: forall (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (@fst (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label dstatelet (union_mapUMC Label dstatelet) s)))) (_ : @InMem (@UMC.sort Label dstatelet (union_mapUMC Label dstatelet)) s (@Mem state (PredPredType state) (Coh U))) (_ : @InMem (PCM.sort (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet))) (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) hooks (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : not_hooked_by K l) (_ : all_hooks_fire (geth U) l st s n msg to), all_hooks_fire (geth (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) hooks (@PCM.unit (union_mapPCM Label protocol)) K))) l st (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') n msg to *)
move=>G1 G2 G D' C1 C' N A z lc hk F D1 D2; move: F.
(* Goal: forall _ : @eq (option hook_type) (@Some hook_type hk) (@UMC.find (prod_ordType (prod_ordType nat_ordType Label) (prod_ordType Label nat_ordType)) hook_type (union_mapUMC (prod_ordType (prod_ordType nat_ordType Label) (prod_ordType Label nat_ordType)) hook_type) (@pair (prod (Ordered.sort nat_ordType) (Ordered.sort Label)) (prod (Ordered.sort Label) (Ordered.sort nat_ordType)) (@pair (Ordered.sort nat_ordType) (Ordered.sort Label) z lc) (@pair (Ordered.sort Label) (Ordered.sort nat_ordType) l st)) (geth (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) hooks (@PCM.unit (union_mapPCM Label protocol)) K)))), hk (getLocal n (getStatelet (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') lc)) (getLocal n (getStatelet (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') l)) msg to *)
case/andP: (cohW C')=>/=V1 V2.
(* Goal: forall (_ : is_true (@PCM.valid (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)))) (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (getc (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : world_not_hooked U K), injects U (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) K *)
move: (cohUnKR (coh_hooks C') C1 G2) => C2.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
rewrite findUnL ?V2//=; case: ifP=>D3; last first.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
- move => F; apply sym_eq in F; move: F.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
  by move/find_some/N/negP; rewrite eqxx. 
(* Goal: forall _ : @eq (option hook_type) (@Some hook_type hk) (@UMC.find (prod_ordType (prod_ordType nat_ordType Label) (prod_ordType Label nat_ordType)) hook_type (union_mapUMC (prod_ordType (prod_ordType nat_ordType Label) (prod_ordType Label nat_ordType)) hook_type) (@pair (prod nat nat) (prod nat nat) (@pair nat nat z lc) (@pair nat nat l st)) (@PCM.join (union_mapPCM hook_domain hook_type) (@snd (UMDef.tp Label protocol) (UMDef.tp hook_domain hook_type) U) (@snd (UMDef.tp Label protocol) (UMDef.tp hook_domain hook_type) W))), hk (getLocal n (getStatelet (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') lc)) (getLocal n (getStatelet (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') l)) msg to *)
rewrite findUnR ?(validL V2)//; case: ifP=>[D|_].
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
+ case/G2/andP: D=>_ D; rewrite (cohD C2) in D.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
  by case: validUn (cohS C')=>//_ _/(_ _ D'); rewrite D.
(* Goal: forall (_ : is_true (@PCM.valid (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)))) (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (getc (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : world_not_hooked U K), injects U (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) K *)
move => F.
(* Goal: hk (getLocal n (getStatelet (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') lc)) (getLocal n (getStatelet (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') l)) msg to *)
apply sym_eq in F.
(* Goal: Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
have D'': lc \in dom s by case/andP:(G1 _ _ _ _ (find_some F)); rewrite (cohD C1).
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
have E: getStatelet s l = getStatelet (s \+ s') l
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  by rewrite (getSUn (cohS C'))// -?(cohD C1').
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
have E': getStatelet s lc = getStatelet (s \+ s') lc.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  by rewrite (getSUn (cohS C'))// -?(cohD C1').
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
move: (getStatelet (s \+ s') l) (getStatelet (s \+ s') lc) E E'.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
by move=>y1 y2 Z1 Z2; subst y1 y2; apply sym_eq in F; apply: (A z).
Qed.

(********************************************************************)
(*                      Framing result                              *)
(********************************************************************)

Lemma inject_frame U W K this s1 s2 s:
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  s1 \+ s \In Coh (U \+ W \+ (Unit, K)) ->
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  network_step U this s1 s2 ->
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  hook_complete U -> hook_complete W ->
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  hooks_consistent (U \+ W).1 K ->
  (* State something about hook direction *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  world_not_hooked U K ->
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  network_step (U \+ W \+ (Unit, K)) this (s1 \+ s) (s2 \+ s).
Proof.
(* Goal: forall (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (@fst (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label dstatelet (union_mapUMC Label dstatelet) s)))) (_ : @InMem (@UMC.sort Label dstatelet (union_mapUMC Label dstatelet)) s (@Mem state (PredPredType state) (Coh U))) (_ : @InMem (PCM.sort (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet))) (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) hooks (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : not_hooked_by K l) (_ : all_hooks_fire (geth U) l st s n msg to), all_hooks_fire (geth (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) hooks (@PCM.unit (union_mapPCM Label protocol)) K))) l st (@PCM.join (@union_map_classPCM Label dstatelet (union_mapUMC Label dstatelet)) s s') n msg to *)
move=>C1 S Ku Kw Hk N; move/step_coh: (S)=>[C1' C2'].
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
case: S; first by move=>[_ <-]; apply: Idle. 

(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
(* Send-transition *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
- move=>l st H1 to msg h H2 H3 _ S A H4 G.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  have E: getProtocol U l = getProtocol (U \+ W \+ (Unit, K)) l.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  have Y: getProtocol U l = getProtocol (U \+ W) l.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
    + by rewrite (getPUn (validL (cohW C1)))// (cohD C1').
    rewrite Y; rewrite (getPUn (cohW C1))// domUn inE (cohD C1') H3/=.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
    by case/andP: (validL (cohW C1))=>->.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  have E': getStatelet s1 l = getStatelet (s1 \+ s) l.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
    by rewrite (getSUn (cohS C1))// -?(cohD C1').
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  have X: l \in dom (s1 \+ s) by rewrite domUn inE H3 (cohS C1).
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  move: (getProtocol U) (E) H2=>_ -> H2.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  rewrite /get_st /InMem/= in H1.
  rewrite E' in H2 G S H4; clear E'.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  move: (getProtocol U l) E st H1 S H4 G H2 A=>_->st H1 S H4 G H2 A.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  apply: (SendMsg H1 H2 X C1 _ H4 (s2 := s2 \+ s)); last first.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  - by rewrite updUnL H3; congr (_ \+ _).
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  by apply: hooks_frame=>//; apply: N; rewrite -(cohD C1') in H3.
 
    
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
(* Receive-transition *)
(* Goal: forall (_ : is_true (@PCM.valid (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)))) (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (getc (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : world_not_hooked U K), injects U (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) K *)
move=> l rt H1 msg from H2 H3 C tms G [G1 G2/= G3].
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
have E: getProtocol U l = getProtocol (U \+ W \+ (Unit, K)) l.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  have Y: getProtocol U l = getProtocol (U \+ W) l.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  - by rewrite (getPUn (validL (cohW C1)))// (cohD C1').
  rewrite Y; rewrite (getPUn (cohW C1))// domUn inE (cohD C1') H3/=.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  by case/andP: (validL (cohW C1))=>->.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
have E': getStatelet s1 l = getStatelet (s1 \+ s) l.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  by rewrite (getSUn (cohS C1))// -?(cohD C1').
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
have X: l \in dom (s1 \+ s) by rewrite domUn inE (cohS C1) H3.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
rewrite /get_rt /InMem /= in H1.
move: (getProtocol U l) (getStatelet s1 l) E E' C H2
      (coh_s l C) rt G3 G G2 H1 G1=>z1 z2 Z1 Z2.
(* Goal: Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
subst z1 z2=>C pf C' G3 G G2 H1 H2 G1.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
apply: (ReceiveMsg H2 X G2 (i := msg) (from := from) (s2 := s2 \+ s)).
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
split=>//=; first by rewrite (pf_irr (coh_s l C1) C').
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
rewrite updUnL H3; congr (_ \+ _); move: (NetworkSem.coh_s l C1)=>pf'. 
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
by rewrite (pf_irr pf' C').
Qed.


Lemma injectL (U W : world) K :
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  valid (U \+ W \+ (Unit, K)) ->
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  hook_complete U -> hook_complete W ->
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  hooks_consistent (getc (U \+ W)) K ->
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  world_not_hooked U K ->
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  injects U (U \+ W \+ (Unit, K)) K.
Proof.
(* Goal: forall (_ : is_true (@PCM.valid (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)))) (_ : hook_complete U) (_ : hook_complete W) (_ : hooks_consistent (getc (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W)) K) (_ : world_not_hooked U K), injects U (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) K *)
move=>H G1 G2 G N.
(* Goal: injects U (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) K *)
exists W=>//[s|s1 s2 s this|s1 s2 s1' s2' this]; [split | |].
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
- move/coh_hooks=>C; exists (projectS U s), (projectS W s).
  split; [by apply projectSE|by apply: (projectS_cohL C)|
          by apply: (projectS_cohR C)].
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
- case=>s1[s2][Z]C1 C2; subst s.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  have W1 : valid (s1 \+ s2).
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  + case: validUn; rewrite ?(cohS C1) ?(cohS C2)//.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
    move=>l; rewrite -(cohD C1)-(cohD C2).
    case/validL/andP: H=>H _;
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
    by case: validUn H=>//_ _/(_ l) G' _/G'; move/negbTE=>->.
(* Goal: Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  split=>//[||l].
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  + by apply: inj_hooks_complete.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  + move=>l; rewrite !domUn !inE !unitR dom0 orbC/=.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
    rewrite W1/= -(cohD C1)-(cohD C2) domUn !inE//=.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
    by move/validL/andP:H=>[->]_.
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  + rewrite (get_protocol_hooks K l (validL H)).
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
    rewrite /getProtocol/getStatelet !findUnL//; last by case/validL/andP:H.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
    by rewrite (cohD C1); case B: (l \in dom s1)=>//; apply: coh_coh.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
- by move=>C1 C2; apply: inject_frame. 
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
by move=>C1 C2; apply: (inject_step (validL H)).
Qed.


Lemma injectR (U W : world) K :
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  valid (W \+ U \+ (Unit, K)) ->
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  hook_complete U -> hook_complete W ->
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  hooks_consistent (getc (U \+ W)) K ->
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  world_not_hooked U K ->
(* Goal: @Coherence.sort (Protocols.nodes (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (coh (getProtocol (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) l)) (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) *)
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  injects U (W \+ U \+ (Unit, K)) K.
Proof. by rewrite (joinC W); apply: injectL. Qed.

Lemma locProjL (W1 W2 : world) l s1 s2:
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  (s1 \+ s2) \In Coh (W1 \+ W2) -> l \in dom W1.1 ->
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  s1 \In Coh W1 -> getStatelet (s1 \+ s2) l = getStatelet s1 l.
Proof.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W1))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s1 (@Mem state (PredPredType state) (Coh W1))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s1 l) *)
move=>C D C1; rewrite (cohD C1) in D.
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s2) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) W1 W2)))) (_ : is_true (@in_mem (Equality.sort (Ordered.eqType Label)) l (@mem (Equality.sort (Ordered.eqType Label)) (seq_predType (Ordered.eqType Label)) (@UMC.dom Label protocol (union_mapUMC Label protocol) (@fst context hooks W2))))) (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) s2 (@Mem state (PredPredType state) (Coh W2))), @eq dstatelet (getStatelet (@PCM.join (union_mapPCM Label dstatelet) s1 s2) l) (getStatelet s2 l) *)
by rewrite (getSUn (cohS C) D).
Qed.

Lemma locProjR (W1 W2 : world) l s1 s2:
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  (s1 \+ s2) \In Coh (W1 \+ W2) -> l \in dom W2.1 ->
(* Goal: forall (_ : @InMem (PCM.sort (union_mapPCM Label dstatelet)) (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@Mem state (PredPredType state) (Coh (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K))))) (_ : network_step U this s1 s2), network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s) (@PCM.join (union_mapPCM Label dstatelet) s2 s) *)
(* Goal: forall (_ : @InMem state s1 (@Mem state (PredPredType state) (Coh U))) (_ : @InMem state s2 (@Mem state (PredPredType state) (Coh U))) (_ : network_step (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) (@PCM.join (prodPCM (union_mapPCM Label protocol) (union_mapPCM hook_domain hook_type)) U W) (@pair (PCM.sort (union_mapPCM Label protocol)) (PCM.sort (union_mapPCM hook_domain hook_type)) (@PCM.unit (union_mapPCM Label protocol)) K)) this (@PCM.join (union_mapPCM Label dstatelet) s1 s1') (@PCM.join (union_mapPCM Label dstatelet) s2 s2')), or (and (network_step U this s1 s2) (@eq (PCM.sort (union_mapPCM Label dstatelet)) s1' s2')) (and (network_step W this s1' s2') (@eq state s1 s2)) *)
  s2 \In Coh W2 -> getStatelet (s1 \+ s2) l = getStatelet s2 l.
Proof. by rewrite !(joinC W1) !(joinC s1); apply: locProjL. Qed.

End InjectExtra.

Export InjectExtra.
