Section MacroMachine_secion.
Definition Word := list Σ.
Record RepeatWord := {
w: Word;
min_cnt: nat;
is_const: bool;
}.
Inductive RepW_match:RepeatWord->Word->Prop :=
| RepW_match_O w0:
RepW_match {| w:=w0; min_cnt:=0; is_const:=true |} nil
| RepW_match_S0 w0 w1 n:
RepW_match {| w:=w0; min_cnt:=n; is_const:=true |} w1 ->
RepW_match {| w:=w0; min_cnt:=S n; is_const:=true |} (w0++w1)
| RepW_match_S1 w0 w1 n n0:
n<=n0 ->
RepW_match {| w:=w0; min_cnt:=n0; is_const:=true |} w1 ->
RepW_match {| w:=w0; min_cnt:=n; is_const:=false |} w1
.
Inductive RepWL_match:(list RepeatWord)->(nat->Σ)->Prop :=
| RepWL_match_O:
RepWL_match nil half_tape_all0
| RepWL_match_S h t fh ft:
RepW_match h fh ->
RepWL_match t ft ->
RepWL_match (h::t) (app_halftape fh ft)
.
Record RepeatWordList_ES := {
l: list RepeatWord;
r: list RepeatWord;
s: St;
sgn: Dir;
}.
Fixpoint all0(x:Word):bool :=
match x with
| nil => true
| Σ0::t => all0 t
| _::t => false
end.
Fixpoint Word_eqb(x1 x2:Word):bool :=
match x1,x2 with
| nil,nil => true
| h1::t1,h2::t2 =>
if Σ_eqb h1 h2 then Word_eqb t1 t2 else false
| _,_ => false
end.
Hypothesis len:nat.
Definition pop(wl:list RepeatWord): option (Word*(list (list RepeatWord))) :=
match wl with
| nil => Some (repeat Σ0 len,(nil)::nil)
| v::wl0 =>
match min_cnt v with
| O => None
| S n0 => Some
(w v,(match n0 with
| S _ => ({| w:=w v; min_cnt:=n0; is_const:=true |}::wl0)
| O => (wl0)
end)::(if (is_const v) then nil else ((wl)::nil)))
end
end.
Ltac Word_eq_dec s1 s2 := eq_dec Word_eqb_spec Word_eqb s1 s2.
Ltac nat_lt_dec s1 s2 := eq_dec nat_lt_spec Nat.ltb s1 s2.
Hypothesis min_nonconst_len:nat.
Definition push(wl:list RepeatWord)(w0:Word) :=
match wl with
| v0::wl0 =>
if Word_eqb (w v0) w0 then
let cnt := S (min_cnt v0) in
(if Nat.ltb cnt min_nonconst_len then
{| w:=w0; min_cnt:=cnt; is_const:=(is_const v0) |}
else
{| w:=w0; min_cnt:=min_nonconst_len; is_const:=false |})::wl0
else
{| w:=w0; min_cnt:=1; is_const:=true |}::wl
| nil =>
if all0 w0 then nil else {| w:=w0; min_cnt:=1; is_const:=true |}::wl
end.
Definition WordUpdate_step0(tm:TM Σ)(x:ListES):option (ListES*(option Dir)) :=
let (l0,r0,m0,s0):=x in
match tm s0 m0 with
| None => None
| Some tr =>
let (s1,d,o) := tr in
Some
match d with
| Dpos =>
match r0 with
| m1::r1 => (Build_ListES (o::l0) r1 m1 s1,None)
| nil => (Build_ListES l0 nil o s1,Some Dpos)
end
| Dneg =>
match l0 with
| m1::l1 => (Build_ListES l1 (o::r0) m1 s1,None)
| nil => (Build_ListES nil r0 o s1,Some Dneg)
end
end
end.
Fixpoint WordUpdate_steps(tm:TM Σ)(x:ListES)(n:nat):option (ListES*Dir) :=
match n with
| O => None
| S n0 =>
match WordUpdate_step0 tm x with
| Some (x0,None) => WordUpdate_steps tm x0 n0
| Some (x0,Some d) => Some (x0,d)
| None => None
end
end.
Hypothesis WordUpdate_MAXT:nat.
Definition WordUpdate(tm:TM Σ)(s0:St)(w0:Word)(sgn0:Dir):option (St*Word*bool) :=
match w0 with
| nil => None
| m0::w1 =>
match
match sgn0 with
| Dpos => WordUpdate_steps tm (Build_ListES nil w1 m0 s0) WordUpdate_MAXT
| Dneg => WordUpdate_steps tm (Build_ListES w1 nil m0 s0) WordUpdate_MAXT
end
with
| None => None
| Some (Build_ListES l1 r1 m1 s1,d) =>
match d with
| Dpos => Some (s1,m1::l1,negb (Dir_eqb sgn0 d))
| Dneg => Some (s1,m1::r1,negb (Dir_eqb sgn0 d))
end
end
end.
Definition make_tape'' l1 w1 r1 (sgn1:Dir):=
match w1 with
| m1::w2 =>
match sgn1 with
| Dpos => make_tape' l1 nil m1 w2 r1
| Dneg => make_tape' r1 w2 m1 nil l1
end
| nil =>
match sgn1 with
| Dpos => make_tape' l1 nil (r1 0) nil (half_tape_cdr r1)
| Dneg => make_tape' (half_tape_cdr r1) nil (r1 0) nil l1
end
end.
Definition RepWL_step00(tm:TM Σ)(x:RepeatWordList_ES)(w0:Word)(r1:list RepeatWord):=
let (l0,_,s0,sgn0):=x in
match WordUpdate tm s0 w0 sgn0 with
| None => None
| Some (s1,w1,is_back) =>
if is_back
then Some {| l:=push r1 w1; r:=l0; s:=s1; sgn:=Dir_rev sgn0 |}
else Some {| l:=push l0 w1; r:=r1; s:=s1; sgn:=sgn0 |}
end.
Fixpoint RepWL_step0(tm:TM Σ)(x:RepeatWordList_ES)(w0:Word)(ls:list (list RepeatWord)):option (list RepeatWordList_ES) :=
match ls with
| nil => Some nil
| r1::ls0 =>
match RepWL_step00 tm x w0 r1 with
| None => None
| Some x1 =>
match RepWL_step0 tm x w0 ls0 with
| None => None
| Some ret => Some (x1::ret)
end
end
end.
Definition RepWL_step(tm:TM Σ)(x:RepeatWordList_ES) :=
let (l0,r0,s0,sgn0):=x in
match pop r0 with
| None => None
| Some (w0,ls) =>
RepWL_step0 tm x w0 ls
end.
Inductive In_RepWL_ES:(ExecState Σ)->RepeatWordList_ES->Prop :=
| In_RepWL_ES_intro l1 r1 l0 r0 s0 sgn0:
RepWL_match l0 l1 ->
RepWL_match r0 r1 ->
In_RepWL_ES (s0,make_tape'' l1 nil r1 sgn0) (Build_RepeatWordList_ES l0 r0 s0 sgn0)
.
Definition push'(wl:list RepeatWord)(w0:Word):=
{| w := w0; min_cnt := 1; is_const := true |} :: wl.
Definition halftape_skipn(n:nat)(f:nat->Σ):nat->Σ :=
fun m => f (n+m).
Definition Dir_enc(d:Dir):=
match d with
| Dpos => xI xH
| Dneg => xH
end.
Definition bool_enc(x:bool):=
if x then xI xH else xH.
Definition RepeatWord_enc(x:RepeatWord):positive :=
let (w0,mc,isc):=x in
enc_list ((listΣ_enc w0)::(Pos.of_succ_nat mc)::(bool_enc isc)::nil).
Definition list_enc{T}(T_enc:T->positive)(ls:list T) :=
enc_list (map T_enc ls).
Definition RepWL_ES_enc(x:RepeatWordList_ES):positive :=
let (l0,r0,s0,sgn0):=x in
enc_list ((Dir_enc sgn0)::(St_enc s0)::(list_enc RepeatWord_enc l0)::(list_enc RepeatWord_enc r0)::nil).
Definition RepWL_InitES :=
{| l:=nil; r:=nil; s:=St0; sgn:=Dpos |}.

Lemma In_RepWL_ES_InitES:
In_RepWL_ES (InitES Σ Σ0) RepWL_InitES.