Require RndHoare.axiom. Import RndHoare.axiom.NatChoice.
Fixpoint app_fin_inf {ora: RandomOracle} (l: list RandomQA) (f: nat -> RandomQA) :=
match l with
| nil => f
| qa :: l0 => fun n =>
match n with
| 0 => qa
| S m => app_fin_inf l0 f m
end
end.

(* Specifications: *)
Lemma app_fin_inf_list {ora: RandomOracle}: forall l h m, m < length l -> Some (app_fin_inf l h m) = nth_error l m.
Lemma app_fin_inf_fun {ora: RandomOracle}: forall l h m, length l <= m -> app_fin_inf l h m = h (m - length l).
(* These three lemmas are copied from veric/assert_lemmas.v and veric/initial_world.v *)
Lemma nth_error_in_bounds: forall {A} (l: list A) i, (O <= i < length l)%nat
-> exists x, nth_error l i = value x.
Lemma nth_error_app: forall {T} (al bl : list T) (j: nat),
nth_error (al++bl) (length al + j) = nth_error bl j.
Lemma nth_error_app1: forall {T} (al bl : list T) (j: nat),
(j < length al)%nat ->
nth_error (al++bl) j = nth_error al j.
Lemma length_firstn_list_from_fun: forall {A} (f: nat -> A) n, length (fisrtn_list_from_fun f n) = n.
Lemma nth_error_firstn_list_from_fun: forall {A} (f: nat -> A) n m, m < n -> nth_error (fisrtn_list_from_fun f n) m = Some (f m).
Lemma fstn_app_inf_fin {ora: RandomOracle}: forall l h n,
n >= length l ->
fstn_history n (inf_history (app_fin_inf l h)) = fin_history (l ++ fisrtn_list_from_fun h (n - length l)).
Lemma inf_history_construction {ora: RandomOracle}: forall (P: RandomHistory -> Prop) (init: list RandomQA),
P (fin_history init) ->
(forall l, P (fin_history l) -> exists qa, P (fin_history (l ++ qa :: nil))) ->
exists h, is_inf_history h /\ forall n, n >= length init -> P (fstn_history n h).