Ltac SepOpSolve :=
    match goal with
      | H : (match ?f ?x with | Some _ => _ | None => _ end) |- _ =>
        let e := fresh "e" in let y := fresh "y" in remember (f x) as e;
            destruct e as [y |]; SepOpSolve
      | H : _ \/ _ |- _ => destruct H as [H | H]; SepOpSolve
      | H : _ /\ _ |- _ => let H1 := fresh "H" in destruct H as [H H1]; SepOpSolve
      | H : ?f ?x = _ |- context [match ?f ?x with | Some _ => _ | None => _ end] =>
        rewrite H; SepOpSolve
      | H : forall x : X, _ |- _ =>
                   match goal with
                       | x : X |- _ => specialize (H x)
                   end; SepOpSolve
      | _ => subst; try intuition congruence
    end.(* We can create a separation algebra for partial functions with the following
     definitions for sa_unit and sa_mul *)

  Global Instance PFunSepAlgOps : SepAlgOps (X -> option Y) := {
     sa_unit f := pfun_eq f emptyFun;
     sa_mul    := fun a b c => forall x,
                    match c x with
                      | Some y => (a x = Some y /\ b x = None) \/
                                     (b x = Some y /\ a x = None)
                      | None => a x = None /\ b x = None
                    end

  }.(* Proving that partial functions actually form a separation algebra is straightforward
     modulo some LTac magic. *)

  Global Instance PFunSepAlg : SepAlg (rel := pfun_eq) (X -> option Y).Definition UUPFunSepAlg : @UUSepAlg (X -> option Y) pfun_eq _.

(* Specifications: *)
Lemma pfun_in_sa_mulR (a b c : X -> option Y) (x : X) (H : sa_mul a b c) (Hin : pfun_in c x) : pfun_in a x \/ pfun_in b x.
Lemma pfun_mapsto_sa_mulR (a b c : X -> option Y) (x : X) (y : Y) (H : sa_mul a b c) (Hmap : c x = Some y) : a x = Some y \/ b x = Some y.