Require Equations.Prop.EqDec. (*TODO: Remove Import *)
From Undecidability.H10 Require Import H10 dio_single dio_logic.
From Undecidability.L.Datatypes Require Import LNat Lists LOptions LSum.
From Undecidability.L Require Import Tactics.LTactics Computability.MuRec Computability.Synthetic Tactics.GenEncode.
From Undecidability.Shared Require Import DLW.Utils.finite DLW.Vec.vec DLW.Vec.pos.
From Undecidability.MuRec Require Import recalg ra_bs ra_sem_eq.
Reserved Notation "  '[' f ';' v ';' min ';' c ']' '~~>' x " (at level 70).
(* Bigstep semantics for recursive algorithms *)
Inductive ra_bs_c : nat -> nat -> forall k, recalg k -> vec nat k -> nat -> Prop :=
| in_ra_bs_c_cst  : forall min c n v,             [ra_cst n;        v; min; S c] ~~> n
| in_ra_bs_c_zero : forall min c v,               [ra_zero;         v; min; S c] ~~> 0
| in_ra_bs_c_succ : forall min c v,               [ra_succ;         v; min; S c] ~~> S (vec_head v)
| in_ra_bs_c_proj : forall min c k v j,           [@ra_proj k j;    v; min; S c] ~~> vec_pos v j
| in_ra_bs_c_comp : forall min c k i f (gj : vec (recalg i) k) v w x,
(forall j, [vec_pos gj j;    v; min; c - pos2nat j] ~~> vec_pos w j)
->             [f;               w; min; S c] ~~> x
->             [ra_comp f gj;    v; min; S (S c)] ~~> x
| in_ra_bs_c_rec_0 : forall min c k f (g : recalg (S (S k))) v x,
[f;               v; min; c] ~~> x
->             [ra_rec f g;   0##v; min; S c] ~~> x
| in_ra_bs_c_rec_S : forall min c k f (g : recalg (S (S k))) v n x y,
[ra_rec f g;   n##v; min; c] ~~> x
->             [g;         n##x##v; min; c] ~~> y
->             [ra_rec f g; S n##v; min; S c] ~~> y
| in_ra_bs_c_min : forall min c k (f : recalg (S k)) v x w , x >= min ->
(forall j : pos x, pos2nat j >= min -> [f;    pos2nat j##v; 0; c - (pos2nat j - min)] ~~> S (vec_pos w j))
->             [f;            x##v; 0; c - (x - min)] ~~> 0
->             [ra_min f;        v; min; S c] ~~> x
where " [ f ; v ; min ; c ] ~~> x " := (@ra_bs_c min c _ f v x).

Lemma vec_sum_le:
forall (k : nat) (cst : vec nat k) (j : pos k), vec_pos cst j <= vec_sum cst.