(** Least upper bound *)

Definition combine_ablock (ob1 ob2: option ablock) : option ablock :=
  match ob1, ob2 with
  | Some b1, Some b2 => Some (blub b1 b2)
  | _, _ => None
  end.Definition mlub (m1 m2: amem) : amem :=
{| am_stack := blub m1.(am_stack) m2.(am_stack);
   am_glob  := PTree.combine combine_ablock m1.(am_glob) m2.(am_glob);
   am_nonstack := plub m1.(am_nonstack) m2.(am_nonstack);
   am_top := plub m1.(am_top) m2.(am_top) |}.

(* Specifications: *)
Lemma mmatch_lub_l: forall m x y, mmatch m x -> mmatch m (mlub x y).
Lemma mmatch_lub_r: forall m x y, mmatch m y -> mmatch m (mlub x y).
Lemma genv_match_exten: forall ge (bc1 bc2: block_classification), genv_match bc1 ge -> (forall b id, bc1 b = BCglob id <-> bc2 b = BCglob id) -> (forall b, bc1 b = BCother -> bc2 b = BCother) -> genv_match bc2 ge.
Lemma romatch_exten: forall (bc1 bc2: block_classification) m rm, romatch bc1 m rm -> (forall b id, bc2 b = BCglob id <-> bc1 b = BCglob id) -> romatch bc2 m rm.