(** A [combine] operation over the type [PTree.t L.t] that attempts to share its result with its arguments. *)
Variable f: option L.t -> option L.t -> option L.t.
Hypothesis f_none_none: f None None = None.
Definition opt_eq (ox oy: option L.t) : Prop :=
match ox, oy with
| None, None => True
| Some x, Some y => L.eq x y
| _, _ => False
end.

(* Specifications: *)
Lemma opt_eq_refl: forall ox, opt_eq ox ox.
Lemma opt_eq_sym: forall ox oy, opt_eq ox oy -> opt_eq oy ox.
Lemma opt_eq_trans: forall ox oy oz, opt_eq ox oy -> opt_eq oy oz -> opt_eq ox oz.
Definition opt_beq (ox oy: option L.t) : bool :=
match ox, oy with
| None, None => true
| Some x, Some y => L.beq x y
| _, _ => false
end.
Lemma opt_beq_correct:
forall ox oy, opt_beq ox oy = true -> opt_eq ox oy.
Lemma opt_eq_refl: forall ox, opt_eq ox ox.
Lemma opt_eq_sym: forall ox oy, opt_eq ox oy -> opt_eq oy ox.
Lemma opt_eq_trans: forall ox oy oz, opt_eq ox oy -> opt_eq oy oz -> opt_eq ox oz.
Definition opt_beq (ox oy: option L.t) : bool :=
match ox, oy with
| None, None => true
| Some x, Some y => L.beq x y
| _, _ => false
end.
Lemma opt_beq_correct:
forall ox oy, opt_beq ox oy = true -> opt_eq ox oy.