Definition prefix_history {ora: RandomOracle} (h1 h2: RandomHistory): Prop :=
  forall n, h1 n = None \/ h1 n = h2 n.Definition strict_prefix_history {ora: RandomOracle} (h1 h2: RandomHistory): Prop :=
  prefix_history h1 h2 /\ exists n, h1 n <> h2 n.Definition n_bounded_prefix_history {ora: RandomOracle} (m: nat) (h1 h2: RandomHistory): Prop :=
  forall n, (h1 n = None /\ h2 (n + m) = None) \/ h1 n = h2 n.Definition n_conflict_history {ora: RandomOracle} (n: nat) (h1 h2: RandomHistory): Prop :=
  match h1 n, h2 n with
  | Some a1, Some a2 => projT1 a1 <> projT1 a2
  | Some _, None => True
  | None, Some _ => True
  | None, None => False
  end.Definition conflict_history {ora: RandomOracle} (h1 h2: RandomHistory): Prop :=
  exists n, history_coincide n h1 h2 /\ n_conflict_history n h1 h2.Definition strict_conflict_history {ora: RandomOracle} (h1 h2: RandomHistory): Prop :=
  exists n,
    history_coincide n h1 h2 /\
    match h1 n, h2 n with
    | Some a1, Some a2 => projT1 a1 <> projT1 a2
    | _, _ => False
    end.

(* Specifications: *)
Lemma history_coincide_sym {ora: RandomOracle}: forall h1 h2 n, history_coincide n h1 h2 -> history_coincide n h2 h1.
Lemma n_conflict_history_sym {ora: RandomOracle}: forall h1 h2 n, n_conflict_history n h1 h2 -> n_conflict_history n h2 h1.
Lemma conflict_history_sym {ora: RandomOracle}: forall h1 h2, conflict_history h1 h2 -> conflict_history h2 h1.
Lemma strict_conflict_history_sym {ora: RandomOracle}: forall h1 h2, strict_conflict_history h1 h2 -> strict_conflict_history h2 h1.
Lemma history_coincide_trans {ora: RandomOracle}: forall h1 h2 h3 n, history_coincide n h1 h2 -> history_coincide n h2 h3 -> history_coincide n h1 h3.
Lemma is_0_history_non_conflict {ora: RandomOracle}: forall h1 h2, is_n_history 0 h1 -> is_n_history 0 h2 -> conflict_history h1 h2 -> False.
Lemma fstn_history_Some {ora: RandomOracle}: forall n m h, m < n -> (fstn_history n h) m = h m.
Lemma fstn_history_None {ora: RandomOracle}: forall n m h, n <= m -> (fstn_history n h) m = None.
Lemma history_coincide_weaken {ora: RandomOracle}: forall n m h1 h2, n <= m -> history_coincide m h1 h2 -> history_coincide n h1 h2.
Lemma is_n_history_None {ora: RandomOracle}: forall n m h, n <= m -> is_n_history n h -> h m = None.
Lemma fstn_history_is_n_history {ora: RandomOracle}: forall n m h, m <= n -> is_n_history n h -> is_n_history m (fstn_history m h).
Lemma fstn_history_coincide {ora: RandomOracle}: forall n h, history_coincide n h (fstn_history n h).
Lemma prefix_history_refl {ora: RandomOracle}: forall h, prefix_history h h.
Lemma prefix_history_trans {ora: RandomOracle}: forall h1 h2 h3, prefix_history h1 h2 -> prefix_history h2 h3 -> prefix_history h1 h3.
Lemma prefix_history_anti_sym {ora: RandomOracle}: forall h1 h2, prefix_history h1 h2 -> prefix_history h2 h1 -> h1 = h2.
Lemma prefix_history_comparable {ora: RandomOracle}: forall h1 h2 h, prefix_history h1 h -> prefix_history h2 h -> prefix_history h1 h2 \/ prefix_history h2 h1.
Lemma conflict_history_strict_conflict {ora: RandomOracle}: forall h h', is_inf_history h -> conflict_history h' h -> prefix_history h' h \/ strict_conflict_history h' h.
Lemma fstn_history_finite {ora: RandomOracle}: forall n h, is_fin_history (fstn_history n h).
Lemma fstn_history_prefix {ora: RandomOracle}: forall n h, prefix_history (fstn_history n h) h.
Lemma n_conflict_at_least_n_history1 {ora: RandomOracle}: forall n h1 h2, history_coincide n h1 h2 -> n_conflict_history n h1 h2 -> is_at_least_n_history n h1.
Lemma n_conflict_at_least_n_history2 {ora: RandomOracle}: forall n h1 h2, history_coincide n h1 h2 -> n_conflict_history n h1 h2 -> is_at_least_n_history n h2.
Lemma prefix_history_coincide {ora: RandomOracle}: forall n h1 h2, prefix_history h1 h2 -> is_at_least_n_history n h1 -> history_coincide n h1 h2.
Lemma is_at_least_n_history_fstn_history {ora: RandomOracle}: forall n m h, n <= m -> (is_at_least_n_history n (fstn_history m h) <-> is_at_least_n_history n h).
Lemma n_conflict_proper_aux_right {ora: RandomOracle}: forall n h1 h2 h3, history_coincide (S n) h2 h3 -> (history_coincide n h1 h2 /\ n_conflict_history n h1 h2 <-> history_coincide n h1 h3 /\ n_conflict_history n h1 h3).
Lemma n_conflict_proper_aux_left {ora: RandomOracle}: forall n h1 h2 h3, history_coincide (S n) h2 h3 -> (history_coincide n h2 h1 /\ n_conflict_history n h2 h1 <-> history_coincide n h3 h1 /\ n_conflict_history n h3 h1).
Lemma n_conflict_proper_aux {ora: RandomOracle}: forall n l1 l2 r1 r2, history_coincide (S n) l1 l2 -> history_coincide (S n) r1 r2 -> (history_coincide n l1 r1 /\ n_conflict_history n l1 r1 <-> history_coincide n l2 r2 /\ n_conflict_history n l2 r2).
Lemma squeeze_history_coincide {ora: RandomOracle}: forall n h1 h2, prefix_history (fstn_history n h1) h2 -> prefix_history h2 h1 -> history_coincide n h1 h2.
Lemma strict_conflict_prefix_conflict_left {ora: RandomOracle}: forall h h1 h2, strict_conflict_history h2 h -> prefix_history h1 h2 -> conflict_history h1 h.
Lemma strict_conflict_prefix_conflict_right {ora: RandomOracle}: forall h h1 h2, strict_conflict_history h h2 -> prefix_history h1 h2 -> conflict_history h h1.
Lemma strict_conflict_prefix_left {ora: RandomOracle}: forall h h1 h2, strict_conflict_history h2 h -> prefix_history h1 h2 -> prefix_history h1 h \/ strict_conflict_history h1 h.
Lemma strict_conflict_prefix_right {ora: RandomOracle}: forall h h1 h2, strict_conflict_history h h2 -> prefix_history h1 h2 -> prefix_history h1 h \/ strict_conflict_history h h1.