Definition ghost : Type := list (option ({g: Ghost & {a: @G g | ghost.valid a}} * preds)%type).
Instance preds_join : Join _ := Join_equiv preds.
Inductive ghost_elem_join : Join {g: Ghost & {a: @G g | ghost.valid a}} :=
| elem_join_I g a b c va vb vc: join a b c ->
ghost_elem_join (existT _ g (exist _ a va)) (existT _ g (exist _ b vb))
(existT _ g (exist _ c vc)).
Existing Instance ghost_elem_join.
Inductive ghost_join : Join ghost :=
| ghost_join_nil_l m: ghost_join nil m m
| ghost_join_nil_r m: ghost_join m nil m
| ghost_join_cons a1 a2 m1 m2 a3 m3: join a1 a2 a3 -> ghost_join m1 m2 m3 ->
ghost_join (a1 :: m1) (a2 :: m2) (a3 :: m3).
Existing Instance ghost_join.

(* Specifications: *)
Axiom Perm_ghost: Perm_alg ghost. Existing Instance Perm_ghost.
Axiom Sep_ghost: Sep_alg ghost. Existing Instance Sep_ghost.
Axiom ghost_core: forall (g: ghost), core g = nil.
Definition ghost_fmap (f g:pred rmap -> pred rmap)(x:ghost) : ghost :=
map (option_map (fun '(a, b) => (a, preds_fmap f g b))) x.
Axiom ghost_fmap_id : ghost_fmap (id _) (id _) = id ghost.
Axiom ghost_fmap_comp : forall f1 f2 g1 g2,
ghost_fmap g1 g2 oo ghost_fmap f1 f2 = ghost_fmap (g1 oo f1) (f2 oo g2).