Ltac common_contradictions:=
match goal with
| [H: Share.glb _ _ = Share.top |- _ ] =>
exfalso;
eapply shares.glb_Rsh_not_top; eassumption
| [ H: Share.bot = Share.top |- _ ] => exfalso; apply Share.nontrivial; symmetry; assumption
| [ H: Share.top = Share.bot |- _ ] => exfalso; apply Share.nontrivial; assumption
| [ H: ~ shares.readable_share Share.top |- _ ] => pose proof shares.readable_share_top; contradiction
| [ H: ~ shares.writable0_share Share.top |- _ ] => pose proof writable0_share_top; contradiction
| [ H: shares.readable_share Share.bot |- _ ] => pose proof shares.bot_unreadable; contradiction
| [ H: shares.writable0_share Share.bot |- _ ] => apply shares.writable0_readable in H; pose proof shares.bot_unreadable; contradiction
| [ H: shares.writable0_share ?sh, H0: ~ shares.readable_share ?sh   |- _ ] =>
exfalso; apply H0; eapply shares.writable0_readable; assumption
| _ => contradiction
end.
Ltac join_share_contradictions_oneside:=
match goal with
| [ H: @join Share.t _ Share.top _ _ |- _ ] =>
pose proof (join_top_l H); first [common_contradictions | subst]
| [ H: @join Share.t _ Share.bot _ _ |- _ ] =>
pose proof (join_with_bot_l _ _ H); first [common_contradictions | subst]
| [ H: @join Share.t _ _ _ Share.bot |- _ ] =>
pose proof (join_to_bot_l H); pose proof (join_to_bot_r H);
first [common_contradictions | subst]
| [ H1: ~ shares.readable_share ?sh1,
H2: ~ shares.readable_share ?sh2,
H: join ?sh1 ?sh2 _ |- _ ] =>
pose proof (shares.join_unreadable_shares H H1 H2);
first [common_contradictions | subst]
| [ H1: ~ shares.writable0_share ?sh1,
H2: ~ shares.readable_share ?sh2,
H: join ?sh1 ?sh2 _ |- _ ] =>
pose proof (join_readable_unreadable _ _ _ H H1 H2);
first [common_contradictions | subst]
| [ H1: shares.writable0_share ?sh1,
H2: shares.writable0_share ?sh2,
H: join ?sh1 ?sh2 _ |- _ ] =>
exfalso; eapply shares.join_writable0_readable;
try eapply shares.writable0_readable; eassumption
| [ H1: shares.writable0_share ?sh1,
H: join ?sh1 _ _ |- _ ] =>
pose proof (shares.join_writable01 H H1);
first [common_contradictions | subst]
| [ H1: shares.readable_share ?sh1,
H: join ?sh1 ?sh2 _ |- _ ] =>
pose proof (shares.join_readable1 H H1);
common_contradictions
end.
Ltac join_share_contradictions:=
try join_share_contradictions_oneside;
match goal with
| [ H: @join Share.t _ _ _ _ |- _ ] =>
apply join_comm in H; join_share_contradictions_oneside
end; try contradiction.

Lemma join_permjoin r1 r2 r3 :
join r1 r2 r3 ->
permjoin (perm_of_res r1) (perm_of_res r2) (perm_of_res r3).