Definition list_disjoint {A: Type} (l1 l2: list A) : Prop :=   (* THIS IS FROM compcert/Coqlib.v *)
  forall (x y: A), In x l1 -> In y l2 -> x <> y.Inductive pshareval_join' {A}{JA: Join A}
  : option (pshare * A) ->  option (pshare * A) ->  option (pshare * A) -> Prop :=
  | pshareval_None1: forall x, pshareval_join' None x x
  | pshareval_None2: forall x, pshareval_join' x None x
  | pshareval_Some: forall x y z,
      join (fst x) (fst y) (fst z) ->
      join (snd x) (snd y) (snd z) ->
      pshareval_join' (Some x) (Some y) (Some z).Inductive pshareval_join' {A}{JA: Join A}
  : option (pshare * A) ->  option (pshare * A) ->  option (pshare * A) -> Prop :=
  | pshareval_None1: forall x, pshareval_join' None x x
  | pshareval_None2: forall x, pshareval_join' x None x
  | pshareval_Some: forall x y z,
      join (fst x) (fst y) (fst z) ->
      join (snd x) (snd y) (snd z) ->
      pshareval_join' (Some x) (Some y) (Some z).Inductive pshareval_join' {A}{JA: Join A}
  : option (pshare * A) ->  option (pshare * A) ->  option (pshare * A) -> Prop :=
  | pshareval_None1: forall x, pshareval_join' None x x
  | pshareval_None2: forall x, pshareval_join' x None x
  | pshareval_Some: forall x y z,
      join (fst x) (fst y) (fst z) ->
      join (snd x) (snd y) (snd z) ->
      pshareval_join' (Some x) (Some y) (Some z).Inductive pshareval_join' {A}{JA: Join A}
  : option (pshare * A) ->  option (pshare * A) ->  option (pshare * A) -> Prop :=
  | pshareval_None1: forall x, pshareval_join' None x x
  | pshareval_None2: forall x, pshareval_join' x None x
  | pshareval_Some: forall x y z,
      join (fst x) (fst y) (fst z) ->
      join (snd x) (snd y) (snd z) ->
      pshareval_join' (Some x) (Some y) (Some z).

(* Specifications: *)
Lemma pshareval_join_e{A}{JA: Join A}: forall a b c, join a b c -> pshareval_join' a b c.
Lemma pshareval_join_i{A}{JA: Join A}: forall a b c, pshareval_join' a b c -> join a b c.