Section NGramCPS.
Hypothesis Σ:Set.
Hypothesis len_l:nat.
Hypothesis len_r:nat.
Record MidWord:Set := {
l:list Σ;
r:list Σ;
m:Σ;
s:St;
}.
Fixpoint tape_seg(t:Z->Σ)(x:Z)(d:Dir)(n:nat):list Σ :=
match n with
| O => nil
| S n0 => (t x)::(tape_seg t (x+(Dir_to_Z d))%Z d n0)
end.
Definition MidWord_matches(st:ExecState Σ)(mw:MidWord):Prop :=
let (s,t) := st in
let (l0,r0,m0,s0):=mw in
s = s0 /\
m0 = t Z0 /\
l0 = tape_seg t ((-1)%Z) Dneg len_l /\
r0 = tape_seg t (1%Z) Dpos len_r.
Record AbstractES:Type := {
lset: (list Σ)->Prop;
rset: (list Σ)->Prop;
mset: MidWord->Prop;
}.
Definition xset_matches(t:Z->Σ)(xs:(list Σ)->Prop)(d:Dir)(len:nat):Prop :=
forall n:nat,
1<n ->
exists ls,
xs ls /\
ls = tape_seg t ((Z.of_nat n)*(Dir_to_Z d)%Z) d len.
Definition InAES(st:ExecState Σ)(S:AbstractES):Prop :=
let (s,t) := st in
let (ls,rs,ms) := S in
(exists mw, ms mw /\ MidWord_matches st mw) /\
xset_matches t ls Dneg len_l /\
xset_matches t rs Dpos len_r.
Definition AES_isClosed(tm:TM Σ)(S:AbstractES):Prop :=
forall st0,
InAES st0 S ->
exists st1,
step Σ tm st0 = Some st1 /\
InAES st1 S.
Definition AES_CloseAt(tm:TM Σ)(S:AbstractES)(mw:MidWord):Prop :=
let (ls,rs,ms) := S in
let (l0,r0,m0,s0):=mw in
match l0,r0 with
| hl::l1,hr::r1 =>
match tm s0 m0 with
| Some tr =>
let (s1,d,o):=tr in
match d with
| Dpos =>
ls l0 /\
forall x:Σ, rs (r1++(x::nil)) ->
ms {|
l:=o::(pop_back hl l1);
m:=hr;
r:=r1++(x::nil);
s:=s1;
|}
| Dneg =>
rs r0 /\
forall x:Σ, ls (l1++(x::nil)) ->
ms {|
r:=o::(pop_back hr r1);
m:=hl;
l:=l1++(x::nil);
s:=s1;
|}
end
| _ => False
end
| _,_ => False
end.
Definition AES_isClosed'(tm:TM Σ)(S:AbstractES):Prop :=
let (ls,rs,ms) := S in
forall mw,
ms mw ->
AES_CloseAt tm S mw.
Hypothesis Σ_enc: Σ->positive.
Hypothesis Σ_enc_inj: is_inj Σ_enc.
Hypothesis listΣ_enc: (list Σ)->positive.
Hypothesis listΣ_enc_inj: is_inj listΣ_enc.
Definition MidWord_enc(mw:MidWord):positive :=
let (l,r,m,s):=mw in
enc_list ((St_enc s)::(Σ_enc m)::(listΣ_enc l)::(listΣ_enc r)::nil).
Definition xset_impl:Type := (PositiveMap.tree ((list Σ)*(PositiveMap.tree unit))).
Definition mset_impl:Type := (list MidWord)*(PositiveMap.tree unit).
Definition xset_in(xs:xset_impl)(x:list Σ):Prop :=
match x with
| h::t =>
let (x1,x2):=pop_back' h t in
match PositiveMap.find (listΣ_enc x1) xs with
| Some v =>
set_in Σ_enc v x2
| None => False
end
| nil => False
end.
Definition xset_ins0(xs:xset_impl)(v:(list Σ)*(PositiveMap.tree unit))(x1:list Σ)(x2:Σ):xset_impl*bool :=
let (v',flag):=(set_ins Σ_enc v x2) in
(PositiveMap.add (listΣ_enc x1) v' xs, flag).
Definition xset_ins(xs:xset_impl)(x:list Σ):xset_impl*bool :=
match x with
| h::t =>
let (x1,x2):=pop_back' h t in
match PositiveMap.find (listΣ_enc x1) xs with
| Some v =>
xset_ins0 xs v x1 x2
| None =>
xset_ins0 xs (nil, PositiveMap.empty unit) x1 x2
end
| nil => (xs,false)
end.
Definition xset_as_list(xs:xset_impl)(x1:list Σ):list Σ :=
match PositiveMap.find (listΣ_enc x1) xs with
| Some v => fst v
| None => nil
end.
Definition xset_WF(xs:xset_impl):Prop :=
forall (x1:list Σ)(x2:Σ),
xset_in xs (x1++x2::nil) <->
match PositiveMap.find (listΣ_enc x1) xs with
| Some v =>
In x2 (fst v)
| None => False
end.
Definition mset_in(ms:mset_impl)(x:MidWord):Prop := set_in MidWord_enc ms x.
Definition mset_WF(ms:mset_impl):Prop :=
set_WF MidWord_enc ms.
Definition mset_ins0(ms:mset_impl)(mw:MidWord):mset_impl*bool :=
set_ins MidWord_enc ms mw.
Fixpoint mset_ins(q:list MidWord)(ms:mset_impl)(flag:bool)(f:Σ->MidWord)(ls:list Σ):((list MidWord)*mset_impl)*bool :=
match ls with
| nil => ((q,ms),flag)
| h::t =>
let (ms',flag'):=mset_ins0 ms (f h) in
let q' := if flag' then q else ((f h)::q) in
mset_ins q' ms' (andb flag flag') f t
end.
Record AES_impl := {
lset': xset_impl;
rset': xset_impl;
mset': mset_impl;
}.
Definition AES_impl_to_AES(x:AES_impl):AbstractES :=
let (ls,rs,ms):=x in
{|
lset := xset_in ls;
rset := xset_in rs;
mset := mset_in ms;
|}.
Definition AES_impl_WF(x:AES_impl):Prop :=
let (ls,rs,ms):=x in
xset_WF ls /\
xset_WF rs /\
mset_WF ms.
Definition update_AES_MidWord(tm:TM Σ)(q:list MidWord)(mw:MidWord)(SI:AES_impl):((list MidWord)*AES_impl)*bool :=
let (l0,r0,m0,s0):=mw in
let (ls,rs,ms):=SI in
match l0,r0 with
| hl::l1,hr::r1 =>
match tm s0 m0 with
| Some tr =>
let (s1,d,o):=tr in
match d with
| Dpos =>
let (ls',flag1):= xset_ins ls l0 in
match
mset_ins q ms true
(fun x => {|
l:=o::(pop_back hl l1);
m:=hr;
r:=r1++(x::nil);
s:=s1;
|}) (xset_as_list rs r1)
with (q',ms',flag2) =>
((q',{| lset':=ls'; rset':=rs; mset':=ms' |}), andb flag1 flag2)
end
| Dneg =>
let (rs',flag1):= xset_ins rs r0 in
match
mset_ins q ms true
(fun x => {|
r:=o::(pop_back hr r1);
m:=hl;
l:=l1++(x::nil);
s:=s1;
|}) (xset_as_list ls l1)
with (q',ms',flag2) =>
((q',{| lset':=ls; rset':=rs'; mset':=ms' |}), andb flag1 flag2)
end
end
| _ => ((q,SI),false)
end
| _,_ => ((q,SI),false)
end.
Fixpoint update_AES(tm:TM Σ)(ms:list MidWord)(SI:AES_impl)(flag:bool)(n:nat):AES_impl*bool*nat :=
match n with
| O => (SI,false,O)
| S n0 =>
match ms with
| nil => (SI,flag,n0)
| mw::ms0 =>
let (S',flag'):=update_AES_MidWord tm ms0 mw SI in
let (q',SI'):=S' in
update_AES tm q' SI' (andb flag flag') n0
end
end.

Lemma update_AES_MidWord_spec tm q mw SI:
AES_impl_WF SI ->
match update_AES_MidWord tm q mw SI with
| (q',SI',flag) =>
AES_impl_WF SI' /\
(flag=true -> (q'=q /\ SI'=SI /\ AES_CloseAt tm (AES_impl_to_AES SI) mw))
end.