@@ -20,7 +20,8 @@ Set Default Goal Selector "!".
2020
2121Section 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+
210376End Construction.
211377
212378Require Import Undecidability.Synthetic.Definitions.
@@ -215,15 +381,18 @@ Theorem reduction :
215381 SBTM_HALT ⪯ BSM_HALTING.
216382Proof .
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.
229398Qed .
0 commit comments