Module Type ADR_VAL.
Parameter address : Type.
Parameter some_address:address.
(* Validity of traces.  The "valid" predicate ensures that related addresses don't get split apart from each other.  *)
Parameter kind: Type.
Parameter valid : (address -> option (pshare * kind)) -> Prop.
Parameter valid_empty: valid (fun _ => None).
Parameter valid_join: forall f g h : address -> option (pshare * kind),
@join _ (Join_fun address (option (pshare * kind))
(Join_lower (Join_prod pshare Join_pshare kind (Join_equiv kind))))
f g h  ->
valid f -> valid g -> valid h.
End ADR_VAL.
Module Type ADR_VAL0.
Parameter address : Type.
Parameter some_address:address.
Parameter kind: Type.
End ADR_VAL0.
Module SimpleAdrVal (AV0: ADR_VAL0) <:
ADR_VAL with Definition address := AV0.address
with Definition kind := AV0.kind.
Definition address := address.
Definition some_address := some_address.
Definition kind := kind.
Definition valid (_: address -> option (pshare * kind)) := True.

(* Specifications: *)
Lemma valid_empty: valid (fun _ => None).
Definition f_res : functor res := Functor ff_res.