Definition plub (p q: aptr) : aptr :=
  match p, q with
  | Pbot, _ => q
  | _, Pbot => p
  | Gl id1 ofs1, Gl id2 ofs2 =>
      if ident_eq id1 id2 then if Ptrofs.eq_dec ofs1 ofs2 then p else Glo id1 else Glob
  | Gl id1 ofs1, Glo id2 =>
      if ident_eq id1 id2 then q else Glob
  | Glo id1, Gl id2 ofs2 =>
      if ident_eq id1 id2 then p else Glob
  | Glo id1, Glo id2 =>
      if ident_eq id1 id2 then p else Glob
  | (Gl _ _ | Glo _ | Glob), Glob => Glob
  | Glob, (Gl _ _ | Glo _) => Glob
  | (Gl _ _ | Glo _ | Glob | Nonstack), Nonstack =>
      Nonstack
  | Nonstack, (Gl _ _ | Glo _ | Glob) =>
      Nonstack
  | Stk ofs1, Stk ofs2 =>
      if Ptrofs.eq_dec ofs1 ofs2 then p else Stack
  | (Stk _ | Stack), Stack =>
      Stack
  | Stack, Stk _ =>
      Stack
  | _, _ => Ptop
  end.

(* Specifications: *)
Lemma plub_comm: forall p q, plub p q = plub q p.
Lemma pge_lub_l: forall p q, pge (plub p q) p.
Lemma pge_lub_r: forall p q, pge (plub p q) q.
Lemma pmatch_lub_l: forall b ofs p q, pmatch b ofs p -> pmatch b ofs (plub p q).
Lemma pmatch_lub_r: forall b ofs p q, pmatch b ofs q -> pmatch b ofs (plub p q).
Lemma plub_least: forall r p q, pge r p -> pge r q -> pge r (plub p q).