(* Some None represents the empty permission. None is used for
  permissions that conflict/race. *)

  Definition perm_union (p1 p2 : option permission) : option (option permission) :=
    match p1,p2 with
      | None, _ => Some p2
      | _, None => Some p1
      | Some p1', Some p2' =>
        match p1', p2' with
          | Freeable, _ => None
          | _, Freeable => None
          | Nonempty, _ => Some p2
          | _, Nonempty => Some p1
          | Writable, _ => None
          | _, Writable => None
          | Readable, Readable => Some (Some Readable)
        end
    end.

(* Specifications: *)
Lemma perm_union_comm : forall p1 p2, perm_union p1 p2 = perm_union p2 p1.
Lemma perm_union_result : forall p1 p2 pu (Hunion: perm_union p1 p2 = Some pu), pu = p1 \/ pu = p2.
Lemma perm_union_ord : forall p1 p2 pu (Hunion: perm_union p1 p2 = Some pu), Mem.perm_order'' pu p1 /\ Mem.perm_order'' pu p2.
Lemma perm_union_lower: forall p1 p2 p3 (Hpu: exists pu, perm_union p1 p2 = Some pu) (Hperm: Mem.perm_order'' p2 p3), exists pu, perm_union p1 p3 = Some pu.
Lemma perm_union_lower_2: forall p1 p2 p3 p4 (Hpu: exists pu, perm_union p1 p2 = Some pu) (Hperm: Mem.perm_order'' p1 p3) (Hperm': Mem.perm_order'' p2 p4), exists pu, perm_union p3 p4 = Some pu.