Definition Inv_free
           {resource state: Type}
           (r: resource)
           (Inv: list (resource * (state -> Prop))): Prop :=
  fold_right or True (map (fun ri => fst ri = r) Inv).Inductive Inv_cons {resource state: Type} (r: resource) (I: state -> Prop):
  list (resource * (state -> Prop)) ->
  list (resource * (state -> Prop)) ->
  Prop :=
| Inv_cons_spec: forall Inv1 Inv2,
   Inv_free r Inv1 ->
   Inv_free r Inv2 ->
   Inv_cons r I (Inv1 ++ Inv2) (Inv1 ++ (r, I) :: Inv2).Inductive Inv_cons {resource state: Type} (r: resource) (I: state -> Prop):
  list (resource * (state -> Prop)) ->
  list (resource * (state -> Prop)) ->
  Prop :=
| Inv_cons_spec: forall Inv1 Inv2,
   Inv_free r Inv1 ->
   Inv_free r Inv2 ->
   Inv_cons r I (Inv1 ++ Inv2) (Inv1 ++ (r, I) :: Inv2).Record split_hint {state: Type} {J: Join state} (s: state) : Type := {
  split_piece1: state;
  split_piece2: state;
  split_sound: join split_piece1 split_piece2 s
}.Record split_hint {state: Type} {J: Join state} (s: state) : Type := {
  split_piece1: state;
  split_piece2: state;
  split_sound: join split_piece1 split_piece2 s
}.Record split_hint {state: Type} {J: Join state} (s: state) : Type := {
  split_piece1: state;
  split_piece2: state;
  split_sound: join split_piece1 split_piece2 s
}.Record split_hint {state: Type} {J: Join state} (s: state) : Type := {
  split_piece1: state;
  split_piece2: state;
  split_sound: join split_piece1 split_piece2 s
}.Class Resource_BigStepSemantics
      (P: ProgrammingLanguage)
      {Res: Resource}
      {CPP: ConcurrentProgrammingLanguage_Sparallel P}
      {CPR: ConcurrentProgrammingLanguage_Sresource P Res}
      (state: Type)
      {J: Join state}
      {R: Relation state}
      {po_R: PreOrder Krelation}
      (TLBSS: ThreadLocalBigStepSemantics P state
                (list (resource * (state -> Prop)))): Type :=
{
  hint_Sparallel: forall Inv c1 c2,
    (forall (s: state), split_hint s -> Prop) ->
    hint Inv c1 ->
    hint Inv c2 ->
    hint Inv (Sparallel c1 c2);
  hint_Sresource: forall Inv Inv' I r c,
    Inv_cons r I Inv Inv' ->
    hint Inv c ->
    hint Inv' (Sresource r c);
  access_Sparallel:
    forall Inv
      c1 c2 hs h1 h2 (m: state) (n: MetaState state),
    tl_access Inv m (existT _ _ (hint_Sparallel Inv c1 c2 hs h1 h2)) n ->
    exists (m1 m2: state) H (n1' n2' n1 n2: MetaState state),
    hs m (Build_split_hint _ _ m m1 m2 H) /\
    tl_access Inv m1 (existT _ c1 h1) n1' /\
    tl_access Inv m2 (existT _ c2 h2) n2' /\
    forward n1' n1 /\
    forward n2' n2 /\
    strong_lift_join n1 n2 n;
  access_Sresource:
    forall (I: state -> Prop) Inv Inv' (r: resource) c (h: hint Inv c) m n
      (H_Inv: Inv_cons r I Inv Inv'),
    tl_access Inv' m (existT _ _ (hint_Sresource _ _ _ _ _ H_Inv h)) n ->
    exists m_acq m' n1 n2 n3,
    join m_acq m m' /\
    forward (Terminating m') n1 /\
    lift_tl_access Inv n1 (existT _ c h) n2 /\
    forward n2 n3 /\
    match n3, n with
    | Terminating nn3, Terminating nn => greatest_cut nn3 I nn
    | NonTerminating, NonTerminating => True
    | Error, Error => True
    | _, _ => False
    end /\
    I m_acq
}.Class Resource_BigStepSemantics
      (P: ProgrammingLanguage)
      {Res: Resource}
      {CPP: ConcurrentProgrammingLanguage_Sparallel P}
      {CPR: ConcurrentProgrammingLanguage_Sresource P Res}
      (state: Type)
      {J: Join state}
      {R: Relation state}
      {po_R: PreOrder Krelation}
      (TLBSS: ThreadLocalBigStepSemantics P state
                (list (resource * (state -> Prop)))): Type :=
{
  hint_Sparallel: forall Inv c1 c2,
    (forall (s: state), split_hint s -> Prop) ->
    hint Inv c1 ->
    hint Inv c2 ->
    hint Inv (Sparallel c1 c2);
  hint_Sresource: forall Inv Inv' I r c,
    Inv_cons r I Inv Inv' ->
    hint Inv c ->
    hint Inv' (Sresource r c);
  access_Sparallel:
    forall Inv
      c1 c2 hs h1 h2 (m: state) (n: MetaState state),
    tl_access Inv m (existT _ _ (hint_Sparallel Inv c1 c2 hs h1 h2)) n ->
    exists (m1 m2: state) H (n1' n2' n1 n2: MetaState state),
    hs m (Build_split_hint _ _ m m1 m2 H) /\
    tl_access Inv m1 (existT _ c1 h1) n1' /\
    tl_access Inv m2 (existT _ c2 h2) n2' /\
    forward n1' n1 /\
    forward n2' n2 /\
    strong_lift_join n1 n2 n;
  access_Sresource:
    forall (I: state -> Prop) Inv Inv' (r: resource) c (h: hint Inv c) m n
      (H_Inv: Inv_cons r I Inv Inv'),
    tl_access Inv' m (existT _ _ (hint_Sresource _ _ _ _ _ H_Inv h)) n ->
    exists m_acq m' n1 n2 n3,
    join m_acq m m' /\
    forward (Terminating m') n1 /\
    lift_tl_access Inv n1 (existT _ c h) n2 /\
    forward n2 n3 /\
    match n3, n with
    | Terminating nn3, Terminating nn => greatest_cut nn3 I nn
    | NonTerminating, NonTerminating => True
    | Error, Error => True
    | _, _ => False
    end /\
    I m_acq
}.Class Resource_BigStepSemantics
      (P: ProgrammingLanguage)
      {Res: Resource}
      {CPP: ConcurrentProgrammingLanguage_Sparallel P}
      {CPR: ConcurrentProgrammingLanguage_Sresource P Res}
      (state: Type)
      {J: Join state}
      {R: Relation state}
      {po_R: PreOrder Krelation}
      (TLBSS: ThreadLocalBigStepSemantics P state
                (list (resource * (state -> Prop)))): Type :=
{
  hint_Sparallel: forall Inv c1 c2,
    (forall (s: state), split_hint s -> Prop) ->
    hint Inv c1 ->
    hint Inv c2 ->
    hint Inv (Sparallel c1 c2);
  hint_Sresource: forall Inv Inv' I r c,
    Inv_cons r I Inv Inv' ->
    hint Inv c ->
    hint Inv' (Sresource r c);
  access_Sparallel:
    forall Inv
      c1 c2 hs h1 h2 (m: state) (n: MetaState state),
    tl_access Inv m (existT _ _ (hint_Sparallel Inv c1 c2 hs h1 h2)) n ->
    exists (m1 m2: state) H (n1' n2' n1 n2: MetaState state),
    hs m (Build_split_hint _ _ m m1 m2 H) /\
    tl_access Inv m1 (existT _ c1 h1) n1' /\
    tl_access Inv m2 (existT _ c2 h2) n2' /\
    forward n1' n1 /\
    forward n2' n2 /\
    strong_lift_join n1 n2 n;
  access_Sresource:
    forall (I: state -> Prop) Inv Inv' (r: resource) c (h: hint Inv c) m n
      (H_Inv: Inv_cons r I Inv Inv'),
    tl_access Inv' m (existT _ _ (hint_Sresource _ _ _ _ _ H_Inv h)) n ->
    exists m_acq m' n1 n2 n3,
    join m_acq m m' /\
    forward (Terminating m') n1 /\
    lift_tl_access Inv n1 (existT _ c h) n2 /\
    forward n2 n3 /\
    match n3, n with
    | Terminating nn3, Terminating nn => greatest_cut nn3 I nn
    | NonTerminating, NonTerminating => True
    | Error, Error => True
    | _, _ => False
    end /\
    I m_acq
}.Class Resource_BigStepSemantics
      (P: ProgrammingLanguage)
      {Res: Resource}
      {CPP: ConcurrentProgrammingLanguage_Sparallel P}
      {CPR: ConcurrentProgrammingLanguage_Sresource P Res}
      (state: Type)
      {J: Join state}
      {R: Relation state}
      {po_R: PreOrder Krelation}
      (TLBSS: ThreadLocalBigStepSemantics P state
                (list (resource * (state -> Prop)))): Type :=
{
  hint_Sparallel: forall Inv c1 c2,
    (forall (s: state), split_hint s -> Prop) ->
    hint Inv c1 ->
    hint Inv c2 ->
    hint Inv (Sparallel c1 c2);
  hint_Sresource: forall Inv Inv' I r c,
    Inv_cons r I Inv Inv' ->
    hint Inv c ->
    hint Inv' (Sresource r c);
  access_Sparallel:
    forall Inv
      c1 c2 hs h1 h2 (m: state) (n: MetaState state),
    tl_access Inv m (existT _ _ (hint_Sparallel Inv c1 c2 hs h1 h2)) n ->
    exists (m1 m2: state) H (n1' n2' n1 n2: MetaState state),
    hs m (Build_split_hint _ _ m m1 m2 H) /\
    tl_access Inv m1 (existT _ c1 h1) n1' /\
    tl_access Inv m2 (existT _ c2 h2) n2' /\
    forward n1' n1 /\
    forward n2' n2 /\
    strong_lift_join n1 n2 n;
  access_Sresource:
    forall (I: state -> Prop) Inv Inv' (r: resource) c (h: hint Inv c) m n
      (H_Inv: Inv_cons r I Inv Inv'),
    tl_access Inv' m (existT _ _ (hint_Sresource _ _ _ _ _ H_Inv h)) n ->
    exists m_acq m' n1 n2 n3,
    join m_acq m m' /\
    forward (Terminating m') n1 /\
    lift_tl_access Inv n1 (existT _ c h) n2 /\
    forward n2 n3 /\
    match n3, n with
    | Terminating nn3, Terminating nn => greatest_cut nn3 I nn
    | NonTerminating, NonTerminating => True
    | Error, Error => True
    | _, _ => False
    end /\
    I m_acq
}.Class Resource_BigStepSemantics
      (P: ProgrammingLanguage)
      {Res: Resource}
      {CPP: ConcurrentProgrammingLanguage_Sparallel P}
      {CPR: ConcurrentProgrammingLanguage_Sresource P Res}
      (state: Type)
      {J: Join state}
      {R: Relation state}
      {po_R: PreOrder Krelation}
      (TLBSS: ThreadLocalBigStepSemantics P state
                (list (resource * (state -> Prop)))): Type :=
{
  hint_Sparallel: forall Inv c1 c2,
    (forall (s: state), split_hint s -> Prop) ->
    hint Inv c1 ->
    hint Inv c2 ->
    hint Inv (Sparallel c1 c2);
  hint_Sresource: forall Inv Inv' I r c,
    Inv_cons r I Inv Inv' ->
    hint Inv c ->
    hint Inv' (Sresource r c);
  access_Sparallel:
    forall Inv
      c1 c2 hs h1 h2 (m: state) (n: MetaState state),
    tl_access Inv m (existT _ _ (hint_Sparallel Inv c1 c2 hs h1 h2)) n ->
    exists (m1 m2: state) H (n1' n2' n1 n2: MetaState state),
    hs m (Build_split_hint _ _ m m1 m2 H) /\
    tl_access Inv m1 (existT _ c1 h1) n1' /\
    tl_access Inv m2 (existT _ c2 h2) n2' /\
    forward n1' n1 /\
    forward n2' n2 /\
    strong_lift_join n1 n2 n;
  access_Sresource:
    forall (I: state -> Prop) Inv Inv' (r: resource) c (h: hint Inv c) m n
      (H_Inv: Inv_cons r I Inv Inv'),
    tl_access Inv' m (existT _ _ (hint_Sresource _ _ _ _ _ H_Inv h)) n ->
    exists m_acq m' n1 n2 n3,
    join m_acq m m' /\
    forward (Terminating m') n1 /\
    lift_tl_access Inv n1 (existT _ c h) n2 /\
    forward n2 n3 /\
    match n3, n with
    | Terminating nn3, Terminating nn => greatest_cut nn3 I nn
    | NonTerminating, NonTerminating => True
    | Error, Error => True
    | _, _ => False
    end /\
    I m_acq
}.Module Partial := Resource_BigStepSemantics (ProgramState.Partial).Module Total := Resource_BigStepSemantics (ProgramState.Total).

Lemma hoare_parallel_partial_sound: forall (Inv: list (resource * (model -> Prop))) c1 c2 P1 P2 Q1 Q2, guarded_triple_partial_valid Inv P1 c1 Q1 -> guarded_triple_partial_valid Inv P2 c2 Q2 -> guarded_triple_partial_valid Inv (P1 * P2) (Sparallel c1 c2) (Q1 * Q2).