Inductive permjoin : option permission -> option permission -> option permission -> Prop :=
| permjoin_None_l x : permjoin None x x
| permjoin_None_r x : permjoin x None x
(* NE + NE = NE *)
| permjoin_NNN : permjoin (Some Nonempty) (Some Nonempty) (Some Nonempty)
(* NE + R = R *)
| permjoin_NRR : permjoin (Some Nonempty) (Some Readable) (Some Readable)
| permjoin_RNR : permjoin (Some Readable) (Some Nonempty) (Some Readable)
(* NE + W = W or F *)
| permjoin_NWW : permjoin (Some Nonempty) (Some Writable) (Some Writable)
| permjoin_NWF : permjoin (Some Nonempty) (Some Writable) (Some Freeable)
| permjoin_WNW : permjoin (Some Writable) (Some Nonempty) (Some Writable)
| permjoin_WNF : permjoin (Some Writable) (Some Nonempty) (Some Freeable)
(* R + R = R or W or F *)
| permjoin_RRR : permjoin (Some Readable) (Some Readable) (Some Readable)
| permjoin_RRW : permjoin (Some Readable) (Some Readable) (Some Writable)
| permjoin_RRF : permjoin (Some Readable) (Some Readable) (Some Freeable)
(* R + W = W or F *)
| permjoin_RWW : permjoin (Some Readable) (Some Writable) (Some Writable)
| permjoin_WRW : permjoin (Some Writable) (Some Readable) (Some Writable)
| permjoin_RWF : permjoin (Some Readable) (Some Writable) (Some Freeable)
| permjoin_WRF : permjoin (Some Writable) (Some Readable) (Some Freeable).

(* Specifications: *)
Lemma permjoin_comm:
forall p1 p2 p3,
permjoin p1 p2 p3 <-> permjoin p2 p1 p3.
Lemma permjoin_readable_if:
forall p1 p2 p3
(Hjoin: permjoin p1 p2 p3)
(Hp1: Mem.perm_order' p1 Readable),
Mem.perm_order' p3 Readable.
Lemma permjoin_readable_iff:
forall p1 p2 p3
(Hjoin: permjoin p1 p2 p3),
Mem.perm_order' p3 Readable <-> Mem.perm_order' p1 Readable \/ Mem.perm_order' p2 Readable.
Lemma permjoin_order:
forall p1 p2 p3
(Hjoin: permjoin p1 p2 p3),
Mem.perm_order'' p3 p1 /\ Mem.perm_order'' p3 p2.