intros a b c H1 H2.
destruct a, b; try solve[inversion H2];
try solve[exists c; reflexivity].
simpl in H2.
destruct H1 as [k H1].
inversion H2; subst.
- exists k; assumption.
- destruct c; inversion H1.
exists (Some p0); reflexivity.
- destruct c; inversion H1.
destruct p; inversion H0.
exists (Some Readable); reflexivity.
- exists (Some Readable); reflexivity.
- destruct c; inversion H1;
try solve[exists (Some Nonempty); reflexivity].
destruct p; inversion H0; try(destruct p0; inversion H3);
try solve[exists (Some Nonempty); reflexivity];
try solve[exists (Some Readable); reflexivity];
try solve[exists (Some Writable); reflexivity].
Qed.
(* 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))). *)
(*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.