Definition valid (m: address -> resource) : Prop :=
    AV.valid (res_option oo m).Inductive res_join : resource -> resource -> resource -> Prop :=
   | res_join_NO1 : res_join NO NO NO
   | res_join_NO2 : forall sh k p, res_join (YES sh k p) NO (YES sh k p)
   | res_join_NO3 : forall sh k p, res_join NO (YES sh k p) (YES sh k p)
   | res_join_YES : forall (sh1 sh2 sh3:pshare) k p,
        join sh1 sh2 sh3 ->
        res_join (YES sh1 k p) (YES sh2 k p) (YES sh3 k p)
   | res_join_PURE : forall k p, res_join (PURE k p) (PURE k p) (PURE k p).Inductive res_join : resource -> resource -> resource -> Prop :=
   | res_join_NO1 : res_join NO NO NO
   | res_join_NO2 : forall sh k p, res_join (YES sh k p) NO (YES sh k p)
   | res_join_NO3 : forall sh k p, res_join NO (YES sh k p) (YES sh k p)
   | res_join_YES : forall (sh1 sh2 sh3:pshare) k p,
        join sh1 sh2 sh3 ->
        res_join (YES sh1 k p) (YES sh2 k p) (YES sh3 k p)
   | res_join_PURE : forall k p, res_join (PURE k p) (PURE k p) (PURE k p).Inductive res_join : resource -> resource -> resource -> Prop :=
   | res_join_NO1 : res_join NO NO NO
   | res_join_NO2 : forall sh k p, res_join (YES sh k p) NO (YES sh k p)
   | res_join_NO3 : forall sh k p, res_join NO (YES sh k p) (YES sh k p)
   | res_join_YES : forall (sh1 sh2 sh3:pshare) k p,
        join sh1 sh2 sh3 ->
        res_join (YES sh1 k p) (YES sh2 k p) (YES sh3 k p)
   | res_join_PURE : forall k p, res_join (PURE k p) (PURE k p) (PURE k p).Inductive res_join : resource -> resource -> resource -> Prop :=
   | res_join_NO1 : res_join NO NO NO
   | res_join_NO2 : forall sh k p, res_join (YES sh k p) NO (YES sh k p)
   | res_join_NO3 : forall sh k p, res_join NO (YES sh k p) (YES sh k p)
   | res_join_YES : forall (sh1 sh2 sh3:pshare) k p,
        join sh1 sh2 sh3 ->
        res_join (YES sh1 k p) (YES sh2 k p) (YES sh3 k p)
   | res_join_PURE : forall k p, res_join (PURE k p) (PURE k p) (PURE k p).Inductive res_join : resource -> resource -> resource -> Prop :=
   | res_join_NO1 : res_join NO NO NO
   | res_join_NO2 : forall sh k p, res_join (YES sh k p) NO (YES sh k p)
   | res_join_NO3 : forall sh k p, res_join NO (YES sh k p) (YES sh k p)
   | res_join_YES : forall (sh1 sh2 sh3:pshare) k p,
        join sh1 sh2 sh3 ->
        res_join (YES sh1 k p) (YES sh2 k p) (YES sh3 k p)
   | res_join_PURE : forall k p, res_join (PURE k p) (PURE k p) (PURE k p).Inductive res_join : resource -> resource -> resource -> Prop :=
   | res_join_NO1 : res_join NO NO NO
   | res_join_NO2 : forall sh k p, res_join (YES sh k p) NO (YES sh k p)
   | res_join_NO3 : forall sh k p, res_join NO (YES sh k p) (YES sh k p)
   | res_join_YES : forall (sh1 sh2 sh3:pshare) k p,
        join sh1 sh2 sh3 ->
        res_join (YES sh1 k p) (YES sh2 k p) (YES sh3 k p)
   | res_join_PURE : forall k p, res_join (PURE k p) (PURE k p) (PURE k p).Instance Join_resource: Join resource := res_join.Instance Perm_resource: Perm_alg resource.Instance Sep_resource: Sep_alg resource.Instance Canc_resource: Canc_alg resource.Instance Disj_resource: Disj_alg resource.

Lemma rmapj_valid_join : forall (x y z : address -> resource), join x y z -> valid x -> valid y -> valid z.