Section mk_init.
Variable Σ : finType.
Variable s b : Σ^+.
Variable (H_disj : s <> b).
Context (retr_pro : Retract sigPro Σ) (retr_bools : Retract (sigList bool) Σ).
Variable m k : nat.
Variable sim : term.
Notation aux n := (Fin.L k (Fin.L m n)) (only parsing).
Notation auxm n := (Fin.L k (Fin.R 6 n)) (only parsing).
Notation auxk n := (Fin.R (6 + m) n) (only parsing).
Fixpoint M_init' k' : (Vector.t (Fin.t k) k') -> pTM (Σ) ^+ unit ((6 + m)+ k).
Proof using m s retr_bools sim retr_pro.
simple notypeclasses refine (match k' with
0 => fun _ => MK_isVoid_multi _ @ [|aux Fin1;aux Fin2;aux Fin3;aux Fin4; aux Fin5|];;
WriteValue ( (compile sim)) ⇑ retr_pro @ [|aux Fin1|]
| S k' =>
fun ren =>
_;;M_init_one s retr_pro retr_bools @ [|auxk (ren[@Fin0]);aux Fin1;aux Fin2;aux Fin3;aux Fin4;aux Fin5|]
end). all:try exact _.
2:{apply (M_init' _ (Vector.tl ren)). }
Defined.
Proof using All.
depind ren. all:cbn [compile Vector.fold_left M_init' Vector.tl Vector.caseS].
{
eexists. cbn.
hstep. hsteps_cbn;cbn. exact (MK_isVoid_multi_SpecT 5). cbn;cleanupParamTM. 2:reflexivity.
hsteps_cbn. reflexivity.
cleanupParamTM.
apply EntailsI. intros t H. eapply tspec_ext. eassumption. easy.
intros i. clear - i.
repeat (destruct (fin_destruct_S i) as [(i'&->) | ->];[rename i' into i;cbn| ]);try (intros H;exact H).
}
{
eexists. cbn. hstep.
3:reflexivity. now apply (projT2 (IHren v)). clear IHren.
cbn. intros _. hstep. { cbn. rewrite Vector_nth_R,nth_map'. cbn. eapply (projT2 (M_init_one_Spec H_disj _ _)). }
cbn;fold Nat.add;rewrite Nat.eqb_refl;cbn. intros _.
apply EntailsI. intros t H. eapply tspec_ext. eassumption. easy.
intros i. clear - i.
repeat (destruct (fin_destruct_S i) as [(i'&->) | ->];[rename i' into i;cbn| ]);try (intros H;exact H).
rewrite nth_tabulate. destruct (Fin.eqb _ _) eqn:H'. 2:tauto.
cbn. eapply Fin.eqb_eq in H' as ->. rewrite Vector_nth_R,nth_map'. cbn. tauto.
}
Qed.
Program Definition startRen := Vectors.tabulate (n:=k) (fun i => Fin.of_nat_lt (n:=k) (p:=k - 1 -proj1_sig (Fin.to_nat i)) _).
Next Obligation.
destruct Fin.to_nat;cbn. nia.
Defined.
Definition M_init : pTM (Σ) ^+ unit ((6 + m)+ k) :=
M_init' startRen.

Theorem M_init_SpecT (v:Vector.t (list bool) k):
{ k &
TripleT ≃≃([],Vector.const (Custom (eq niltape)) (6+m) ++ Vector.map (fun bs => Custom (eq (encBoolsTM s b bs))) v)
k M_init
(fun _ => ≃≃([],
([|Custom (eq niltape);
Contains retr_pro (compile (Vector.fold_left (fun s l_i => L.app s (encBoolsL l_i)) sim v));
Void;Void;Void;Void|]
++Vector.const (Custom (eq niltape)) m) ++ Vector.map (fun bs => Custom (eq (encBoolsTM s b bs))) v))}.