Section Linearizability.
Variable K : Type.
Variable K_eq_dec : forall x y : K, {x = y} + {x <> y}.
Inductive op : Type :=
| I : K -> op
| O : K -> op.
Definition op_eq_dec :
forall x y : op, {x = y} + {x <> y}.
Proof using K_eq_dec.
decide equality.
Qed.
Inductive IR : Type :=
| IRI : K -> IR
| IRO : K -> IR
| IRU : K -> IR.
Definition IR_eq_dec :
forall x y : IR, {x = y} + {x <> y}.
Proof using K_eq_dec.
decide equality.
Qed.
(* Hypothesis trace_NoDup : NoDup trace. *)
(* also maybe: no Us *)
(* alse maybe: every O has corresponding I before it *)
Definition acknowledged_op (k : K) (trace : list op) :=
In (O k) trace.
Definition acknowledged_op_dec (k : K) (tr : list op) : {acknowledged_op k tr} + {~acknowledged_op k tr} :=
in_dec op_eq_dec (O k) tr.
Inductive acknowledge_all_ops : list op ->  list IR -> Prop :=
| AAO_nil : acknowledge_all_ops [] []
| AAO_IU : forall k tr out,
~ acknowledged_op k tr ->
acknowledge_all_ops tr out ->
acknowledge_all_ops (I k :: tr) (IRI k :: IRU k :: out)
| AAO_I_dorp : forall k tr out,
~ acknowledged_op k tr ->
acknowledge_all_ops tr out ->
acknowledge_all_ops (I k :: tr) out
| AAO_IO : forall k tr out,
acknowledged_op k tr ->
acknowledge_all_ops tr out ->
acknowledge_all_ops (I k :: tr) (IRI k :: out)
| AAO_O : forall k tr out,
acknowledge_all_ops tr out ->
acknowledge_all_ops (O k :: tr) (IRO k :: out).

(* Specifications: *)
Lemma acknowledge_all_ops_was_in :
forall l ir,
acknowledge_all_ops l ir ->
forall k,
In (IRI k) ir ->
In (I k) l.