(** Comparing option types. *)

Definition option_eq (A: Type) (eqA: forall (x y: A), {x=y} + {x<>y}):
  forall (x y: option A), {x=y} + {x<>y}.(** Lifting a relation to an option type. *)

Inductive option_rel (A B: Type) (R: A -> B -> Prop) : option A -> option B -> Prop :=
  | option_rel_none: option_rel R None None
  | option_rel_some: forall x y, R x y -> option_rel R (Some x) (Some y).(** Lifting a relation to an option type. *)

Inductive option_rel (A B: Type) (R: A -> B -> Prop) : option A -> option B -> Prop :=
  | option_rel_none: option_rel R None None
  | option_rel_some: forall x y, R x y -> option_rel R (Some x) (Some y).(** Lifting a relation to an option type. *)

Inductive option_rel (A B: Type) (R: A -> B -> Prop) : option A -> option B -> Prop :=
  | option_rel_none: option_rel R None None
  | option_rel_some: forall x y, R x y -> option_rel R (Some x) (Some y).(** Mapping a function over an option type. *)

Definition option_map (A B: Type) (f: A -> B) (x: option A) : option B :=
  match x with
  | None => None
  | Some y => Some (f y)
  end.(** Mapping a function over a sum type. *)

Definition sum_left_map (A B C: Type) (f: A -> B) (x: A + C) : B + C :=
  match x with
  | inl y => inl C (f y)
  | inr z => inr B z
  end.

(* Specifications: *)
Lemma nth_error_in: forall (A: Type) (n: nat) (l: list A) (x: A), List.nth_error l n = Some x -> In x l.
Lemma nth_error_nil: forall (A: Type) (idx: nat), nth_error (@nil A) idx = None.
Lemma nth_error_in: forall (A: Type) (n: nat) (l: list A) (x: A), List.nth_error l n = Some x -> In x l.
Lemma nth_error_nil: forall (A: Type) (idx: nat), nth_error (@nil A) idx = None.