Skip to content

Commit 1df2d1c

Browse files
authored
Merge pull request #238 from alexandralatys/remove-KOSBTM
Remove KOSBTM and rework TM-computable to BSM-computable
2 parents 4f6a1d6 + 68101d3 commit 1df2d1c

File tree

9 files changed

+1799
-1393
lines changed

9 files changed

+1799
-1393
lines changed

theories/StackMachines/Reductions/SBTM_HALT_to_HaltBSM.v

Lines changed: 221 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ Set Default Goal Selector "!".
2020

2121
Section Construction.
2222

23-
Context (M : SBTM) (q0 : state M).
23+
(* Shift by shift to the right*)
24+
Context (M : SBTM) (q0 : state M) (shift : nat).
2425

2526
#[local] Notation δ := (trans' M).
2627

@@ -33,18 +34,24 @@ Section Construction.
3334
| (ls, a, rs) => [ ls ; [a]%list ; rs ; []%list ]%vector
3435
end.
3536

36-
Definition encode_state (q : state M) := (2 + sval (Fin.to_nat q) * c).
37+
(* Shift everything back by one *)
38+
Definition encode_state (q : state M) := (1 + shift + sval (Fin.to_nat q) * c).
3739

3840
#[local] Arguments encode_state : simpl never.
3941
#[local] Notation "! p" := (encode_state p) (at level 1).
4042

4143
Definition encode_config '(q, t) : bsm_state 4 := (!q, encode_tape t).
4244

4345
#[local] Notation JMP i := (POP ZERO i i).
44-
46+
47+
(* Jump to after Program *)
48+
Notation POST_TRUE := (1 + shift + c * (num_states M)).
49+
Notation POST_FALSE := (3 + shift + c * (num_states M)).
50+
Notation END := (5 + shift + c * (num_states M)).
51+
4552
Definition box '(q, a) (f : (state M * bool * direction) -> bsm_instr 4) : bsm_instr 4 :=
4653
match δ (q, a) with
47-
| None => JMP 0
54+
| None => JMP (if a then POST_TRUE else POST_FALSE)
4855
| Some t => f t
4956
end.
5057

@@ -73,22 +80,53 @@ Section Construction.
7380

7481
Opaque c.
7582

83+
Lemma c_spec : c = 13.
84+
Proof. easy. Qed.
85+
7686
Fixpoint all_fins (n : nat) : list (Fin.t n) :=
7787
if n is S n' then Fin.F1 :: map Fin.FS (all_fins n') else nil.
7888

89+
Definition POST : list (bsm_instr 4) :=
90+
PUSH CURR' true ::
91+
JMP END ::
92+
PUSH CURR' false ::
93+
JMP END :: [].
94+
7995
(* constructed BSM *)
8096
Definition P : list (bsm_instr 4) :=
81-
JMP (!q0) :: flat_map PROG (all_fins (num_states M)).
97+
JMP (!q0) :: flat_map PROG (all_fins (num_states M)) ++ POST.
8298

83-
Lemma P_length : length P = 1 + num_states M * c.
99+
Lemma length_flat_map_PROG_M : length (flat_map PROG (all_fins (num_states M))) = num_states M * c.
84100
Proof.
85-
rewrite /P /=. congr S. have := PROG_length.
101+
have := PROG_length.
86102
elim: (num_states M) (PROG); first done.
87103
move=> n IH PROG' H. have ->: S n * c = n * c + c by lia.
88104
rewrite /= length_app flat_map_concat_map map_map -flat_map_concat_map H.
89105
by rewrite IH; [|lia].
90106
Qed.
91107

108+
Lemma state_map_length_spec M1 : length (all_fins (num_states M1)) = num_states M1.
109+
Proof.
110+
induction (num_states M1) as [| n IHn];[reflexivity|].
111+
cbn.
112+
rewrite length_map.
113+
now rewrite IHn.
114+
Qed.
115+
116+
Lemma state_number_length M1 (q1 : SBTMNotations.state M1) :
117+
proj1_sig (Fin.to_nat q1) < length (all_fins (num_states M1)).
118+
Proof.
119+
unfold proj1_sig.
120+
destruct (Fin.to_nat q1) as [n H].
121+
rewrite state_map_length_spec.
122+
apply H.
123+
Qed.
124+
125+
Lemma P_length : length P = 5 + num_states M * c.
126+
Proof.
127+
rewrite /= length_app /= length_flat_map_PROG_M. lia.
128+
Qed.
129+
92130
Definition Q_step (Q : list (bsm_instr 4)) offset i v : option (bsm_state 4) :=
93131
match nth_error Q i with
94132
| None => None
@@ -111,7 +149,7 @@ Section Construction.
111149
move: E => /(@nth_error_split (bsm_instr 4)) => - [l] [r] [-> <-].
112150
move=> Ht. exists offset, l, t, r, v. split; [|split]; [done|congr pair; lia|].
113151
move: t Ht => [].
114-
- move=> x p' q' [<-].
152+
- move=> x p' q' [<-].
115153
move Ex: (vec_pos v x) => [|[] ?]; by auto using bsm_sss.
116154
- move=> x b [<-] <-. by auto using bsm_sss.
117155
Qed.
@@ -129,72 +167,186 @@ Section Construction.
129167
all: do ? ((by apply: in_sss_steps_0) || (apply: in_sss_steps_S; [by apply: Q_step_spec|])).
130168
Qed.
131169

132-
Lemma PROG_spec_None q t : step M (q, t) = None ->
133-
exists v, (!q, PROG q) // (encode_config (q, t)) ->> (0, v).
170+
Lemma PROG_spec_None a q ls rs : step M (q, (ls, a, rs)) = None ->
171+
(!q, PROG q) // (encode_config (q, (ls, a, rs))) ->> (if a then POST_TRUE else POST_FALSE, [ls; []%list; rs; []%list]%vector).
134172
Proof.
135-
move: t => [[ls a] rs] /=. rewrite /step.
136-
case E: (δ (q, a)) => [[[??]d]|]; first done.
137-
move=> _. have ->: !q = 0 + !q by done.
138-
move: a E => [] E.
139-
all: exists [ ls ; []%list ; rs ; []%list ]%vector.
140-
all: eexists; rewrite /PROG /box E.
141-
all: do ? ((by apply: in_sss_steps_0) || (apply: in_sss_steps_S; [by apply: Q_step_spec|])).
173+
rewrite /step.
174+
case E: (δ (q, a)) => [[[??]?]|]; first done.
175+
move=> _.
176+
rewrite /PROG. eexists _.
177+
apply in_sss_steps_S with (st2:= (if a then 1 +! q else 7 +! q, [ls; []%list; rs; []%list]%vector)).
178+
{ eexists _, [], _, _, _.
179+
split; [reflexivity|split; [by rewrite (Nat.add_comm (!q))|]].
180+
replace ([ls; []%list; rs; []%list]%vector) with (vec_change ([ls; [a]%list; rs; []%list]%vector) CURR' []) by done.
181+
destruct a; by constructor. }
182+
apply in_sss_steps_S with (st2:= (if a then POST_TRUE else POST_FALSE, [ls; []%list; rs; []%list]%vector)).
183+
{ destruct a.
184+
- eexists _, [_], _, _, _.
185+
split; [reflexivity|split; [by rewrite (Nat.add_comm (!q))|]].
186+
rewrite /= E. by constructor.
187+
- eexists _, [_; _; _; _; _; _; _], _, _, _.
188+
split; [reflexivity|split; [by rewrite (Nat.add_comm (!q))|]].
189+
rewrite /= E; by constructor. }
190+
by apply: in_sss_steps_0.
191+
Qed.
192+
193+
Lemma PROG_sc (q : state M) : (!q, PROG q) <sc (shift, P).
194+
Proof.
195+
apply: subcode_cons.
196+
apply: subcode_app_end.
197+
suff: forall n, (n + shift + sval (Fin.to_nat q) * c, PROG q) <sc
198+
(n + shift, flat_map PROG (all_fins (num_states M))) by apply.
199+
move: (num_states M) q (PROG) (PROG_length)=> ?.
200+
elim; first by eexists [], _.
201+
move=> m q IH PROG' H' n. apply: subcode_trans.
202+
- have := (IH (fun q => PROG' (Fin.FS q)) (fun q => H' (Fin.FS q)) (n+c)).
203+
congr subcode. congr pair.
204+
rewrite /=. move: (Fin.to_nat q) => [] /=. lia.
205+
- rewrite /= !flat_map_concat_map map_map -!flat_map_concat_map.
206+
exists (PROG' Fin.F1), []. rewrite app_nil_r H'.
207+
by split; [|lia].
208+
Qed.
209+
210+
Lemma POST_spec a ls rs:
211+
(POST_TRUE, POST) // (if a then POST_TRUE else POST_FALSE, [ls; []%list; rs; []%list]%vector) ->> (END, encode_tape (ls, a, rs)).
212+
Proof.
213+
exists 2.
214+
apply in_sss_steps_S with (st2:= (1 + if a then POST_TRUE else POST_FALSE, [ls; [a]%list; rs; []%list]%vector)).
215+
{ case: a.
216+
- eexists _, [], _, _, _.
217+
split; [reflexivity|split;[by rewrite (Nat.add_comm _ (length _))|]].
218+
by constructor.
219+
- eexists _, [_; _], _, _, _.
220+
split; [reflexivity|split;[by rewrite (Nat.add_comm _ (length _))|]].
221+
by constructor. }
222+
apply in_sss_steps_S with (st2:= (END, [ls; [a]%list; rs; []%list]%vector)).
223+
{ case: a.
224+
- eexists _, [_], _, _, _.
225+
split; [reflexivity|split;[by rewrite (Nat.add_comm _ (length _))|]].
226+
by constructor.
227+
- eexists _, [_; _; _], _, _, _.
228+
split; [reflexivity|split;[by rewrite (Nat.add_comm _ (length _))|]].
229+
by constructor. }
230+
by apply in_sss_steps_0.
142231
Qed.
143232

144-
Lemma PROG_sc (q : state M) : (!q, PROG q) <sc (1, P).
233+
Lemma POST_sc : (POST_TRUE, POST) <sc (shift, P).
145234
Proof.
146-
apply: subcode_cons. rewrite /P /encode_state [1+1]/=.
147-
suff: forall n, (n + sval (Fin.to_nat q) * c, PROG q) <sc
148-
(n, flat_map PROG (all_fins (num_states M))) by done.
149-
have := PROG_length. move: (num_states M) q (PROG) => ?.
150-
elim. { move=> /= *. by eexists [], _. }
151-
move=> m q IH PROG' H' n.
152-
have := IH (fun q => PROG' (Fin.FS q)) => /(_ ltac:(done) (n+c)).
153-
rewrite /= !flat_map_concat_map map_map -!flat_map_concat_map.
154-
move=> [l] [r] [{}IH {}IH']. exists (PROG' Fin.F1 ++ l), r. split.
155-
- by rewrite IH -app_assoc.
156-
- move: (Fin.to_nat q) IH' => [? ?] /=. rewrite length_app H'. lia.
235+
eexists (_ :: _), [].
236+
rewrite app_nil_r /=.
237+
split; first done.
238+
rewrite length_flat_map_PROG_M. lia.
157239
Qed.
158240

159-
Opaque P.
241+
(* Opaque P. *)
160242

161243
Lemma simulation_step_Some q t q' t' : step M (q, t) = Some (q', t') ->
162-
exists k, (1, P) // (encode_config (q, t)) -[S k]-> (encode_config (q', t')).
244+
exists k, (shift, P) // (encode_config (q, t)) -[S k]-> (encode_config (q', t')).
163245
Proof.
164246
move=> /PROG_spec_Some [k] H. exists k.
165247
apply: subcode_sss_steps; [|by eassumption].
166248
by apply: PROG_sc.
167249
Qed.
168250

169251
Lemma simulation_step_None q t : step M (q, t) = None ->
170-
exists v, (1, P) // (encode_config (q, t)) ->> (0, v).
252+
(shift, P) // (encode_config (q, t)) ->> (shift + length P, encode_tape t).
253+
Proof.
254+
move: t => [[ls a] rs] /PROG_spec_None.
255+
have /subcode_sss_compute := PROG_sc q.
256+
move=> /[apply] /sss_compute_trans. apply.
257+
apply: subcode_sss_compute; first by apply POST_sc.
258+
have ->: shift + length P = END.
259+
{ rewrite P_length. cbn. lia. }
260+
by apply: POST_spec.
261+
Qed.
262+
263+
Lemma simulation_output q q' t t' k :
264+
steps M k (q, t) = Some (q', t') ->
265+
(shift, P) // (encode_config (q, t)) ->> (encode_config (q', t')).
171266
Proof.
172-
move=> /PROG_spec_None [v Hv]. exists v.
173-
by apply: subcode_sss_compute; [apply: PROG_sc|].
267+
elim: k q t.
268+
- move=> ?? [-> ->].
269+
exists 0.
270+
by constructor.
271+
- move=> k IH q t. rewrite (steps_plus 1) /=.
272+
case E: (step M (q, t)) => [[q'' t'']|].
273+
+ move=> /IH [v] Hv.
274+
move: E => /simulation_step_Some [k' Hk'].
275+
exists ((S k') + v).
276+
apply: sss_steps_trans; by eassumption.
277+
+ by move: E => /simulation_step_None.
278+
Qed.
279+
280+
Lemma simulation_output'' q q' t t' k :
281+
steps M k (q, t) = Some (q', t') ->
282+
steps M (S k) (q, t) = None ->
283+
(shift, P) // (encode_config (q, t)) ->> (shift + length P, encode_tape t').
284+
Proof.
285+
have ->: S k = k + 1 by lia.
286+
rewrite (steps_plus).
287+
move=> /[dup] /simulation_output /sss_compute_trans + -> /= H. apply.
288+
by apply: simulation_step_None.
174289
Qed.
175290

176291
Lemma simulation q t k :
177292
steps M k (q, t) = None ->
178-
exists v, (1, P) // (encode_config (q, t)) ->> (0, v).
293+
exists v, (shift, P) // (encode_config (q, t)) ->> (shift + length P, v).
179294
Proof.
180295
elim: k q t; first done.
181-
move=> k IH q t. rewrite (steps_plus 1) /=.
182-
case E: (step M (q, t)) => [[q' t']|].
183-
- move=> /IH [v] Hv. exists v.
184-
move: E => /simulation_step_Some [?] /sss_steps_compute /sss_compute_trans.
185-
by apply.
186-
- by move: E => /simulation_step_None.
296+
move=> k IH q t /[dup] HSk.
297+
have ->: S k = k + 1 by lia.
298+
rewrite steps_plus.
299+
case E: (steps M k (q, t)) => [[q' t']|].
300+
- move: E HSk => /simulation_output'' /[apply] ??.
301+
eexists. by eassumption.
302+
- move=> ?. by apply: IH.
303+
Qed.
304+
305+
Lemma sss_step_shift t : sss_step (bsm_sss (n:=4)) (shift, P) (shift, encode_tape t) (encode_config (q0, t)).
306+
Proof.
307+
eexists _, [], _, _, _.
308+
split; [reflexivity|split; [by rewrite Nat.add_comm|]].
309+
move: (t) => [[??]?].
310+
by constructor.
311+
Qed.
312+
313+
Lemma simulation_output' q' t t' k :
314+
steps M k (q0, t) = Some (q', t') ->
315+
steps M (S k) (q0, t) = None ->
316+
(shift, P) // (shift, encode_tape t) ->> (shift + length P, encode_tape t').
317+
Proof.
318+
move=> /simulation_output'' /[apply] ?.
319+
apply: sss_compute_trans; last by eassumption.
320+
exists 1.
321+
apply: in_sss_steps_S; last by apply: in_sss_steps_0.
322+
by apply: sss_step_shift.
323+
Qed.
324+
325+
Lemma simulation' t k :
326+
steps M k (q0, t) = None ->
327+
exists v, (shift, P) // (shift, encode_tape t) ->> (shift + length P, v).
328+
Proof.
329+
elim: k; first done.
330+
move=> k IH /[dup] HSk.
331+
have ->: S k = k + 1 by lia.
332+
rewrite steps_plus.
333+
case E: (steps M k (q0, t)) => [[??]|].
334+
- move: E HSk => /simulation_output' /[apply] *.
335+
eexists. by eassumption.
336+
- move=> ?. by apply: IH.
187337
Qed.
188338

189339
Lemma inverse_simulation q t n i v :
190-
(1, P) // (encode_config (q, t)) -[n]-> (i, v) ->
191-
out_code i (1, P) ->
340+
(shift, P) // (encode_config (q, t)) -[n]-> (shift + i, v) ->
341+
out_code (shift + i) (shift, P) ->
192342
exists k, steps M k (q, t) = None.
193343
Proof.
194344
elim /(Nat.measure_induction _ id) : n q t => - [|n] IH q t.
195-
{ move=> /sss_steps_0_inv [] /= <- _.
196-
rewrite /encode_state P_length (ltac:(done) : c = (S (c-1))).
197-
have := svalP (Fin.to_nat q). nia. }
345+
{ move=> /sss_steps_0_inv [] /= <- _ [|].
346+
- rewrite /encode_state. lia.
347+
- rewrite /encode_state length_app length_flat_map_PROG_M.
348+
destruct (Fin.to_nat q).
349+
cbn. nia. }
198350
case E: (step M (q, t)) => [[q' t']|]; last by (move=> _; exists 1).
199351
move: (E) => /simulation_step_Some [m].
200352
move=> Hn Hm Hi. have := (IH (n - m) ltac:(lia) q' t' _ Hi).
@@ -207,6 +359,20 @@ Section Construction.
207359
move=> k Hk. exists (1+k). by rewrite (steps_plus 1) /= E.
208360
Qed.
209361

362+
Lemma inverse_simulation' t n i v :
363+
(shift, P) // (shift, encode_tape t) -[n]-> (shift + i, v) ->
364+
out_code (shift + i) (shift, P) ->
365+
exists k, steps M k (q0, t) = None.
366+
Proof.
367+
case: n.
368+
- move=> /sss_steps_0_inv [] <- _ /=. lia.
369+
- move=> n /sss_steps_S_inv' [[q' t']] [].
370+
have := @bsm_sss_fun 4.
371+
have := sss_step_shift t.
372+
move=> /sss_step_fun /[apply] /[apply] <-.
373+
by apply: inverse_simulation.
374+
Qed.
375+
210376
End Construction.
211377

212378
Require Import Undecidability.Synthetic.Definitions.
@@ -215,15 +381,18 @@ Theorem reduction :
215381
SBTM_HALT ⪯ BSM_HALTING.
216382
Proof.
217383
exists (fun '(existT _ M (q, t)) =>
218-
existT _ 4 (existT _ 1 (existT _ (@P M q) (encode_tape t)))).
384+
existT _ 4 (existT _ 0 (existT _ (@P M q 0) (encode_tape t)))).
219385
move=> [M [q [[ls a] rs]]]. split.
220-
- move=> [k] /simulation => /(_ q) [v Hv] /=.
221-
exists (0, v). split => /=; [|lia].
222-
rewrite /P.
223-
bsm sss POP empty with ZERO (encode_state M q) (encode_state M q).
386+
- move=> [k] /simulation => /(_ q 0) [v Hv] /=.
387+
exists ((5 + (num_states M) * c), v). split => /=.
388+
+ rewrite /P.
389+
rewrite P_length in Hv.
390+
bsm sss POP empty with ZERO (encode_state M 0 q ) (encode_state M 0 q).
391+
+ right.
392+
rewrite length_app length_flat_map_PROG_M /=. lia.
224393
- move=> [] [i v] [] [?] H /= ?.
225394
rewrite /P in H.
226-
bsm inv POP empty with H ZERO (encode_state M q) (encode_state M q).
395+
bsm inv POP empty with H ZERO (encode_state M 0 q) (encode_state M 0 q).
227396
+ move: H => [?] [?] /inverse_simulation. by apply.
228397
+ move=> []. lia.
229398
Qed.

0 commit comments

Comments
 (0)