(* Lemma join_sh_permDisjoint: forall rsh1 rsh2 rsh3 (sh1 sh2 sh3: pshare),
      join rsh1 rsh2 rsh3 ->
      join sh1 sh2 sh3 ->
      permDisjoint (perm_of_sh (Share.glb Share.Rsh sh1))) (perm_of_sh (Share.glb Share.Rsh sh1))).
  Proof.
    intros rsh1 rsh2 rsh3 sh1 sh2 sh3.
    intros H1.
    intros H2.
    move: (perm_of_sh_pshare rsh1 sh1) (perm_of_sh_pshare rsh2 sh2) =>
    [] p1 HH1 [] p2 HH2.
    rewrite HH1 HH2 /permDisjoint /=.
    destruct p1.
    - apply perm_of_sh_Freeable_top in HH1; inversion HH1; subst.
      destruct sh1.
      unfold join, Join_pshare, Join_lift in H2.
      simpl in H2.
      simpl in H3; subst x.
      apply pshare_join_full_false4 in H2.
      exfalso; assumption.
    - move: HH1.
      unfold perm_of_sh.
      repeat if_tac; try solve[intros HH; inversion HH].
      destruct sh1.
      unfold join, Join_pshare, Join_lift in H2.
      simpl in H2.
      simpl in H; subst x.
      apply pshare_join_full_false4 in H2.
      exfalso; assumption.
    - move: HH1.
      unfold perm_of_sh.
      repeat if_tac; try solve[intros HH; inversion HH].
      destruct p2; try solve[eexists; reflexivity].
      + apply perm_of_sh_Freeable_top in HH2; inversion HH2; subst.
        destruct sh2.
        unfold join, Join_pshare, Join_lift in H2.
        simpl in H2.
        simpl in H5; subst x.
        apply pshare_join_full_false3 in H2.
        exfalso; assumption.
      + move: HH2.
        unfold perm_of_sh.
        repeat if_tac; try solve[intros HH; inversion HH].
        destruct sh2.
        unfold join, Join_pshare, Join_lift in H2.
        simpl in H2.
        simpl in H3; subst x.
        apply pshare_join_full_false3 in H2.
        exfalso; assumption.
    - destruct p2; try solve[eexists; reflexivity].
      apply perm_of_sh_Freeable_top in HH2; inversion HH2; subst.
      destruct sh2.
      unfold join, Join_pshare, Join_lift in H2.
      simpl in H2.
      simpl in H3; subst x.
      apply pshare_join_full_false3 in H2.
      exfalso; assumption.
  Qed.
   *)
  (*The new version of the above*)
  Ltac if_simpl:=
    repeat match goal with
           | [ H: ?X = true |- context[if ?X then _ else _] ] => rewrite H; simpl 
           | [ H: ?X = false |- context[if ?X then _ else _] ] => rewrite H; simpl 
           | [ H: ?X = left _ |- context[match ?X with left _ => _ | right _ => _ end] ]=>
             rewrite H; simpl 
           | [ H: ?X = right _ |- context[match ?X with left _ => _ | right _ => _ end] ]=>
             rewrite H; simpl 
           | [ H: (@is_left _ _ ?X) = true |-
               context [match ?X with left _ => _ | right _ => _ end ]] => destruct X; inversion H
           | [ H: (@is_left _ _ ?X) = false |-
               context [match ?X with left _ => _ | right _ => _ end ]] => destruct X; inversion H
           end.Ltac permDisj_solve:= eexists; simpl; reflexivity.

(* Specifications: *)
Lemma join_sh_permDisjoint: forall sh1 sh2, joins sh1 sh2 -> permDisjoint (perm_of_sh sh1) (perm_of_sh sh2).
Lemma writable0_not_join_readable: forall sh1 sh2, joins sh1 sh2 -> writable0_share sh1 -> ~ readable_share sh2.
Lemma writable0_not_join_writable0 : forall sh1 sh2, joins sh1 sh2 -> writable0_share sh1 -> ~ writable0_share sh2.