Repository navigation
Expand file tree
/
Copy pathSubroutines.lean
More file actions
3692 lines (3373 loc) · 191 KB
/
Copy pathSubroutines.lean
File metadata and controls
3692 lines (3373 loc) · 191 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/-
Copyright (c) 2026 Google LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
-/
module
public import Cryptids.Semantics.Zf.Dispatcher
public import Cryptids.Semantics.Zf.RegisterMachine
/-!
# Call-Stack Subroutine Verification for `zf_432_wade.tm`
This module bridges the abstract call-stack + register machine (`Layer2.ZfRegHalts` in
`Cryptids.Semantics.Zf.Dispatcher`) and the functional main-loop model (`MainLoopHalts` in
`Cryptids.Semantics.Zf.RegisterMachine`).
-/
@[expose] public section
namespace ConjectureMachines.Semantics.Zf
open Turing (Dir)
open StateTransition ConjectureMachines.Semantics.Zf ConjectureMachines.Semantics.Zf.Layer2
attribute [-simp] Nat.add_eq_right
/-! ## Section 1: Fixed-Width 11-Register Machine (`zfReg11Step`) -/
/-- Fixed-width 11-register step: identical to `zfRegStep` except that `decnz` success does not
append a trailing `0` register, keeping `regs.length = 11` invariant. -/
def zfReg11Step (c : ZfRegCfg) : Option ZfRegCfg :=
match evalStack c.stack with
| .halt => none
| .jump stack' => some ⟨stack', c.regs⟩
| .inc r stack_succ =>
some ⟨stack_succ, c.regs.set r (c.regs.getD r 0 + 1)⟩
| .decnz r stack_succ stack_fail =>
if c.regs.getD r 0 == 0 then
some ⟨stack_fail, c.regs⟩
else
some ⟨stack_succ, c.regs.set r (c.regs.getD r 0 - 1)⟩
/-- `n`-step execution of `zfReg11Step`. -/
def zfReg11NSteps : ℕ → ZfRegCfg → Option ZfRegCfg
| 0, c => some c
| n + 1, c => (zfReg11Step c).bind (zfReg11NSteps n)
@[simp]
theorem zfReg11NSteps_zero (c : ZfRegCfg) : zfReg11NSteps 0 c = some c := rfl
@[simp]
theorem zfReg11NSteps_succ (n : ℕ) (c : ZfRegCfg) :
zfReg11NSteps (n + 1) c = (zfReg11Step c).bind (zfReg11NSteps n) := rfl
theorem zfReg11Step_one {c c' : ZfRegCfg} (h : zfReg11Step c = some c') :
zfReg11NSteps 1 c = some c' := by
simp [zfReg11NSteps, h]
theorem step_zfReg11NSteps {n : ℕ} {c₁ c₂ c₃ : ZfRegCfg}
(h1 : zfReg11Step c₁ = some c₂) (h2 : zfReg11NSteps n c₂ = some c₃) :
zfReg11NSteps (n + 1) c₁ = some c₃ := by
simp [zfReg11NSteps, h1, h2]
theorem zfReg11NSteps_add (m n : ℕ) (c : ZfRegCfg) :
zfReg11NSteps (m + n) c = (zfReg11NSteps m c).bind (zfReg11NSteps n) := by
induction m generalizing c with
| zero => simp
| succ m ih =>
simp only [Nat.succ_add, zfReg11NSteps_succ]
cases zfReg11Step c <;> simp [ih]
theorem zfReg11NSteps_bind_eq {m n : ℕ} {c₁ c₂ c₃ : ZfRegCfg}
(h1 : zfReg11NSteps m c₁ = some c₂) (h2 : zfReg11NSteps n c₂ = some c₃) :
zfReg11NSteps (m + n) c₁ = some c₃ := by
rw [zfReg11NSteps_add, h1, Option.bind_some, h2]
theorem zfReg11Step_sim {c₁ c₂ : ZfRegCfg} (hsim : ZfRegSim c₁ c₂) :
match zfRegStep c₁, zfReg11Step c₂ with
| none, none => True
| some c₁', some c₂' => ZfRegSim c₁' c₂'
| _, _ => False := by
rcases hsim with ⟨hstack, hlen₁, hlen₂, htake⟩
have hr_lt := evalStack_reg_lt_11 c₁.stack
unfold zfRegStep zfReg11Step
rw [← hstack]
rcases hev : evalStack c₁.stack with _ | stack' | ⟨r, stack_succ⟩ | ⟨r, stack_succ, stack_fail⟩
· trivial
· exact ⟨rfl, hlen₁, hlen₂, htake⟩
· rw [hev] at hr_lt
have hget := getD_eq_of_take_11 hr_lt htake
refine ⟨rfl, by simp [hlen₁], by simp [hlen₂], ?_⟩
rw [List.take_set, List.take_set, hget, htake]
· rw [hev] at hr_lt
have hget := getD_eq_of_take_11 hr_lt htake
dsimp only
rw [hget]
by_cases hz : (c₂.regs.getD r 0 == 0) = true
· simp only [hz, ↓reduceIte]
exact ⟨rfl, hlen₁, hlen₂, htake⟩
· simp only [hz, Bool.false_eq_true, ↓reduceIte]
refine ⟨rfl, by simp; omega, by simp [hlen₂], ?_⟩
dsimp only
have hle₁ : 11 ≤ (c₁.regs.set r (c₂.regs.getD r 0 - 1)).length := by simp [hlen₁]
rw [List.take_append_of_le_length hle₁, List.take_set, List.take_set, htake]
theorem zfRegHalts_iff_exists_zfReg11NSteps :
ZfRegHalts ↔ ∃ n c, zfReg11NSteps n zfRegInit = some c ∧ zfReg11Step c = none := by
rw [zfRegHalts_iff_exists_zfRegNSteps]
have hsim₀ : ZfRegSim zfRegInit zfRegInit := ⟨rfl, by decide, by decide, rfl⟩
constructor
· rintro ⟨n, ch₁, hn, hnone⟩
have hstep_n : ∀ m {a₁ a₂ : ZfRegCfg}, ZfRegSim a₁ a₂ →
zfRegNSteps m a₁ = some ch₁ →
∃ ch₂, zfReg11NSteps m a₂ = some ch₂ ∧ ZfRegSim ch₁ ch₂ := by
intro m
induction m with
| zero =>
intro a₁ a₂ hsim_a hm
injection hm with hm'; subst hm'
exact ⟨a₂, rfl, hsim_a⟩
| succ m ih =>
intro a₁ a₂ hsim_a hm
unfold zfRegNSteps at hm
unfold zfReg11NSteps
have hstep := zfReg11Step_sim hsim_a
rcases hs₁ : zfRegStep a₁ with _ | a₁' <;> rcases hs₂ : zfReg11Step a₂ with _ | a₂'
· rw [hs₁] at hm; cases hm
· rw [hs₁, hs₂] at hstep; cases hstep
· rw [hs₁, hs₂] at hstep; cases hstep
· rw [hs₁, hs₂] at hstep
rw [hs₁, Option.bind_some] at hm
exact ih hstep hm
obtain ⟨ch₂, hn₂, hsim_ch⟩ := hstep_n n hsim₀ hn
have hstep_ch := zfReg11Step_sim hsim_ch
rw [hnone] at hstep_ch
rcases hs₂ : zfReg11Step ch₂ with _ | ch₂'
· exact ⟨n, ch₂, hn₂, hs₂⟩
· rw [hs₂] at hstep_ch; cases hstep_ch
· rintro ⟨n, ch₂, hn, hnone⟩
have hstep_n : ∀ m {a₁ a₂ : ZfRegCfg}, ZfRegSim a₁ a₂ →
zfReg11NSteps m a₂ = some ch₂ →
∃ ch₁, zfRegNSteps m a₁ = some ch₁ ∧ ZfRegSim ch₁ ch₂ := by
intro m
induction m with
| zero =>
intro a₁ a₂ hsim_a hm
injection hm with hm'; subst hm'
exact ⟨a₁, rfl, hsim_a⟩
| succ m ih =>
intro a₁ a₂ hsim_a hm
unfold zfReg11NSteps at hm
unfold zfRegNSteps
have hstep := zfReg11Step_sim hsim_a
rcases hs₁ : zfRegStep a₁ with _ | a₁' <;> rcases hs₂ : zfReg11Step a₂ with _ | a₂'
· rw [hs₂] at hm; cases hm
· rw [hs₁, hs₂] at hstep; cases hstep
· rw [hs₁, hs₂] at hstep; cases hstep
· rw [hs₁, hs₂] at hstep
rw [hs₂, Option.bind_some] at hm
exact ih hstep hm
obtain ⟨ch₁, hn₁, hsim_ch⟩ := hstep_n n hsim₀ hn
have hstep_ch := zfReg11Step_sim hsim_ch
rw [hnone] at hstep_ch
rcases hs₁ : zfRegStep ch₁ with _ | ch₁'
· exact ⟨n, ch₁, hn₁, hs₁⟩
· rw [hs₁] at hstep_ch; cases hstep_ch
/-! ## Section 2: Return-Stack & Prefix-Invariance Lemmas -/
/-- Return stack when breaking out of a subroutine at call-stack prefix `P`. -/
def retStack (P : List (Fin 2)) : List (Fin 2) :=
(popBreakRev 0 P.reverse).reverse
@[simp]
theorem retStack_append_zero (P : List (Fin 2)) :
retStack (P ++ [0]) = P ++ [1] := by
simp [retStack]
@[simp]
theorem retStack_append_one (P : List (Fin 2)) :
retStack (P ++ [1]) = retStack P := by
simp [retStack]
@[simp]
theorem retStack_replicate_one (k : ℕ) :
retStack (List.replicate k 1) = [] := by
induction k with
| zero => rfl
| succ k ih =>
rw [List.replicate_succ', retStack_append_one, ih]
@[simp]
theorem trimZeros_append_zero (P : List (Fin 2)) :
trimZeros (P ++ [0]) = trimZeros P := by
simp [trimZeros]
@[simp]
theorem trimZeros_append_one (P : List (Fin 2)) :
trimZeros (P ++ [1]) = P ++ [1] := by
simp [trimZeros]
@[simp]
theorem trimZeros_replicate_zero (k : ℕ) :
trimZeros (List.replicate k 0) = [] := by
induction k with
| zero => rfl
| succ k ih =>
rw [List.replicate_succ', trimZeros_append_zero, ih]
@[simp]
theorem trimZeros_replicate_one (k : ℕ) :
trimZeros (List.replicate k 1) = List.replicate k 1 := by
cases k with
| zero => rfl
| succ k =>
rw [List.replicate_succ', trimZeros_append_one]
theorem popContinueRev_zero_eq_dropLeadingZeros (rev : List (Fin 2)) :
popContinueRev 0 rev = dropLeadingZeros rev := by
induction rev with
| nil => rfl
| cons b rest ih =>
rcases b with ⟨_ | _ | n, hn⟩
· simp [ih]
· rfl
· omega
theorem applyContinue_zero_eq_trimZeros (bits : List (Fin 2)) (pos : ℕ) :
applyContinue bits pos 0 = trimZeros (padTo bits pos) := by
simp [applyContinue, trimZeros, popContinueRev_zero_eq_dropLeadingZeros]
theorem walkInternal_snoc {q q_mid q_end : Fin 432} {P : List (Fin 2)} {b : Fin 2}
(hP : walkInternal q P = some q_mid)
(htr : refTrans q_mid b = some (b, .right, q_end))
(hq_end : 96 ≤ q_end.val) :
walkInternal q (P ++ [b]) = some q_end := by
have hge := (walkInternal_ge_96 hP).2
rw [walkInternal_append, hP, Option.bind_some]
simp [walkInternal, hge, htr, hq_end]
theorem count_zero_replicate_zero (m : ℕ) :
(List.replicate m (0 : Fin 2)).count 0 = m := by
simp
/-- Key prefix-invariance theorem: for any `P` that walks in `96..431` from `126` to `q`,
`evalStack (trimZeros P)` and `evalStack P` produce the exact same instruction, and it is
the leaf instruction at `zeroLeaf q` after `zeroDepth q` zero-steps from `P`. -/
theorem evalStack_of_walkInternal {P : List (Fin 2)} {q : Fin 432}
(h : walkInternal 126 P = some q) :
evalStack (trimZeros P) = evalStack P ∧
evalStack P =
if isLeafInc (zeroLeaf q) then
.inc (leafReg (zeroLeaf q)) (applyBreak P (P.length + zeroDepth q) 0)
else
.decnz (leafReg (zeroLeaf q)) (applyBreak P (P.length + zeroDepth q) 0)
(applyBreak P (P.length + zeroDepth q) 1) := by
have hq : 96 ≤ q.val := (walkInternal_ge_96 h).2
have hz := zeroStepBool_all q
simp only [zeroStepBool, hq, ↓reduceIte, Bool.and_eq_true, decide_eq_true_eq,
Bool.and_assoc] at hz
rcases hz with ⟨hd1, _, hd_max0, _, _, _⟩
have hb := walkInternal_root_bounds h
have hd_eq : zeroDepth q = (zeroDepth q - 1) + 1 := by omega
have hrep := walkTape_replicate_zero (zeroDepth q - 1) hq hd_eq P (pad := 12) (by omega)
rcases hrep with ⟨hw_pad, _, _⟩
rw [← hd_eq] at hw_pad
have hwalk_P : walkTape 126 [] (P ++ List.replicate 12 0) =
.regLeaf (zeroLeaf q) (P ++ List.replicate (zeroDepth q) 0)
(List.replicate (12 - zeroDepth q) 0) := by
rw [walkTape_of_walkInternal h [] (List.replicate 12 0), List.nil_append, hw_pad]
have hev_P : evalStack P =
if isLeafInc (zeroLeaf q) then
.inc (leafReg (zeroLeaf q)) (applyBreak P (P.length + zeroDepth q) 0)
else
.decnz (leafReg (zeroLeaf q)) (applyBreak P (P.length + zeroDepth q) 0)
(applyBreak P (P.length + zeroDepth q) 1) :=
evalStack_of_regLeaf hwalk_P
let m := P.length - (trimZeros P).length
have hm_def : m = P.length - (trimZeros P).length := rfl
have hP_split : P = trimZeros P ++ List.replicate m 0 := eq_trimZeros_append_replicate P
have hm_cnt : m ≤ P.count 0 := by
have hcnt := congrArg (List.count 0) hP_split
rw [List.count_append, count_zero_replicate_zero] at hcnt
omega
have hm_12 : m + zeroDepth q ≤ 12 := by omega
have h12_split : List.replicate 12 (0 : Fin 2) =
List.replicate m 0 ++ List.replicate (12 - m) 0 := by
rw [← List.replicate_add, Nat.add_sub_of_le (by omega)]
have hrep_trim :=
walkTape_replicate_zero (zeroDepth q - 1) hq hd_eq P (pad := 12 - m) (by omega)
rcases hrep_trim with ⟨hw_pad_trim, _, _⟩
rw [← hd_eq] at hw_pad_trim
have hwalk_trim : walkTape 126 [] (trimZeros P ++ List.replicate 12 0) =
.regLeaf (zeroLeaf q) (P ++ List.replicate (zeroDepth q) 0)
(List.replicate (12 - m - zeroDepth q) 0) := by
rw [h12_split, ← List.append_assoc, ← hP_split,
walkTape_of_walkInternal h [] (List.replicate (12 - m) 0), List.nil_append, hw_pad_trim]
have hpad_eq : padTo (trimZeros P) (P.length + zeroDepth q) =
padTo P (P.length + zeroDepth q) := by
have hle1 : (trimZeros P).length ≤ P.length := trimZeros_length_le P
rw [padTo_of_le (by omega), padTo_of_le (by omega)]
have hsub : P.length + zeroDepth q - (trimZeros P).length = m + zeroDepth q := by omega
rw [hsub, List.replicate_add, ← List.append_assoc, ← hP_split, Nat.add_sub_cancel_left]
have hbrk_eq : ∀ k, applyBreak (trimZeros P) (P.length + zeroDepth q) k =
applyBreak P (P.length + zeroDepth q) k := by
intro k
simp [applyBreak, hpad_eq]
have hev_trim : evalStack (trimZeros P) = evalStack P := by
unfold evalStack
rw [hwalk_trim, hwalk_P]
unfold outcomeToInstr
simp [hbrk_eq]
exact ⟨hev_trim, hev_P⟩
theorem evalStack_trimZeros_of_walkInternal {P : List (Fin 2)} {q : Fin 432}
(h : walkInternal 126 P = some q) :
evalStack (trimZeros P) = evalStack P :=
(evalStack_of_walkInternal h).1
/-- When `q` has a direct `0`-transition to a leaf `q' ∈ {49..70}`, `evalStack P` (and hence
`evalStack (trimZeros P)`) executes `q'` with success stack `P ++ [1]` and fail stack
`retStack P`. -/
theorem evalStack_leaf0_of_walkInternal {P : List (Fin 2)} {q q' : Fin 432}
(h : walkInternal 126 P = some q)
(htr : refTrans q 0 = some (0, .right, q'))
(h49 : 49 ≤ q'.val) (h70 : q'.val ≤ 70) :
evalStack P =
if isLeafInc q' then
.inc (leafReg q') (P ++ [1])
else
.decnz (leafReg q') (P ++ [1]) (retStack P) := by
have hleaf : (49 ≤ q'.val && q'.val ≤ 70) = true := by
rw [Bool.and_eq_true, decide_eq_true_eq, decide_eq_true_eq]; exact ⟨h49, h70⟩
have hwalk : walkTape 126 [] (P ++ List.replicate 12 0) =
.regLeaf q' (P ++ [0]) (List.replicate 11 0) := by
rw [walkTape_of_walkInternal h [] (List.replicate 12 0), List.nil_append]
change walkTape q P (0 :: List.replicate 11 0) = _
simp [walkTape, htr, hleaf]
have hev := evalStack_of_regLeaf (m := 1) hwalk
have hpad : padTo P (P.length + 1) = P ++ [0] := by
rw [padTo_of_le (by omega)]
simp
have hbrk0 : applyBreak P (P.length + 1) 0 = P ++ [1] := by
simp [applyBreak, hpad]
have hbrk1 : applyBreak P (P.length + 1) 1 = retStack P := by
simp [applyBreak, hpad, retStack]
rw [hev, hbrk0, hbrk1]
/-- When `q` has a direct `1`-transition to an increment leaf `q' ∈ {49..70}`,
`evalStack (P ++ [1])` increments `leafReg q'` and transitions to `retStack P`. -/
theorem evalStack_leaf1_inc_of_walkInternal {P : List (Fin 2)} {q q' : Fin 432}
(h : walkInternal 126 P = some q)
(htr : refTrans q 1 = some (1, .right, q'))
(h49 : 49 ≤ q'.val) (h70 : q'.val ≤ 70) (hinc : isLeafInc q' = true) :
evalStack (P ++ [1]) = .inc (leafReg q') (retStack P) := by
have hleaf : (49 ≤ q'.val && q'.val ≤ 70) = true := by
rw [Bool.and_eq_true, decide_eq_true_eq, decide_eq_true_eq]; exact ⟨h49, h70⟩
have hwalk : walkTape 126 [] ((P ++ [1]) ++ List.replicate 12 0) =
.regLeaf q' (P ++ [1]) (List.replicate 12 0) := by
rw [List.append_assoc, walkTape_of_walkInternal h [] ([1] ++ List.replicate 12 0),
List.nil_append]
change walkTape q P (1 :: List.replicate 12 0) = _
simp [walkTape, htr, hleaf]
have hev := evalStack_of_regLeaf (bits := P ++ [1]) (m := 0) (by simpa using hwalk)
have hpad : padTo (P ++ [1]) (P.length + 1) = P ++ [1] := by
rw [padTo_of_le (by simp)]
simp
have hbrk0 : applyBreak (P ++ [1]) ((P ++ [1]).length + 0) 0 = retStack P := by
simp [applyBreak, hpad, retStack]
rw [hev, hbrk0]
simp [hinc]
/-- When `q` has a `1`-transition `(0, .left, 89 + k)` (`6.break.k`, `k ≤ 2`),
`evalStack (P ++ [1])` jumps to `(popBreakRev k P.reverse).reverse`. -/
theorem evalStack_break1_of_walkInternal {P : List (Fin 2)} {q : Fin 432} {k : ℕ}
(hk2 : k ≤ 2) (h : walkInternal 126 P = some q)
(htr : refTrans q 1 = some (0, .left, ⟨89 + k, by omega⟩)) :
evalStack (P ++ [1]) = .jump (popBreakRev k P.reverse).reverse := by
have hwalk : walkTape 126 [] ((P ++ [1]) ++ List.replicate 12 0) =
.jumpLeft ⟨89 + k, by omega⟩ P (List.replicate 12 0) := by
rw [List.append_assoc, walkTape_of_walkInternal h [] ([1] ++ List.replicate 12 0),
List.nil_append]
change walkTape q P (1 :: List.replicate 12 0) = _
simp [walkTape, htr]
rw [evalStack_of_jumpBreak hk2 hwalk]
have hpad : padTo (P ++ [1]) P.length = P := by
rw [padTo_of_ge (by simp)]
simp
simp [applyBreak, hpad]
/-- When `q` has a `1`-transition `(0, .left, 92 + k)` (`6.continue.k`, `k ≤ 3`),
`evalStack (P ++ [1])` jumps to `(popContinueRev k P.reverse).reverse`. -/
theorem evalStack_continue1_of_walkInternal {P : List (Fin 2)} {q : Fin 432} {k : ℕ}
(hk3 : k ≤ 3) (h : walkInternal 126 P = some q)
(htr : refTrans q 1 = some (0, .left, ⟨92 + k, by omega⟩)) :
evalStack (P ++ [1]) = .jump (popContinueRev k P.reverse).reverse := by
have hwalk : walkTape 126 [] ((P ++ [1]) ++ List.replicate 12 0) =
.jumpLeft ⟨92 + k, by omega⟩ P (List.replicate 12 0) := by
rw [List.append_assoc, walkTape_of_walkInternal h [] ([1] ++ List.replicate 12 0),
List.nil_append]
change walkTape q P (1 :: List.replicate 12 0) = _
simp [walkTape, htr]
rw [evalStack_of_jumpContinue hk3 hwalk]
have hpad : padTo (P ++ [1]) P.length = P := by
rw [padTo_of_ge (by simp)]
simp
simp [applyContinue, hpad]
/-! ## Section 3: Universal Subroutine Specification (`SubEval`) & Combinators -/
/-- Universal specification of a decision-tree subroutine node `q ∈ {96..431}`:
for any call-stack prefix `P` reaching `q` from `126` (`walkInternal 126 P = some q`) and any
11-register bank `regs`, starting from `⟨trimZeros P, regs⟩` reaches `⟨retStack P, f regs⟩`
in `s ≥ 1` steps of `zfReg11Step`. -/
def SubEval (q : Fin 432) (f : List ℕ → List ℕ) : Prop :=
∀ (P : List (Fin 2)),
walkInternal 126 P = some q →
∀ (regs : List ℕ), regs.length = 11 →
∃ s ≥ 1, zfReg11NSteps s ⟨trimZeros P, regs⟩ = some ⟨retStack P, f regs⟩ ∧
(f regs).length = 11
theorem SubEval.congr {q : Fin 432} {f g : List ℕ → List ℕ}
(h : SubEval q f) (heq : ∀ regs, regs.length = 11 → f regs = g regs) :
SubEval q g := by
intro P hP regs hlen
obtain ⟨s, hs, hsteps, hflen⟩ := h P hP regs hlen
rw [heq regs hlen] at hsteps hflen
exact ⟨s, hs, hsteps, hflen⟩
/-- Sequential composition combinator: if `q` transitions on `0` to `q₀` (`96 ≤ q₀.val`) and on
`1` to `q₁` (`96 ≤ q₁.val`), then `SubEval q₀ f₀` and `SubEval q₁ f₁` compose to
`SubEval q (fun regs => f₁ (f₀ regs))`. -/
theorem subEval_seq {q q₀ q₁ : Fin 432} {f₀ f₁ : List ℕ → List ℕ}
(htr0 : refTrans q 0 = some (0, .right, q₀)) (hq₀ : 96 ≤ q₀.val)
(htr1 : refTrans q 1 = some (1, .right, q₁)) (hq₁ : 96 ≤ q₁.val)
(h0 : SubEval q₀ f₀) (h1 : SubEval q₁ f₁) :
SubEval q (fun regs => f₁ (f₀ regs)) := by
intro P hP regs hlen
have hP0 : walkInternal 126 (P ++ [0]) = some q₀ := walkInternal_snoc hP htr0 hq₀
have hP1 : walkInternal 126 (P ++ [1]) = some q₁ := walkInternal_snoc hP htr1 hq₁
obtain ⟨s₀, hs₀, hsteps₀, hlen₀⟩ := h0 (P ++ [0]) hP0 regs hlen
rw [trimZeros_append_zero, retStack_append_zero] at hsteps₀
obtain ⟨s₁, hs₁, hsteps₁, hlen₁⟩ := h1 (P ++ [1]) hP1 (f₀ regs) hlen₀
rw [trimZeros_append_one, retStack_append_one] at hsteps₁
exact ⟨s₀ + s₁, by omega, zfReg11NSteps_bind_eq hsteps₀ hsteps₁, hlen₁⟩
theorem zfReg11Step_of_jump {s s' : List (Fin 2)} {regs : List ℕ}
(h : evalStack s = .jump s') :
zfReg11Step ⟨s, regs⟩ = some ⟨s', regs⟩ := by
unfold zfReg11Step; dsimp only; rw [h]
theorem zfReg11Step_of_inc {s s' : List (Fin 2)} {r : ℕ} {regs : List ℕ}
(h : evalStack s = .inc r s') :
zfReg11Step ⟨s, regs⟩ = some ⟨s', regs.set r (regs.getD r 0 + 1)⟩ := by
unfold zfReg11Step; dsimp only; rw [h]
theorem zfReg11Step_of_decnz_zero {s s_succ s_fail : List (Fin 2)} {r : ℕ} {regs : List ℕ}
(h : evalStack s = .decnz r s_succ s_fail) (hz : regs.getD r 0 = 0) :
zfReg11Step ⟨s, regs⟩ = some ⟨s_fail, regs⟩ := by
unfold zfReg11Step; dsimp only; rw [h]; dsimp only; rw [hz]; rfl
theorem zfReg11Step_of_decnz_succ {s s_succ s_fail : List (Fin 2)} {r v : ℕ} {regs : List ℕ}
(h : evalStack s = .decnz r s_succ s_fail) (hv : regs.getD r 0 = v + 1) :
zfReg11Step ⟨s, regs⟩ = some ⟨s_succ, regs.set r v⟩ := by
unfold zfReg11Step; dsimp only; rw [h]; dsimp only; rw [hv]; rfl
/-- Sequential + increment leaf combinator: if `q` transitions on `0` to `q₀` (`96 ≤ q₀.val`) and
on `1` to an increment leaf `q₁ ∈ {49..70}`, then `SubEval q₀ f₀` composes with the increment of
`leafReg q₁`. -/
theorem subEval_seq_inc {q q₀ q₁ : Fin 432} {f₀ : List ℕ → List ℕ}
(htr0 : refTrans q 0 = some (0, .right, q₀)) (hq₀ : 96 ≤ q₀.val)
(htr1 : refTrans q 1 = some (1, .right, q₁))
(h49 : 49 ≤ q₁.val) (h70 : q₁.val ≤ 70) (hinc : isLeafInc q₁ = true)
(h0 : SubEval q₀ f₀) :
SubEval q (fun regs =>
let r := f₀ regs
r.set (leafReg q₁) (r.getD (leafReg q₁) 0 + 1)) := by
intro P hP regs hlen
have hP0 : walkInternal 126 (P ++ [0]) = some q₀ := walkInternal_snoc hP htr0 hq₀
obtain ⟨s₀, hs₀, hsteps₀, hlen₀⟩ := h0 (P ++ [0]) hP0 regs hlen
rw [trimZeros_append_zero, retStack_append_zero] at hsteps₀
have hev1 := evalStack_leaf1_inc_of_walkInternal hP htr1 h49 h70 hinc
have hstep1 := zfReg11Step_of_inc (regs := f₀ regs) hev1
refine ⟨s₀ + 1, by omega, zfReg11NSteps_bind_eq hsteps₀ (zfReg11Step_one hstep1), ?_⟩
simp [hlen₀]
/-- Two-increment leaf node combinator: if `q` transitions on `0` to increment leaf `q₀` and on
`1` to increment leaf `q₁`, then `q` increments `leafReg q₀` followed by `leafReg q₁`. -/
theorem subEval_inc_inc {q q₀ q₁ : Fin 432}
(htr0 : refTrans q 0 = some (0, .right, q₀))
(h0_49 : 49 ≤ q₀.val) (h0_70 : q₀.val ≤ 70) (hinc0 : isLeafInc q₀ = true)
(htr1 : refTrans q 1 = some (1, .right, q₁))
(h1_49 : 49 ≤ q₁.val) (h1_70 : q₁.val ≤ 70) (hinc1 : isLeafInc q₁ = true) :
SubEval q (fun regs =>
let r₁ := regs.set (leafReg q₀) (regs.getD (leafReg q₀) 0 + 1)
r₁.set (leafReg q₁) (r₁.getD (leafReg q₁) 0 + 1)) := by
intro P hP regs hlen
have hev0 : evalStack (trimZeros P) = .inc (leafReg q₀) (P ++ [1]) := by
rw [evalStack_trimZeros_of_walkInternal hP, evalStack_leaf0_of_walkInternal hP htr0 h0_49 h0_70]
simp [hinc0]
have hstep0 := zfReg11Step_of_inc (regs := regs) hev0
have hev1 := evalStack_leaf1_inc_of_walkInternal hP htr1 h1_49 h1_70 hinc1
let r₁ := regs.set (leafReg q₀) (regs.getD (leafReg q₀) 0 + 1)
have hstep1 := zfReg11Step_of_inc (regs := r₁) hev1
refine ⟨2, by omega, step_zfReg11NSteps hstep0 (zfReg11Step_one hstep1), ?_⟩
simp [hlen]
/-- Increment leaf + sequential combinator: if `q` transitions on `0` to an increment leaf
`q₀ ∈ {49..70}` and on `1` to `q₁` (`96 ≤ q₁.val`), then `q` increments `leafReg q₀` followed by
`f₁`. -/
theorem subEval_inc_seq {q q₀ q₁ : Fin 432} {f₁ : List ℕ → List ℕ}
(htr0 : refTrans q 0 = some (0, .right, q₀))
(h49 : 49 ≤ q₀.val) (h70 : q₀.val ≤ 70) (hinc : isLeafInc q₀ = true)
(htr1 : refTrans q 1 = some (1, .right, q₁)) (hq₁ : 96 ≤ q₁.val)
(h1 : SubEval q₁ f₁) :
SubEval q (fun regs =>
f₁ (regs.set (leafReg q₀) (regs.getD (leafReg q₀) 0 + 1))) := by
intro P hP regs hlen
have hev0 : evalStack (trimZeros P) = .inc (leafReg q₀) (P ++ [1]) := by
rw [evalStack_trimZeros_of_walkInternal hP, evalStack_leaf0_of_walkInternal hP htr0 h49 h70]
simp [hinc]
let r₀ := regs.set (leafReg q₀) (regs.getD (leafReg q₀) 0 + 1)
have hstep0 : zfReg11Step ⟨trimZeros P, regs⟩ = some ⟨P ++ [1], r₀⟩ :=
zfReg11Step_of_inc hev0
have hP1 : walkInternal 126 (P ++ [1]) = some q₁ := walkInternal_snoc hP htr1 hq₁
obtain ⟨s₁, hs₁, hsteps₁, hlen₁⟩ := h1 (P ++ [1]) hP1 r₀ (by simp [r₀, hlen])
rw [trimZeros_append_one, retStack_append_one] at hsteps₁
exact ⟨s₁ + 1, by omega, step_zfReg11NSteps hstep0 hsteps₁, hlen₁⟩
/-! ## Section 4: Register Bank Arithmetic Helpers & Parametric Loop Lemmas -/
theorem getD_set_self (regs : List ℕ) (r v : ℕ) (hr : r < regs.length) :
(regs.set r v).getD r 0 = v := by
simp [List.getD_eq_getElem?_getD, hr]
theorem getD_set_ne (regs : List ℕ) {r₁ r₂ : ℕ} (v : ℕ) (hne : r₁ ≠ r₂) :
(regs.set r₁ v).getD r₂ 0 = regs.getD r₂ 0 := by
simp [List.getD_eq_getElem?_getD, hne]
theorem set_getD_self (regs : List ℕ) (r : ℕ) :
regs.set r (regs.getD r 0) = regs := by
apply List.ext_getElem
· simp
· intro i hi1 hi2
rw [List.getElem_set]
split_ifs with heq
· subst heq
simp [List.getD_eq_getElem?_getD, List.getElem?_eq_getElem hi2]
· rfl
theorem set_eq_self_of_getD_eq {regs : List ℕ} {r v : ℕ} (h : regs.getD r 0 = v) :
regs.set r v = regs := by
rw [← h, set_getD_self]
theorem set_comm_of_ne (regs : List ℕ) {r₁ r₂ : ℕ} (v₁ v₂ : ℕ) (hne : r₁ ≠ r₂) :
(regs.set r₁ v₁).set r₂ v₂ = (regs.set r₂ v₂).set r₁ v₁ :=
List.set_comm v₁ v₂ hne
/-- Parametric `while_decnz(r, ())` loop: clears register `r` to `0`.
Covers states `381, 385, 391, 395, 398, 415, 420, 421`. -/
theorem subEval_while_clear {q q_dec : Fin 432} (r : ℕ) (hr : r < 11)
(htr0 : refTrans q 0 = some (0, .right, q_dec))
(h49 : 49 ≤ q_dec.val) (h70 : q_dec.val ≤ 70) (hdec : isLeafInc q_dec = false)
(hlr : leafReg q_dec = r)
(htr1 : refTrans q 1 = some (0, .left, 92)) :
SubEval q (fun regs => regs.set r 0) := by
intro P hP
have hev0 : evalStack (trimZeros P) = .decnz r (P ++ [1]) (retStack P) := by
rw [evalStack_trimZeros_of_walkInternal hP, evalStack_leaf0_of_walkInternal hP htr0 h49 h70]
simp [hdec, hlr]
have hev1 : evalStack (P ++ [1]) = .jump (trimZeros P) := by
have h := evalStack_continue1_of_walkInternal (k := 0) (by omega) hP htr1
simpa [popContinueRev_zero_eq_dropLeadingZeros, trimZeros] using h
have hloop : ∀ (v : ℕ) (regs : List ℕ), regs.length = 11 → regs.getD r 0 = v →
∃ s ≥ 1, zfReg11NSteps s ⟨trimZeros P, regs⟩ = some ⟨retStack P, regs.set r 0⟩ ∧
(regs.set r 0).length = 11 := by
intro v
induction v with
| zero =>
intro regs hlen hv
have hstep := zfReg11Step_of_decnz_zero hev0 hv
rw [set_eq_self_of_getD_eq hv]
exact ⟨1, le_refl 1, zfReg11Step_one hstep, hlen⟩
| succ v ih =>
intro regs hlen hv
have hstep1 := zfReg11Step_of_decnz_succ hev0 hv
have hstep2 := zfReg11Step_of_jump (regs := regs.set r v) hev1
have hlen' : (regs.set r v).length = 11 := by simp [hlen]
have hv' : (regs.set r v).getD r 0 = v := getD_set_self regs r v (by omega)
obtain ⟨s, hs, hsteps, _⟩ := ih (regs.set r v) hlen' hv'
rw [List.set_set] at hsteps
exact ⟨s + 2, by omega,
step_zfReg11NSteps hstep1 (step_zfReg11NSteps hstep2 hsteps), by simp [hlen]⟩
intro regs hlen
exact hloop (regs.getD r 0) regs hlen rfl
/-- Parametric `while_decnz(r₁, 3.<r₂>.inc)` loop: adds `r₁` into `r₂` and zeroes `r₁`.
Covers states `399, 401, 403, 405, 407, 409, 410, 411, 416, 418, 419, 425, 427, 428`. -/
theorem subEval_while_move1 {q q_dec q₁ q_inc : Fin 432} (r₁ r₂ : ℕ)
(hr₁ : r₁ < 11) (_hr₂ : r₂ < 11) (hne : r₁ ≠ r₂)
(htr0 : refTrans q 0 = some (0, .right, q_dec))
(hdec49 : 49 ≤ q_dec.val) (hdec70 : q_dec.val ≤ 70) (hdec : isLeafInc q_dec = false)
(hlr1 : leafReg q_dec = r₁)
(htr1 : refTrans q 1 = some (1, .right, q₁)) (hq₁ : 96 ≤ q₁.val)
(htr10 : refTrans q₁ 0 = some (0, .right, q_inc))
(hinc49 : 49 ≤ q_inc.val) (hinc70 : q_inc.val ≤ 70) (hinc : isLeafInc q_inc = true)
(hlr2 : leafReg q_inc = r₂)
(htr11 : refTrans q₁ 1 = some (0, .left, 93)) :
SubEval q (fun regs => (regs.set r₁ 0).set r₂ (regs.getD r₂ 0 + regs.getD r₁ 0)) := by
intro P hP
have hP1 : walkInternal 126 (P ++ [1]) = some q₁ := walkInternal_snoc hP htr1 hq₁
have hev0 : evalStack (trimZeros P) = .decnz r₁ (P ++ [1]) (retStack P) := by
rw [evalStack_trimZeros_of_walkInternal hP,
evalStack_leaf0_of_walkInternal hP htr0 hdec49 hdec70]
simp [hdec, hlr1]
have hev10 : evalStack (P ++ [1]) = .inc r₂ (P ++ [1] ++ [1]) := by
have h := evalStack_leaf0_of_walkInternal hP1 htr10 hinc49 hinc70
simpa [hinc, hlr2] using h
have hev11 : evalStack (P ++ [1] ++ [1]) = .jump (trimZeros P) := by
have h := evalStack_continue1_of_walkInternal (P := P ++ [1]) (k := 1) (by omega) hP1 htr11
simpa [popContinueRev_zero_eq_dropLeadingZeros, trimZeros] using h
have hloop : ∀ (v : ℕ) (regs : List ℕ), regs.length = 11 → regs.getD r₁ 0 = v →
∃ s ≥ 1, zfReg11NSteps s ⟨trimZeros P, regs⟩ =
some ⟨retStack P, (regs.set r₁ 0).set r₂ (regs.getD r₂ 0 + v)⟩ ∧
((regs.set r₁ 0).set r₂ (regs.getD r₂ 0 + v)).length = 11 := by
intro v
induction v with
| zero =>
intro regs hlen hv
have hstep := zfReg11Step_of_decnz_zero hev0 hv
have hset : (regs.set r₁ 0).set r₂ (regs.getD r₂ 0 + 0) = regs := by
rw [Nat.add_zero, set_eq_self_of_getD_eq hv, set_getD_self]
rw [hset]
exact ⟨1, le_refl 1, zfReg11Step_one hstep, hlen⟩
| succ v ih =>
intro regs hlen hv
let regs₁ := (regs.set r₁ v).set r₂ (regs.getD r₂ 0 + 1)
have hstep1 := zfReg11Step_of_decnz_succ hev0 hv
have hstep2 : zfReg11Step ⟨P ++ [1], regs.set r₁ v⟩ = some ⟨P ++ [1] ++ [1], regs₁⟩ := by
rw [zfReg11Step_of_inc hev10, getD_set_ne _ _ hne]
have hstep3 := zfReg11Step_of_jump (regs := regs₁) hev11
have hlen₁ : regs₁.length = 11 := by simp [regs₁, hlen]
have hv₁ : regs₁.getD r₁ 0 = v := by
dsimp [regs₁]
rw [getD_set_ne _ _ hne.symm, getD_set_self regs r₁ v (by omega)]
obtain ⟨s, hs, hsteps, _⟩ := ih regs₁ hlen₁ hv₁
have hregs_eq : (regs₁.set r₁ 0).set r₂ (regs₁.getD r₂ 0 + v) =
(regs.set r₁ 0).set r₂ (regs.getD r₂ 0 + (v + 1)) := by
have hr₂_get : regs₁.getD r₂ 0 = regs.getD r₂ 0 + 1 :=
getD_set_self (regs.set r₁ v) r₂ (regs.getD r₂ 0 + 1) (by simp; omega)
rw [hr₂_get]
dsimp only [regs₁]
rw [set_comm_of_ne (regs.set r₁ v) (regs.getD r₂ 0 + 1) 0 hne.symm,
List.set_set, List.set_set]
congr 1
omega
rw [hregs_eq] at hsteps
exact ⟨s + 3, by omega,
step_zfReg11NSteps hstep1 (step_zfReg11NSteps hstep2 (step_zfReg11NSteps hstep3 hsteps)),
by simp [hlen]⟩
intro regs hlen
exact hloop (regs.getD r₁ 0) regs hlen rfl
/-- Parametric `while_decnz(r₁, { inc r₂; inc r₃ })` loop: adds `r₁` into both `r₂` and `r₃`
and zeroes `r₁`. Covers states `382, 386, 387, 388, 392, 393, 394, 396, 397, 412, 422`. -/
theorem subEval_while_move2 {q q_dec q₁ q₂ q_inc1 q_inc2 : Fin 432} (r₁ r₂ r₃ : ℕ)
(hr₁ : r₁ < 11) (hr₂ : r₂ < 11) (hr₃ : r₃ < 11)
(hne12 : r₁ ≠ r₂) (hne13 : r₁ ≠ r₃) (hne23 : r₂ ≠ r₃)
(htr0 : refTrans q 0 = some (0, .right, q_dec))
(hdec49 : 49 ≤ q_dec.val) (hdec70 : q_dec.val ≤ 70) (hdec : isLeafInc q_dec = false)
(hlr1 : leafReg q_dec = r₁)
(htr1 : refTrans q 1 = some (1, .right, q₁)) (hq₁ : 96 ≤ q₁.val)
(htr10 : refTrans q₁ 0 = some (0, .right, q₂)) (hq₂ : 96 ≤ q₂.val)
(htr11 : refTrans q₁ 1 = some (0, .left, 93))
(htr20 : refTrans q₂ 0 = some (0, .right, q_inc1))
(hinc1_49 : 49 ≤ q_inc1.val) (hinc1_70 : q_inc1.val ≤ 70) (hinc1 : isLeafInc q_inc1 = true)
(hlr2 : leafReg q_inc1 = r₂)
(htr21 : refTrans q₂ 1 = some (1, .right, q_inc2))
(hinc2_49 : 49 ≤ q_inc2.val) (hinc2_70 : q_inc2.val ≤ 70) (hinc2 : isLeafInc q_inc2 = true)
(hlr3 : leafReg q_inc2 = r₃) :
SubEval q (fun regs =>
((regs.set r₁ 0).set r₂ (regs.getD r₂ 0 + regs.getD r₁ 0)).set
r₃ (regs.getD r₃ 0 + regs.getD r₁ 0)) := by
intro P hP
have hP1 : walkInternal 126 (P ++ [1]) = some q₁ := walkInternal_snoc hP htr1 hq₁
have hP10 : walkInternal 126 (P ++ [1] ++ [0]) = some q₂ := walkInternal_snoc hP1 htr10 hq₂
have hbody := subEval_inc_inc htr20 hinc1_49 hinc1_70 hinc1 htr21 hinc2_49 hinc2_70 hinc2
have hev0 : evalStack (trimZeros P) = .decnz r₁ (P ++ [1]) (retStack P) := by
rw [evalStack_trimZeros_of_walkInternal hP,
evalStack_leaf0_of_walkInternal hP htr0 hdec49 hdec70]
simp [hdec, hlr1]
have hev11 : evalStack (P ++ [1] ++ [1]) = .jump (trimZeros P) := by
have h := evalStack_continue1_of_walkInternal (P := P ++ [1]) (k := 1) (by omega) hP1 htr11
simpa [popContinueRev_zero_eq_dropLeadingZeros, trimZeros] using h
have hloop : ∀ (v : ℕ) (regs : List ℕ), regs.length = 11 → regs.getD r₁ 0 = v →
∃ s ≥ 1, zfReg11NSteps s ⟨trimZeros P, regs⟩ =
some ⟨retStack P,
((regs.set r₁ 0).set r₂ (regs.getD r₂ 0 + v)).set r₃ (regs.getD r₃ 0 + v)⟩ ∧
(((regs.set r₁ 0).set r₂ (regs.getD r₂ 0 + v)).set
r₃ (regs.getD r₃ 0 + v)).length = 11 := by
intro v
induction v with
| zero =>
intro regs hlen hv
have hstep := zfReg11Step_of_decnz_zero hev0 hv
have hset :
((regs.set r₁ 0).set r₂ (regs.getD r₂ 0 + 0)).set r₃ (regs.getD r₃ 0 + 0) = regs := by
rw [Nat.add_zero, Nat.add_zero, set_eq_self_of_getD_eq hv, set_getD_self, set_getD_self]
rw [hset]
exact ⟨1, le_refl 1, zfReg11Step_one hstep, hlen⟩
| succ v ih =>
intro regs hlen hv
have hstep1 := zfReg11Step_of_decnz_succ hev0 hv
obtain ⟨sb, hsb, hsteps_b, hlen_b⟩ :=
hbody (P ++ [1] ++ [0]) hP10 (regs.set r₁ v) (by simp [hlen])
rw [trimZeros_append_zero, trimZeros_append_one, retStack_append_zero, hlr2, hlr3] at hsteps_b
let regs₁ := ((regs.set r₁ v).set r₂ (regs.getD r₂ 0 + 1)).set r₃ (regs.getD r₃ 0 + 1)
have hb_eq : ((regs.set r₁ v).set r₂ ((regs.set r₁ v).getD r₂ 0 + 1)).set
r₃ (((regs.set r₁ v).set r₂ ((regs.set r₁ v).getD r₂ 0 + 1)).getD r₃ 0 + 1) = regs₁ := by
dsimp only [regs₁]
rw [getD_set_ne _ _ hne12, getD_set_ne _ _ hne23, getD_set_ne _ _ hne13]
dsimp only at hsteps_b
rw [hb_eq] at hsteps_b
have hstep3 := zfReg11Step_of_jump (regs := regs₁) hev11
have hlen₁ : regs₁.length = 11 := by simp [regs₁, hlen]
have hv₁ : regs₁.getD r₁ 0 = v := by
dsimp [regs₁]
rw [getD_set_ne _ _ hne13.symm, getD_set_ne _ _ hne12.symm,
getD_set_self regs r₁ v (by omega)]
obtain ⟨s, hs, hsteps, _⟩ := ih regs₁ hlen₁ hv₁
have hregs_eq :
((regs₁.set r₁ 0).set r₂ (regs₁.getD r₂ 0 + v)).set r₃ (regs₁.getD r₃ 0 + v) =
((regs.set r₁ 0).set r₂ (regs.getD r₂ 0 + (v + 1))).set
r₃ (regs.getD r₃ 0 + (v + 1)) := by
have hr₂_get : regs₁.getD r₂ 0 = regs.getD r₂ 0 + 1 := by
dsimp [regs₁]
rw [getD_set_ne _ _ hne23.symm,
getD_set_self (regs.set r₁ v) r₂ (regs.getD r₂ 0 + 1) (by simp; omega)]
have hr₃_get : regs₁.getD r₃ 0 = regs.getD r₃ 0 + 1 := by
dsimp [regs₁]
exact getD_set_self _ r₃ (regs.getD r₃ 0 + 1) (by simp; omega)
rw [hr₂_get, hr₃_get]
dsimp only [regs₁]
rw [set_comm_of_ne _ (regs.getD r₃ 0 + 1) 0 hne13.symm,
set_comm_of_ne (regs.set r₁ v) (regs.getD r₂ 0 + 1) 0 hne12.symm,
List.set_set,
set_comm_of_ne _ (regs.getD r₃ 0 + 1) (regs.getD r₂ 0 + 1 + v) hne23.symm,
List.set_set, List.set_set]
have hadd1 : regs.getD r₂ 0 + 1 + v = regs.getD r₂ 0 + (v + 1) := by omega
have hadd2 : regs.getD r₃ 0 + 1 + v = regs.getD r₃ 0 + (v + 1) := by omega
rw [hadd1, hadd2]
rw [hregs_eq] at hsteps
have hchain1 := step_zfReg11NSteps hstep1 hsteps_b
have hchain2 := zfReg11NSteps_bind_eq hchain1 (step_zfReg11NSteps hstep3 hsteps)
exact ⟨(sb + 1) + (s + 1), by omega, hchain2, by simp [hlen]⟩
intro regs hlen
exact hloop (regs.getD r₁ 0) regs hlen rfl
/-! ## Section 5: Concrete `while_decnz` Subroutine Instantiations -/
/-- `while_decnz(axiomcode,()).0` (State `381`): clears register `4`. -/
theorem subEval_381 : SubEval 381 (fun regs => regs.set 4 0) :=
subEval_while_clear 4 (by decide) rfl (by decide) (by decide) rfl rfl rfl
/-- `while_decnz(param1,()).0` (State `385`): clears register `5`. -/
theorem subEval_385 : SubEval 385 (fun regs => regs.set 5 0) :=
subEval_while_clear 5 (by decide) rfl (by decide) (by decide) rfl rfl rfl
/-- `while_decnz(param2,()).0` (State `391`): clears register `6`. -/
theorem subEval_391 : SubEval 391 (fun regs => regs.set 6 0) :=
subEval_while_clear 6 (by decide) rfl (by decide) (by decide) rfl rfl rfl
/-- `while_decnz(param3,()).0` (State `395`): clears register `7`. -/
theorem subEval_395 : SubEval 395 (fun regs => regs.set 7 0) :=
subEval_while_clear 7 (by decide) rfl (by decide) (by decide) rfl rfl rfl
/-- `while_decnz(scratch1,()).0` (State `398`): clears register `8`. -/
theorem subEval_398 : SubEval 398 (fun regs => regs.set 8 0) :=
subEval_while_clear 8 (by decide) rfl (by decide) (by decide) rfl rfl rfl
/-- `while_decnz(scratch2,()).0` (State `415`): clears register `9`. -/
theorem subEval_415 : SubEval 415 (fun regs => regs.set 9 0) :=
subEval_while_clear 9 (by decide) rfl (by decide) (by decide) rfl rfl rfl
/-- `while_decnz(scratch3,()).0` (State `420`): clears register `10`. -/
theorem subEval_420 : SubEval 420 (fun regs => regs.set 10 0) :=
subEval_while_clear 10 (by decide) rfl (by decide) (by decide) rfl rfl rfl
/-- `while_decnz(topwff,()).0` (State `421`): clears register `2`. -/
theorem subEval_421 : SubEval 421 (fun regs => regs.set 2 0) :=
subEval_while_clear 2 (by decide) rfl (by decide) (by decide) rfl rfl rfl
/-- `while_decnz(scratch1,3.axiomcode.inc).0` (State `399`):
adds register `8` into `4` and zeroes `8`. -/
theorem subEval_399 :
SubEval 399 (fun regs => (regs.set 8 0).set 4 (regs.getD 4 0 + regs.getD 8 0)) :=
subEval_while_move1 8 4 (by decide) (by decide) (by decide) rfl (by decide) (by decide)
rfl rfl rfl (by decide) rfl (by decide) (by decide) rfl rfl rfl
/-- `while_decnz(scratch1,3.nextproof.inc).0` (State `401`):
adds register `8` into `1` and zeroes `8`. -/
theorem subEval_401 :
SubEval 401 (fun regs => (regs.set 8 0).set 1 (regs.getD 1 0 + regs.getD 8 0)) :=
subEval_while_move1 8 1 (by decide) (by decide) (by decide) rfl (by decide) (by decide)
rfl rfl rfl (by decide) rfl (by decide) (by decide) rfl rfl rfl
/-- `while_decnz(scratch1,3.param1.inc).0` (State `403`):
adds register `8` into `5` and zeroes `8`. -/
theorem subEval_403 :
SubEval 403 (fun regs => (regs.set 8 0).set 5 (regs.getD 5 0 + regs.getD 8 0)) :=
subEval_while_move1 8 5 (by decide) (by decide) (by decide) rfl (by decide) (by decide)
rfl rfl rfl (by decide) rfl (by decide) (by decide) rfl rfl rfl
/-- `while_decnz(scratch1,3.param2.inc).0` (State `405`):
adds register `8` into `6` and zeroes `8`. -/
theorem subEval_405 :
SubEval 405 (fun regs => (regs.set 8 0).set 6 (regs.getD 6 0 + regs.getD 8 0)) :=
subEval_while_move1 8 6 (by decide) (by decide) (by decide) rfl (by decide) (by decide)
rfl rfl rfl (by decide) rfl (by decide) (by decide) rfl rfl rfl
/-- `while_decnz(scratch1,3.param3.inc).0` (State `407`):
adds register `8` into `7` and zeroes `8`. -/
theorem subEval_407 :
SubEval 407 (fun regs => (regs.set 8 0).set 7 (regs.getD 7 0 + regs.getD 8 0)) :=
subEval_while_move1 8 7 (by decide) (by decide) (by decide) rfl (by decide) (by decide)
rfl rfl rfl (by decide) rfl (by decide) (by decide) rfl rfl rfl
/-- `while_decnz(scratch1,3.scratch2.inc).0` (State `409`):
adds register `8` into `9` and zeroes `8`. -/
theorem subEval_409 :
SubEval 409 (fun regs => (regs.set 8 0).set 9 (regs.getD 9 0 + regs.getD 8 0)) :=
subEval_while_move1 8 9 (by decide) (by decide) (by decide) rfl (by decide) (by decide)
rfl rfl rfl (by decide) rfl (by decide) (by decide) rfl rfl rfl
/-- `while_decnz(scratch1,3.topwff.inc).0` (State `410`):
adds register `8` into `2` and zeroes `8`. -/
theorem subEval_410 :
SubEval 410 (fun regs => (regs.set 8 0).set 2 (regs.getD 2 0 + regs.getD 8 0)) :=
subEval_while_move1 8 2 (by decide) (by decide) (by decide) rfl (by decide) (by decide)
rfl rfl rfl (by decide) rfl (by decide) (by decide) rfl rfl rfl
/-- `while_decnz(scratch1,3.wffstack.inc).0` (State `411`):
adds register `8` into `3` and zeroes `8`. -/
theorem subEval_411 :
SubEval 411 (fun regs => (regs.set 8 0).set 3 (regs.getD 3 0 + regs.getD 8 0)) :=
subEval_while_move1 8 3 (by decide) (by decide) (by decide) rfl (by decide) (by decide)
rfl rfl rfl (by decide) rfl (by decide) (by decide) rfl rfl rfl
/-- `while_decnz(scratch2,3.prooflist.inc).0` (State `416`):
adds register `9` into `0` and zeroes `9`. -/
theorem subEval_416 :
SubEval 416 (fun regs => (regs.set 9 0).set 0 (regs.getD 0 0 + regs.getD 9 0)) :=
subEval_while_move1 9 0 (by decide) (by decide) (by decide) rfl (by decide) (by decide)
rfl rfl rfl (by decide) rfl (by decide) (by decide) rfl rfl rfl
/-- `while_decnz(scratch2,3.topwff.inc).0` (State `418`):
adds register `9` into `2` and zeroes `9`. -/
theorem subEval_418 :
SubEval 418 (fun regs => (regs.set 9 0).set 2 (regs.getD 2 0 + regs.getD 9 0)) :=
subEval_while_move1 9 2 (by decide) (by decide) (by decide) rfl (by decide) (by decide)
rfl rfl rfl (by decide) rfl (by decide) (by decide) rfl rfl rfl
/-- `while_decnz(scratch2,3.wffstack.inc).0` (State `419`):
adds register `9` into `3` and zeroes `9`. -/
theorem subEval_419 :
SubEval 419 (fun regs => (regs.set 9 0).set 3 (regs.getD 3 0 + regs.getD 9 0)) :=
subEval_while_move1 9 3 (by decide) (by decide) (by decide) rfl (by decide) (by decide)
rfl rfl rfl (by decide) rfl (by decide) (by decide) rfl rfl rfl
/-- `while_decnz(topwff,3.scratch1.inc).0` (State `425`):
adds register `2` into `8` and zeroes `2`. -/
theorem subEval_425 :
SubEval 425 (fun regs => (regs.set 2 0).set 8 (regs.getD 8 0 + regs.getD 2 0)) :=
subEval_while_move1 2 8 (by decide) (by decide) (by decide) rfl (by decide) (by decide)
rfl rfl rfl (by decide) rfl (by decide) (by decide) rfl rfl rfl
/-- `while_decnz(topwff,3.scratch2.inc).0` (State `427`):
adds register `2` into `9` and zeroes `2`. -/
theorem subEval_427 :
SubEval 427 (fun regs => (regs.set 2 0).set 9 (regs.getD 9 0 + regs.getD 2 0)) :=
subEval_while_move1 2 9 (by decide) (by decide) (by decide) rfl (by decide) (by decide)
rfl rfl rfl (by decide) rfl (by decide) (by decide) rfl rfl rfl
/-- `while_decnz(wffstack,3.topwff.inc).0` (State `428`):
adds register `3` into `2` and zeroes `3`. -/
theorem subEval_428 :
SubEval 428 (fun regs => (regs.set 3 0).set 2 (regs.getD 2 0 + regs.getD 3 0)) :=
subEval_while_move1 3 2 (by decide) (by decide) (by decide) rfl (by decide) (by decide)
rfl rfl rfl (by decide) rfl (by decide) (by decide) rfl rfl rfl
/-- `while_decnz(nextproof,67).0` (State `382`):
adds register `1` into `8` and `0` and zeroes `1`. -/
theorem subEval_382 :
SubEval 382 (fun regs =>
((regs.set 1 0).set 8 (regs.getD 8 0 + regs.getD 1 0)).set
0 (regs.getD 0 0 + regs.getD 1 0)) :=
subEval_while_move2 1 8 0 (by decide) (by decide) (by decide)
(by decide) (by decide) (by decide) rfl (by decide) (by decide) rfl rfl
rfl (by decide) rfl (by decide) rfl rfl (by decide) (by decide) rfl rfl
rfl (by decide) (by decide) rfl rfl
/-- `while_decnz(param1,113).0` (State `386`): adds register `5` into `8` and `9` and zeroes `5`. -/
theorem subEval_386 :
SubEval 386 (fun regs =>
((regs.set 5 0).set 8 (regs.getD 8 0 + regs.getD 5 0)).set
9 (regs.getD 9 0 + regs.getD 5 0)) :=
subEval_while_move2 5 8 9 (by decide) (by decide) (by decide)
(by decide) (by decide) (by decide) rfl (by decide) (by decide) rfl rfl
rfl (by decide) rfl (by decide) rfl rfl (by decide) (by decide) rfl rfl
rfl (by decide) (by decide) rfl rfl
/-- `while_decnz(param1,42).0` (State `387`): adds register `5` into `2` and `8` and zeroes `5`. -/
theorem subEval_387 :
SubEval 387 (fun regs =>
((regs.set 5 0).set 2 (regs.getD 2 0 + regs.getD 5 0)).set
8 (regs.getD 8 0 + regs.getD 5 0)) :=
subEval_while_move2 5 2 8 (by decide) (by decide) (by decide)
(by decide) (by decide) (by decide) rfl (by decide) (by decide) rfl rfl
rfl (by decide) rfl (by decide) rfl rfl (by decide) (by decide) rfl rfl
rfl (by decide) (by decide) rfl rfl
/-- `while_decnz(param1,99).0` (State `388`): adds register `5` into `8` and `2` and zeroes `5`. -/
theorem subEval_388 :
SubEval 388 (fun regs =>
((regs.set 5 0).set 8 (regs.getD 8 0 + regs.getD 5 0)).set
2 (regs.getD 2 0 + regs.getD 5 0)) :=
subEval_while_move2 5 8 2 (by decide) (by decide) (by decide)
(by decide) (by decide) (by decide) rfl (by decide) (by decide) rfl rfl
rfl (by decide) rfl (by decide) rfl rfl (by decide) (by decide) rfl rfl
rfl (by decide) (by decide) rfl rfl
/-- `while_decnz(param2,113).0` (State `392`): adds register `6` into `8` and `9` and zeroes `6`. -/
theorem subEval_392 :
SubEval 392 (fun regs =>
((regs.set 6 0).set 8 (regs.getD 8 0 + regs.getD 6 0)).set
9 (regs.getD 9 0 + regs.getD 6 0)) :=
subEval_while_move2 6 8 9 (by decide) (by decide) (by decide)
(by decide) (by decide) (by decide) rfl (by decide) (by decide) rfl rfl
rfl (by decide) rfl (by decide) rfl rfl (by decide) (by decide) rfl rfl
rfl (by decide) (by decide) rfl rfl
/-- `while_decnz(param2,42).0` (State `393`): adds register `6` into `2` and `8` and zeroes `6`. -/
theorem subEval_393 :
SubEval 393 (fun regs =>
((regs.set 6 0).set 2 (regs.getD 2 0 + regs.getD 6 0)).set
8 (regs.getD 8 0 + regs.getD 6 0)) :=
subEval_while_move2 6 2 8 (by decide) (by decide) (by decide)
(by decide) (by decide) (by decide) rfl (by decide) (by decide) rfl rfl
rfl (by decide) rfl (by decide) rfl rfl (by decide) (by decide) rfl rfl
rfl (by decide) (by decide) rfl rfl
/-- `while_decnz(param2,96).0` (State `394`): adds register `6` into `8` and `10` and zeroes `6`. -/
theorem subEval_394 :
SubEval 394 (fun regs =>
((regs.set 6 0).set 8 (regs.getD 8 0 + regs.getD 6 0)).set
10 (regs.getD 10 0 + regs.getD 6 0)) :=
subEval_while_move2 6 8 10 (by decide) (by decide) (by decide)
(by decide) (by decide) (by decide) rfl (by decide) (by decide) rfl rfl
rfl (by decide) rfl (by decide) rfl rfl (by decide) (by decide) rfl rfl
rfl (by decide) (by decide) rfl rfl
/-- `while_decnz(param3,42).0` (State `396`): adds register `7` into `2` and `8` and zeroes `7`. -/
theorem subEval_396 :
SubEval 396 (fun regs =>
((regs.set 7 0).set 2 (regs.getD 2 0 + regs.getD 7 0)).set
8 (regs.getD 8 0 + regs.getD 7 0)) :=
subEval_while_move2 7 2 8 (by decide) (by decide) (by decide)
(by decide) (by decide) (by decide) rfl (by decide) (by decide) rfl rfl
rfl (by decide) rfl (by decide) rfl rfl (by decide) (by decide) rfl rfl
rfl (by decide) (by decide) rfl rfl
/-- `while_decnz(param3,96).0` (State `397`): adds register `7` into `8` and `10` and zeroes `7`. -/
theorem subEval_397 :
SubEval 397 (fun regs =>
((regs.set 7 0).set 8 (regs.getD 8 0 + regs.getD 7 0)).set
10 (regs.getD 10 0 + regs.getD 7 0)) :=
subEval_while_move2 7 8 10 (by decide) (by decide) (by decide)
(by decide) (by decide) (by decide) rfl (by decide) (by decide) rfl rfl
rfl (by decide) rfl (by decide) rfl rfl (by decide) (by decide) rfl rfl
rfl (by decide) (by decide) rfl rfl
/-- `while_decnz(scratch1,9).0` (State `412`):
adds register `8` into `2` and `9` and zeroes `8`. -/
theorem subEval_412 :
SubEval 412 (fun regs =>
((regs.set 8 0).set 2 (regs.getD 2 0 + regs.getD 8 0)).set
9 (regs.getD 9 0 + regs.getD 8 0)) :=
subEval_while_move2 8 2 9 (by decide) (by decide) (by decide)
(by decide) (by decide) (by decide) rfl (by decide) (by decide) rfl rfl
rfl (by decide) rfl (by decide) rfl rfl (by decide) (by decide) rfl rfl
rfl (by decide) (by decide) rfl rfl
/-- `while_decnz(topwff,21).0` (State `422`):
adds register `2` into `3` and `8` and zeroes `2`. -/
theorem subEval_422 :
SubEval 422 (fun regs =>
((regs.set 2 0).set 3 (regs.getD 3 0 + regs.getD 2 0)).set
8 (regs.getD 8 0 + regs.getD 2 0)) :=
subEval_while_move2 2 3 8 (by decide) (by decide) (by decide)
(by decide) (by decide) (by decide) rfl (by decide) (by decide) rfl rfl