Definition complete_option {A : Type} x0 (x : option A) : A :=
match x with
| None => x0
| Some x => x
end.Definition option_le x y : Prop := 
 exists vx vy, x = Some vx /\ y = Some vy /\ le vx vy.Notation "x ≤p y" := (option_le x y) (at level 60).Definition option_choice {A B: Type} (f g: A -> option B) x :=
match f x with 
| Some v => Some v
| None => g x
end.Notation " f ;; g " := (option_choice f g) (at level 60).

(* Specifications: *)
Lemma option_choice_assoc {A B: Type} (f g h : A -> option B) x: (f;;(g;;h)) x = (f;;g;;h) x.
Lemma option_choice_none_right {A B: Type} (f : A -> option B) x: (f;;fun _ => None) x = f x.
Lemma option_choice_none_left {A B: Type} (f : A -> option B) x : ((fun _ => None) ;; f) x = f x.
Lemma option_choice_ext_left {A B: Type} (f f' g: A -> option B) x: (forall x, f x = f' x) -> (f;;g) x = (f';; g) x.
Lemma option_choice_ext_right {A B: Type} (f f' g: A -> option B) x: (forall x, f x = f' x) -> (g;;f) x = (g;;f') x.
Lemma option_map_Some {A B : Type} (f : A -> B) x v: option_map f x = Some v -> exists v', x = Some v'.
Lemma option_bind_Some {A B : Type} (f : A -> option B) x v: option_bind f x = Some v -> exists v', x = Some v' /\ f v' = Some v.