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