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.

Lemma WordUpdate_steps_spec tm (x:ListES) n0:
let (l0,r0,m0,s0):=x in
match WordUpdate_steps tm x n0 with
| None => True
| Some (x1,Dpos) =>
let (l1,r1,m1,s1):=x1 in
length l0 + length r0 = length l1 + length r1 /\
exists n,
forall L R,
Steps Σ tm (S n) (makeES x L R) (s1,make_tape' L (m1::l1) (R 0) nil (half_tape_cdr R))
| Some (x1,Dneg) =>
let (l1,r1,m1,s1):=x1 in
length l0 + length r0 = length l1 + length r1 /\
exists n,
forall L R,
Steps Σ tm (S n) (makeES x L R) (s1,make_tape' (half_tape_cdr L) nil (L 0) (m1::r1) R)
end.