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.

Lemma mset_ins0_spec ms mw ms' flag:
mset_WF ms ->
mset_ins0 ms mw = (ms',flag) ->
(mset_WF ms' /\
(flag=true -> (ms'=ms /\ mset_in ms mw))).