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).