phanerozoic commited on
Commit
0eb76eb
·
1 Parent(s): d95ab3c

Prove the stored host's construction, copies, period and network in Rocq for every word width, give each unit its own window cell, and revise Section 8 with the new records

Browse files
.gitignore CHANGED
@@ -20,6 +20,10 @@ rocq/extract/physnet.mli
20
  rocq/extract/hostnet.ml
21
  rocq/extract/hostnet.mli
22
  rocq/extract/dumphost
 
 
 
 
23
  rocq/.nia.cache
24
  rocq/extract/dump
25
  rocq/extract/*.cm*
 
20
  rocq/extract/hostnet.ml
21
  rocq/extract/hostnet.mli
22
  rocq/extract/dumphost
23
+ rocq/extract/storednet.ml
24
+ rocq/extract/storednet.mli
25
+ rocq/extract/dumpstored
26
+ rocq/extract/stored_rocq.bin
27
  rocq/.nia.cache
28
  rocq/extract/dump
29
  rocq/extract/*.cm*
README.md CHANGED
@@ -600,19 +600,20 @@ proves for every window of 2^α cells, number of banks, bank and tape. `rocq/`
600
  also proves that the host family computes SUBLEQ at every word width, that the
601
  21- and 27-instruction programs do what the paper states at every word width from
602
  8 on, and that the H_8 it defines is the netlist of the published serialization.
603
- The host itself, compiled by `src/twohead.py` into 36,080 records of two inputs
604
- with records that load its memory, its tape device and a hand-over, and stored in
605
- the member with 4096 window cells, runs the 27-instruction program on a recipe
606
- for its own records: it writes them into the next bank, copies the recipe onto
607
- the next tape and hands control to the copy, so that it reproduces itself,
608
- weights included, by the dynamics alone, and the copies accumulate until every
609
- bank holds one; `src/ring_run.c` runs six generations of 79,501,750,295 steps
610
- each in a ring of three banks. The fixed network's own weights are the
611
- transition rule and are not reproduced. The paper proves that every member of the
612
- host family with wider words does the same in a larger window. An organism of 143
 
 
613
  records on the member with 64 window cells does the same with a description code
614
- of its own, and its universal construction, its reproduction in every ring and
615
- the period of the state are proved in Rocq. Its robustness section gives the
616
  margin every orbit has against perturbation, a certificate of the leakage an
617
  orbit tolerates from the inputs active along it, a bound on the failure rate
618
  under read noise that lies within the 95% interval of the measured rate, and the
@@ -1020,9 +1021,11 @@ paper/ the manuscript, and the record of every run
1020
  rocq/ Rocq proofs: the host family H_A computes SUBLEQ for every word
1021
  width, P and P* do what the paper states at every width from 8,
1022
  the netlist of the ring machine computes its step for every
1023
- window, ring, bank and tape, and the organism builds every image
1024
- that fits a bank from any description of it and reproduces in
1025
- every ring, the state periodic once every bank holds a copy
 
 
1026
  tools/play.py the playground, and a demonstration on each machine
1027
  llm_integration/
1028
  ├── llm.py SmolLM2 with the frozen circuits: the circuit wrapper, the
 
600
  also proves that the host family computes SUBLEQ at every word width, that the
601
  21- and 27-instruction programs do what the paper states at every word width from
602
  8 on, and that the H_8 it defines is the netlist of the published serialization.
603
+ The host itself, compiled into 36,080 records of two inputs with records that
604
+ load its memory, its tape device and a hand-over, and stored in the member with
605
+ 32,768 window cells, runs the 27-instruction program on a recipe for its own
606
+ records: it writes them into the next bank, copies the recipe onto the next tape
607
+ and hands control to the copy, so that it reproduces itself, weights included, by
608
+ the dynamics alone, and the copies accumulate until every bank holds one;
609
+ `src/ring_run.c` runs six generations of 95,762,842,100 steps each in a ring of
610
+ three banks. The fixed network's own weights are the transition rule and are not
611
+ reproduced. `rocq/` defines the stored host for every word width from 8 on, the
612
+ records `src/twohead.py` writes among them, and proves its universal
613
+ construction, its reproduction in every ring, the accumulation of the copies and
614
+ the period of the state, in the machine and in the network. An organism of 143
615
  records on the member with 64 window cells does the same with a description code
616
+ of its own, also proved in Rocq. Its robustness section gives the
 
617
  margin every orbit has against perturbation, a certificate of the leakage an
618
  orbit tolerates from the inputs active along it, a bound on the failure rate
619
  under read noise that lies within the 95% interval of the measured rate, and the
 
1021
  rocq/ Rocq proofs: the host family H_A computes SUBLEQ for every word
1022
  width, P and P* do what the paper states at every width from 8,
1023
  the netlist of the ring machine computes its step for every
1024
+ window, ring, bank and tape, the host stored as records builds
1025
+ every image that fits a bank and reproduces in every ring at
1026
+ every width from 8, and the organism builds every image that
1027
+ fits a bank from any description of it and reproduces in every
1028
+ ring, the state periodic once every bank holds a copy
1029
  tools/play.py the playground, and a demonstration on each machine
1030
  llm_integration/
1031
  ├── llm.py SmolLM2 with the frozen circuits: the circuit wrapper, the
paper/README.md CHANGED
@@ -36,7 +36,7 @@ Each command is `python src/<file>.py <command>` and writes its record to `runs/
36
  | `paper.py family-gate` | `paper_runs_family_gate.json` | four of them on the netlist of sigma |
37
  | `paper.py c` | `paper_c_evaluator.json` | the host on the evaluator in C, `src/netlist_eval.c` |
38
  | `paper.py throughput` | `paper_throughput.json` | the rate of each evaluator |
39
- | `paper.py rocq` | `paper_rocq.json` | the Rocq development of `rocq/`, its assumptions, the host family extracted from it for A = 8, 9, 10 against sigma(N_host) and the generator, the memory images of P and P*, and the ring netlist extracted for three members |
40
  | `twohead.py organism` | `paper_twohead.json` | the organism on the ring machine M_{3,160,3200}, six generations with the copies and the period (`organism run --generations 6 --S 160 --L 3200`); `organism rocq` writes `rocq/Organism.v` |
41
  | `twohead.py net` | `paper_twohead_net.json` | the netlist N_{K,S,L} against the machine on random states of three members (`net check`), one generation of the organism on it in C beside the machine (`net lockstep`), the netlists extracted from Rocq (`net extract`), and the rows of its levelization with the noise a generation of the stored host survives (`net lev`) |
42
  | `twohead.py stored` | `paper_stored_host.json` | the host compiled into records of the ring machine: one pass against the host's step and its device on random states (`stored check`), the startup, step, device and hand-over records on decision diagrams (`stored symbolic`), and six generations in C in a ring of three banks (`stored run 6`); `--width A` checks H_A in place of H_8, and `stored widths` tabulates A = 8 to 12 |
 
36
  | `paper.py family-gate` | `paper_runs_family_gate.json` | four of them on the netlist of sigma |
37
  | `paper.py c` | `paper_c_evaluator.json` | the host on the evaluator in C, `src/netlist_eval.c` |
38
  | `paper.py throughput` | `paper_throughput.json` | the rate of each evaluator |
39
+ | `paper.py rocq` | `paper_rocq.json` | the Rocq development of `rocq/`, its assumptions, the host family extracted from it for A = 8, 9, 10 against sigma(N_host) and the generator, the stored host extracted for A = 8, 9 against the image `twohead.py stored` builds, the memory images of P and P*, and the ring netlist extracted for three members |
40
  | `twohead.py organism` | `paper_twohead.json` | the organism on the ring machine M_{3,160,3200}, six generations with the copies and the period (`organism run --generations 6 --S 160 --L 3200`); `organism rocq` writes `rocq/Organism.v` |
41
  | `twohead.py net` | `paper_twohead_net.json` | the netlist N_{K,S,L} against the machine on random states of three members (`net check`), one generation of the organism on it in C beside the machine (`net lockstep`), the netlists extracted from Rocq (`net extract`), and the rows of its levelization with the noise a generation of the stored host survives (`net lev`) |
42
  | `twohead.py stored` | `paper_stored_host.json` | the host compiled into records of the ring machine: one pass against the host's step and its device on random states (`stored check`), the startup, step, device and hand-over records on decision diagrams (`stored symbolic`), and six generations in C in a ring of three banks (`stored run 6`); `--width A` checks H_A in place of H_8, and `stored widths` tabulates A = 8 to 12 |
paper/runs/paper_rocq.json CHANGED
@@ -1,7 +1,7 @@
1
  {
2
  "rocq": "The Rocq Prover, version 9.1.1",
3
- "files": 27,
4
- "build_seconds": 66.5,
5
  "theorems": {
6
  "PhysSem.netlist_step": "closed",
7
  "PhysMain.network_orbit": "closed",
@@ -22,10 +22,27 @@
22
  "Pstar.constructor_run": "closed",
23
  "Pstar.selfrep_run": "closed",
24
  "Pstar.image_Pstar_8": "closed",
25
- "Pstar.image_P_8": "closed"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  },
27
  "extraction_identical": true,
28
- "lines": 7391,
29
  "host_extraction": {
30
  "members": [
31
  {
@@ -55,5 +72,26 @@
55
  "pstar_images": {
56
  "m_star": true,
57
  "m_P": true
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  }
59
  }
 
1
  {
2
  "rocq": "The Rocq Prover, version 9.1.1",
3
+ "files": 44,
4
+ "build_seconds": 198.9,
5
  "theorems": {
6
  "PhysSem.netlist_step": "closed",
7
  "PhysMain.network_orbit": "closed",
 
22
  "Pstar.constructor_run": "closed",
23
  "Pstar.selfrep_run": "closed",
24
  "Pstar.image_Pstar_8": "closed",
25
+ "Pstar.image_P_8": "closed",
26
+ "StoredBoot.startup_run": "closed",
27
+ "StoredPass.step_view": "closed",
28
+ "StoredDev.device_run": "closed",
29
+ "StoredBoot.handover_run": "closed",
30
+ "StoredOk.stored_ok": "closed",
31
+ "StoredPass.pass_first": "closed",
32
+ "StoredPass.pass_next": "closed",
33
+ "StoredRun.machine_pass": "closed",
34
+ "StoredRun.stored_construct": "closed",
35
+ "StoredWbr.wbr_stored": "closed",
36
+ "StoredMain.reproduces": "closed",
37
+ "StoredMain.copies": "closed",
38
+ "StoredMain.periodic": "closed",
39
+ "StoredMain.network_reproduces": "closed",
40
+ "StoredMain.network_periodic": "closed",
41
+ "StoredWidth.width_exists": "closed",
42
+ "StoredWidth.recipe_of_image": "closed"
43
  },
44
  "extraction_identical": true,
45
+ "lines": 13795,
46
  "host_extraction": {
47
  "members": [
48
  {
 
72
  "pstar_images": {
73
  "m_star": true,
74
  "m_P": true
75
+ },
76
+ "stored_extraction": {
77
+ "members": [
78
+ {
79
+ "A": 8,
80
+ "w": 20,
81
+ "records": 36080,
82
+ "bytes": 239030,
83
+ "identical": true,
84
+ "sha256": "9a7821a540fed2ed58fbb263213f65aead6bbbd8cca6344abcabcc5f4289903c"
85
+ },
86
+ {
87
+ "A": 9,
88
+ "w": 21,
89
+ "records": 80463,
90
+ "bytes": 563241,
91
+ "identical": true,
92
+ "sha256": "8fe4d6719955e5e4c776514f3910facf60d8d6357f677f9978682e4932b1fbf8"
93
+ }
94
+ ],
95
+ "identical": true
96
  }
97
  }
paper/runs/paper_stored_host.json CHANGED
@@ -3,19 +3,19 @@
3
  "A": 8,
4
  "K": 3,
5
  "S": 36085,
6
- "L": 1600072,
7
  "records": 36080,
8
- "window_cells": 2901,
9
- "record_bits": 44,
10
  "counter_bits": 20,
11
- "image_bytes": 198440,
12
- "tau_bytes": 200001,
13
- "passes_expected": 2203180,
14
- "steps_expected": 79501750295,
15
  "generations": [
16
  {
17
  "generation": 1,
18
- "steps": 79501750295,
19
  "kappa": 1,
20
  "copies": 2,
21
  "descriptions": 2,
@@ -24,7 +24,7 @@
24
  },
25
  {
26
  "generation": 2,
27
- "steps": 79501750295,
28
  "kappa": 2,
29
  "copies": 3,
30
  "descriptions": 3,
@@ -33,7 +33,7 @@
33
  },
34
  {
35
  "generation": 3,
36
- "steps": 79501750295,
37
  "kappa": 0,
38
  "copies": 3,
39
  "descriptions": 3,
@@ -42,7 +42,7 @@
42
  },
43
  {
44
  "generation": 4,
45
- "steps": 79501750295,
46
  "kappa": 1,
47
  "copies": 3,
48
  "descriptions": 3,
@@ -51,7 +51,7 @@
51
  },
52
  {
53
  "generation": 5,
54
- "steps": 79501750295,
55
  "kappa": 2,
56
  "copies": 3,
57
  "descriptions": 3,
@@ -60,7 +60,7 @@
60
  },
61
  {
62
  "generation": 6,
63
- "steps": 79501750295,
64
  "kappa": 0,
65
  "copies": 3,
66
  "descriptions": 3,
@@ -68,17 +68,17 @@
68
  "equals_generation_minus_K": 1
69
  }
70
  ],
71
- "seconds": 2599.9,
72
- "sha256_image": "2aad2478143153562622be27d67385523203f5c0519604ef43eca0a510b986a0",
73
- "sha256_tau": "c74c4f479fa5f60cd561ea66ff071003f3d559890171c217f27d2943e79ff14d",
74
  "every_generation_exact": true
75
  },
76
  "pass_check": {
77
  "trials": 300,
78
  "disagreements": 0,
79
  "records": 36080,
80
- "window_cells": 2901,
81
- "seconds": 506.3
82
  },
83
  "symbolic": {
84
  "A": 8,
@@ -91,53 +91,53 @@
91
  "step_exact": true,
92
  "device_exact": true,
93
  "handover_exact": true,
94
- "sha256_image": "2aad2478143153562622be27d67385523203f5c0519604ef43eca0a510b986a0",
95
- "nodes": 87140,
96
- "seconds": 0.8
97
  },
98
  "symbolic_A9": {
99
  "A": 9,
100
- "startup_records": 4665,
101
  "step_records": 75366,
102
- "device_records": 414,
103
- "padding_records": 7,
104
  "handover_records": 4,
105
  "startup_exact": true,
106
  "step_exact": true,
107
  "device_exact": true,
108
  "handover_exact": true,
109
- "sha256_image": "6b06f29515b866070e60efafe286302d71400d5c6be4ec03b9c542c4aa50c148",
110
- "nodes": 185281,
111
- "seconds": 2.0
112
  },
113
  "symbolic_A10": {
114
  "A": 10,
115
  "startup_records": 10302,
116
  "step_records": 167351,
117
  "device_records": 449,
118
- "padding_records": 2,
119
  "handover_records": 4,
120
  "startup_exact": true,
121
  "step_exact": true,
122
  "device_exact": true,
123
  "handover_exact": true,
124
- "sha256_image": "0be370b9ffb824a7cc0e8a4612c16dc4e35cb6f0e48a51acbd28f1126df41405",
125
- "nodes": 401141,
126
- "seconds": 5.6
127
  },
128
  "pass_check_A9": {
129
- "trials": 300,
130
  "disagreements": 0,
131
- "records": 80448,
132
- "window_cells": 6228,
133
- "seconds": 204.6
134
  },
135
  "pass_check_A10": {
136
- "trials": 100,
137
  "disagreements": 0,
138
- "records": 178100,
139
- "window_cells": 13404,
140
- "seconds": 156.2
141
  },
142
  "widths": [
143
  {
@@ -148,97 +148,97 @@
148
  "device": 403,
149
  "padding": 1,
150
  "handover": 4,
151
- "window_cells": 2901,
152
- "alpha": 12,
153
- "record_bits": 44,
154
  "counter_bits": 20,
155
- "image_bytes": 198440,
156
- "tau_bytes": 200001,
157
- "literal_tokens": 1565,
158
- "repeat_tokens": 2,
159
- "passes": 2203180,
160
- "applications": 79490734400,
161
- "seconds": 1.1
162
  },
163
  {
164
  "A": 9,
165
- "records": 80456,
166
- "startup": 4665,
167
  "step": 75366,
168
- "device": 414,
169
- "padding": 7,
170
  "handover": 4,
171
- "window_cells": 6233,
172
- "alpha": 13,
173
- "record_bits": 47,
174
- "counter_bits": 20,
175
- "image_bytes": 472679,
176
- "tau_bytes": 476363,
177
- "literal_tokens": 3723,
178
- "repeat_tokens": 2,
179
- "passes": 5247618,
180
- "applications": 422202353808,
181
  "seconds": 2.7
182
  },
183
  {
184
  "A": 10,
185
- "records": 178108,
186
  "startup": 10302,
187
  "step": 167351,
188
  "device": 449,
189
- "padding": 2,
190
  "handover": 4,
191
- "window_cells": 13409,
192
- "alpha": 14,
193
- "record_bits": 50,
194
  "counter_bits": 22,
195
- "image_bytes": 1113175,
196
- "tau_bytes": 1121929,
197
- "literal_tokens": 8766,
198
- "repeat_tokens": 2,
199
- "passes": 12358822,
200
- "applications": 2201205068776,
201
- "seconds": 11.7
202
  },
203
  {
204
  "A": 11,
205
- "records": 391224,
206
  "startup": 22593,
207
  "step": 368148,
208
  "device": 472,
209
- "padding": 7,
210
  "handover": 4,
211
- "window_cells": 28775,
212
- "alpha": 15,
213
- "record_bits": 53,
214
  "counter_bits": 23,
215
- "image_bytes": 2591859,
216
- "tau_bytes": 2612223,
217
- "literal_tokens": 20410,
218
- "repeat_tokens": 2,
219
- "passes": 28775480,
220
- "applications": 11257658387520,
221
- "seconds": 34.0
222
  },
223
  {
224
  "A": 12,
225
- "records": 853173,
226
  "startup": 49220,
227
  "step": 803454,
228
  "device": 495,
229
- "padding": 0,
230
  "handover": 4,
231
- "window_cells": 61549,
232
- "alpha": 16,
233
- "record_bits": 56,
234
  "counter_bits": 24,
235
- "image_bytes": 5972211,
236
- "tau_bytes": 6019191,
237
- "literal_tokens": 47060,
238
- "repeat_tokens": 40,
239
- "passes": 66305830,
240
- "applications": 56570343898590,
241
- "seconds": 83.7
242
  }
243
  ]
244
  }
 
3
  "A": 8,
4
  "K": 3,
5
  "S": 36085,
6
+ "L": 1927264,
7
  "records": 36080,
8
+ "window_cells": 19765,
9
+ "record_bits": 53,
10
  "counter_bits": 20,
11
+ "image_bytes": 239030,
12
+ "tau_bytes": 240900,
13
+ "passes_expected": 2653813,
14
+ "steps_expected": 95762842100,
15
  "generations": [
16
  {
17
  "generation": 1,
18
+ "steps": 95762842100,
19
  "kappa": 1,
20
  "copies": 2,
21
  "descriptions": 2,
 
24
  },
25
  {
26
  "generation": 2,
27
+ "steps": 95762842100,
28
  "kappa": 2,
29
  "copies": 3,
30
  "descriptions": 3,
 
33
  },
34
  {
35
  "generation": 3,
36
+ "steps": 95762842100,
37
  "kappa": 0,
38
  "copies": 3,
39
  "descriptions": 3,
 
42
  },
43
  {
44
  "generation": 4,
45
+ "steps": 95762842100,
46
  "kappa": 1,
47
  "copies": 3,
48
  "descriptions": 3,
 
51
  },
52
  {
53
  "generation": 5,
54
+ "steps": 95762842100,
55
  "kappa": 2,
56
  "copies": 3,
57
  "descriptions": 3,
 
60
  },
61
  {
62
  "generation": 6,
63
+ "steps": 95762842100,
64
  "kappa": 0,
65
  "copies": 3,
66
  "descriptions": 3,
 
68
  "equals_generation_minus_K": 1
69
  }
70
  ],
71
+ "seconds": 2929.7,
72
+ "sha256_image": "9a7821a540fed2ed58fbb263213f65aead6bbbd8cca6344abcabcc5f4289903c",
73
+ "sha256_tau": "dbb2cfe5fe8e53e303a51ddbe52964f70f83169181ec4dc05450cb244b9b5a97",
74
  "every_generation_exact": true
75
  },
76
  "pass_check": {
77
  "trials": 300,
78
  "disagreements": 0,
79
  "records": 36080,
80
+ "window_cells": 19765,
81
+ "seconds": 693.5
82
  },
83
  "symbolic": {
84
  "A": 8,
 
91
  "step_exact": true,
92
  "device_exact": true,
93
  "handover_exact": true,
94
+ "sha256_image": "9a7821a540fed2ed58fbb263213f65aead6bbbd8cca6344abcabcc5f4289903c",
95
+ "nodes": 115812,
96
+ "seconds": 2.6
97
  },
98
  "symbolic_A9": {
99
  "A": 9,
100
+ "startup_records": 4667,
101
  "step_records": 75366,
102
+ "device_records": 426,
103
+ "padding_records": 0,
104
  "handover_records": 4,
105
  "startup_exact": true,
106
  "step_exact": true,
107
  "device_exact": true,
108
  "handover_exact": true,
109
+ "sha256_image": "8fe4d6719955e5e4c776514f3910facf60d8d6357f677f9978682e4932b1fbf8",
110
+ "nodes": 243216,
111
+ "seconds": 5.4
112
  },
113
  "symbolic_A10": {
114
  "A": 10,
115
  "startup_records": 10302,
116
  "step_records": 167351,
117
  "device_records": 449,
118
+ "padding_records": 6,
119
  "handover_records": 4,
120
  "startup_exact": true,
121
  "step_exact": true,
122
  "device_exact": true,
123
  "handover_exact": true,
124
+ "sha256_image": "222e17b6fab50dfe3c4b97274826bc740b799e35a3cdd8a1825f2d915ad8d3a5",
125
+ "nodes": 515829,
126
+ "seconds": 8.0
127
  },
128
  "pass_check_A9": {
129
+ "trials": 100,
130
  "disagreements": 0,
131
+ "records": 80463,
132
+ "window_cells": 43862,
133
+ "seconds": 602.8
134
  },
135
  "pass_check_A10": {
136
+ "trials": 30,
137
  "disagreements": 0,
138
+ "records": 178112,
139
+ "window_cells": 96632,
140
+ "seconds": 362.4
141
  },
142
  "widths": [
143
  {
 
148
  "device": 403,
149
  "padding": 1,
150
  "handover": 4,
151
+ "window_cells": 19765,
152
+ "alpha": 15,
153
+ "record_bits": 53,
154
  "counter_bits": 20,
155
+ "image_bytes": 239030,
156
+ "tau_bytes": 240900,
157
+ "literal_tokens": 1888,
158
+ "repeat_tokens": 8,
159
+ "passes": 2653813,
160
+ "applications": 95749573040,
161
+ "seconds": 1.0
162
  },
163
  {
164
  "A": 9,
165
+ "records": 80463,
166
+ "startup": 4667,
167
  "step": 75366,
168
+ "device": 426,
169
+ "padding": 0,
170
  "handover": 4,
171
+ "window_cells": 43862,
172
+ "alpha": 16,
173
+ "record_bits": 56,
174
+ "counter_bits": 21,
175
+ "image_bytes": 563241,
176
+ "tau_bytes": 567647,
177
+ "literal_tokens": 4462,
178
+ "repeat_tokens": 28,
179
+ "passes": 6253470,
180
+ "applications": 503172956610,
181
  "seconds": 2.7
182
  },
183
  {
184
  "A": 10,
185
+ "records": 178112,
186
  "startup": 10302,
187
  "step": 167351,
188
  "device": 449,
189
+ "padding": 6,
190
  "handover": 4,
191
+ "window_cells": 96632,
192
+ "alpha": 17,
193
+ "record_bits": 59,
194
  "counter_bits": 22,
195
+ "image_bytes": 1313576,
196
+ "tau_bytes": 1323842,
197
+ "literal_tokens": 10372,
198
+ "repeat_tokens": 33,
199
+ "passes": 14583670,
200
+ "applications": 2597526631040,
201
+ "seconds": 7.3
202
  },
203
  {
204
  "A": 11,
205
+ "records": 391220,
206
  "startup": 22593,
207
  "step": 368148,
208
  "device": 472,
209
+ "padding": 3,
210
  "handover": 4,
211
+ "window_cells": 211355,
212
+ "alpha": 18,
213
+ "record_bits": 62,
214
  "counter_bits": 23,
215
+ "image_bytes": 3031955,
216
+ "tau_bytes": 3055757,
217
+ "literal_tokens": 23912,
218
+ "repeat_tokens": 45,
219
+ "passes": 33661915,
220
+ "applications": 13169214386300,
221
+ "seconds": 18.8
222
  },
223
  {
224
  "A": 12,
225
+ "records": 853176,
226
  "startup": 49220,
227
  "step": 803454,
228
  "device": 495,
229
+ "padding": 3,
230
  "handover": 4,
231
+ "window_cells": 459199,
232
+ "alpha": 19,
233
+ "record_bits": 65,
234
  "counter_bits": 24,
235
+ "image_bytes": 6932055,
236
+ "tau_bytes": 6986545,
237
+ "literal_tokens": 54626,
238
+ "repeat_tokens": 52,
239
+ "passes": 76962164,
240
+ "applications": 65662271232864,
241
+ "seconds": 48.1
242
  }
243
  ]
244
  }
paper/runs/paper_twohead_net.json CHANGED
@@ -107,63 +107,63 @@
107
  },
108
  "levelized": {
109
  "K": 3,
110
- "alpha": 12,
111
  "members": [
112
  {
113
  "S": 2,
114
  "L": 3,
115
  "depth": 19,
116
- "rows": 151066
117
  },
118
  {
119
  "S": 3,
120
  "L": 3,
121
  "depth": 19,
122
- "rows": 155095
123
  },
124
  {
125
  "S": 2,
126
  "L": 5,
127
  "depth": 19,
128
- "rows": 151372
129
  },
130
  {
131
  "S": 3,
132
  "L": 5,
133
  "depth": 19,
134
- "rows": 155401
135
  },
136
  {
137
  "S": 4,
138
  "L": 9,
139
  "depth": 19,
140
- "rows": 160042
141
  },
142
  {
143
  "S": 6,
144
  "L": 4,
145
  "depth": 19,
146
- "rows": 167335
147
  }
148
  ],
149
  "rows": {
150
- "constant": 142549,
151
- "per_slot": 4029,
152
  "per_cell": 153
153
  },
154
  "affine": true,
155
  "depth": 19,
156
  "stored_member": {
157
  "S": 36085,
158
- "L": 1600072,
159
- "rows": 390340030,
160
- "steps": 79501750295
161
  },
162
  "s_max_0999": {
163
- "1": 0.0504,
164
- "3": 0.1495,
165
- "5": 0.2479
166
  },
167
- "seconds": 4.3
168
  }
169
  }
 
107
  },
108
  "levelized": {
109
  "K": 3,
110
+ "alpha": 15,
111
  "members": [
112
  {
113
  "S": 2,
114
  "L": 3,
115
  "depth": 19,
116
+ "rows": 1128191
117
  },
118
  {
119
  "S": 3,
120
  "L": 3,
121
  "depth": 19,
122
+ "rows": 1133030
123
  },
124
  {
125
  "S": 2,
126
  "L": 5,
127
  "depth": 19,
128
+ "rows": 1128497
129
  },
130
  {
131
  "S": 3,
132
  "L": 5,
133
  "depth": 19,
134
+ "rows": 1133336
135
  },
136
  {
137
  "S": 4,
138
  "L": 9,
139
  "depth": 19,
140
+ "rows": 1138787
141
  },
142
  {
143
  "S": 6,
144
  "L": 4,
145
  "depth": 19,
146
+ "rows": 1147700
147
  }
148
  ],
149
  "rows": {
150
+ "constant": 1118054,
151
+ "per_slot": 4839,
152
  "per_cell": 153
153
  },
154
  "affine": true,
155
  "depth": 19,
156
  "stored_member": {
157
  "S": 36085,
158
+ "L": 1927264,
159
+ "rows": 470604761,
160
+ "steps": 95762842100
161
  },
162
  "s_max_0999": {
163
+ "1": 0.0502,
164
+ "3": 0.1489,
165
+ "5": 0.247
166
  },
167
+ "seconds": 23.8
168
  }
169
  }
paper/universal_construction_ternary.pdf CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:87c4967c252151a84821cf702b931e88738fd04599d65cbac7c7a61944567f83
3
- size 354390
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:922ef023fe09cef59891dc62bd7eab1b68b15be41216f4425959ef241ec8b9ad
3
+ size 355574
paper/universal_construction_ternary.tex CHANGED
@@ -80,10 +80,12 @@ of banks and tapes. Stored in the ring as $36{,}080$ records of two inputs, the
80
  SUBLEQ computer decodes a description of its own records into the next bank, copies
81
  the description onto the next tape and hands control to the copy. The fixed network
82
  thus rebuilds the stored computer, weights included, in every generation; its own
83
- weights are the transition rule and are not reproduced. A constructor of $143$
84
- records builds every image that fits a bank from its description, and its
85
- reproduction is proved in Rocq for every ring: the copies accumulate until every
86
- bank holds one, and from then on the whole state repeats every $K$ generations.
 
 
87
  Every pre-activation is an integer, so every orbit survives perturbations below
88
  $1/2$ of each pre-activation. Under independent Gaussian noise on the
89
  pre-activations, a bound computed from the orbit lies within the $95\%$ interval of
@@ -172,13 +174,13 @@ Stored in the ring, the host $H_A$ of every word width $A\ge8$ running $P^\ast$
172
  builds every image that fits a bank, from every recipe that fits a tape, into the
173
  next bank and hands control to it. Started on a recipe for its own records it
174
  reproduces in every generation, weights included; the copies accumulate until every
175
- bank holds one, and from then on the state repeats every $K$ generations
176
- (Theorems~\ref{thm:storedconstruct} to~\ref{thm:widths}). Six generations of $H_8$,
177
- $36{,}080$ records and $7.95\times10^{10}$ steps each, were run in a ring of three
 
178
  banks. A constructor of $143$ records with a description code of its own does the
179
- same in the machine with $64$ window cells, and its universal construction and its
180
- reproduction in every ring, with the copies and the period, are proved in Rocq
181
- (Section~\ref{sec:organism}).
182
  \item \emph{Robustness.} Every orbit survives perturbations below $1/2$ of each
183
  pre-activation. Under independent Gaussian noise on the pre-activations, the
184
  probability that some unit fails in a step, computed from the pre-activation profile
@@ -220,8 +222,8 @@ Margin $1/2$ and the profile bound & Thm.~\ref{thm:margin}, Prop.~\ref{prop:prof
220
  Amplification under the three noise models & Thm.~\ref{thm:amplify}, Cor.~\ref{cor:synapse}, Prop.~\ref{prop:flip} & proof\\
221
  Restoration bound for $N_3$ & Prop.~\ref{prop:restore} & proof; measured rates of Table~\ref{tab:bound3}\\
222
  The netlist computes the ring machine; its size and weights & Thm.~\ref{thm:physnet} & Rocq; extraction equal to the generator's; random states\\
223
- A pass of the stored host & Prop.~\ref{prop:storedpass} & proof; decision diagrams of all four blocks and random states, $A=8,9,10$\\
224
- Construction and reproduction by the stored host & Thms.~\ref{thm:storedconstruct}--\ref{thm:widths} & proof over the Rocq results; six generations of $\mathcal S_8$ run\\
225
  The organism: code, pass, construction, copies, period, network & Lem.~\ref{lem:code}, Prop.~\ref{prop:pass}, Thms.~\ref{thm:construct}, \ref{thm:organism} & Rocq; six generations run, one on the netlist\\
226
  \bottomrule
227
  \end{tabularx}
@@ -1762,12 +1764,13 @@ every step.
1762
  Inside the ring machine the instantiation step of Section~\ref{sec:selfrep} is a
1763
  write into the next bank followed by a hand-over. This section stores the host, and
1764
  every member of its family with wider words, as a network of two-input records in a
1765
- bank of a ring machine whose window holds its state bits, $4096$ cells for
1766
  $\Nhost$. A device compiled into the same records writes the bytes the host emits
1767
  under the arm until the tape is rewound, and under the copy head after it. Run on a
1768
  recipe for its own records, $P^\ast$ then writes the host into the next bank, copies
1769
  the recipe onto the next tape and hands control to the copy
1770
- (Figure~\ref{fig:generation}).
 
1771
 
1772
  \begin{lemma}[Stored netlists]\label{lem:feedback}
1773
  If the active bank holds records followed by empty slots and no record but the last
@@ -1814,12 +1817,13 @@ others are, and its base cases are the chains and the constants.
1814
  \end{proof}
1815
 
1816
  \begin{construction}[The stored host]\label{con:stored}
1817
- Let $A\ge8$ and $w\ge20$. The window holds, after the thirteen cells of
1818
  Definition~\ref{def:twohead}, a cell $\mathrm{booted}$ at $13$, a counter
1819
  $\mathrm{cnt}$ of $w$ bits from $14$ on, least significant first, a cell
1820
  $\mathrm{dest}$, a limit $\mathrm{lim}$ of $w$ bits, the $n=A+1+A2^A$ state bits of
1821
- $H_A$ in the order of Construction~\ref{con:host}, and temporaries. The stored host
1822
- $\mathcal S_{A,w}$ lists the following records.
 
1823
  \begin{enumerate}[label=(\alph*),leftmargin=2em]
1824
  \item \emph{Startup}, $A2^A+A+2w+8$ records: for each memory bit $c$,
1825
  $c\leftarrow c\vee\neg\mathrm{booted}$ if its value in $m^\ast_A$ is $1$ and
@@ -1828,12 +1832,11 @@ $c\leftarrow c\wedge\mathrm{booted}$ for the bits of the counter, the halt bit a
1828
  the bits of $\mathrm{cnt}$, $\mathrm{lim}$ and $\mathrm{dest}$; then five records
1829
  copying $\neg\mathrm{booted}$ into RR, CB, RA, CT and RC; then
1830
  $\mathrm{booted}\leftarrow1$.
1831
- \item \emph{Step}: the units of $H_A$ compiled by Lemma~\ref{cor:compile}, in two
1832
- stages. The first evaluates every unit that a next value depends on, other than the
1833
- units of the next values and the units read by a single unit, each after its
1834
- predecessors. The second takes the counter bits, the halt bit and the memory bits
1835
- in this order, and evaluates for each the unit of its next value, with the units
1836
- read by it alone just before it, its last record writing the bit.
1837
  \item \emph{Device}, $11A+12w+75$ records: the device of Definition~\ref{def:ring}
1838
  on the state that~(b) leaves.
1839
  \item \emph{Hand-over}: the fewest empty records, at most seven, that make the image
@@ -1841,12 +1844,12 @@ a whole number of bytes; then $\mathrm{booted}\leftarrow\mathrm{booted}\wedge\ne
1841
  where $h$ is the halt bit, and three records copying $h$ into RA, RC and HO, the
1842
  last record.
1843
  \end{enumerate}
1844
- Temporaries whose live intervals, from the first write to the last read, are
1845
- disjoint share a cell, and the window is the least $2^\alpha$ that holds the cells
1846
- used. The host $\mathcal S=\mathcal S_{8,20}$ has $36{,}080$ records, its state bits at $55$ to $2111$
1847
- and $789$ cells of temporaries after them, so $\alpha=12$; its image, its records in
1848
- order, has $1{,}587{,}520$ bits, read as $198{,}440$ bytes most significant bit
1849
- first, and $\tau_{\mathcal S}=\describe(\mathcal S)$ has $200{,}001$ bytes.
1850
  \end{construction}
1851
 
1852
  \begin{definition}[The device of the stored host]\label{def:ring}
@@ -1887,7 +1890,7 @@ to cell $0$;
1887
  \node[note,anchor=south] at (a3.north) {$403$};
1888
  \node[note,anchor=south] at (a4.north) {$1+4$};
1889
  \node[lab] at (0,-1.1) {read tape $D_\kappa$};
1890
- \node[s,minimum width=76mm] (d0) at (0.15,-1.1) {$\tau_{\mathcal S}=\describe(\mathcal S)$, $200{,}001$ bytes};
1891
  \node[lab] at (0,-2.2) {next bank $Q_{\kappa+1}$};
1892
  \node[s,densely dashed,minimum width=76mm] (q1) at (0.15,-2.2) {$\mathcal S$, written under the arm in phase~(A)};
1893
  \node[lab] at (0,-3.3) {next tape $D_{\kappa+1}$};
@@ -1930,14 +1933,11 @@ Construction~\ref{con:stored} in order. The startup records leave every cell
1930
  unchanged when $\mathrm{booted}=1$. Otherwise they set each memory bit to its value
1931
  in $m^\ast_A$, clear the other cells they name, and set the five requests that
1932
  return the heads and clear the idle bank and the copy tape. The step block is $H_A$
1933
- compiled by Lemma~\ref{cor:compile}, in an order that Lemma~\ref{lem:feedback}
1934
- admits. The first stage writes temporaries only. In the second, the group of a state
1935
- bit evaluates with its unit only units read by that unit alone: $HP_i$, $Q_i$,
1936
- $TA_i$ and $TB_i$ for a counter bit, $AC$, $HA$ and $HB$ for the halt bit, and
1937
- $KP_{j,t}$ and $WR_{j,t}$ for a memory bit (Table~\ref{tab:blocks}). Besides
1938
- temporaries these read only that bit and, for a counter bit, the halt bit, whose
1939
- group comes later. So after the block the state bits hold the next state of $H_A$,
1940
- which Remark~\ref{rem:storedcheck} also checks on every window for $A\le10$.
1941
 
1942
  The device records form the requests $[y_c=1]$ as conjunctions of $A$ literals, the
1943
  bit $[\mathrm{cnt}=\mathrm{lim}]$ as a conjunction of $w$ equivalences, and its
@@ -1956,34 +1956,35 @@ return the arm and the copy head and, last, HO. Every temporary is written in th
1956
  pass before it is read and is not written after its last read, so a cell shared by
1957
  temporaries holds, at each read, the value of the temporary read. No record writes
1958
  the active bank, and the empty slots after the records change nothing but the slot
1959
- head.
 
1960
  \end{proof}
1961
 
1962
- The theorems below use only what Proposition~\ref{prop:storedpass} states. Call an
1963
- image $\mathcal S'$ of $G$ records a \emph{stored host} if, on the window cells of
1964
- Construction~\ref{con:stored}, a pass of $M^\alpha_{K,S,L}$ over it does what
1965
- Proposition~\ref{prop:storedpass} states for some $\mathcal S_{A,w}$, and every cell
1966
- that a record after the startup records reads, other than the cells under the heads
1967
- and the sink, is written earlier in the pass. It has $B=bG/8$ bytes, with
1968
- $b=8+3\alpha$, and $w$ is the width of its counters; its step block may compile any
1969
- netlist whose step is that of $H_A$. Every $\mathcal S_{A,w}$ is a stored host, and
1970
- $\mathcal S$ is one with $\alpha=12$, $G=36{,}080$ and $B=198{,}440$.
1971
 
1972
  \begin{theorem}[Universal construction by the dynamics]\label{thm:storedconstruct}
1973
- Let $\mathcal S'$ be a stored host of $G$ records, $K\ge2$ and $S\ge G$. Let $X$ be a byte
1974
- string of at most $Sb/8$ bytes, $r$ a recipe with $\delta(r)=X$ and $|r|<2^w$, and
1975
- $L\ge8|r|$. Let $x$ be a state of $M^\alpha_{K,S,L}$ with $\mathcal S'$ in the active bank
1976
- from slot $0$, followed by empty slots, with the slot head at slot $0$, $r$ on the
1977
- read tape from cell $0$, and in the window $\mathrm{booted}=0$ and clear requests,
1978
- whatever the other banks, tapes and cells hold. Let $P$ be the number of steps that
 
1979
  Proposition~\ref{prop:steps} gives for $r$. After $P$ passes, each of $S$ steps but
1980
  the last, which has $G$:
1981
  \begin{enumerate}[label=(\roman*),leftmargin=2em]
1982
  \item the next bank holds the bits of $X$ from slot $0$, followed by zeros, with
1983
  both its heads at $0$, and the next tape holds $r$ from cell $0$, followed by zeros,
1984
  with its head at $0$;
1985
- \item the active bank still holds $\mathcal S'$ and the read tape $r$, the window
1986
- holds $\mathrm{booted}=0$ and clear requests, and no other bank or tape has changed;
 
1987
  \item the bank index has moved to the next bank.
1988
  \end{enumerate}
1989
  From then on $M^\alpha_{K,S,L}$ evaluates the records of $X$.
@@ -2013,67 +2014,77 @@ bit $0$ of the cleared bank, the arm moving on by one bit after each, and fit si
2013
  $8|X|\le Sb$. Those emitted after it, $r$, are written under the copy head from cell
2014
  $0$ of the cleared tape, and fit since $8|r|\le L$. The active bank and the read tape
2015
  are not written, and no other bank or tape is addressed. From the next step on the
2016
- bank holding $X$ is active, at slot $0$.
 
 
2017
  \end{proof}
2018
 
2019
- By Lemma~\ref{lem:complete} every byte string has a recipe, so a stored host builds
2020
- every image that fits a bank from a recipe that fits a tape, itself among them; the
2021
- images need not have its size.
2022
 
2023
  \begin{theorem}[Self-reproduction of the host by the dynamics]\label{thm:storedrep}
2024
- Let $\mathcal S'$ be a stored host of $G$ records and $B$ bytes, $\tau'=\describe(\mathcal S')$ with
2025
- $|\tau'|<2^w$, $K\ge2$, $S\ge G$ and $L\ge8|\tau'|$. Let $x_0$ be a state of
2026
- $M^\alpha_{K,S,L}$ with $\kappa=0$, $\mathcal S'$ in bank $0$ from slot $0$ with its slot
2027
- head at slot $0$, $\tau'$ on tape $0$ from cell $0$ followed by zeros, and in the
2028
- window $\mathrm{booted}=0$ and clear requests, whatever the other banks, tapes and
2029
- cells hold. A generation is $(P-1)S+G$ steps, where $P=11B+13\lceil B/127\rceil+16$
2030
- if $\mathcal S'$ has no four equal consecutive bytes and $P\le\tfrac{25}{2}B+29$ in any case.
2031
- For every $g\ge1$, after $g$ generations $\kappa=g\bmod K$, and the banks
2032
- $0,\dots,\min(g,K-1)$ of the ring, counted back from bank $\kappa$, hold $\mathcal S'$ from
2033
- slot $0$ and their tapes $\tau'$ from cell $0$: the copies accumulate until every
2034
- bank holds one. From the $K$-th generation on the state repeats every $K$
2035
- generations. The network $N^\alpha_{K,S,L}$ started from the bits of $x_0$ holds the
2036
- bits of these states at the same steps. For $\mathcal S$, with $K=3$, $S=G+5=36{,}085$ and
2037
- $L=8|\tau_{\mathcal S}|+64=1{,}600{,}072$, a generation is $P=2{,}203{,}180$ passes,
2038
- $79{,}501{,}750{,}295$ applications of $M^{12}_{3,S,L}$.
 
 
 
2039
  \end{theorem}
2040
 
2041
  \begin{proof}
2042
- The first generation is Theorem~\ref{thm:storedconstruct} with $X=\mathcal S'$ and
2043
- $r=\tau'$, a recipe for $\mathcal S'$ by Lemma~\ref{lem:describe}. After it the next bank
2044
- holds $\mathcal S'$ from slot $0$ with its heads at $0$, the next tape $\tau'$ from cell $0$
2045
- followed by zeros, and the window $\mathrm{booted}=0$ and clear requests, so the
2046
- state satisfies the hypothesis of Theorem~\ref{thm:storedconstruct} for the next
2047
- bank. A generation changes only the active bank's slot head, the read tape's head,
2048
- and the next bank and tape, which it rebuilds; induction over the generations gives
2049
- $\kappa$ and the copies. Let $\tau'$ have $\ell$ literal and $R$ repeat tokens.
2050
- Since $|\tau'|=f_{\mathrm{lit}}+\ell+2R+1$, Proposition~\ref{prop:steps} gives
2051
  $P=11f_{\mathrm{lit}}+4f_{\mathrm{rep}}+13\ell+21R+16$. Without four equal
2052
  consecutive bytes $\describe$ emits $\lceil B/127\rceil$ literal tokens and
2053
  nothing else (Lemma~\ref{lem:describe}); in general its proof gives
2054
  $\ell\le f_{\mathrm{lit}}/127+R+1$ and $4R\le f_{\mathrm{rep}}$, hence
2055
- $P\le\tfrac{25}{2}B+29$; $\tau_{\mathcal S}$ has $1565$ literal and $2$ repeat tokens.
2056
 
2057
  For the period, let $g\ge K$. Every bank has then been rebuilt and has been active
2058
- since: the bank active $a$ generations ago, $1\le a<K$, holds $\mathcal S'$ with its slot head
2059
- where its hand-over pass left it, at slot $G\bmod S$, and its bit head at $0$, and
2060
- its tape holds $\tau'$ followed by zeros with the head where the copying left it,
2061
- after $\tau'$; the active bank and its tape have all heads at $0$. So the banks, the
2062
- tapes and $\kappa$ after generation $g$ depend only on $g\bmod K$. In the window,
2063
- the cells no record writes keep their values. Every other cell is written in every
2064
- pass, and after a generation holds what the last pass, the one that hands over,
2065
- left in it. That pass starts in every generation from the same state of the host,
2066
- the halted run of $P^\ast$ on $\tau'$, the same registers and the same cells under
2067
- the heads, and every cell a record reads in it is written earlier in the pass,
2068
- apart from the cells under the heads and the sink. So the windows after any two
2069
- generations agree, and the state after generation $g+K$ equals the state after
2070
- generation $g$. Theorem~\ref{thm:physnet} carries the statement to the network.
 
 
 
2071
  \end{proof}
2072
 
2073
  \begin{theorem}[Every word width]\label{thm:widths}
2074
- For every $A\ge8$ there is a least $w_A\ge20$ for which $\mathcal S_A=\mathcal S_{A,w_A}$ has
2075
- $|\describe(\mathcal S_A)|<2^{w_A}$. The stored host $\mathcal S_A$ builds every image that fits a bank
2076
- and reproduces itself by the dynamics of $N^{\alpha_A}_{K,S,L}$ as
 
 
2077
  Theorems~\ref{thm:storedconstruct} and~\ref{thm:storedrep} state, with
2078
  \[
2079
  G_A=35A2^{A-1}-2^{A+1}+\tfrac16(A^3-A)+A^2+29A+14w_A+91+\pi_A
@@ -2084,36 +2095,38 @@ of $\Theta(A^34^A)$ applications of $M^{\alpha_A}_{K,S,L}$.
2084
  \end{theorem}
2085
 
2086
  \begin{proof}
2087
- A pass of $\mathcal S_A$ does what Proposition~\ref{prop:storedpass} states, and every cell
2088
- a record after the startup reads, other than the cells under the heads and the sink,
2089
- is written earlier in the pass, so $\mathcal S_A$ is a stored host; $w_A$ exists since
2090
- $|\describe(\mathcal S_A)|\le2B+1$ grows with $w$ far slower than $2^w$. The startup and device
 
2091
  records are counted in Construction~\ref{con:stored} and the hand-over has
2092
  $4+\pi_A$. Lemma~\ref{cor:compile} compiles a conjunction or a disjunction of
2093
  $k\ge2$ literals into $k-1$ records and a unit of threshold $2$ on three or four
2094
  literals into four or eight, and summing over the blocks of Table~\ref{tab:blocks}
2095
  gives $\tfrac{33}{2}A2^A-2^{A+1}+\tfrac16(A^3-A)+A^2+17A+4$ step records, the cubic
2096
- term from the carry terms. The window holds the $A2^A+A+1$ state bits and at most
2097
- $G_A$ temporaries, so $\alpha_A=A+\Theta(\log A)$; then $b=8+3\alpha_A=\Theta(A)$,
 
2098
  $B=bG_A/8=\Theta(A^22^A)$, and Theorem~\ref{thm:storedrep} gives a generation of
2099
  $\Theta(B)$ passes of $S=G_A$ steps.
2100
  \end{proof}
2101
 
2102
- For $A=8$ to $12$, $\mathcal S_A$ has $36{,}080$, $80{,}456$, $178{,}108$, $391{,}224$ and
2103
- $853{,}173$ records, windows of $2^{12}$ to $2^{16}$ cells, counters of $20$, $20$,
2104
- $22$, $23$ and $24$ bits and images of $198{,}440$ to $5{,}972{,}211$ bytes, and a
2105
- generation takes $2{,}203{,}180$, $5{,}247{,}618$, $12{,}358{,}822$,
2106
- $28{,}775{,}480$ and $66{,}305{,}830$ passes, $7.95\times10^{10}$ to
2107
- $5.66\times10^{13}$ applications of $M$ with $S=G_A$.
2108
 
2109
  \begin{corollary}[Self-reproduction under noise]\label{cor:storednoise}
2110
- $\Lev(N^{12}_{3,S,L})$ has depth $19$ and $142{,}549+4{,}029S+153L$ rows,
2111
- $M=390{,}340{,}030$ for the member of Theorem~\ref{thm:storedrep} that holds $\mathcal S$.
2112
  Under independent centred Gaussian perturbations of deviation $s$ on every
2113
- pre-activation, a generation of $\mathcal S$, $T=79{,}501{,}750{,}295$ applications, runs
2114
  exactly with probability at least $1-TM\erfc\bigl(1/(2\sqrt2\,s)\bigr)$, which
2115
  exceeds $0.999$ for $s\le0.050$. The threefold and fivefold amplifications of
2116
- Definition~\ref{def:amplify} reach the same probability for $s\le0.149$ and
2117
  $s\le0.247$.
2118
  \end{corollary}
2119
 
@@ -2126,7 +2139,7 @@ members and the affine form fits all of them.
2126
 
2127
  \begin{remark}[Corroboration]\label{rem:storedcheck}
2128
  Six generations of $\mathcal S$ from $x_0$ were run in a ring of three banks,
2129
- $S=36{,}085$ and $L=1{,}600{,}072$, on a transcription of Definition~\ref{def:twohead}
2130
  in C. After each, the new active bank held $\mathcal S$ and the new read tape
2131
  $\tau_{\mathcal S}$ from their origins with their heads there. The copies accumulated,
2132
  two after the first generation and three from the second on, and the full states
@@ -2134,8 +2147,8 @@ after the sixth and the fifth generation equalled those after the third and the
2134
  second. One pass of $\mathcal S$ agreed with the startup, one step of $\Nhost$ and
2135
  the device of Definition~\ref{def:ring} from $300$ random states, a fifth of them not
2136
  booted and a third with requests holding random words, with random tapes, banks,
2137
- registers and temporaries; so did one pass of $\mathcal S_9$ from $300$ and of
2138
- $\mathcal S_{10}$ from $100$.
2139
 
2140
  All four blocks of $\mathcal S_8$ to $\mathcal S_{10}$ were also evaluated on reduced
2141
  ordered decision diagrams over variables for the window, the cells under the heads
@@ -2153,14 +2166,13 @@ with the construction for $A=8$ to $12$.
2153
  \end{remark}
2154
 
2155
  % =============================================================================
2156
- \section{A constructor proved in Rocq}\label{sec:organism}
2157
  % =============================================================================
2158
 
2159
- Theorem~\ref{thm:storedrep} is proved on paper over the Rocq proofs of
2160
- Proposition~\ref{prop:host}, Theorems~\ref{thm:univ} and~\ref{thm:selfrep} and
2161
- Theorem~\ref{thm:physnet}. This section gives a smaller stored network, the
2162
- organism, that performs von Neumann's cycle in $M_{K,S,L}$, the machine of $64$
2163
- window cells, with a description code of its own. Its universal construction, its
2164
  reproduction in every ring, the accumulation of its copies and the period of the
2165
  state are proved in Rocq, in the machine and in the network.
2166
 
@@ -2531,17 +2543,18 @@ The ring machine was evaluated by transcriptions of Definition~\ref{def:twohead}
2531
  Python and in C and by the netlist $N^\alpha_{K,S,L}$ in Python and in C. The
2532
  stored host is built from $\sigma(\Nhost)$ by \texttt{src/twohead.py}, and its
2533
  generations are run by \texttt{src/ring\_run.c}, which decodes the active bank once
2534
- per hand-over and steps over its empty slots, about seven minutes per generation.
2535
  Separate code in \texttt{src/independent.py}, written from the definitions of this
2536
  paper, rebuilds $H_A$ for $A=3$ to $12$, levelizes $\sigma(\Nhost)$ and repeats the
2537
  measurements of Section~\ref{sec:certified} and Appendix~\ref{app:measure} in C and
2538
  on the accelerator; it gives the sizes, depths and exact runs stated here, and noisy
2539
  runs within sampling error.
2540
 
2541
- The Rocq development, \texttt{rocq/} in the artifact, has $27$ files and
2542
- $7{,}391$ lines and builds with Rocq 9.1.1 in about seventy seconds on the machine
2543
  below, most of it in the kernel's evaluation of the $15{,}872$ abstract passes of
2544
- Proposition~\ref{prop:pass}. It defines the host family $H_A$ block by block and
 
2545
  proves that its step is the step of $\mathrm{SUBLEQ}_A$ for every $A\ge3$
2546
  (Proposition~\ref{prop:host}). It defines the device of
2547
  Definition~\ref{def:transducer} and the programs $P$ and $P^\ast$ in $2^A$ words,
@@ -2552,14 +2565,22 @@ block by block, the organism, the description code and the decoder, and proves
2552
  Theorem~\ref{thm:physnet} for every $\alpha\ge4$, $K\ge2$ and $S,L\ge1$, together
2553
  with the number of units and the weights; and it proves Lemma~\ref{lem:code},
2554
  Proposition~\ref{prop:pass}, Theorem~\ref{thm:construct} and
2555
- Theorem~\ref{thm:organism}, with the copies, the period and the network.
 
 
 
 
 
 
2556
 
2557
  The file that defines the organism and its description is written by
2558
  \texttt{src/twohead.py}. The netlist definitions, extracted to OCaml, write for $H_8$
2559
  the netlist that $\sigma(\Nhost)$ denotes, for $H_9$ and $H_{10}$ those that
2560
  \texttt{src/host.py} generates, and for $N^6_{3,160,3200}$, $N^{12}_{2,3,40}$ and
2561
  $N^6_{5,2,7}$ files byte for byte equal to those that \texttt{src/twohead.py}
2562
- writes.
 
 
2563
 
2564
  The encoder satisfies $\delta(\describe(f))=f$ within the bound of
2565
  Lemma~\ref{lem:describe} on the $29$ serialized machines of the artifact,
@@ -2587,8 +2608,8 @@ $1$:
2587
  \normalfont $N^6_{3,160,3200}$ & 5ca111e612df8546683a9f8a9e3873c967537a963a6f4fb4a196d84676d6bb9f\\
2588
  \normalfont organism $\rho$ & d4913db0b5ef6d3f122c44974cf9a58015fe7dabacb7176cf377d5cd0743f00b\\
2589
  \normalfont $\describe(\rho)$ & b0c8dc6efa0e7b581790304b21eb4698d3aeb2f442e02d26948fcef5c88a5ec0\\
2590
- \normalfont stored host $\mathcal S$ & 2aad2478143153562622be27d67385523203f5c0519604ef43eca0a510b986a0\\
2591
- \normalfont $\tau_{\mathcal S}$ & c74c4f479fa5f60cd561ea66ff071003f3d559890171c217f27d2943e79ff14d
2592
  \end{tabular}
2593
  \end{center}
2594
  The layouts behind these digests are the following. The metadata of
@@ -2614,10 +2635,9 @@ index of the signal computing its next value, the state bits being numbered firs
2614
  in the order of Theorem~\ref{thm:physnet}, and the units after them in the order of
2615
  the Rocq definition. The records of the organism and of $\mathcal S$ are laid out as in
2616
  Definition~\ref{def:twohead}, with the window cells of
2617
- Constructions~\ref{con:organism} and~\ref{con:stored}; within each block of
2618
- Construction~\ref{con:stored} the order of the records is that of
2619
- \texttt{src/twohead.py}, which gives each temporary the least cell free over
2620
- its live interval.
2621
  One generation of $\Omega^\ast$ takes $0.3$ seconds on~(a), $45$ seconds on~(d)
2622
  and $9$ minutes on~(b). All figures were
2623
  produced with Python 3.12.3, PyTorch 2.14.0 with CUDA 12.6, NumPy 2.5.3,
 
80
  SUBLEQ computer decodes a description of its own records into the next bank, copies
81
  the description onto the next tape and hands control to the copy. The fixed network
82
  thus rebuilds the stored computer, weights included, in every generation; its own
83
+ weights are the transition rule and are not reproduced. For every word width from
84
+ $8$ on and every ring it is proved in Rocq that the stored computer builds every
85
+ image that fits a bank from a description of it, and that, started on its own, it
86
+ reproduces: the copies accumulate until every bank holds one, and from then on the
87
+ whole state repeats every $K$ generations. A constructor of $143$ records with a
88
+ description code of its own does the same, also proved in Rocq.
89
  Every pre-activation is an integer, so every orbit survives perturbations below
90
  $1/2$ of each pre-activation. Under independent Gaussian noise on the
91
  pre-activations, a bound computed from the orbit lies within the $95\%$ interval of
 
174
  builds every image that fits a bank, from every recipe that fits a tape, into the
175
  next bank and hands control to it. Started on a recipe for its own records it
176
  reproduces in every generation, weights included; the copies accumulate until every
177
+ bank holds one, and from then on the state repeats every $K$ generations. All of it
178
+ is proved in Rocq for every $A\ge8$ and every ring
179
+ (Theorems~\ref{thm:storedconstruct} to~\ref{thm:widths}), and six generations of
180
+ $H_8$, $36{,}080$ records and $9.58\times10^{10}$ steps each, were run in a ring of three
181
  banks. A constructor of $143$ records with a description code of its own does the
182
+ same in the machine with $64$ window cells, with its universal construction, its
183
+ reproduction, the copies and the period proved in Rocq (Section~\ref{sec:organism}).
 
184
  \item \emph{Robustness.} Every orbit survives perturbations below $1/2$ of each
185
  pre-activation. Under independent Gaussian noise on the pre-activations, the
186
  probability that some unit fails in a step, computed from the pre-activation profile
 
222
  Amplification under the three noise models & Thm.~\ref{thm:amplify}, Cor.~\ref{cor:synapse}, Prop.~\ref{prop:flip} & proof\\
223
  Restoration bound for $N_3$ & Prop.~\ref{prop:restore} & proof; measured rates of Table~\ref{tab:bound3}\\
224
  The netlist computes the ring machine; its size and weights & Thm.~\ref{thm:physnet} & Rocq; extraction equal to the generator's; random states\\
225
+ A pass of the stored host, every $A\ge8$ & Prop.~\ref{prop:storedpass} & Rocq, block by block; decision diagrams of all four blocks and random states, $A=8,9,10$\\
226
+ Construction and reproduction by the stored host: copies, period, network, every $A\ge8$ & Thms.~\ref{thm:storedconstruct}--\ref{thm:widths} & Rocq, the counts of Thm.~\ref{thm:widths} by counting; the extracted image equal to the generator's for $A=8,9$; six generations of $\mathcal S_8$ run\\
227
  The organism: code, pass, construction, copies, period, network & Lem.~\ref{lem:code}, Prop.~\ref{prop:pass}, Thms.~\ref{thm:construct}, \ref{thm:organism} & Rocq; six generations run, one on the netlist\\
228
  \bottomrule
229
  \end{tabularx}
 
1764
  Inside the ring machine the instantiation step of Section~\ref{sec:selfrep} is a
1765
  write into the next bank followed by a hand-over. This section stores the host, and
1766
  every member of its family with wider words, as a network of two-input records in a
1767
+ bank of a ring machine whose window holds its state bits, $32{,}768$ cells for
1768
  $\Nhost$. A device compiled into the same records writes the bytes the host emits
1769
  under the arm until the tape is rewound, and under the copy head after it. Run on a
1770
  recipe for its own records, $P^\ast$ then writes the host into the next bank, copies
1771
  the recipe onto the next tape and hands control to the copy
1772
+ (Figure~\ref{fig:generation}). The Rocq development defines the stored host for
1773
+ every word width from $8$ on and proves its construction and its reproduction.
1774
 
1775
  \begin{lemma}[Stored netlists]\label{lem:feedback}
1776
  If the active bank holds records followed by empty slots and no record but the last
 
1817
  \end{proof}
1818
 
1819
  \begin{construction}[The stored host]\label{con:stored}
1820
+ Let $A\ge8$ and $w\ge1$. The window holds, after the thirteen cells of
1821
  Definition~\ref{def:twohead}, a cell $\mathrm{booted}$ at $13$, a counter
1822
  $\mathrm{cnt}$ of $w$ bits from $14$ on, least significant first, a cell
1823
  $\mathrm{dest}$, a limit $\mathrm{lim}$ of $w$ bits, the $n=A+1+A2^A$ state bits of
1824
+ $H_A$ in the order of Construction~\ref{con:host}, a cell for each unit of $H_A$,
1825
+ three cells for each level of the recursion of Lemma~\ref{cor:compile}, and $2w+9$
1826
+ cells for the device. The stored host $\mathcal S_{A,w}$ lists the following records.
1827
  \begin{enumerate}[label=(\alph*),leftmargin=2em]
1828
  \item \emph{Startup}, $A2^A+A+2w+8$ records: for each memory bit $c$,
1829
  $c\leftarrow c\vee\neg\mathrm{booted}$ if its value in $m^\ast_A$ is $1$ and
 
1832
  the bits of $\mathrm{cnt}$, $\mathrm{lim}$ and $\mathrm{dest}$; then five records
1833
  copying $\neg\mathrm{booted}$ into RR, CB, RA, CT and RC; then
1834
  $\mathrm{booted}\leftarrow1$.
1835
+ \item \emph{Step}: the units of $H_A$ in the order of the netlist, each compiled by
1836
+ Lemma~\ref{cor:compile} into its own cell, which also accumulates its chain; the
1837
+ unit of the next value of a state bit writes that bit instead, with its last
1838
+ record. A unit compiled by the recursion holds $T_t$, $T_{t-1}$ and the conjunction
1839
+ of each level in the three cells of that level.
 
1840
  \item \emph{Device}, $11A+12w+75$ records: the device of Definition~\ref{def:ring}
1841
  on the state that~(b) leaves.
1842
  \item \emph{Hand-over}: the fewest empty records, at most seven, that make the image
 
1844
  where $h$ is the halt bit, and three records copying $h$ into RA, RC and HO, the
1845
  last record.
1846
  \end{enumerate}
1847
+ The window is the least $2^\alpha$ that holds these cells. The host
1848
+ $\mathcal S=\mathcal S_{8,20}$ has $36{,}080$ records, its state bits at $55$ to
1849
+ $2111$, the cells of its $17{,}598$ units after them, and $19{,}765$ cells in all,
1850
+ so $\alpha=15$ and $b=53$; its image, its records in order, has $1{,}912{,}240$ bits,
1851
+ read as $239{,}030$ bytes most significant bit first, and
1852
+ $\tau_{\mathcal S}=\describe(\mathcal S)$ has $240{,}900$ bytes.
1853
  \end{construction}
1854
 
1855
  \begin{definition}[The device of the stored host]\label{def:ring}
 
1890
  \node[note,anchor=south] at (a3.north) {$403$};
1891
  \node[note,anchor=south] at (a4.north) {$1+4$};
1892
  \node[lab] at (0,-1.1) {read tape $D_\kappa$};
1893
+ \node[s,minimum width=76mm] (d0) at (0.15,-1.1) {$\tau_{\mathcal S}=\describe(\mathcal S)$, $240{,}900$ bytes};
1894
  \node[lab] at (0,-2.2) {next bank $Q_{\kappa+1}$};
1895
  \node[s,densely dashed,minimum width=76mm] (q1) at (0.15,-2.2) {$\mathcal S$, written under the arm in phase~(A)};
1896
  \node[lab] at (0,-3.3) {next tape $D_{\kappa+1}$};
 
1933
  unchanged when $\mathrm{booted}=1$. Otherwise they set each memory bit to its value
1934
  in $m^\ast_A$, clear the other cells they name, and set the five requests that
1935
  return the heads and clear the idle bank and the copy tape. The step block is $H_A$
1936
+ compiled by Lemma~\ref{cor:compile} in the order of the netlist, which
1937
+ Lemma~\ref{lem:feedback} admits: every unit follows its predecessors, a unit that
1938
+ reads a state bit comes no later than the unit of its next value, which reads the bit
1939
+ before its last record writes it, and no unit reads the unit of a next value. So
1940
+ after the block the state bits hold the next state of $H_A$.
 
 
 
1941
 
1942
  The device records form the requests $[y_c=1]$ as conjunctions of $A$ literals, the
1943
  bit $[\mathrm{cnt}=\mathrm{lim}]$ as a conjunction of $w$ equivalences, and its
 
1956
  pass before it is read and is not written after its last read, so a cell shared by
1957
  temporaries holds, at each read, the value of the temporary read. No record writes
1958
  the active bank, and the empty slots after the records change nothing but the slot
1959
+ head. Each block is proved in Rocq from every window and every state of $H_A$, and
1960
+ the records of a pass are carried to the steps of the machine.
1961
  \end{proof}
1962
 
1963
+ The theorems below use what Proposition~\ref{prop:storedpass} states and one more
1964
+ property of the image: every cell that a record after the startup records reads,
1965
+ other than the cells under the heads and the sink, is written earlier in the pass.
1966
+ The image $\mathcal S_{A,w}$ has this property for every $A\ge8$ and $w\ge1$, and
1967
+ $B=bG/8$ bytes, with $b=8+3\alpha$; $\mathcal S$ has $\alpha=15$, $G=36{,}080$ and
1968
+ $B=239{,}030$. The proofs apply to every image with these two properties, whatever
1969
+ netlist with the step of $H_A$ its step block compiles.
 
 
1970
 
1971
  \begin{theorem}[Universal construction by the dynamics]\label{thm:storedconstruct}
1972
+ Let $A\ge8$ and $w\ge1$, let $\mathcal S_{A,w}$ have $G$ records, and let $K\ge2$ and
1973
+ $S\ge G$. Let $X$ be a byte string of at most $Sb/8$ bytes, $r$ a recipe with
1974
+ $\delta(r)=X$ and $|r|<2^w$, and $L\ge8|r|$. Let $x$ be a state of
1975
+ $M^\alpha_{K,S,L}$ with $\mathcal S_{A,w}$ in the active bank from slot $0$,
1976
+ followed by empty slots, with the slot head at slot $0$, $r$ on the read tape from
1977
+ cell $0$ followed by zeros, and in the window $\mathrm{booted}=0$ and clear
1978
+ requests, whatever the other banks, tapes and cells hold. Let $P$ be the number of steps that
1979
  Proposition~\ref{prop:steps} gives for $r$. After $P$ passes, each of $S$ steps but
1980
  the last, which has $G$:
1981
  \begin{enumerate}[label=(\roman*),leftmargin=2em]
1982
  \item the next bank holds the bits of $X$ from slot $0$, followed by zeros, with
1983
  both its heads at $0$, and the next tape holds $r$ from cell $0$, followed by zeros,
1984
  with its head at $0$;
1985
+ \item the active bank still holds $\mathcal S_{A,w}$ and the read tape $r$, the
1986
+ window holds $\mathrm{booted}=0$ and clear requests, and no other bank or tape has
1987
+ changed;
1988
  \item the bank index has moved to the next bank.
1989
  \end{enumerate}
1990
  From then on $M^\alpha_{K,S,L}$ evaluates the records of $X$.
 
2014
  $8|X|\le Sb$. Those emitted after it, $r$, are written under the copy head from cell
2015
  $0$ of the cleared tape, and fit since $8|r|\le L$. The active bank and the read tape
2016
  are not written, and no other bank or tape is addressed. From the next step on the
2017
+ bank holding $X$ is active, at slot $0$. The proof is checked in Rocq for every
2018
+ $A\ge8$, $w\ge1$, $K\ge2$, $S\ge G$ and $L\ge8|r|$, each pass related to one step of
2019
+ the run of $P^\ast$ on $r$ with the device of Definition~\ref{def:transducer}.
2020
  \end{proof}
2021
 
2022
+ By Lemma~\ref{lem:complete} every byte string has a recipe, so $\mathcal S_{A,w}$
2023
+ builds every image that fits a bank from a recipe that fits a tape, itself among
2024
+ them; the images need not have its size.
2025
 
2026
  \begin{theorem}[Self-reproduction of the host by the dynamics]\label{thm:storedrep}
2027
+ Let $A\ge8$ and $w\ge1$, let $\mathcal S_{A,w}$ have $G$ records and $B$ bytes, let
2028
+ $\tau'$ be a recipe of its image with $|\tau'|<2^w$, and let $K\ge2$, $S\ge G$ and
2029
+ $L\ge8|\tau'|$. Let $x_0$ be a state of $M^\alpha_{K,S,L}$ with $\kappa=0$,
2030
+ $\mathcal S_{A,w}$ in bank $0$ from slot $0$ with its slot head at slot $0$, $\tau'$ on
2031
+ tape $0$ from cell $0$ followed by zeros, and in the window $\mathrm{booted}=0$ and
2032
+ clear requests, whatever the other banks, tapes and cells hold. A generation is
2033
+ $(P-1)S+G$ steps, where $P$ is the number of steps that
2034
+ Proposition~\ref{prop:steps} gives for $\tau'$; for $\tau'=\describe(\mathcal S_{A,w})$,
2035
+ $P=11B+13\lceil B/127\rceil+16$ if the image has no four equal consecutive bytes and
2036
+ $P\le\tfrac{25}{2}B+29$ in any case. For every $g\ge1$, after $g$ generations
2037
+ $\kappa=g\bmod K$, and the banks $0,\dots,\min(g,K-1)$ of the ring, counted back from
2038
+ bank $\kappa$, hold $\mathcal S_{A,w}$ from slot $0$ and their tapes $\tau'$ from cell
2039
+ $0$: the copies accumulate until every bank holds one. From the $K$-th generation on
2040
+ the state repeats every $K$ generations. The network $N^\alpha_{K,S,L}$ started from
2041
+ the bits of $x_0$ holds the bits of these states at the same steps. For $\mathcal S$,
2042
+ with $K=3$, $S=G+5=36{,}085$ and $L=8|\tau_{\mathcal S}|+64=1{,}927{,}264$, a
2043
+ generation is $P=2{,}653{,}813$ passes, $95{,}762{,}842{,}100$ applications of
2044
+ $M^{15}_{3,S,L}$.
2045
  \end{theorem}
2046
 
2047
  \begin{proof}
2048
+ The first generation is Theorem~\ref{thm:storedconstruct} with $X$ the image of
2049
+ $\mathcal S_{A,w}$ and $r=\tau'$. After it the next bank holds $\mathcal S_{A,w}$ from
2050
+ slot $0$ with its heads at $0$, the next tape $\tau'$ from cell $0$ followed by
2051
+ zeros, and the window $\mathrm{booted}=0$ and clear requests, so the state satisfies
2052
+ the hypothesis of Theorem~\ref{thm:storedconstruct} for the next bank. A generation
2053
+ changes only the active bank's slot head, the read tape's head, and the next bank
2054
+ and tape, which it rebuilds; induction over the generations gives $\kappa$ and the
2055
+ copies. Let $\tau'$ have $\ell$ literal and $R$ repeat tokens. Since
2056
+ $|\tau'|=f_{\mathrm{lit}}+\ell+2R+1$, Proposition~\ref{prop:steps} gives
2057
  $P=11f_{\mathrm{lit}}+4f_{\mathrm{rep}}+13\ell+21R+16$. Without four equal
2058
  consecutive bytes $\describe$ emits $\lceil B/127\rceil$ literal tokens and
2059
  nothing else (Lemma~\ref{lem:describe}); in general its proof gives
2060
  $\ell\le f_{\mathrm{lit}}/127+R+1$ and $4R\le f_{\mathrm{rep}}$, hence
2061
+ $P\le\tfrac{25}{2}B+29$; $\tau_{\mathcal S}$ has $1888$ literal and $8$ repeat tokens.
2062
 
2063
  For the period, let $g\ge K$. Every bank has then been rebuilt and has been active
2064
+ since: the bank active $a$ generations ago, $1\le a<K$, holds $\mathcal S_{A,w}$
2065
+ with its slot head where its hand-over pass left it, at slot $G\bmod S$, and its bit
2066
+ head at $0$, and its tape holds $\tau'$ followed by zeros with the head where the
2067
+ copying left it, after $\tau'$; the active bank and its tape have all heads at $0$.
2068
+ So the banks, the tapes and $\kappa$ after generation $g$ depend only on $g\bmod K$.
2069
+ In the window, the cells no record writes keep their values. The first pass of a
2070
+ generation loads the same state of the host and the same registers into every
2071
+ window with $\mathrm{booted}=0$, and the heads and the tapes they read are the same
2072
+ in every generation; every cell a record after the startup reads is written earlier
2073
+ in the pass, apart from the cells under the heads and the sink. So, pass by pass,
2074
+ the windows of any two generations agree on every cell the records read or write,
2075
+ and after a generation the window is the same in every generation. The state after
2076
+ generation $g+K$ therefore equals the state after generation $g$, and
2077
+ Theorem~\ref{thm:physnet} carries the statement to the network. All of it is
2078
+ checked in Rocq for every $A\ge8$, $w\ge1$, every recipe $\tau'$ of the image with
2079
+ $|\tau'|<2^w$, $K\ge2$, $S\ge G$ and $L\ge8|\tau'|$.
2080
  \end{proof}
2081
 
2082
  \begin{theorem}[Every word width]\label{thm:widths}
2083
+ For every $A\ge8$ there is a least $w_A\ge20$ for which the image of
2084
+ $\mathcal S_A=\mathcal S_{A,w_A}$, of $B_A$ bytes, has $2B_A+1<2^{w_A}$; then its
2085
+ recipe of literal tokens and $\describe(\mathcal S_A)$ are shorter than $2^{w_A}$.
2086
+ The stored host $\mathcal S_A$ builds every image that fits a bank and reproduces
2087
+ itself by the dynamics of $N^{\alpha_A}_{K,S,L}$ as
2088
  Theorems~\ref{thm:storedconstruct} and~\ref{thm:storedrep} state, with
2089
  \[
2090
  G_A=35A2^{A-1}-2^{A+1}+\tfrac16(A^3-A)+A^2+29A+14w_A+91+\pi_A
 
2095
  \end{theorem}
2096
 
2097
  \begin{proof}
2098
+ The records of $\mathcal S_{A,w}$ grow linearly in $w$ and its window
2099
+ logarithmically, so $B$ grows quadratically in $w$ while $2^w$ grows exponentially,
2100
+ and $w_A$ exists; this is proved in Rocq. The recipe of literal tokens of
2101
+ Lemma~\ref{lem:complete} has $B+\lceil B/127\rceil+1\le2B+1$ bytes, and
2102
+ $\describe$ gives no more by Lemma~\ref{lem:describe}. The startup and device
2103
  records are counted in Construction~\ref{con:stored} and the hand-over has
2104
  $4+\pi_A$. Lemma~\ref{cor:compile} compiles a conjunction or a disjunction of
2105
  $k\ge2$ literals into $k-1$ records and a unit of threshold $2$ on three or four
2106
  literals into four or eight, and summing over the blocks of Table~\ref{tab:blocks}
2107
  gives $\tfrac{33}{2}A2^A-2^{A+1}+\tfrac16(A^3-A)+A^2+17A+4$ step records, the cubic
2108
+ term from the carry terms. The window holds the $A2^A+A+1$ state bits, a cell for
2109
+ each of the $\Theta(A2^A)$ units of $H_A$ and $O(A+w_A)$ further cells, so
2110
+ $\alpha_A=A+\Theta(\log A)$; then $b=8+3\alpha_A=\Theta(A)$,
2111
  $B=bG_A/8=\Theta(A^22^A)$, and Theorem~\ref{thm:storedrep} gives a generation of
2112
  $\Theta(B)$ passes of $S=G_A$ steps.
2113
  \end{proof}
2114
 
2115
+ For $A=8$ to $12$, $\mathcal S_A$ has $36{,}080$, $80{,}463$, $178{,}112$, $391{,}220$ and
2116
+ $853{,}176$ records, windows of $2^{15}$ to $2^{19}$ cells, counters of $20$, $21$,
2117
+ $22$, $23$ and $24$ bits and images of $239{,}030$ to $6{,}932{,}055$ bytes, and a
2118
+ generation takes $2{,}653{,}813$, $6{,}253{,}470$, $14{,}583{,}670$,
2119
+ $33{,}661{,}915$ and $76{,}962{,}164$ passes, $9.57\times10^{10}$ to
2120
+ $6.57\times10^{13}$ applications of $M$ with $S=G_A$.
2121
 
2122
  \begin{corollary}[Self-reproduction under noise]\label{cor:storednoise}
2123
+ $\Lev(N^{15}_{3,S,L})$ has depth $19$ and $1{,}118{,}054+4{,}839S+153L$ rows,
2124
+ $M=470{,}604{,}761$ for the member of Theorem~\ref{thm:storedrep} that holds $\mathcal S$.
2125
  Under independent centred Gaussian perturbations of deviation $s$ on every
2126
+ pre-activation, a generation of $\mathcal S$, $T=95{,}762{,}842{,}100$ applications, runs
2127
  exactly with probability at least $1-TM\erfc\bigl(1/(2\sqrt2\,s)\bigr)$, which
2128
  exceeds $0.999$ for $s\le0.050$. The threefold and fivefold amplifications of
2129
+ Definition~\ref{def:amplify} reach the same probability for $s\le0.148$ and
2130
  $s\le0.247$.
2131
  \end{corollary}
2132
 
 
2139
 
2140
  \begin{remark}[Corroboration]\label{rem:storedcheck}
2141
  Six generations of $\mathcal S$ from $x_0$ were run in a ring of three banks,
2142
+ $S=36{,}085$ and $L=1{,}927{,}264$, on a transcription of Definition~\ref{def:twohead}
2143
  in C. After each, the new active bank held $\mathcal S$ and the new read tape
2144
  $\tau_{\mathcal S}$ from their origins with their heads there. The copies accumulated,
2145
  two after the first generation and three from the second on, and the full states
 
2147
  second. One pass of $\mathcal S$ agreed with the startup, one step of $\Nhost$ and
2148
  the device of Definition~\ref{def:ring} from $300$ random states, a fifth of them not
2149
  booted and a third with requests holding random words, with random tapes, banks,
2150
+ registers and temporaries; so did one pass of $\mathcal S_9$ from $100$ and of
2151
+ $\mathcal S_{10}$ from $30$.
2152
 
2153
  All four blocks of $\mathcal S_8$ to $\mathcal S_{10}$ were also evaluated on reduced
2154
  ordered decision diagrams over variables for the window, the cells under the heads
 
2166
  \end{remark}
2167
 
2168
  % =============================================================================
2169
+ \section{A constructor with a description code of its own}\label{sec:organism}
2170
  % =============================================================================
2171
 
2172
+ The stored host reproduces through a computer of $36{,}080$ records that runs a
2173
+ program. This section gives a stored network of $143$ records, the organism, that
2174
+ performs von Neumann's cycle directly in $M_{K,S,L}$, the machine of $64$ window
2175
+ cells, with a description code of its own. Its universal construction, its
 
2176
  reproduction in every ring, the accumulation of its copies and the period of the
2177
  state are proved in Rocq, in the machine and in the network.
2178
 
 
2543
  Python and in C and by the netlist $N^\alpha_{K,S,L}$ in Python and in C. The
2544
  stored host is built from $\sigma(\Nhost)$ by \texttt{src/twohead.py}, and its
2545
  generations are run by \texttt{src/ring\_run.c}, which decodes the active bank once
2546
+ per hand-over and steps over its empty slots, about eight minutes per generation.
2547
  Separate code in \texttt{src/independent.py}, written from the definitions of this
2548
  paper, rebuilds $H_A$ for $A=3$ to $12$, levelizes $\sigma(\Nhost)$ and repeats the
2549
  measurements of Section~\ref{sec:certified} and Appendix~\ref{app:measure} in C and
2550
  on the accelerator; it gives the sizes, depths and exact runs stated here, and noisy
2551
  runs within sampling error.
2552
 
2553
+ The Rocq development, \texttt{rocq/} in the artifact, has $44$ files and
2554
+ $13{,}795$ lines and builds with Rocq 9.1.1 in about three minutes on the machine
2555
  below, most of it in the kernel's evaluation of the $15{,}872$ abstract passes of
2556
+ Proposition~\ref{prop:pass} and in the device records of the stored host. It defines
2557
+ the host family $H_A$ block by block and
2558
  proves that its step is the step of $\mathrm{SUBLEQ}_A$ for every $A\ge3$
2559
  (Proposition~\ref{prop:host}). It defines the device of
2560
  Definition~\ref{def:transducer} and the programs $P$ and $P^\ast$ in $2^A$ words,
 
2565
  Theorem~\ref{thm:physnet} for every $\alpha\ge4$, $K\ge2$ and $S,L\ge1$, together
2566
  with the number of units and the weights; and it proves Lemma~\ref{lem:code},
2567
  Proposition~\ref{prop:pass}, Theorem~\ref{thm:construct} and
2568
+ Theorem~\ref{thm:organism}, with the copies, the period and the network. It
2569
+ defines the stored host $\mathcal S_{A,w}$ of Construction~\ref{con:stored} for
2570
+ every $A\ge8$ and $w\ge1$ and proves its four blocks from every window
2571
+ (Proposition~\ref{prop:storedpass}), that every cell a pass reads after the startup
2572
+ is written earlier in the pass, Theorems~\ref{thm:storedconstruct}
2573
+ and~\ref{thm:storedrep} with the copies, the period and the network, and the
2574
+ existence of $w_A$ in Theorem~\ref{thm:widths}.
2575
 
2576
  The file that defines the organism and its description is written by
2577
  \texttt{src/twohead.py}. The netlist definitions, extracted to OCaml, write for $H_8$
2578
  the netlist that $\sigma(\Nhost)$ denotes, for $H_9$ and $H_{10}$ those that
2579
  \texttt{src/host.py} generates, and for $N^6_{3,160,3200}$, $N^{12}_{2,3,40}$ and
2580
  $N^6_{5,2,7}$ files byte for byte equal to those that \texttt{src/twohead.py}
2581
+ writes. The definition of $\mathcal S_{A,w}$, extracted to OCaml, writes for $A=8$
2582
+ and $9$ the images of $\mathcal S_8$ and $\mathcal S_9$ that \texttt{src/twohead.py}
2583
+ builds.
2584
 
2585
  The encoder satisfies $\delta(\describe(f))=f$ within the bound of
2586
  Lemma~\ref{lem:describe} on the $29$ serialized machines of the artifact,
 
2608
  \normalfont $N^6_{3,160,3200}$ & 5ca111e612df8546683a9f8a9e3873c967537a963a6f4fb4a196d84676d6bb9f\\
2609
  \normalfont organism $\rho$ & d4913db0b5ef6d3f122c44974cf9a58015fe7dabacb7176cf377d5cd0743f00b\\
2610
  \normalfont $\describe(\rho)$ & b0c8dc6efa0e7b581790304b21eb4698d3aeb2f442e02d26948fcef5c88a5ec0\\
2611
+ \normalfont stored host $\mathcal S$ & 9a7821a540fed2ed58fbb263213f65aead6bbbd8cca6344abcabcc5f4289903c\\
2612
+ \normalfont $\tau_{\mathcal S}$ & dbb2cfe5fe8e53e303a51ddbe52964f70f83169181ec4dc05450cb244b9b5a97
2613
  \end{tabular}
2614
  \end{center}
2615
  The layouts behind these digests are the following. The metadata of
 
2635
  in the order of Theorem~\ref{thm:physnet}, and the units after them in the order of
2636
  the Rocq definition. The records of the organism and of $\mathcal S$ are laid out as in
2637
  Definition~\ref{def:twohead}, with the window cells of
2638
+ Constructions~\ref{con:organism} and~\ref{con:stored}; in $\mathcal S$ the cells of
2639
+ the units, of the levels and of the device follow the state bits in that order, and
2640
+ the order of the records is that of the Rocq definition.
 
2641
  One generation of $\Omega^\ast$ takes $0.3$ seconds on~(a), $45$ seconds on~(d)
2642
  and $9$ minutes on~(b). All figures were
2643
  produced with Python 3.12.3, PyTorch 2.14.0 with CUDA 12.6, NumPy 2.5.3,
rocq/Assumptions.v CHANGED
@@ -1,5 +1,6 @@
1
  (* The assumptions of the main theorems, printed by src/paper.py rocq after the build. *)
2
- From TH Require Import PhysSem PhysMain PhysFacts NetMain Complete Decoder Run PassLemma Main HostSem Pstar.
 
3
 
4
  Print Assumptions PhysSem.netlist_step.
5
  Print Assumptions PhysMain.network_orbit.
@@ -21,3 +22,20 @@ Print Assumptions Pstar.constructor_run.
21
  Print Assumptions Pstar.selfrep_run.
22
  Print Assumptions Pstar.image_Pstar_8.
23
  Print Assumptions Pstar.image_P_8.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  (* The assumptions of the main theorems, printed by src/paper.py rocq after the build. *)
2
+ From TH Require Import PhysSem PhysMain PhysFacts NetMain Complete Decoder Run PassLemma Main HostSem Pstar
3
+ StoredBoot StoredPass StoredDev StoredOk StoredRun StoredWbr StoredMain StoredWidth.
4
 
5
  Print Assumptions PhysSem.netlist_step.
6
  Print Assumptions PhysMain.network_orbit.
 
22
  Print Assumptions Pstar.selfrep_run.
23
  Print Assumptions Pstar.image_Pstar_8.
24
  Print Assumptions Pstar.image_P_8.
25
+ Print Assumptions StoredBoot.startup_run.
26
+ Print Assumptions StoredPass.step_view.
27
+ Print Assumptions StoredDev.device_run.
28
+ Print Assumptions StoredBoot.handover_run.
29
+ Print Assumptions StoredOk.stored_ok.
30
+ Print Assumptions StoredPass.pass_first.
31
+ Print Assumptions StoredPass.pass_next.
32
+ Print Assumptions StoredRun.machine_pass.
33
+ Print Assumptions StoredRun.stored_construct.
34
+ Print Assumptions StoredWbr.wbr_stored.
35
+ Print Assumptions StoredMain.reproduces.
36
+ Print Assumptions StoredMain.copies.
37
+ Print Assumptions StoredMain.periodic.
38
+ Print Assumptions StoredMain.network_reproduces.
39
+ Print Assumptions StoredMain.network_periodic.
40
+ Print Assumptions StoredWidth.width_exists.
41
+ Print Assumptions StoredWidth.recipe_of_image.
rocq/ExtractStored.v ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ From Stdlib Require Import Extraction ExtrOcamlBasic ExtrOcamlNatInt ExtrOcamlZInt.
2
+ From TH Require Import Stored.
3
+ Extraction Language OCaml.
4
+ Set Extraction Output Directory "extract".
5
+ Extraction "storednet.ml" stored_bits.
rocq/HostIP.v ADDED
@@ -0,0 +1,329 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* The host netlist read in its own order, for every A >= 3: every weight is 1 or -1, no unit reads the
2
+ unit of a next value, and a unit that reads a state bit comes no later than the unit of that bit's next
3
+ value. So the unit of each next value may write its state bit in place. *)
4
+ From Stdlib Require Import List Bool Arith ZArith Lia.
5
+ Import ListNotations.
6
+ From TH Require Import TwoHead Net Gates Host HostWF PhysFacts.
7
+
8
+ (* ---- flat indices and block coordinates ------------------------------------------------------------ *)
9
+ Lemma flat_loc : forall bs, Forall shaped bs -> forall k, k < boff bs (length bs) ->
10
+ exists b j r, b < length bs /\ j < bcount (nth b bs blk0) /\ r < bsize (nth b bs blk0)
11
+ /\ k = boff bs b + bsize (nth b bs blk0) * j + r.
12
+ Proof.
13
+ intros bs Hsh. induction Hsh as [|blk t Hs Ht IH]; intros k Hk; cbn [boff length] in Hk; [lia|].
14
+ destruct (Nat.lt_ge_cases k (bcount blk * bsize blk)) as [Hl|Hg].
15
+ - exists 0, (k / bsize blk), (k mod bsize blk).
16
+ assert (bsize blk <> 0) by (intro E; rewrite E in Hl; lia).
17
+ cbn [nth length boff]. split; [lia|]. split; [apply Nat.Div0.div_lt_upper_bound; nia|].
18
+ split; [apply Nat.mod_upper_bound; exact H|]. rewrite (Nat.div_mod k (bsize blk)) at 1 by exact H. lia.
19
+ - destruct (IH (k - bcount blk * bsize blk) ltac:(lia)) as (b & j & r & Hb & Hj & Hr & Hk').
20
+ exists (S b), j, r. cbn [nth length boff]. split; [lia|]. split; [exact Hj|]. split; [exact Hr|]. lia.
21
+ Qed.
22
+
23
+ Lemma idx_inj : forall bs n x y, valid bs n x -> valid bs n y -> idx n bs x = idx n bs y -> x = y.
24
+ Proof.
25
+ intros bs n [i|b j r] [i'|b' j' r'] Hx Hy E; cbn [valid idx] in Hx, Hy, E.
26
+ - subst. reflexivity.
27
+ - lia.
28
+ - lia.
29
+ - destruct Hx as (Hb & Hj & Hr). destruct Hy as (Hb' & Hj' & Hr').
30
+ assert (Bb : b = b').
31
+ { destruct (Nat.lt_trichotomy b b') as [L|[L|L]]; [|exact L|].
32
+ - pose proof (boff_mono bs b' b L ltac:(lia)). nia.
33
+ - pose proof (boff_mono bs b b' L ltac:(lia)). nia. }
34
+ subst b'. assert (Jj : j = j') by nia. subst j'. f_equal. lia.
35
+ Qed.
36
+
37
+ (* ---- the inputs of the last four blocks ------------------------------------------------------------ *)
38
+ Ltac solve_disj := repeat (first [left; reflexivity | right]); reflexivity.
39
+
40
+ Ltac lits3 Hin := let H := fresh "H" in
41
+ first [pose proof (in_sin_lits _ _ _ (or_introl Hin)) as H | pose proof (in_sin_lits _ _ _ (or_intror Hin)) as H];
42
+ cbn [map fst] in H; destruct H as [<-|[<-|[<-|[]]]]; solve_disj.
43
+
44
+ Ltac lits2 Hin := let H := fresh "H" in
45
+ first [pose proof (in_sin_lits _ _ _ (or_introl Hin)) as H | pose proof (in_sin_lits _ _ _ (or_intror Hin)) as H];
46
+ cbn [map fst] in H; destruct H as [<-|[<-|[]]]; solve_disj.
47
+
48
+ Section Last.
49
+ Variable A : nat.
50
+ Hypothesis HA : 3 <= A.
51
+
52
+ Lemma len_hb : length (hblocks A) = tb A + 15.
53
+ Proof. apply length_hblocks. lia. Qed.
54
+
55
+ Lemma inputs_NP : forall j r x w, j < A -> r < 1 -> In (x, w) (sin (sunit (hblocks A) (tb A + 11) j r)) ->
56
+ x = SRef 1 j 0 \/ x = SRef (tb A + 9) j 0 \/ x = SRef (tb A + 10) j 0.
57
+ Proof.
58
+ intros j r x w Hj Hr Hin. unfold sunit in Hin. rewrite nth_hb_post in Hin by lia.
59
+ cbn [nth hpost bshape blk_NP] in Hin. destruct r as [|r]; [|lia]. cbn [nth] in Hin. lits3 Hin.
60
+ Qed.
61
+
62
+ Lemma inputs_HAB : forall j r x w, j < 1 -> r < 3 -> In (x, w) (sin (sunit (hblocks A) (tb A + 12) j r)) ->
63
+ x = haltb A \/ x = SRef (tb A + 8) 0 0 \/ x = SRef 9 0 0 \/ x = SRef 0 (SW A - 4) 0
64
+ \/ x = SRef (tb A + 12) 0 0 \/ x = SRef (tb A + 12) 0 1.
65
+ Proof.
66
+ intros j r x w Hj Hr Hin. unfold sunit in Hin. rewrite nth_hb_post in Hin by lia.
67
+ cbn [nth hpost bshape blk_HAB] in Hin.
68
+ assert (Hr3 : r = 0 \/ r = 1 \/ r = 2) by lia.
69
+ destruct Hr3 as [->|[->| ->]]; cbn [nth] in Hin; lits3 Hin.
70
+ Qed.
71
+
72
+ Lemma inputs_WR : forall j r x w, r < 1 -> In (x, w) (sin (sunit (hblocks A) (tb A + 13) j r)) ->
73
+ x = rbit A (A - 1 - j mod A) \/ x = SRef 10 (j / A) 0.
74
+ Proof.
75
+ intros j r x w Hr Hin. unfold sunit in Hin. rewrite nth_hb_post in Hin by lia.
76
+ cbn [nth hpost bshape blk_WR] in Hin. destruct r as [|r]; [|lia]. cbn [nth] in Hin. lits2 Hin.
77
+ Qed.
78
+
79
+ Lemma inputs_NM : forall j r x w, r < 1 -> In (x, w) (sin (sunit (hblocks A) (tb A + 14) j r)) ->
80
+ x = SRef 13 j 0 \/ x = SRef (tb A + 13) j 0.
81
+ Proof.
82
+ intros j r x w Hr Hin. unfold sunit in Hin. rewrite nth_hb_post in Hin by lia.
83
+ cbn [nth hpost bshape blk_NM] in Hin. destruct r as [|r]; [|lia]. cbn [nth] in Hin. lits2 Hin.
84
+ Qed.
85
+
86
+ Lemma rbit_not : forall k b j r, rbit A k = SRef b j r -> b < tb A + 8.
87
+ Proof.
88
+ intros k b j r. unfold rbit. destruct (Nat.eqb_spec k 0); intro E; injection E as <- _ _; unfold tb; lia.
89
+ Qed.
90
+
91
+ Lemma bsize_post : forall i, i < 15 -> bsize (nth (tb A + i) (hblocks A) blk0) = bsize (nth i (hpost A) blk0).
92
+ Proof. intros i Hi. rewrite nth_hb_post by lia. reflexivity. Qed.
93
+
94
+ Lemma bcount_post : forall i, i < 15 -> bcount (nth (tb A + i) (hblocks A) blk0) = bcount (nth i (hpost A) blk0).
95
+ Proof. intros i Hi. rewrite nth_hb_post by lia. reflexivity. Qed.
96
+
97
+ (* the units of the next values are valid units *)
98
+ Lemma hout_valid : forall i, i < nH A -> valid (hblocks A) (nH A) (hout A i).
99
+ Proof.
100
+ intros i Hi. pose proof (SW_ge A HA). unfold hout.
101
+ destruct (Nat.ltb_spec i A); [|destruct (Nat.eqb_spec i A)]; cbn [valid]; rewrite len_hb;
102
+ (split; [lia|]); rewrite ?bcount_post, ?bsize_post by lia;
103
+ cbn [nth hpost bcount bsize blk_NP blk_HAB blk_NM]; unfold nH in Hi; nia.
104
+ Qed.
105
+
106
+ (* no unit reads the unit of a next value *)
107
+ Theorem reads_no_out : forall b j r x w,
108
+ b < length (hblocks A) -> j < bcount (nth b (hblocks A) blk0) -> r < bsize (nth b (hblocks A) blk0) ->
109
+ In (x, w) (sin (sunit (hblocks A) b j r)) -> forall i, i < nH A -> x <> hout A i.
110
+ Proof.
111
+ intros b j r x w Hb Hj Hr Hin i Hi E. rewrite len_hb in Hb.
112
+ pose proof (proj2 (host_wf A HA) b j r x w ltac:(rewrite len_hb; lia) Hj Hr Hin) as Hrb.
113
+ unfold hout in E.
114
+ destruct (Nat.ltb_spec i A) as [Hia|Hia]; [|destruct (Nat.eqb_spec i A) as [Hie|Hie]]; subst x;
115
+ cbn [reads_back] in Hrb.
116
+ - (* SRef (tb + 11) i 0 *)
117
+ destruct Hrb as [(Hb' & _ & _)|(Eb & Ej & Hr')].
118
+ + assert (Hc : b = tb A + 12 \/ b = tb A + 13 \/ b = tb A + 14) by lia.
119
+ destruct Hc as [->|[->| ->]].
120
+ * rewrite bcount_post in Hj by lia. rewrite bsize_post in Hr by lia.
121
+ cbn [nth hpost bcount bsize blk_HAB] in Hj, Hr.
122
+ destruct (inputs_HAB j r _ w Hj Hr Hin) as [E|[E|[E|[E|[E|E]]]]]; try discriminate;
123
+ injection E; unfold tb; lia.
124
+ * rewrite bsize_post in Hr by lia. cbn [nth hpost bsize blk_WR] in Hr.
125
+ destruct (inputs_WR j r _ w Hr Hin) as [E|E]; [|injection E; unfold tb; lia].
126
+ pose proof (rbit_not (A - 1 - j mod A) _ _ _ (eq_sym E)). lia.
127
+ * rewrite bsize_post in Hr by lia. cbn [nth hpost bsize blk_NM] in Hr.
128
+ destruct (inputs_NM j r _ w Hr Hin) as [E|E]; injection E; unfold tb; lia.
129
+ + subst b. rewrite bsize_post in Hr by lia. cbn [nth hpost bsize blk_NP] in Hr. lia.
130
+ - (* SRef (tb + 12) 0 2 *)
131
+ destruct Hrb as [(Hb' & _ & _)|(Eb & Ej & Hr')].
132
+ + assert (Hc : b = tb A + 13 \/ b = tb A + 14) by lia.
133
+ destruct Hc as [->| ->].
134
+ * rewrite bsize_post in Hr by lia. cbn [nth hpost bsize blk_WR] in Hr.
135
+ destruct (inputs_WR j r _ w Hr Hin) as [E|E]; [|injection E; unfold tb; lia].
136
+ pose proof (rbit_not (A - 1 - j mod A) _ _ _ (eq_sym E)). lia.
137
+ * rewrite bsize_post in Hr by lia. cbn [nth hpost bsize blk_NM] in Hr.
138
+ destruct (inputs_NM j r _ w Hr Hin) as [E|E]; injection E; unfold tb; lia.
139
+ + subst b. rewrite bsize_post in Hr by lia. cbn [nth hpost bsize blk_HAB] in Hr. lia.
140
+ - (* SRef (tb + 14) (i - A - 1) 0 *)
141
+ destruct Hrb as [(Hb' & _ & _)|(Eb & Ej & Hr')]; [lia|].
142
+ subst b. rewrite bsize_post in Hr by lia. cbn [nth hpost bsize blk_NM] in Hr. lia.
143
+ Qed.
144
+
145
+ (* the state bits the last four blocks read: the halt bit, read by the halt latch alone *)
146
+ Lemma last_reads_halt : forall b j r i w, tb A + 11 <= b < tb A + 15 ->
147
+ j < bcount (nth b (hblocks A) blk0) -> r < bsize (nth b (hblocks A) blk0) ->
148
+ In (SIn i, w) (sin (sunit (hblocks A) b j r)) -> b = tb A + 12 /\ i = A.
149
+ Proof.
150
+ intros b j r i w Hb Hj Hr Hin.
151
+ assert (Hc : b = tb A + 11 \/ b = tb A + 12 \/ b = tb A + 13 \/ b = tb A + 14) by lia.
152
+ destruct Hc as [->|[->|[->| ->]]].
153
+ - rewrite bcount_post in Hj by lia. rewrite bsize_post in Hr by lia.
154
+ cbn [nth hpost bcount bsize blk_NP] in Hj, Hr.
155
+ destruct (inputs_NP j r _ w Hj Hr Hin) as [E|[E|E]]; discriminate.
156
+ - rewrite bcount_post in Hj by lia. rewrite bsize_post in Hr by lia.
157
+ cbn [nth hpost bcount bsize blk_HAB] in Hj, Hr.
158
+ destruct (inputs_HAB j r _ w Hj Hr Hin) as [E|[E|[E|[E|[E|E]]]]]; try discriminate.
159
+ unfold haltb in E. injection E as <-. split; reflexivity.
160
+ - rewrite bsize_post in Hr by lia. cbn [nth hpost bsize blk_WR] in Hr.
161
+ destruct (inputs_WR j r _ w Hr Hin) as [E|E]; [|discriminate].
162
+ unfold rbit in E. destruct (Nat.eqb (A - 1 - j mod A) 0); discriminate.
163
+ - rewrite bsize_post in Hr by lia. cbn [nth hpost bsize blk_NM] in Hr.
164
+ destruct (inputs_NM j r _ w Hr Hin) as [E|E]; discriminate.
165
+ Qed.
166
+
167
+ (* a unit that reads state bit i comes no later than the unit of its next value *)
168
+ Theorem reads_in_before : forall b j r i w,
169
+ b < length (hblocks A) -> j < bcount (nth b (hblocks A) blk0) -> r < bsize (nth b (hblocks A) blk0) ->
170
+ In (SIn i, w) (sin (sunit (hblocks A) b j r)) ->
171
+ i < nH A /\ idx (nH A) (hblocks A) (SRef b j r) <= idx (nH A) (hblocks A) (hout A i).
172
+ Proof.
173
+ intros b j r i w Hb Hj Hr Hin.
174
+ pose proof (proj2 (host_wf A HA) b j r (SIn i) w Hb Hj Hr Hin) as Hi. cbn [reads_back] in Hi.
175
+ split; [exact Hi|]. rewrite len_hb in Hb.
176
+ pose proof (hout_valid i Hi) as Hv.
177
+ destruct (Nat.lt_ge_cases b (tb A + 11)) as [Hlt|Hge].
178
+ - (* every unit before the next counter comes before every unit of a next value *)
179
+ assert (Hb2 : forall b' j' r', tb A + 11 <= b' -> b' < tb A + 15 ->
180
+ idx (nH A) (hblocks A) (SRef b j r) < idx (nH A) (hblocks A) (SRef b' j' r')).
181
+ { intros b' j' r' H1 H2. cbn [idx].
182
+ pose proof (boff_mono (hblocks A) b' b ltac:(lia) ltac:(rewrite len_hb; lia)). nia. }
183
+ unfold hout in *. destruct (Nat.ltb i A); [|destruct (Nat.eqb i A)]; apply Nat.lt_le_incl, Hb2; lia.
184
+ - destruct (last_reads_halt b j r i w ltac:(lia) Hj Hr Hin) as [-> ->].
185
+ unfold hout. rewrite Nat.ltb_irrefl, Nat.eqb_refl. cbn [idx].
186
+ rewrite bcount_post in Hj by lia. rewrite bsize_post in Hr by lia.
187
+ cbn [nth hpost bcount bsize blk_HAB] in Hj, Hr.
188
+ rewrite bsize_post by lia. cbn [nth hpost bsize blk_HAB]. lia.
189
+ Qed.
190
+
191
+ (* every weight of the host is 1 or -1 *)
192
+ Lemma ter_hblocks : forall b j, Forall ter (bshape (nth b (hblocks A) blk0) j).
193
+ Proof.
194
+ intros b j.
195
+ assert (Hm : forall f n, (forall i, ter (f i)) -> Forall ter (map f (seq 0 n)))
196
+ by (intros f n Hf; apply Forall_map, Forall_forall; intros; apply Hf).
197
+ assert (Hsu : forall bb ws, Forall (fun p => snd p = 1%Z \/ snd p = (-1)%Z) ws -> ter (SU bb ws)).
198
+ { intros bb ws H x w0 Hin. rewrite Forall_forall in H. exact (H (x, w0) Hin). }
199
+ destruct (Nat.lt_ge_cases b (length (hblocks A))) as [Hb|Hb];
200
+ [|rewrite nth_overflow by exact Hb; cbn [bshape blk0]; constructor].
201
+ rewrite len_hb in Hb.
202
+ destruct (Nat.lt_ge_cases b 17) as [Hp|Hp].
203
+ { rewrite nth_hb_pre by exact Hp.
204
+ assert (Hc : b = 0 \/ b = 1 \/ b = 2 \/ b = 3 \/ b = 4 \/ b = 5 \/ b = 6 \/ b = 7 \/ b = 8 \/ b = 9
205
+ \/ b = 10 \/ b = 11 \/ b = 12 \/ b = 13 \/ b = 14 \/ b = 15 \/ b = 16) by lia.
206
+ destruct Hc as [->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->| ->]]]]]]]]]]]]]]]];
207
+ cbn [nth hpre bshape blk_P blk_HP blk_FA blk_Q blk_F blk_PA blk_PB blk_AC blk_W
208
+ blk_RX blk_RY blk_KP blk_X blk_Y blk_PR];
209
+ apply Forall_forall; intros u Hu; destruct Hu as [<-|[]]; first [apply ter_and | apply ter_or]. }
210
+ destruct (Nat.lt_ge_cases b (tb A)) as [HT|HT].
211
+ { unfold tb in HT. replace b with (16 + (b - 16)) by lia.
212
+ rewrite nth_hb_T by lia. cbn [bshape blk_T].
213
+ constructor; [apply ter_and | apply Forall_map, Forall_forall; intros; apply ter_and]. }
214
+ replace b with (tb A + (b - tb A)) by lia. rewrite nth_hb_post by lia.
215
+ assert (Hi : b - tb A < 15) by lia. remember (b - tb A) as i eqn:Ei. clear Ei.
216
+ assert (Hc : i = 0 \/ i = 1 \/ i = 2 \/ i = 3 \/ i = 4 \/ i = 5 \/ i = 6 \/ i = 7 \/ i = 8 \/ i = 9
217
+ \/ i = 10 \/ i = 11 \/ i = 12 \/ i = 13 \/ i = 14) by lia.
218
+ assert (Hw : forall bb ws, (forall p, In p ws -> snd p = 1%Z \/ snd p = (-1)%Z) -> ter (SU bb ws))
219
+ by (intros bb ws H; apply Hsu, Forall_forall, H).
220
+ destruct Hc as [->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->| ->]]]]]]]]]]]]]];
221
+ cbn [nth hpost bshape blk_C blk_AX blk_NX blk_XN blk_EQ blk_R0 blk_H blk_R blk_LEQ
222
+ blk_TA blk_TB blk_NP blk_HAB blk_WR blk_NM map];
223
+ apply Forall_forall; intros u Hu;
224
+ repeat (destruct Hu as [<-|Hu];
225
+ [first [apply ter_and | apply ter_or
226
+ | apply Hw; intros p Hq; repeat (destruct Hq as [<-|Hq]; [cbn [snd]; lia|]); destruct Hq] |]);
227
+ destruct Hu.
228
+ Qed.
229
+
230
+ End Last.
231
+
232
+ (* ---- the same facts on the flat netlist ------------------------------------------------------------- *)
233
+ Section Flat.
234
+ Variable A : nat.
235
+ Hypothesis HA : 3 <= A.
236
+
237
+ Let us := host_units A.
238
+
239
+ Lemma hb_shaped : Forall shaped (hblocks A).
240
+ Proof. exact (proj1 (host_wf A HA)). Qed.
241
+
242
+ Lemma length_hu : length us = boff (hblocks A) (length (hblocks A)).
243
+ Proof. apply length_compile. exact hb_shaped. Qed.
244
+
245
+ Lemma hu_loc : forall k, k < length us -> exists b j r,
246
+ b < length (hblocks A) /\ j < bcount (nth b (hblocks A) blk0) /\ r < bsize (nth b (hblocks A) blk0)
247
+ /\ nH A + k = idx (nH A) (hblocks A) (SRef b j r)
248
+ /\ nth k us tu0 = flat_unit (nH A) (hblocks A) (sunit (hblocks A) b j r).
249
+ Proof.
250
+ intros k Hk. rewrite length_hu in Hk.
251
+ destruct (flat_loc (hblocks A) hb_shaped k Hk) as (b & j & r & Hb & Hj & Hr & ->).
252
+ exists b, j, r. split; [exact Hb|]. split; [exact Hj|]. split; [exact Hr|]. split.
253
+ - cbn [idx]. lia.
254
+ - apply compile_nth; [exact hb_shaped | exact Hb | exact Hj | exact Hr].
255
+ Qed.
256
+
257
+ (* an input of a unit, in block coordinates *)
258
+ Lemma hu_input : forall k i w, k < length us -> In (i, w) (tin (nth k us tu0)) ->
259
+ exists b j r x, b < length (hblocks A) /\ j < bcount (nth b (hblocks A) blk0) /\ r < bsize (nth b (hblocks A) blk0)
260
+ /\ nH A + k = idx (nH A) (hblocks A) (SRef b j r) /\ In (x, w) (sin (sunit (hblocks A) b j r))
261
+ /\ i = idx (nH A) (hblocks A) x /\ valid (hblocks A) (nH A) x.
262
+ Proof.
263
+ intros k i w Hk Hin. destruct (hu_loc k Hk) as (b & j & r & Hb & Hj & Hr & Hidx & Hu).
264
+ rewrite Hu in Hin. unfold flat_unit in Hin. cbn [tin] in Hin.
265
+ apply in_map_iff in Hin as ([x w'] & E & Hx). cbn [fst snd] in E. injection E as <- <-.
266
+ exists b, j, r, x. refine (conj Hb (conj Hj (conj Hr (conj Hidx (conj Hx (conj eq_refl _)))))).
267
+ pose proof (proj2 (host_wf A HA) b j r x w' Hb Hj Hr Hx) as Hrb.
268
+ destruct x as [i|b' j' r']; cbn [reads_back valid] in *; [exact Hrb|].
269
+ destruct Hrb as [(H1 & H2 & H3)|(-> & -> & H3)]; [split; [lia | auto] | split; [exact Hb | split; [exact Hj | lia]]].
270
+ Qed.
271
+
272
+ Lemma hnext_nth : forall i, i < nH A -> nth i (host_next A) 0 = idx (nH A) (hblocks A) (hout A i).
273
+ Proof. intros i Hi. unfold host_next. apply nth_map_seq. exact Hi. Qed.
274
+
275
+ Lemma hout_inj : forall i i', hout A i = hout A i' -> i = i'.
276
+ Proof.
277
+ intros i i'. unfold hout.
278
+ destruct (Nat.ltb_spec i A), (Nat.ltb_spec i' A); try destruct (Nat.eqb_spec i A); try destruct (Nat.eqb_spec i' A);
279
+ intro E; try injection E; intros; unfold tb in *; lia.
280
+ Qed.
281
+
282
+ Theorem host_weights : forall k i w, k < length us -> In (i, w) (tin (nth k us tu0)) -> w = 1%Z \/ w = (-1)%Z.
283
+ Proof.
284
+ intros k i w Hk Hin. destruct (hu_input k i w Hk Hin) as (b & j & r & x & _ & _ & _ & _ & Hx & _).
285
+ unfold sunit in Hx. pose proof (ter_hblocks A HA b j) as T.
286
+ destruct (Nat.lt_ge_cases r (length (bshape (nth b (hblocks A) blk0) j))) as [Hr|Hr].
287
+ - exact (ter_nth _ r T x w Hx).
288
+ - rewrite nth_overflow in Hx by exact Hr. destruct Hx.
289
+ Qed.
290
+
291
+ Theorem host_no_out : forall k i w, k < length us -> In (i, w) (tin (nth k us tu0)) ->
292
+ forall i', i' < nH A -> i <> nth i' (host_next A) 0.
293
+ Proof.
294
+ intros k i w Hk Hin i' Hi' E. destruct (hu_input k i w Hk Hin) as (b & j & r & x & Hb & Hj & Hr & _ & Hx & -> & Hv).
295
+ rewrite hnext_nth in E by exact Hi'.
296
+ apply (idx_inj _ _ _ _ Hv (hout_valid A HA i' Hi')) in E.
297
+ exact (reads_no_out A HA b j r x w Hb Hj Hr Hx i' Hi' E).
298
+ Qed.
299
+
300
+ Theorem host_in_before : forall k i w, k < length us -> In (i, w) (tin (nth k us tu0)) -> i < nH A ->
301
+ nH A + k <= nth i (host_next A) 0.
302
+ Proof.
303
+ intros k i w Hk Hin Hi. destruct (hu_input k i w Hk Hin) as (b & j & r & x & Hb & Hj & Hr & Hidx & Hx & Ex & Hv).
304
+ destruct x as [i0|b' j' r']; cbn [idx] in Ex; [subst i0|lia].
305
+ rewrite hnext_nth by exact Hi. rewrite Hidx.
306
+ exact (proj2 (reads_in_before A HA b j r i w Hb Hj Hr Hx)).
307
+ Qed.
308
+
309
+ Lemma host_next_range : forall i, i < nH A -> nH A <= nth i (host_next A) 0 < nH A + length us.
310
+ Proof.
311
+ intros i Hi. rewrite hnext_nth by exact Hi. pose proof (hout_valid A HA i Hi) as Hv.
312
+ pose proof (idx_lt_total _ _ _ Hv) as H. rewrite <- length_hu in H.
313
+ unfold hout in *. destruct (Nat.ltb i A); [|destruct (Nat.eqb i A)]; cbn [idx] in *;
314
+ (split; [nia | exact H]).
315
+ Qed.
316
+
317
+ Lemma host_next_inj : forall i i', i < nH A -> i' < nH A -> nth i (host_next A) 0 = nth i' (host_next A) 0 -> i = i'.
318
+ Proof.
319
+ intros i i' Hi Hi' E. rewrite !hnext_nth in E by assumption.
320
+ apply hout_inj. exact (idx_inj _ _ _ _ (hout_valid A HA i Hi) (hout_valid A HA i' Hi') E).
321
+ Qed.
322
+
323
+ Lemma host_reads_below : forall k, k < length us -> reads_below (nth k us tu0) (nH A + k).
324
+ Proof. intros k Hk. apply wf_reads_below; [exact (host_wf A HA) | exact Hk]. Qed.
325
+
326
+ Lemma length_host_next : length (host_next A) = nH A.
327
+ Proof. unfold host_next. rewrite length_map, length_seq. reflexivity. Qed.
328
+
329
+ End Flat.
rocq/Stored.v ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* The stored host S_{A,w} of Construction 8.3: the host H_A and its device compiled into records of the
2
+ ring machine. Each unit of H_A has a window cell of its own, the units are evaluated in the order of
3
+ the netlist, and the unit of the next value of a state bit writes that bit with its last record. *)
4
+ From Stdlib Require Import List Bool Arith ZArith Lia.
5
+ Import ListNotations.
6
+ From TH Require Import TwoHead Net Host Device.
7
+
8
+ (* ---- records of two literals ---------------------------------------------------------------- *)
9
+ (* a literal is a window cell and its polarity *)
10
+ Definition pm (p : bool) : Z := if p then 1%Z else (-1)%Z.
11
+
12
+ Definition gAND (x y : nat * bool) (d : nat) : rec :=
13
+ Rec (fst x) (pm (snd x)) (fst y) (pm (snd y)) (- (b2z (snd x) + b2z (snd y)))%Z d.
14
+ Definition gOR (x y : nat * bool) (d : nat) : rec :=
15
+ Rec (fst x) (pm (snd x)) (fst y) (pm (snd y)) (1 - b2z (snd x) - b2z (snd y))%Z d.
16
+ Definition gCOPY (x : nat * bool) (d : nat) : rec :=
17
+ Rec (fst x) (pm (snd x)) SINK 0 (if snd x then (-1)%Z else 0%Z) d.
18
+ Definition gCONST (b : bool) (d : nat) : rec :=
19
+ if b then gOR (SINK, true) (SINK, false) d else gAND (SINK, true) (SINK, false) d.
20
+ Definition EMPTY : rec := Rec 0 0 0 0 0 0.
21
+
22
+ (* the literals joined by g, accumulated in acc, the last record writing d *)
23
+ Fixpoint chain_tail (g : nat * bool -> nat * bool -> nat -> rec) (acc : nat) (l : nat * bool)
24
+ (ls : list (nat * bool)) (d : nat) : list rec :=
25
+ match ls with
26
+ | [] => [g (acc, true) l d]
27
+ | l' :: t => g (acc, true) l acc :: chain_tail g acc l' t d
28
+ end.
29
+
30
+ Definition chain (g : nat * bool -> nat * bool -> nat -> rec) (ls : list (nat * bool)) (d acc : nat) : list rec :=
31
+ match ls with
32
+ | [] => []
33
+ | [l0] => [gCOPY l0 d]
34
+ | [l0; l1] => [g l0 l1 d]
35
+ | l0 :: l1 :: l2 :: t => g l0 l1 acc :: chain_tail g acc l2 t d
36
+ end.
37
+
38
+ (* at least t of the literals, into d: T_t(x1..xk) = T_t(x2..xk) or (x1 and T_{t-1}(x2..xk)), the three
39
+ cells xc lev 0, 1, 2 holding T_t(x2..xk), T_{t-1}(x2..xk) and the conjunction *)
40
+ Section Unit.
41
+ Variable xc : nat -> nat -> nat.
42
+
43
+ Fixpoint ucomp (t : Z) (ls : list (nat * bool)) (d acc lev : nat) {struct ls} : list rec :=
44
+ if Z.leb t 0 then [gCONST true d]
45
+ else if Z.ltb (Z.of_nat (length ls)) t then [gCONST false d]
46
+ else if Z.eqb t 1 then chain gOR ls d acc
47
+ else if Z.eqb t (Z.of_nat (length ls)) then chain gAND ls d acc
48
+ else match ls with
49
+ | [] => []
50
+ | l0 :: rest =>
51
+ ucomp t rest (xc lev 0) (xc lev 0) (S lev) ++ ucomp (t - 1) rest (xc lev 1) (xc lev 1) (S lev)
52
+ ++ [gAND l0 (xc lev 1, true) (xc lev 2); gOR (xc lev 0, true) (xc lev 2, true) d]
53
+ end.
54
+
55
+ End Unit.
56
+
57
+ (* the least number of true literals at which a unit of weights 1 and -1 fires *)
58
+ Definition tval (u : tu) : Z := (Z.of_nat (length (filter (fun p => Z.ltb (snd p) 0) (tin u))) - Net.tb u)%Z.
59
+
60
+ Definition thr_unit (u : tu) : bool := Z.ltb 1 (tval u) && Z.ltb (tval u) (Z.of_nat (length (tin u))).
61
+
62
+ (* the levels of cells the threshold units use *)
63
+ Definition levels (us : list tu) : nat :=
64
+ fold_left Nat.max (map (fun u => if thr_unit u then length (tin u) - 2 else 0) us) 0.
65
+
66
+ Fixpoint setopt (l : list (option nat)) (k x : nat) : list (option nat) :=
67
+ match l, k with
68
+ | [], _ => []
69
+ | _ :: t, O => Some x :: t
70
+ | y :: t, S k' => y :: setopt t k' x
71
+ end.
72
+
73
+ (* the state bit whose next value each of nu units is, if any *)
74
+ Definition next_tbl (n nu : nat) (nx : list nat) : list (option nat) :=
75
+ fold_left (fun tbl p => setopt tbl (snd p - n) (fst p)) (combine (seq 0 n) nx) (repeat None nu).
76
+
77
+ Section Layout.
78
+ Variables A w nu lv : nat.
79
+
80
+ (* ---- the window: the requests, booted, the counter, dest, the limit, the state of H_A, a cell for each
81
+ of the nu units, lv levels of three cells for the threshold units, and the cells of the device ---- *)
82
+ Definition nh : nat := nH A.
83
+
84
+ Definition BOOT : nat := 13.
85
+ Definition CNT (i : nat) : nat := 14 + i.
86
+ Definition DEST : nat := 14 + w.
87
+ Definition LIM (i : nat) : nat := 15 + w + i.
88
+ Definition ST (i : nat) : nat := 15 + 2 * w + i.
89
+ Definition UC (u : nat) : nat := 15 + 2 * w + nh + u.
90
+ Definition XC (lev k : nat) : nat := 15 + 2 * w + nh + nu + 3 * lev + k.
91
+
92
+ Definition DB : nat := 15 + 2 * w + nh + nu + 3 * lv.
93
+ Definition dWR : nat := DB.
94
+ Definition dRD : nat := DB + 1.
95
+ Definition dRW : nat := DB + 2.
96
+ Definition dE (i : nat) : nat := DB + 3 + i.
97
+ Definition dEQ : nat := DB + 3 + w.
98
+ Definition dEOT : nat := DB + 4 + w.
99
+ Definition dCA : nat := DB + 5 + w.
100
+ Definition dCC : nat := DB + 6 + w.
101
+ Definition dG : nat := DB + 7 + w.
102
+ Definition dCAR (i : nat) : nat := DB + 7 + w + i.
103
+ Definition M0 : nat := DB + 7 + 2 * w.
104
+ Definition M1 : nat := DB + 8 + 2 * w.
105
+ Definition ncells : nat := DB + 9 + 2 * w.
106
+
107
+ (* bit t, of value 2^t, of memory word j *)
108
+ Definition MB (j t : nat) : nat := ST (A + 1 + A * j + (A - 1 - t)).
109
+
110
+ (* ---- the startup: while booted is 0, load the memory image m, clear the counter, the halt bit and the
111
+ registers, return the heads to their origins and clear the idle bank and the copy tape ----------- *)
112
+ Definition boot_word (j v : nat) : list rec :=
113
+ map (fun t => if Nat.testbit v t then gOR (MB j t, true) (BOOT, false) (MB j t)
114
+ else gAND (MB j t, true) (BOOT, true) (MB j t)) (seq 0 A).
115
+
116
+ Definition startup (m : list nat) : list rec :=
117
+ concat (map (fun p => boot_word (fst p) (snd p)) (combine (seq 0 (SW A)) m))
118
+ ++ map (fun t => gAND (ST (A - 1 - t), true) (BOOT, true) (ST (A - 1 - t))) (seq 0 A)
119
+ ++ [gAND (ST A, true) (BOOT, true) (ST A)]
120
+ ++ concat (map (fun i => [gAND (CNT i, true) (BOOT, true) (CNT i); gAND (LIM i, true) (BOOT, true) (LIM i)])
121
+ (seq 0 w))
122
+ ++ [gAND (DEST, true) (BOOT, true) DEST]
123
+ ++ map (fun c => gCOPY (BOOT, false) c) [RR; CB; RA; CT; RC]
124
+ ++ [gCONST true BOOT].
125
+
126
+ (* ---- the step of H_A: unit u into its cell, or into the state bit whose next value it is -------- *)
127
+ Definition lit_of (p : nat * Z) : nat * bool :=
128
+ (if fst p <? nh then ST (fst p) else UC (fst p - nh), Z.ltb 0 (snd p)).
129
+
130
+ Fixpoint step_go (u : nat) (us : list tu) (nt : list (option nat)) : list rec :=
131
+ match us, nt with
132
+ | U :: us', o :: nt' =>
133
+ ucomp XC (tval U) (map lit_of (tin U)) (match o with Some i => ST i | None => UC u end) (UC u) 0
134
+ ++ step_go (S u) us' nt'
135
+ | _, _ => []
136
+ end.
137
+
138
+ (* ---- the device of Definition 8.4 ---------------------------------------------------------------- *)
139
+ Definition gMUX (s : nat) (a b : nat * bool) (d : nat) : list rec :=
140
+ [gAND (s, true) a M0; gAND (s, false) b M1; gOR (M0, true) (M1, true) d].
141
+ Definition gXOR (x y : nat * bool) (d : nat) : list rec :=
142
+ [gOR x y M0; gOR (fst x, negb (snd x)) (fst y, negb (snd y)) M1; gAND (M0, true) (M1, true) d].
143
+
144
+ Definition word1 (j d : nat) : list rec :=
145
+ chain gAND ((MB j 0, true) :: map (fun t => (MB j t, false)) (seq 1 (A - 1))) d d.
146
+
147
+ Definition carry (i : nat) : nat := if Nat.eqb i 0 then dG else dCAR i.
148
+
149
+ Definition device : list rec :=
150
+ word1 (cwr A) dWR ++ word1 (crd A) dRD ++ word1 (crw A) dRW
151
+ ++ concat (map (fun i => [gAND (CNT i, true) (LIM i, true) M0; gAND (CNT i, false) (LIM i, false) M1;
152
+ gOR (M0, true) (M1, true) (dE i)]) (seq 0 w))
153
+ ++ chain gAND (map (fun i => (dE i, true)) (seq 0 w)) dEQ dEQ
154
+ ++ [gAND (dEQ, true) (DEST, true) dEOT; gAND (dWR, true) (DEST, false) dCA; gAND (dWR, true) (DEST, true) dCC]
155
+ ++ concat (map (fun k => gMUX dCA (MB (rout A) (7 - k), true) (ARM, true) ARM ++ [gCOPY (dCA, true) AA]
156
+ ++ gMUX dCC (MB (rout A) (7 - k), true) (CPY, true) CPY ++ [gCOPY (dCC, true) AC])
157
+ (seq 0 8))
158
+ ++ map (fun t => gAND (MB (rout A) t, true) (dWR, false) (MB (rout A) t)) (seq 0 A)
159
+ ++ [gAND (dRD, true) (dEOT, false) dG]
160
+ ++ concat (map (fun k => gMUX dG (RD, true) (MB (rin A) (7 - k), true) (MB (rin A) (7 - k))
161
+ ++ [gCOPY (dG, true) AR]) (seq 0 8))
162
+ ++ concat (map (fun t => gMUX dG (MB (rin A) 7, true) (MB (rin A) t, true) (MB (rin A) t)) (seq 8 (A - 8)))
163
+ ++ gMUX dRD (dEOT, true) (MB (ceot A) 0, true) (MB (ceot A) 0)
164
+ ++ map (fun t => gAND (MB (ceot A) t, true) (dRD, false) (MB (ceot A) t)) (seq 1 (A - 1))
165
+ ++ map (fun i => gAND (carry i, true) (CNT i, true) (dCAR (S i))) (seq 0 (w - 1))
166
+ ++ concat (map (fun i => gXOR (CNT i, true) (carry i, true) (CNT i)) (seq 0 w))
167
+ ++ [gCOPY (dRW, true) RR]
168
+ ++ concat (map (fun i => gMUX dRW (CNT i, true) (LIM i, true) (LIM i) ++ [gAND (CNT i, true) (dRW, false) (CNT i)])
169
+ (seq 0 w))
170
+ ++ [gOR (DEST, true) (dRW, true) DEST]
171
+ ++ concat (map (fun c => map (fun t => gCONST false (MB c t)) (seq 0 A)) [cwr A; crd A; crw A]).
172
+
173
+ (* ---- the hand-over: at the halt, booted cleared, the arm and the copy head home, and control to the
174
+ next bank ---------------------------------------------------------------------------------------- *)
175
+ Definition handover : list rec :=
176
+ [gAND (BOOT, true) (ST A, false) BOOT; gCOPY (ST A, true) RA; gCOPY (ST A, true) RC; gCOPY (ST A, true) HO].
177
+
178
+ End Layout.
179
+
180
+ (* ---- the image: the least window that holds the cells, and the fewest empty records before the
181
+ hand-over that make it a whole number of bytes ---------------------------------------------------- *)
182
+ Definition padn (al len : nat) : nat :=
183
+ match find (fun p => Nat.eqb ((recw al * (len + 4 + p)) mod 8) 0) (seq 0 8) with
184
+ | Some p => p
185
+ | None => 0
186
+ end.
187
+
188
+ Definition stored_of (A w : nat) (us : list tu) (nx m : list nat) : list rec * nat :=
189
+ let nu := length us in
190
+ let lv := levels us in
191
+ let al := Nat.log2_up (ncells A w nu lv) in
192
+ let body := startup A w m ++ step_go A w nu 0 us (next_tbl (nH A) nu nx) ++ device A w nu lv in
193
+ (body ++ repeat EMPTY (padn al (length body)) ++ handover A w, al).
194
+
195
+ Definition stored (A w : nat) : list rec := fst (stored_of A w (host_units A) (host_next A) (image A (progPstar A))).
196
+
197
+ Definition alS (A w : nat) : nat := snd (stored_of A w (host_units A) (host_next A) (image A (progPstar A))).
198
+
199
+ Definition stored_bits (A w : nat) : list bool :=
200
+ let sa := stored_of A w (host_units A) (host_next A) (image A (progPstar A)) in
201
+ concat (map (enc_recA (snd sa)) (fst sa)).
rocq/StoredBoot.v ADDED
@@ -0,0 +1,417 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* The startup, padding and hand-over records of the stored host. While booted is 0 the startup loads the
2
+ initial state of the host and clears the registers, the heads and the next bank and tape; when booted
3
+ is 1 it changes nothing. The hand-over clears booted at the halt, returns the arm and the copy head to
4
+ their origins and hands over. *)
5
+ From Stdlib Require Import List Bool Arith ZArith Lia.
6
+ Import ListNotations.
7
+ From TH Require Import TwoHead Net Abstract Indep Run View Stored WinRun ViewOps Host HostSem.
8
+
9
+ (* ---- records that each set their own cell from that cell and booted -------------------------------- *)
10
+ Definition self_rec (r : rec) : Prop :=
11
+ HO < ao_of r /\ ao_of r <> BOOT
12
+ /\ forall w1 w2, wget w1 (ao_of r) = wget w2 (ao_of r) -> wget w1 BOOT = wget w2 BOOT -> wval w1 r = wval w2 r.
13
+
14
+ Lemma wrun_self : forall rs w, NoDup (map ao_of rs) -> Forall self_rec rs -> (forall r, In r rs -> ao_of r < length w) ->
15
+ (forall r, In r rs -> wget (wrun rs w) (ao_of r) = wval w r)
16
+ /\ (forall c, ~ In c (map ao_of rs) -> wget (wrun rs w) c = wget w c).
17
+ Proof.
18
+ induction rs as [|r rs IH]; intros w Hnd Hs Hl; [split; [intros r [] | intros; reflexivity]|].
19
+ inversion Hnd as [|? ? Hni Hnd']; subst. apply Forall_cons_iff in Hs as [(Hr1 & Hr2 & Hr3) Hs'].
20
+ cbn [wrun]. unfold wexec.
21
+ set (w1 := wnext w (ao_of r) (wval w r)).
22
+ assert (Hw1 : forall c, wget w1 c = if Nat.eqb c (ao_of r) then wval w r else wget w c)
23
+ by (intro c; unfold w1; apply wget_wnext; [exact Hr1 | apply Hl; left; reflexivity]).
24
+ assert (Hl1 : forall r', In r' rs -> ao_of r' < length w1)
25
+ by (intros r' Hr'; unfold w1; rewrite length_wnext; apply Hl; right; exact Hr').
26
+ destruct (IH w1 Hnd' Hs' Hl1) as [IH1 IH2]. split.
27
+ - intros r' [<-|Hr'].
28
+ + rewrite IH2 by exact Hni. rewrite Hw1, Nat.eqb_refl. reflexivity.
29
+ + rewrite (IH1 r' Hr'). rewrite Forall_forall in Hs'. destruct (Hs' r' Hr') as (_ & _ & S3). apply S3.
30
+ * rewrite Hw1. replace (Nat.eqb (ao_of r') (ao_of r)) with false; [reflexivity|].
31
+ symmetry. apply Nat.eqb_neq. intro E. apply Hni. rewrite <- E. apply in_map. exact Hr'.
32
+ * rewrite Hw1. replace (Nat.eqb BOOT (ao_of r)) with false by (symmetry; apply Nat.eqb_neq; congruence). reflexivity.
33
+ - intros c Hc. rewrite IH2 by (intro H; apply Hc; right; exact H). rewrite Hw1.
34
+ replace (Nat.eqb c (ao_of r)) with false by (symmetry; apply Nat.eqb_neq; intro E; apply Hc; left; congruence).
35
+ reflexivity.
36
+ Qed.
37
+
38
+ Lemma wval_or_boot : forall w c, HO < c -> wval w (gOR (c, true) (BOOT, false) c) = wget w c || negb (wget w BOOT).
39
+ Proof.
40
+ intros w c H. rewrite wval_or. unfold wl, wcell. cbn [fst snd].
41
+ replace (Nat.eqb c SINK) with false by (symmetry; apply Nat.eqb_neq; unfold SINK, HO in *; lia). reflexivity.
42
+ Qed.
43
+
44
+ Lemma wval_and_boot : forall w c, HO < c -> wval w (gAND (c, true) (BOOT, true) c) = wget w c && wget w BOOT.
45
+ Proof.
46
+ intros w c H. rewrite wval_and. unfold wl, wcell. cbn [fst snd].
47
+ replace (Nat.eqb c SINK) with false by (symmetry; apply Nat.eqb_neq; unfold SINK, HO in *; lia). reflexivity.
48
+ Qed.
49
+
50
+ Lemma self_or : forall c, HO < c -> c <> BOOT -> self_rec (gOR (c, true) (BOOT, false) c).
51
+ Proof.
52
+ intros c H1 H2. cbn [ao_of gOR]. split; [exact H1|]. split; [exact H2|].
53
+ intros w1 w2 E1 E2. cbn [ao_of gOR] in E1. rewrite !wval_or_boot by exact H1. rewrite E1, E2. reflexivity.
54
+ Qed.
55
+
56
+ Lemma self_and : forall c, HO < c -> c <> BOOT -> self_rec (gAND (c, true) (BOOT, true) c).
57
+ Proof.
58
+ intros c H1 H2. cbn [ao_of gAND]. split; [exact H1|]. split; [exact H2|].
59
+ intros w1 w2 E1 E2. cbn [ao_of gAND] in E1. rewrite !wval_and_boot by exact H1. rewrite E1, E2. reflexivity.
60
+ Qed.
61
+
62
+ (* ---- lists of cells ------------------------------------------------------------------------------------ *)
63
+ Lemma map_combine_seq : forall (T : Type) (F : nat -> nat -> T) (m : list nat) k,
64
+ map (fun p => F (fst p) (snd p)) (combine (seq k (length m)) m) = map (fun j => F j (nth (j - k) m 0)) (seq k (length m)).
65
+ Proof.
66
+ intros T F m. induction m as [|x m IH]; intro k; [reflexivity|].
67
+ cbn [length seq combine map fst snd]. rewrite Nat.sub_diag. cbn [nth]. f_equal. rewrite IH.
68
+ apply map_ext_in. intros j Hj. apply in_seq in Hj. replace (j - k) with (S (j - S k)) by lia. reflexivity.
69
+ Qed.
70
+
71
+ Lemma nodup_concat_map : forall (T : Type) (f : nat -> list T) l, NoDup l -> (forall j, In j l -> NoDup (f j)) ->
72
+ (forall j j' x, In j l -> In j' l -> j <> j' -> In x (f j) -> In x (f j') -> False) -> NoDup (concat (map f l)).
73
+ Proof.
74
+ intros T f l. induction l as [|j l IH]; intros Hnd Hf Hdis; [constructor|].
75
+ inversion Hnd as [|? ? Hni Hnd']; subst. cbn [map concat].
76
+ apply NoDup_app; [apply Hf; left; reflexivity | apply IH; [exact Hnd' | intros; apply Hf; right; assumption |] |].
77
+ - intros a b x Ha Hb Hab. apply (Hdis a b x); [right; exact Ha | right; exact Hb | exact Hab].
78
+ - intros x Hx1 Hx2. apply in_concat in Hx2 as (y & Hy & Hx2). apply in_map_iff in Hy as (j' & <- & Hj').
79
+ apply (Hdis j j' x); [left; reflexivity | right; exact Hj' | intro E; apply Hni; subst; exact Hj' | exact Hx1 | exact Hx2].
80
+ Qed.
81
+
82
+ Lemma nodup_map_seq : forall (f : nat -> nat) k N, (forall i j, k <= i < k + N -> k <= j < k + N -> f i = f j -> i = j) ->
83
+ NoDup (map f (seq k N)).
84
+ Proof.
85
+ intros f k N H. apply NoDup_map_NoDup_ForallPairs; [|apply seq_NoDup].
86
+ intros i j Hi Hj E. apply in_seq in Hi, Hj. exact (H i j Hi Hj E).
87
+ Qed.
88
+
89
+ Lemma nodup_app_sep : forall (P : nat -> Prop) l1 l2, NoDup l1 -> NoDup l2 ->
90
+ (forall x, In x l1 -> P x) -> (forall x, In x l2 -> ~ P x) -> NoDup (l1 ++ l2).
91
+ Proof.
92
+ intros P l1 l2 H1 H2 Hp Hn. apply NoDup_app; [exact H1 | exact H2 |].
93
+ intros x Hx1 Hx2. exact (Hn x Hx2 (Hp x Hx1)).
94
+ Qed.
95
+
96
+ Section Boot.
97
+ Variables (A w W Lb L : nat) (m : list nat).
98
+ Hypotheses (HA : 3 <= A) (Hm : length m = SW A).
99
+ Local Notation n := (nH A).
100
+ Hypothesis HW : 15 + 2 * w + n <= W.
101
+
102
+ (* the initial state of the host with memory m *)
103
+ Definition x0m : hst := mkH 0 false m.
104
+
105
+ Definition mem_recs : list rec := concat (map (fun j => boot_word A w j (nth j m 0)) (seq 0 (SW A))).
106
+ Definition pc_recs : list rec := map (fun t => gAND (ST w (A - 1 - t), true) (BOOT, true) (ST w (A - 1 - t))) (seq 0 A).
107
+ Definition reg_recs : list rec :=
108
+ concat (map (fun i => [gAND (CNT i, true) (BOOT, true) (CNT i); gAND (LIM w i, true) (BOOT, true) (LIM w i)]) (seq 0 w)).
109
+ Definition wpart : list rec :=
110
+ mem_recs ++ pc_recs ++ [gAND (ST w A, true) (BOOT, true) (ST w A)] ++ reg_recs ++ [gAND (DEST w, true) (BOOT, true) (DEST w)].
111
+ Definition req_recs : list rec := map (fun c => gCOPY (BOOT, false) c) [RR; CB; RA; CT; RC].
112
+
113
+ Lemma startup_split : startup A w m = wpart ++ req_recs ++ [gCONST true BOOT].
114
+ Proof.
115
+ unfold startup, wpart, mem_recs, req_recs, reg_recs, pc_recs.
116
+ assert (E : map (fun p => boot_word A w (fst p) (snd p)) (combine (seq 0 (SW A)) m)
117
+ = map (fun j => boot_word A w j (nth j m 0)) (seq 0 (SW A))).
118
+ { rewrite <- Hm. rewrite (map_combine_seq _ (boot_word A w) m 0).
119
+ apply map_ext_in. intros j _. rewrite Nat.sub_0_r. reflexivity. }
120
+ rewrite E. rewrite <- !app_assoc. reflexivity.
121
+ Qed.
122
+
123
+ Lemma SW_pos : 1 <= SW A.
124
+ Proof. unfold SW. pose proof (Nat.pow_nonzero 2 A ltac:(lia)). lia. Qed.
125
+
126
+ Lemma MB_ST : forall j t, j < SW A -> t < A -> MB A w j t = ST w (A + 1 + j * A + (A - 1 - t)) /\ A + 1 + j * A + (A - 1 - t) < n.
127
+ Proof.
128
+ intros j t Hj Ht. unfold MB. split; [f_equal; lia|]. unfold nH. nia.
129
+ Qed.
130
+
131
+ Lemma cells_mem : map ao_of mem_recs = concat (map (fun j => map (fun t => MB A w j t) (seq 0 A)) (seq 0 (SW A))).
132
+ Proof.
133
+ unfold mem_recs. rewrite concat_map, map_map. f_equal. apply map_ext. intro j. unfold boot_word.
134
+ rewrite map_map. apply map_ext. intro t. destruct (Nat.testbit _ t); reflexivity.
135
+ Qed.
136
+
137
+ Lemma cells_regs : map ao_of reg_recs = concat (map (fun i => [CNT i; LIM w i]) (seq 0 w)).
138
+ Proof. unfold reg_recs. rewrite concat_map, map_map. reflexivity. Qed.
139
+
140
+ Lemma nodup_wpart : NoDup (map ao_of wpart).
141
+ Proof.
142
+ unfold wpart. rewrite !map_app, cells_mem, cells_regs. unfold pc_recs. rewrite map_map. cbn [map ao_of gAND].
143
+ assert (Nmem : NoDup (concat (map (fun j => map (fun t => MB A w j t) (seq 0 A)) (seq 0 (SW A))))).
144
+ { apply nodup_concat_map; [apply seq_NoDup | |].
145
+ - intros j Hj. apply in_seq in Hj. apply nodup_map_seq. intros t t' Ht Ht' E. unfold MB, ST in E. lia.
146
+ - intros j j' x Hj Hj' Hne Hx Hx'. apply in_seq in Hj, Hj'.
147
+ apply in_map_iff in Hx as (t & <- & Ht). apply in_map_iff in Hx' as (t' & E & Ht').
148
+ apply in_seq in Ht, Ht'. unfold MB, ST in E. apply Hne. nia. }
149
+ assert (Npc : NoDup (map (fun t => ST w (A - 1 - t)) (seq 0 A)))
150
+ by (apply nodup_map_seq; intros i j Hi Hj E; unfold ST in E; lia).
151
+ assert (Nreg : NoDup (concat (map (fun i => [CNT i; LIM w i]) (seq 0 w)))).
152
+ { apply nodup_concat_map; [apply seq_NoDup | |].
153
+ - intros i Hi. apply in_seq in Hi. constructor; [intros [E|[]]; unfold CNT, LIM in E; lia | constructor; [intros []|constructor]].
154
+ - intros i i' x Hi Hi' Hne Hx Hx'. apply in_seq in Hi, Hi'.
155
+ cbn [In] in Hx, Hx'. unfold CNT, LIM in *. lia. }
156
+ apply (nodup_app_sep (fun x => ST w (A + 1) <= x)); [exact Nmem | | |].
157
+ 2:{ intros x Hx. apply in_concat in Hx as (y & Hy & Hx). apply in_map_iff in Hy as (j & <- & Hj).
158
+ apply in_map_iff in Hx as (t & <- & Ht). apply in_seq in Hj, Ht. unfold MB, ST. lia. }
159
+ 2:{ intros x Hx. apply in_app_or in Hx as [Hx|Hx].
160
+ - apply in_map_iff in Hx as (t & <- & Ht). apply in_seq in Ht. unfold ST. lia.
161
+ - cbn [app In] in Hx. destruct Hx as [<-|Hx]; [unfold ST; lia|].
162
+ apply in_app_or in Hx as [Hx|[<-|[]]]; [|unfold DEST, ST; lia].
163
+ apply in_concat in Hx as (y & Hy & Hx). apply in_map_iff in Hy as (i & <- & Hi). apply in_seq in Hi.
164
+ cbn [In] in Hx. unfold CNT, LIM, ST in *. lia. }
165
+ apply (nodup_app_sep (fun x => ST w 0 <= x < ST w A)); [exact Npc | | |].
166
+ 2:{ intros x Hx. apply in_map_iff in Hx as (t & <- & Ht). apply in_seq in Ht. unfold ST. lia. }
167
+ 2:{ intros x Hx. cbn [app In] in Hx. destruct Hx as [<-|Hx]; [unfold ST; lia|].
168
+ apply in_app_or in Hx as [Hx|[<-|[]]]; [|unfold DEST, ST; lia].
169
+ apply in_concat in Hx as (y & Hy & Hx). apply in_map_iff in Hy as (i & <- & Hi). apply in_seq in Hi.
170
+ cbn [In] in Hx. unfold CNT, LIM, ST in *. lia. }
171
+ cbn [app]. constructor.
172
+ - intro Hx. apply in_app_or in Hx as [Hx|[E|[]]]; [|unfold DEST, ST in E; lia].
173
+ apply in_concat in Hx as (y & Hy & Hx). apply in_map_iff in Hy as (i & <- & Hi). apply in_seq in Hi.
174
+ cbn [In] in Hx. unfold CNT, LIM, ST in *. lia.
175
+ - apply NoDup_app; [exact Nreg | constructor; [intros []|constructor] |].
176
+ intros x Hx [<-|[]]. apply in_concat in Hx as (y & Hy & Hx). apply in_map_iff in Hy as (i & <- & Hi).
177
+ apply in_seq in Hi. cbn [In] in Hx. unfold CNT, LIM, DEST in *. lia.
178
+ Qed.
179
+
180
+ Lemma self_wpart : Forall self_rec wpart.
181
+ Proof.
182
+ unfold wpart, mem_recs, pc_recs, reg_recs. rewrite !Forall_app. repeat split.
183
+ - apply Forall_concat. apply Forall_map, Forall_forall. intros j Hj. apply in_seq in Hj.
184
+ unfold boot_word. apply Forall_map, Forall_forall. intros t Ht. apply in_seq in Ht.
185
+ destruct (Nat.testbit (nth j m 0) t); [apply self_or | apply self_and]; unfold MB, ST, BOOT, HO; lia.
186
+ - apply Forall_map, Forall_forall. intros t Ht. apply self_and; unfold ST, BOOT, HO; lia.
187
+ - constructor; [apply self_and; unfold ST, BOOT, HO; lia | constructor].
188
+ - apply Forall_concat. apply Forall_map, Forall_forall. intros i Hi.
189
+ constructor; [apply self_and; unfold CNT, BOOT, HO; lia | constructor; [apply self_and; unfold LIM, BOOT, HO; lia | constructor]].
190
+ - constructor; [apply self_and; unfold DEST, BOOT, HO; lia | constructor].
191
+ Qed.
192
+
193
+ Lemma wrec_wpart : Forall wrec wpart.
194
+ Proof.
195
+ apply Forall_forall. intros r Hr. pose proof self_wpart as Hs. rewrite Forall_forall in Hs.
196
+ unfold wpart, mem_recs, pc_recs, reg_recs in Hr.
197
+ repeat (apply in_app_or in Hr as [Hr|Hr]).
198
+ - apply in_concat in Hr as (y & Hy & Hr). apply in_map_iff in Hy as (j & <- & _). unfold boot_word in Hr.
199
+ apply in_map_iff in Hr as (t & <- & _).
200
+ destruct (Nat.testbit (nth j m 0) t); [apply wrec_or | apply wrec_and];
201
+ unfold rd_ok, MB, ST, BOOT, CPY, HO; cbn [fst]; lia.
202
+ - apply in_map_iff in Hr as (t & <- & _). apply wrec_and; unfold rd_ok, ST, BOOT, CPY, HO; cbn [fst]; lia.
203
+ - destruct Hr as [<-|[]]. apply wrec_and; unfold rd_ok, ST, BOOT, CPY, HO; cbn [fst]; lia.
204
+ - apply in_concat in Hr as (y & Hy & Hr). apply in_map_iff in Hy as (i & <- & _).
205
+ destruct Hr as [<-|[<-|[]]]; apply wrec_and; unfold rd_ok, CNT, LIM, BOOT, CPY, HO; cbn [fst]; lia.
206
+ - destruct Hr as [<-|[]]. apply wrec_and; unfold rd_ok, DEST, BOOT, CPY, HO; cbn [fst]; lia.
207
+ Qed.
208
+
209
+ Lemma wpart_ao_range : forall r, In r wpart -> 14 <= ao_of r < 15 + 2 * w + n.
210
+ Proof.
211
+ intros r Hr. unfold wpart, mem_recs, pc_recs, reg_recs in Hr.
212
+ repeat (apply in_app_or in Hr as [Hr|Hr]).
213
+ - apply in_concat in Hr as (y & Hy & Hr). apply in_map_iff in Hy as (j & <- & Hj). apply in_seq in Hj.
214
+ unfold boot_word in Hr. apply in_map_iff in Hr as (t & <- & Ht). apply in_seq in Ht.
215
+ destruct (MB_ST j t ltac:(lia) ltac:(lia)) as [E1 E2].
216
+ destruct (Nat.testbit (nth j m 0) t); cbn [ao_of gOR gAND]; rewrite E1; unfold ST; lia.
217
+ - apply in_map_iff in Hr as (t & <- & Ht). apply in_seq in Ht. cbn [ao_of gAND]. unfold ST, nH. nia.
218
+ - destruct Hr as [<-|[]]. cbn [ao_of gAND]. unfold ST, nH. nia.
219
+ - apply in_concat in Hr as (y & Hy & Hr). apply in_map_iff in Hy as (i & <- & Hi). apply in_seq in Hi.
220
+ destruct Hr as [<-|[<-|[]]]; cbn [ao_of gAND]; unfold CNT, LIM, nH; nia.
221
+ - destruct Hr as [<-|[]]. cbn [ao_of gAND]. unfold DEST, nH. nia.
222
+ Qed.
223
+
224
+ Theorem wpart_run : forall ww, length ww = W ->
225
+ let b := wget ww BOOT in
226
+ let ww' := wrun wpart ww in
227
+ length ww' = W
228
+ /\ (forall i, i < n -> wget ww' (ST w i) = if b then wget ww (ST w i) else nth i (encodeH A x0m) false)
229
+ /\ (forall i, i < w -> wget ww' (CNT i) = wget ww (CNT i) && b /\ wget ww' (LIM w i) = wget ww (LIM w i) && b)
230
+ /\ wget ww' (DEST w) = wget ww (DEST w) && b
231
+ /\ (forall c, (c <= BOOT \/ 15 + 2 * w + n <= c) -> wget ww' c = wget ww c).
232
+ Proof.
233
+ intros ww Hl b ww'.
234
+ assert (Hlen : forall r, In r wpart -> ao_of r < length ww)
235
+ by (intros r Hr; rewrite Hl; pose proof (wpart_ao_range r Hr); lia).
236
+ destruct (wrun_self wpart ww nodup_wpart self_wpart Hlen) as [S1 S2].
237
+ assert (Hin : forall r, In r wpart -> wget ww' (ao_of r) = wval ww r) by exact S1.
238
+ refine (conj (eq_trans (length_wrun _ _) Hl) (conj _ (conj _ (conj _ _)))).
239
+ - intros i Hi. destruct (Nat.lt_ge_cases i A) as [Hia|Hia]; [|destruct (Nat.eq_dec i A) as [->|Hne]].
240
+ + (* a bit of the counter *)
241
+ set (t := A - 1 - i).
242
+ assert (Hr : In (gAND (ST w (A - 1 - t), true) (BOOT, true) (ST w (A - 1 - t))) wpart).
243
+ { unfold wpart. apply in_or_app. right. apply in_or_app. left. unfold pc_recs. apply in_map_iff.
244
+ exists t. split; [reflexivity | apply in_seq; unfold t; lia]. }
245
+ pose proof (Hin _ Hr) as E. cbn [ao_of gAND] in E. replace (A - 1 - t) with i in E by (unfold t; lia).
246
+ rewrite E, wval_and_boot by (unfold ST, HO; lia). fold b.
247
+ rewrite nth_encodeH_pc by exact Hia. cbn [hpc x0m]. unfold bitof. rewrite Nat.bits_0.
248
+ destruct b; [rewrite andb_true_r | rewrite andb_false_r]; reflexivity.
249
+ + (* the halt bit *)
250
+ assert (Hr : In (gAND (ST w A, true) (BOOT, true) (ST w A)) wpart).
251
+ { unfold wpart. apply in_or_app. right. apply in_or_app. right. left. reflexivity. }
252
+ pose proof (Hin _ Hr) as E. cbn [ao_of gAND] in E. rewrite E, wval_and_boot by (unfold ST, HO; lia). fold b.
253
+ rewrite nth_encodeH_halt. cbn [hhalt x0m]. destruct b; [rewrite andb_true_r | rewrite andb_false_r]; reflexivity.
254
+ + (* a bit of memory *)
255
+ set (j := (i - A - 1) / A). set (k := (i - A - 1) mod A). set (t := A - 1 - k).
256
+ assert (Hk : k < A) by (unfold k; apply Nat.mod_upper_bound; lia).
257
+ assert (Hji : i = A + 1 + j * A + k) by (unfold j, k; pose proof (Nat.div_mod_eq (i - A - 1) A); lia).
258
+ assert (Hj : j < SW A) by (unfold nH in Hi; nia).
259
+ assert (Ht : t < A) by (unfold t; lia).
260
+ destruct (MB_ST j t Hj Ht) as [EM _]. replace (A - 1 - t) with k in EM by (unfold t; lia).
261
+ rewrite <- Hji in EM.
262
+ set (rj := if Nat.testbit (nth j m 0) t then gOR (MB A w j t, true) (BOOT, false) (MB A w j t)
263
+ else gAND (MB A w j t, true) (BOOT, true) (MB A w j t)).
264
+ assert (Hr : In rj wpart).
265
+ { unfold wpart. apply in_or_app. left. unfold mem_recs. apply in_concat.
266
+ exists (boot_word A w j (nth j m 0)).
267
+ split; [apply in_map_iff; exists j; split; [reflexivity | apply in_seq; lia]|].
268
+ unfold boot_word. apply in_map_iff. exists t. split; [reflexivity | apply in_seq; lia]. }
269
+ pose proof (Hin _ Hr) as E.
270
+ assert (Ea : ao_of rj = ST w i) by (unfold rj; destruct (Nat.testbit (nth j m 0) t); cbn [ao_of gOR gAND]; exact EM).
271
+ rewrite Ea in E. rewrite E. rewrite Hji at 2.
272
+ rewrite nth_encodeH_mem by (cbn [hmem x0m]; assumption). cbn [x0m]. unfold memv. cbn [hmem]. unfold bitof.
273
+ replace (A - 1 - k) with t by (unfold t; lia).
274
+ unfold rj. destruct (Nat.testbit (nth j m 0) t) eqn:Eb.
275
+ * rewrite wval_or_boot by (rewrite EM; unfold ST, HO; lia). rewrite EM. fold b.
276
+ destruct b; cbn [negb]; [rewrite orb_false_r; reflexivity | rewrite orb_true_r; symmetry; exact Eb].
277
+ * rewrite wval_and_boot by (rewrite EM; unfold ST, HO; lia). rewrite EM. fold b.
278
+ destruct b; [rewrite andb_true_r; reflexivity | rewrite andb_false_r; symmetry; exact Eb].
279
+ - intros i Hi. split.
280
+ + assert (Hr : In (gAND (CNT i, true) (BOOT, true) (CNT i)) wpart).
281
+ { unfold wpart. do 3 (apply in_or_app; right). apply in_or_app; left. unfold reg_recs. apply in_concat.
282
+ exists [gAND (CNT i, true) (BOOT, true) (CNT i); gAND (LIM w i, true) (BOOT, true) (LIM w i)].
283
+ split; [apply in_map_iff; exists i; split; [reflexivity | apply in_seq; lia] | left; reflexivity]. }
284
+ pose proof (Hin _ Hr) as E. cbn [ao_of gAND] in E. rewrite E, wval_and_boot by (unfold CNT, HO; lia). reflexivity.
285
+ + assert (Hr : In (gAND (LIM w i, true) (BOOT, true) (LIM w i)) wpart).
286
+ { unfold wpart. do 3 (apply in_or_app; right). apply in_or_app; left. unfold reg_recs. apply in_concat.
287
+ exists [gAND (CNT i, true) (BOOT, true) (CNT i); gAND (LIM w i, true) (BOOT, true) (LIM w i)].
288
+ split; [apply in_map_iff; exists i; split; [reflexivity | apply in_seq; lia] | right; left; reflexivity]. }
289
+ pose proof (Hin _ Hr) as E. cbn [ao_of gAND] in E. rewrite E, wval_and_boot by (unfold LIM, HO; lia). reflexivity.
290
+ - assert (Hr : In (gAND (DEST w, true) (BOOT, true) (DEST w)) wpart).
291
+ { unfold wpart. do 4 (apply in_or_app; right). left. reflexivity. }
292
+ pose proof (Hin _ Hr) as E. cbn [ao_of gAND] in E. rewrite E, wval_and_boot by (unfold DEST, HO; lia). reflexivity.
293
+ - intros c Hc. apply S2. intro Hx. apply in_map_iff in Hx as (r & Er & Hr).
294
+ pose proof (wpart_ao_range r Hr). unfold BOOT in Hc. lia.
295
+ Qed.
296
+
297
+ (* ---- the startup on a view ------------------------------------------------------------------------- *)
298
+ Theorem startup_run : forall v, reqclear (vw v) -> length (vw v) = W ->
299
+ let b := wget (vw v) BOOT in
300
+ let v' := vrun Lb L (startup A w m) v in
301
+ reqclear (vw v') /\ length (vw v') = W /\ wget (vw v') BOOT = true
302
+ /\ (forall i, i < n -> wget (vw v') (ST w i) = if b then wget (vw v) (ST w i) else nth i (encodeH A x0m) false)
303
+ /\ (forall i, i < w -> wget (vw v') (CNT i) = wget (vw v) (CNT i) && b /\ wget (vw v') (LIM w i) = wget (vw v) (LIM w i) && b)
304
+ /\ wget (vw v') (DEST w) = wget (vw v) (DEST w) && b
305
+ /\ (forall c, (c < BOOT \/ 15 + 2 * w + n <= c) -> wget (vw v') c = wget (vw v) c)
306
+ /\ vr v' = (if b then vr v else mkT (td (vr v)) 0)
307
+ /\ va v' = (if b then va v else mkT (repeat false Lb) 0)
308
+ /\ vc v' = (if b then vc v else mkT (repeat false L) 0)
309
+ /\ vho v' = vho v.
310
+ Proof.
311
+ intros v Hq Hl b v'. unfold v'. rewrite startup_split, !vrun_app.
312
+ rewrite (vrun_wrun Lb L wpart v wrec_wpart Hq). set (ww := wrun wpart (vw v)).
313
+ destruct (wpart_run (vw v) Hl) as (L1 & S1 & R1 & D1 & U1). fold b ww in L1, S1, R1, D1, U1.
314
+ assert (Hq1 : reqclear ww) by (intros c Hc; unfold ww; rewrite U1 by (unfold BOOT, AR, HO in *; lia); apply Hq; exact Hc).
315
+ assert (Hb1 : wget ww BOOT = b) by (unfold ww; rewrite U1 by (left; reflexivity); reflexivity).
316
+ (* the five requests, each holding not booted *)
317
+ assert (Hreq : forall c v1, AR <= c <= HO -> reqclear (vw v1) -> length (vw v1) = W -> wget (vw v1) BOOT = b ->
318
+ vexec Lb L (gCOPY (BOOT, false) c) v1 = if b then v1 else vact Lb L c v1).
319
+ { intros c v1 Hc Hq' Hl' Hb'. rewrite (vexec_req Lb L _ v1 Hq') by (cbn [ao_of gCOPY]; unfold AR, HO in *; lia).
320
+ rewrite rval_copy. unfold lv. cbn [fst snd]. rewrite vcell_win by (unfold BOOT, CPY; lia). rewrite Hb'.
321
+ destruct b; reflexivity. }
322
+ unfold req_recs. cbn [map vrun].
323
+ set (v1 := mkV ww (vr v) (va v) (vc v) (vho v)).
324
+ assert (Hv1 : reqclear (vw v1) /\ length (vw v1) = W /\ wget (vw v1) BOOT = b) by (cbn [vw v1]; auto).
325
+ destruct Hv1 as (Q1 & L1' & B1).
326
+ rewrite (Hreq RR v1) by (unfold AR, RR, HO; lia || assumption).
327
+ destruct b eqn:Eb.
328
+ - rewrite !(Hreq _ v1) by (unfold AR, CB, RA, CT, RC, HO; lia || assumption).
329
+ rewrite (vexec_cell Lb L _ v1 Q1) by (cbn [ao_of gCONST gOR]; unfold BOOT, HO; lia).
330
+ rewrite rval_const. cbn [vw vr va vc vho v1 ao_of gCONST gOR].
331
+ refine (conj (reqclear_upd _ BOOT _ ltac:(unfold BOOT, HO; lia) Hq1) (conj _ (conj _ (conj _ (conj _ (conj _ (conj _ _))))))).
332
+ + rewrite upd_length. exact L1.
333
+ + rewrite wget_upd, Nat.eqb_refl, (proj2 (Nat.ltb_lt _ _)) by (rewrite L1; unfold BOOT; lia). reflexivity.
334
+ + intros i Hi. rewrite wget_upd_other by (unfold BOOT, ST; lia). apply S1. exact Hi.
335
+ + intros i Hi. rewrite !wget_upd_other by (unfold BOOT, CNT, LIM; lia). apply R1. exact Hi.
336
+ + rewrite wget_upd_other by (unfold BOOT, DEST; lia). exact D1.
337
+ + intros c Hc. rewrite wget_upd_other by (unfold BOOT in *; lia). apply U1. unfold BOOT in *. lia.
338
+ + split; [reflexivity | split; [reflexivity | split; reflexivity]].
339
+ - (* not booted: the read head home, the idle bank cleared and the arm home, the copy tape cleared and its head home *)
340
+ set (v2 := vact Lb L RR v1).
341
+ assert (Hv2 : vw v2 = ww) by reflexivity.
342
+ rewrite (Hreq CB v2) by (unfold AR, CB, HO; lia || (rewrite Hv2; assumption)).
343
+ set (v3 := vact Lb L CB v2).
344
+ rewrite (Hreq RA v3) by (unfold AR, RA, HO; lia || (cbn [vact vw v3 v2 v1]; assumption)).
345
+ set (v4 := vact Lb L RA v3).
346
+ rewrite (Hreq CT v4) by (unfold AR, CT, HO; lia || (cbn [vact vw v4 v3 v2 v1]; assumption)).
347
+ set (v5 := vact Lb L CT v4).
348
+ rewrite (Hreq RC v5) by (unfold AR, RC, HO; lia || (cbn [vact vw v5 v4 v3 v2 v1]; assumption)).
349
+ set (v6 := vact Lb L RC v5).
350
+ assert (Q6 : reqclear (vw v6)) by (cbn [vact vw v6 v5 v4 v3 v2 v1]; exact Hq1).
351
+ rewrite (vexec_cell Lb L _ v6 Q6) by (cbn [ao_of gCONST gOR]; unfold BOOT, HO; lia).
352
+ rewrite rval_const. cbn [vact vw vr va vc vho v6 v5 v4 v3 v2 v1 ao_of gCONST gOR td th RR CB RA CT RC].
353
+ refine (conj (reqclear_upd _ BOOT _ ltac:(unfold BOOT, HO; lia) Hq1) (conj _ (conj _ (conj _ (conj _ (conj _ (conj _ _))))))).
354
+ + rewrite upd_length. exact L1.
355
+ + rewrite wget_upd, Nat.eqb_refl, (proj2 (Nat.ltb_lt _ _)) by (rewrite L1; unfold BOOT; lia). reflexivity.
356
+ + intros i Hi. rewrite wget_upd_other by (unfold BOOT, ST; lia). apply S1. exact Hi.
357
+ + intros i Hi. rewrite !wget_upd_other by (unfold BOOT, CNT, LIM; lia). apply R1. exact Hi.
358
+ + rewrite wget_upd_other by (unfold BOOT, DEST; lia). exact D1.
359
+ + intros c Hc. rewrite wget_upd_other by (unfold BOOT in *; lia). apply U1. unfold BOOT in *. lia.
360
+ + split; [reflexivity | split; [reflexivity | split; reflexivity]].
361
+ Qed.
362
+
363
+ End Boot.
364
+
365
+ (* ---- the padding and the hand-over ----------------------------------------------------------------- *)
366
+ Lemma pad_run : forall Lb L p v, reqclear (vw v) -> vrun Lb L (repeat EMPTY p) v = v.
367
+ Proof.
368
+ intros Lb L p. induction p as [|p IH]; intros v Hq; [reflexivity|].
369
+ cbn [repeat vrun]. rewrite (vexec_sink Lb L EMPTY v Hq eq_refl). apply IH. exact Hq.
370
+ Qed.
371
+
372
+ Section Hand.
373
+ Variables (A w W Lb L : nat).
374
+ Hypothesis HW : 15 + 2 * w + A < W.
375
+
376
+ Theorem handover_run : forall v, reqclear (vw v) -> length (vw v) = W ->
377
+ let h := wget (vw v) (ST w A) in
378
+ let v' := vrun Lb L (handover A w) v in
379
+ reqclear (vw v') /\ length (vw v') = W
380
+ /\ (forall c, wget (vw v') c = if Nat.eqb c BOOT then wget (vw v) BOOT && negb h else wget (vw v) c)
381
+ /\ vr v' = vr v /\ va v' = (if h then mkT (td (va v)) 0 else va v)
382
+ /\ vc v' = (if h then mkT (td (vc v)) 0 else vc v) /\ vho v' = (vho v || h).
383
+ Proof.
384
+ intros v Hq Hl h v'. unfold v', handover. cbn [vrun].
385
+ rewrite (vexec_cell Lb L _ v Hq) by (cbn [ao_of gAND]; unfold BOOT, HO; lia).
386
+ rewrite rval_and. unfold lv. cbn [fst snd ao_of gAND]. rewrite !vcell_win by (unfold BOOT, ST, CPY; lia). fold h.
387
+ set (x := wget (vw v) BOOT && negb h).
388
+ set (v1 := mkV (upd (vw v) BOOT x) (vr v) (va v) (vc v) (vho v)).
389
+ assert (Q1 : reqclear (vw v1)) by (apply reqclear_upd; [unfold BOOT, HO; lia | exact Hq]).
390
+ assert (Hh1 : vcell v1 (ST w A) = h)
391
+ by (rewrite vcell_win by (unfold ST, CPY; lia); cbn [vw v1]; rewrite wget_upd_other by (unfold BOOT, ST; lia); reflexivity).
392
+ assert (Hreq : forall c v2, AR <= c <= HO -> reqclear (vw v2) -> length (vw v2) = W -> vcell v2 (ST w A) = h ->
393
+ vexec Lb L (gCOPY (ST w A, true) c) v2 = if h then vact Lb L c v2 else v2).
394
+ { intros c v2 Hc Hq2 Hl2 Hh2. rewrite (vexec_req Lb L _ v2 Hq2) by (cbn [ao_of gCOPY]; unfold AR, HO in *; lia).
395
+ rewrite rval_copy. unfold lv. cbn [fst snd]. rewrite Hh2. reflexivity. }
396
+ assert (L1 : length (vw v1) = W) by (cbn [vw v1]; rewrite upd_length; exact Hl).
397
+ rewrite (Hreq RA v1) by (unfold AR, RA, HO; lia || assumption).
398
+ destruct h eqn:Eh.
399
+ - set (v2 := vact Lb L RA v1).
400
+ assert (Hh2 : vcell v2 (ST w A) = true) by (rewrite <- Hh1; reflexivity).
401
+ rewrite (Hreq RC v2) by (unfold AR, RC, HO; lia || assumption).
402
+ set (v3 := vact Lb L RC v2).
403
+ assert (Hh3 : vcell v3 (ST w A) = true) by (rewrite <- Hh1; reflexivity).
404
+ rewrite (Hreq HO v3) by (unfold AR, HO; lia || assumption).
405
+ cbn [vact vw vr va vc vho v3 v2 v1 RA RC HO td th].
406
+ refine (conj Q1 (conj L1 (conj _ (conj eq_refl (conj eq_refl (conj eq_refl (eq_sym (orb_true_r _)))))))).
407
+ intros c. rewrite wget_upd. destruct (Nat.eqb_spec c BOOT) as [->|Hc]; [|reflexivity].
408
+ rewrite (proj2 (Nat.ltb_lt _ _)) by (rewrite Hl; unfold BOOT, ST in *; lia). reflexivity.
409
+ - rewrite (Hreq RC v1) by (unfold AR, RC, HO; lia || assumption).
410
+ rewrite (Hreq HO v1) by (unfold AR, HO; lia || assumption).
411
+ cbn [vw vr va vc vho v1]. rewrite orb_false_r.
412
+ refine (conj Q1 (conj L1 (conj _ (conj eq_refl (conj eq_refl (conj eq_refl eq_refl)))))).
413
+ intros c. rewrite wget_upd. destruct (Nat.eqb_spec c BOOT) as [->|Hc]; [|reflexivity].
414
+ rewrite (proj2 (Nat.ltb_lt _ _)) by (rewrite Hl; unfold BOOT, ST in *; lia). reflexivity.
415
+ Qed.
416
+
417
+ End Hand.
rocq/StoredDev.v ADDED
@@ -0,0 +1,1333 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* The device records of the stored host carry out Definition 8.4 on the state the step leaves: a write
2
+ of the low byte of R_out under the arm or the copy head, a read of a byte under the read head into
3
+ R_in with its sign copied, the end of the recipe after the rewind at cnt = lim, the count of reads, the
4
+ rewind, and the request words cleared. *)
5
+ From Stdlib Require Import List Bool Arith ZArith Lia.
6
+ Import ListNotations.
7
+ From TH Require Import TwoHead Net Abstract Indep Run View Stored WinRun WinPar ViewOps Host Device.
8
+
9
+ (* a bit written under a head, which then moves on *)
10
+ Definition wstep (Lt : nat) (b : bool) (t : tape) : tape := mkT (upd (td t) (th t) b) (succ_mod Lt (th t)).
11
+ Definition wseq (Lt : nat) (bs : list bool) (t : tape) : tape := fold_left (fun t b => wstep Lt b t) bs t.
12
+
13
+ (* the position after k moves *)
14
+ Fixpoint adv (Lt k x : nat) : nat := match k with O => x | S k' => succ_mod Lt (adv Lt k' x) end.
15
+
16
+ Lemma forallb_map' : forall (T U : Type) (f : U -> bool) (g : T -> U) l, forallb f (map g l) = forallb (fun x => f (g x)) l.
17
+ Proof. intros T U f g l. induction l as [|x l IH]; [reflexivity|]. cbn [map forallb]. rewrite IH. reflexivity. Qed.
18
+
19
+ Lemma nodup_map_seq_inj : forall (f : nat -> nat) k N, (forall i j, k <= i < k + N -> k <= j < k + N -> f i = f j -> i = j) ->
20
+ NoDup (map f (seq k N)).
21
+ Proof.
22
+ intros f k N H. apply NoDup_map_NoDup_ForallPairs; [|apply seq_NoDup].
23
+ intros i j Hi Hj E. apply in_seq in Hi, Hj. exact (H i j Hi Hj E).
24
+ Qed.
25
+
26
+ Lemma forallb_ext_in' : forall (T : Type) (f g : T -> bool) l, (forall x, In x l -> f x = g x) -> forallb f l = forallb g l.
27
+ Proof.
28
+ intros T f g l. induction l as [|x l IH]; intro H; [reflexivity|]. cbn [forallb].
29
+ rewrite (H x (or_introl eq_refl)), IH by (intros y Hy; apply H; right; exact Hy). reflexivity.
30
+ Qed.
31
+
32
+ Section Dev.
33
+ Variables (A w W Lb L : nat).
34
+ Hypotheses (HA : 8 <= A) (Hw : 1 <= w).
35
+
36
+ Local Notation nu := (length (host_units A)).
37
+ Local Notation lvs := (levels (host_units A)).
38
+ Local Notation n := (nH A).
39
+ Hypothesis HW : ncells A w nu lvs <= W.
40
+
41
+ Local Notation MBc := (MB A w).
42
+ Local Notation cWR := (dWR A w nu lvs).
43
+ Local Notation cRD := (dRD A w nu lvs).
44
+ Local Notation cRW := (dRW A w nu lvs).
45
+ Local Notation cE := (dE A w nu lvs).
46
+ Local Notation cEQ := (dEQ A w nu lvs).
47
+ Local Notation cEOT := (dEOT A w nu lvs).
48
+ Local Notation cCA := (dCA A w nu lvs).
49
+ Local Notation cCC := (dCC A w nu lvs).
50
+ Local Notation cG := (dG A w nu lvs).
51
+ Local Notation cCAR := (dCAR A w nu lvs).
52
+ Local Notation m0 := (M0 A w nu lvs).
53
+ Local Notation m1 := (M1 A w nu lvs).
54
+
55
+ (* ---- the segments of the device ----------------------------------------------------------------------- *)
56
+ Definition segA : list rec := word1 A w (cwr A) cWR ++ word1 A w (crd A) cRD ++ word1 A w (crw A) cRW.
57
+ Definition segB : list rec :=
58
+ concat (map (fun i => [gAND (CNT i, true) (LIM w i, true) m0; gAND (CNT i, false) (LIM w i, false) m1;
59
+ gOR (m0, true) (m1, true) (cE i)]) (seq 0 w)).
60
+ Definition segC : list rec := chain gAND (map (fun i => (cE i, true)) (seq 0 w)) cEQ cEQ.
61
+ Definition segD : list rec := [gAND (cEQ, true) (DEST w, true) cEOT; gAND (cWR, true) (DEST w, false) cCA;
62
+ gAND (cWR, true) (DEST w, true) cCC].
63
+ Definition segE : list rec :=
64
+ concat (map (fun k => gMUX A w nu lvs cCA (MBc (rout A) (7 - k), true) (ARM, true) ARM ++ [gCOPY (cCA, true) AA]
65
+ ++ gMUX A w nu lvs cCC (MBc (rout A) (7 - k), true) (CPY, true) CPY ++ [gCOPY (cCC, true) AC])
66
+ (seq 0 8)).
67
+ Definition segF : list rec := map (fun t => gAND (MBc (rout A) t, true) (cWR, false) (MBc (rout A) t)) (seq 0 A).
68
+ Definition segG : list rec := [gAND (cRD, true) (cEOT, false) cG].
69
+ Definition segH : list rec :=
70
+ concat (map (fun k => gMUX A w nu lvs cG (RD, true) (MBc (rin A) (7 - k), true) (MBc (rin A) (7 - k))
71
+ ++ [gCOPY (cG, true) AR]) (seq 0 8)).
72
+ Definition segI : list rec :=
73
+ concat (map (fun t => gMUX A w nu lvs cG (MBc (rin A) 7, true) (MBc (rin A) t, true) (MBc (rin A) t)) (seq 8 (A - 8))).
74
+ Definition segJ : list rec := gMUX A w nu lvs cRD (cEOT, true) (MBc (ceot A) 0, true) (MBc (ceot A) 0).
75
+ Definition segK : list rec := map (fun t => gAND (MBc (ceot A) t, true) (cRD, false) (MBc (ceot A) t)) (seq 1 (A - 1)).
76
+ Definition segL : list rec := map (fun i => gAND (carry A w nu lvs i, true) (CNT i, true) (cCAR (S i))) (seq 0 (w - 1)).
77
+ Definition segM : list rec := concat (map (fun i => gXOR A w nu lvs (CNT i, true) (carry A w nu lvs i, true) (CNT i)) (seq 0 w)).
78
+ Definition segN : list rec := [gCOPY (cRW, true) RR].
79
+ Definition segO : list rec :=
80
+ concat (map (fun i => gMUX A w nu lvs cRW (CNT i, true) (LIM w i, true) (LIM w i) ++ [gAND (CNT i, true) (cRW, false) (CNT i)])
81
+ (seq 0 w)).
82
+ Definition segP : list rec := [gOR (DEST w, true) (cRW, true) (DEST w)].
83
+ Definition segQ : list rec := concat (map (fun c => map (fun t => gCONST false (MBc c t)) (seq 0 A)) [cwr A; crd A; crw A]).
84
+
85
+ Lemma device_split : Stored.device A w nu lvs =
86
+ (segA ++ segB ++ segC ++ segD) ++ segE ++ (segF ++ segG) ++ segH ++ (segI ++ segJ ++ segK ++ segL ++ segM)
87
+ ++ segN ++ (segO ++ segP ++ segQ).
88
+ Proof.
89
+ unfold Stored.device, segA, segB, segC, segD, segE, segF, segG, segH, segI, segJ, segK, segL, segM, segN, segO, segP, segQ.
90
+ rewrite <- !app_assoc. reflexivity.
91
+ Qed.
92
+
93
+ (* ---- the cells ---------------------------------------------------------------------------------------- *)
94
+ Lemma SW8 : 256 <= SW A.
95
+ Proof. unfold SW. replace A with (8 + (A - 8)) by lia. rewrite Nat.pow_add_r. pose proof (Nat.pow_nonzero 2 (A - 8)). cbn. lia. Qed.
96
+
97
+ Lemma n_eq : n = A + 1 + SW A * A.
98
+ Proof. reflexivity. Qed.
99
+
100
+ Ltac cells := pose proof SW8; pose proof n_eq; pose proof (Nat.mul_le_mono_l 256 (SW A) A SW8);
101
+ unfold carry, dCAR, dG, dCC, dCA, dEOT, dEQ, dE, dRW, dRD, dWR, M0, M1, ncells in *;
102
+ unfold DB, XC, UC, MB in *; unfold ST, CNT, LIM, DEST, BOOT, nh in *;
103
+ unfold HO, CPY, AR, AA, AC, RR, RA, RC, CB, CT, ARM, RD, SINK, cwr, crd, crw, ceot, rin, rout in *;
104
+ rewrite ?Nat.mul_sub_distr_l in *; first [lia | nia].
105
+
106
+ Lemma MB_range : forall j t, j < SW A -> t < A -> 15 + 2 * w + A < MBc j t < 15 + 2 * w + n.
107
+ Proof. intros j t Hj Ht. unfold MB, ST. rewrite n_eq. nia. Qed.
108
+
109
+ Lemma MB_inj : forall j t j' t', j < SW A -> j' < SW A -> t < A -> t' < A -> MBc j t = MBc j' t' -> j = j' /\ t = t'.
110
+ Proof.
111
+ intros j t j' t' Hj Hj' Ht Ht' E. unfold MB, ST in E.
112
+ assert (Ej : j = j').
113
+ { destruct (Nat.lt_trichotomy j j') as [L1|[L1|L1]]; [|exact L1|]; exfalso.
114
+ - assert (A * j + A <= A * j') by nia. lia.
115
+ - assert (A * j' + A <= A * j) by nia. lia. }
116
+ subst j'. split; [reflexivity | lia].
117
+ Qed.
118
+
119
+ Lemma DB_gt : forall j t, j < SW A -> t < A -> MBc j t < DB A w nu lvs.
120
+ Proof. intros j t Hj Ht. pose proof (MB_range j t Hj Ht). unfold DB, nh. lia. Qed.
121
+
122
+ Lemma io_lt : cwr A < SW A /\ ceot A < SW A /\ crw A < SW A /\ crd A < SW A /\ rin A < SW A /\ rout A < SW A.
123
+ Proof. pose proof SW8. unfold cwr, ceot, crw, crd, rin, rout. lia. Qed.
124
+
125
+ Lemma io_ne : cwr A <> crd A /\ cwr A <> crw A /\ crd A <> crw A /\ rout A <> rin A /\ rout A <> ceot A
126
+ /\ rin A <> ceot A /\ cwr A <> rout A /\ crd A <> rout A /\ crw A <> rout A /\ cwr A <> rin A /\ crd A <> rin A
127
+ /\ crw A <> rin A /\ cwr A <> ceot A /\ crd A <> ceot A /\ crw A <> ceot A.
128
+ Proof. pose proof SW8. unfold cwr, ceot, crw, crd, rin, rout. lia. Qed.
129
+
130
+ (* ---- the values the device computes from the window w0 it starts from --------------------------------- *)
131
+ Section Vals.
132
+ Variable w0 : list bool.
133
+
134
+ Definition word1v (j : nat) : bool := wget w0 (MBc j 0) && forallb (fun t => negb (wget w0 (MBc j t))) (seq 1 (A - 1)).
135
+ Definition wrv : bool := word1v (cwr A).
136
+ Definition rdv : bool := word1v (crd A).
137
+ Definition rwv : bool := word1v (crw A).
138
+ Definition eqv : bool := forallb (fun i => Bool.eqb (wget w0 (CNT i)) (wget w0 (LIM w i))) (seq 0 w).
139
+ Definition destv : bool := wget w0 (DEST w).
140
+ Definition eotv : bool := eqv && destv.
141
+ Definition cav : bool := wrv && negb destv.
142
+ Definition ccv : bool := wrv && destv.
143
+ Definition gv : bool := rdv && negb eotv.
144
+ Definition carryv (i : nat) : bool := gv && forallb (fun k => wget w0 (CNT k)) (seq 0 i).
145
+ Definition cntv (i : nat) : bool := xorb (wget w0 (CNT i)) (carryv i).
146
+
147
+ End Vals.
148
+
149
+ (* ---- the first window records: the three requests, cnt = lim, the end of the recipe, where a write goes *)
150
+ Lemma wl_neg : forall ww c, HO < c -> wl ww (c, false) = negb (wget ww c).
151
+ Proof.
152
+ intros ww c H. unfold wl, wcell. cbn [fst snd].
153
+ replace (Nat.eqb c SINK) with false by (symmetry; apply Nat.eqb_neq; unfold SINK, HO in *; lia). reflexivity.
154
+ Qed.
155
+
156
+ Lemma word1_run : forall j d ww, j < SW A -> length ww = W -> DB A w nu lvs <= d < ncells A w nu lvs ->
157
+ let ww' := wrun (word1 A w j d) ww in
158
+ length ww' = W /\ wget ww' d = word1v ww j /\ (forall c, c <> d -> wget ww' c = wget ww c).
159
+ Proof.
160
+ intros j d ww Hj Hl Hd. cbv zeta. unfold word1.
161
+ assert (Hdo : ok_cell W d) by (split; [unfold DB, HO in *; lia | lia]).
162
+ destruct (chain_run W gAND andb (fun x y d' w' => wval_and w' x y d') (fun x y d' => proj1 (ao_gates x y d' true))
163
+ ((MBc j 0, true) :: map (fun t => (MBc j t, false)) (seq 1 (A - 1))) d d ww ltac:(discriminate) Hl Hdo Hdo)
164
+ as (L1 & V1 & U1).
165
+ { intros l Hin. destruct Hin as [<-|Hin]; [cbn [fst]; pose proof (DB_gt j 0 Hj ltac:(lia)); lia|].
166
+ apply in_map_iff in Hin as (t & <- & Ht). apply in_seq in Ht. cbn [fst]. pose proof (DB_gt j t Hj ltac:(lia)). lia. }
167
+ split; [exact L1|]. split; [|intros c Hc; exact (U1 c Hc Hc)].
168
+ rewrite V1. cbn [hd tl]. rewrite fold_and. unfold word1v. rewrite wl_cell by (pose proof (MB_range j 0 Hj ltac:(lia)); unfold HO; lia).
169
+ f_equal. rewrite forallb_map'. apply forallb_ext_in'. intros t Ht. apply in_seq in Ht.
170
+ apply wl_neg. pose proof (MB_range j t Hj ltac:(lia)). unfold HO. lia.
171
+ Qed.
172
+
173
+ (* one record on the window, written out *)
174
+ Lemma wrun1 : forall r ww, wrun [r] ww = wnext ww (ao_of r) (wval ww r).
175
+ Proof. reflexivity. Qed.
176
+
177
+ Lemma wget_set : forall ww d x c, HO < d -> d < length ww -> wget (wnext ww d x) c = if Nat.eqb c d then x else wget ww c.
178
+ Proof. intros. apply wget_wnext; assumption. Qed.
179
+
180
+ Lemma eq_body_run : forall c l d ww, HO < c -> HO < l -> c <> m0 -> c <> m1 -> l <> m0 -> l <> m1 -> length ww = W ->
181
+ HO < d -> d < W -> d <> m0 -> d <> m1 ->
182
+ let ww' := wrun [gAND (c, true) (l, true) m0; gAND (c, false) (l, false) m1; gOR (m0, true) (m1, true) d] ww in
183
+ length ww' = W /\ wget ww' d = Bool.eqb (wget ww c) (wget ww l)
184
+ /\ (forall x, x <> m0 -> x <> m1 -> x <> d -> wget ww' x = wget ww x).
185
+ Proof.
186
+ intros c l d ww Hc Hl C0 C1 L0 L1 Hlen Hd HdW D0 D1. cbv zeta. cbn [wrun]. unfold wexec. cbn [ao_of gAND gOR].
187
+ assert (H0 : HO < m0 /\ m0 < W) by (split; cells). assert (H1 : HO < m1 /\ m1 < W) by (split; cells).
188
+ assert (N01 : m0 <> m1) by cells.
189
+ rewrite !wval_and, wval_or.
190
+ set (w1 := wnext ww m0 (wl ww (c, true) && wl ww (l, true))).
191
+ assert (Lw1 : length w1 = W) by (unfold w1; rewrite length_wnext; exact Hlen).
192
+ set (w2 := wnext w1 m1 (wl w1 (c, false) && wl w1 (l, false))).
193
+ assert (Lw2 : length w2 = W) by (unfold w2; rewrite length_wnext; exact Lw1).
194
+ assert (E1 : forall x, x <> m0 -> wget w1 x = wget ww x)
195
+ by (intros x Hx; unfold w1; rewrite wget_set by (lia || (rewrite Hlen; lia)); rewrite (proj2 (Nat.eqb_neq _ _) Hx); reflexivity).
196
+ assert (E2 : forall x, x <> m1 -> wget w2 x = wget w1 x)
197
+ by (intros x Hx; unfold w2; rewrite wget_set by (lia || (rewrite Lw1; lia)); rewrite (proj2 (Nat.eqb_neq _ _) Hx); reflexivity).
198
+ assert (V0 : wget w2 m0 = wget ww c && wget ww l).
199
+ { rewrite E2 by exact N01. unfold w1. rewrite wget_set by (lia || (rewrite Hlen; lia)). rewrite Nat.eqb_refl.
200
+ rewrite !wl_cell by assumption. reflexivity. }
201
+ assert (V1 : wget w2 m1 = negb (wget ww c) && negb (wget ww l)).
202
+ { unfold w2. rewrite wget_set by (lia || (rewrite Lw1; lia)). rewrite Nat.eqb_refl.
203
+ rewrite !wl_neg by assumption. rewrite (E1 c C0), (E1 l L0). reflexivity. }
204
+ rewrite !wl_cell by lia. rewrite V0, V1.
205
+ split; [rewrite length_wnext; exact Lw2|]. split.
206
+ - rewrite wget_set by (lia || (rewrite Lw2; lia)). rewrite Nat.eqb_refl. destruct (wget ww c), (wget ww l); reflexivity.
207
+ - intros x X0 X1 Xd. rewrite wget_set by (lia || (rewrite Lw2; lia)). rewrite (proj2 (Nat.eqb_neq _ _) Xd).
208
+ rewrite (E2 x X1), (E1 x X0). reflexivity.
209
+ Qed.
210
+
211
+ Definition eq_body (i : nat) : list rec :=
212
+ [gAND (CNT i, true) (LIM w i, true) m0; gAND (CNT i, false) (LIM w i, false) m1; gOR (m0, true) (m1, true) (cE i)].
213
+
214
+ Lemma segB_prefix : forall k ww, k <= w -> length ww = W ->
215
+ let ww' := wrun (concat (map eq_body (seq 0 k))) ww in
216
+ length ww' = W /\ (forall i, i < k -> wget ww' (cE i) = Bool.eqb (wget ww (CNT i)) (wget ww (LIM w i)))
217
+ /\ (forall x, x <> m0 -> x <> m1 -> (forall i, i < k -> x <> cE i) -> wget ww' x = wget ww x).
218
+ Proof.
219
+ induction k as [|k IH]; intros ww Hk Hlen; cbv zeta.
220
+ - split; [exact Hlen|]. split; [intros; lia | intros; reflexivity].
221
+ - rewrite seq_S, map_app, concat_app. cbn [map concat]. rewrite app_nil_r, wrun_app, Nat.add_0_l.
222
+ destruct (IH ww ltac:(lia) Hlen) as (L1 & V1 & U1). cbv zeta in L1, V1, U1.
223
+ set (w1 := wrun (concat (map eq_body (seq 0 k))) ww) in *.
224
+ destruct (eq_body_run (CNT k) (LIM w k) (cE k) w1 ltac:(cells) ltac:(cells) ltac:(cells) ltac:(cells) ltac:(cells)
225
+ ltac:(cells) L1 ltac:(cells) ltac:(cells) ltac:(cells) ltac:(cells)) as (L2 & V2 & U2).
226
+ cbv zeta in L2, V2, U2. unfold eq_body.
227
+ split; [exact L2|]. split.
228
+ + intros i Hi. destruct (Nat.eq_dec i k) as [->|Hik].
229
+ * rewrite V2, !U1 by (try (intros i Hi'; cells); cells). reflexivity.
230
+ * rewrite U2 by cells. apply V1. lia.
231
+ + intros x X0 X1 Xi. rewrite U2 by (try exact X0; try exact X1; apply Xi; lia). apply U1; [exact X0 | exact X1 |].
232
+ intros i Hi. apply Xi. lia.
233
+ Qed.
234
+
235
+ Theorem chunk1_run : forall ww, length ww = W ->
236
+ let ww' := wrun (segA ++ segB ++ segC ++ segD) ww in
237
+ length ww' = W
238
+ /\ wget ww' cWR = wrv ww /\ wget ww' cRD = rdv ww /\ wget ww' cRW = rwv ww
239
+ /\ wget ww' cEOT = eotv ww /\ wget ww' cCA = cav ww /\ wget ww' cCC = ccv ww
240
+ /\ (forall x, x < DB A w nu lvs \/ ncells A w nu lvs <= x -> wget ww' x = wget ww x).
241
+ Proof.
242
+ intros ww Hlen. cbv zeta. rewrite !wrun_app. unfold segA. rewrite !wrun_app.
243
+ pose proof io_lt as (I1 & I2 & I3 & I4 & I5 & I6).
244
+ destruct (word1_run (cwr A) cWR ww I1 Hlen ltac:(cells)) as (La & Va & Ua). cbv zeta in La, Va, Ua.
245
+ set (wa := wrun (word1 A w (cwr A) cWR) ww) in *.
246
+ destruct (word1_run (crd A) cRD wa I4 La ltac:(cells)) as (Lb' & Vb & Ub). cbv zeta in Lb', Vb, Ub.
247
+ set (wb := wrun (word1 A w (crd A) cRD) wa) in *.
248
+ destruct (word1_run (crw A) cRW wb I3 Lb' ltac:(cells)) as (Lc & Vc & Uc). cbv zeta in Lc, Vc, Uc.
249
+ set (wc := wrun (word1 A w (crw A) cRW) wb) in *.
250
+ assert (Wb : word1v wa (crd A) = rdv ww).
251
+ { unfold word1v, rdv, word1v. rewrite !Ua by (pose proof (DB_gt (crd A) 0 I4 ltac:(lia)); cells). f_equal.
252
+ apply forallb_ext_in'. intros t Ht. apply in_seq in Ht. rewrite Ua by (pose proof (DB_gt (crd A) t I4 ltac:(lia)); cells).
253
+ reflexivity. }
254
+ assert (Wc : word1v wb (crw A) = rwv ww).
255
+ { unfold word1v, rwv, word1v. rewrite !Ub, !Ua by (pose proof (DB_gt (crw A) 0 I3 ltac:(lia)); cells). f_equal.
256
+ apply forallb_ext_in'. intros t Ht. apply in_seq in Ht.
257
+ rewrite Ub, Ua by (pose proof (DB_gt (crw A) t I3 ltac:(lia)); cells). reflexivity. }
258
+ rewrite Wb in Vb. rewrite Wc in Vc. fold (wrv ww) in Va.
259
+ assert (Uabc : forall x, x <> cWR -> x <> cRD -> x <> cRW -> wget wc x = wget ww x)
260
+ by (intros x H1 H2 H3; rewrite (Uc x H3), (Ub x H2), (Ua x H1); reflexivity).
261
+ (* cnt = lim, bit by bit *)
262
+ destruct (segB_prefix w wc ltac:(lia) Lc) as (Ld & Vd & Ud). cbv zeta in Ld, Vd, Ud.
263
+ assert (EB : segB = concat (map eq_body (seq 0 w))) by reflexivity. rewrite EB.
264
+ set (wd := wrun (concat (map eq_body (seq 0 w))) wc) in *.
265
+ (* their conjunction *)
266
+ assert (HEQ : ok_cell W cEQ) by (split; cells).
267
+ destruct (chain_run W gAND andb (fun x y d' w' => wval_and w' x y d') (fun x y d' => proj1 (ao_gates x y d' true))
268
+ (map (fun i => (cE i, true)) (seq 0 w)) cEQ cEQ wd ltac:(destruct w; [lia | discriminate]) Ld HEQ HEQ)
269
+ as (Le & Ve & Ue).
270
+ { intros l Hin. apply in_map_iff in Hin as (i & <- & Hi). apply in_seq in Hi. cbn [fst]. cells. }
271
+ unfold segC. set (we := wrun (chain gAND (map (fun i => (cE i, true)) (seq 0 w)) cEQ cEQ) wd) in *.
272
+ assert (Veq : wget we cEQ = eqv ww).
273
+ { assert (Ew : seq 0 w = 0 :: seq 1 (w - 1)) by (replace w with (S (w - 1)) at 1 by lia; reflexivity).
274
+ rewrite Ve, Ew. cbn [map hd tl]. rewrite fold_and.
275
+ unfold eqv. rewrite Ew. cbn [forallb]. rewrite wl_cell by cells. rewrite (Vd 0) by lia.
276
+ rewrite !Uabc by cells. f_equal. rewrite forallb_map'. apply forallb_ext_in'.
277
+ intros i Hi. apply in_seq in Hi. rewrite wl_cell by cells. rewrite (Vd i) by lia. rewrite !Uabc by cells. reflexivity. }
278
+ (* the end of the recipe and where a write goes *)
279
+ unfold segD. cbn [wrun]. unfold wexec. cbn [ao_of gAND]. rewrite !wval_and.
280
+ assert (Rd : forall x, x <> cEQ -> (forall i, i < w -> x <> cE i) -> x <> m0 -> x <> m1 -> wget we x = wget wc x).
281
+ { intros x H1 H2 H3 H4. rewrite (Ue x H1 H1). apply Ud; assumption. }
282
+ assert (Dst : wget we (DEST w) = destv ww).
283
+ { unfold destv. rewrite Rd by (try (intros; cells); cells). apply Uabc; cells. }
284
+ assert (Wr : wget we cWR = wrv ww).
285
+ { rewrite Rd by (try (intros; cells); cells). rewrite Uc by cells. rewrite Ub by cells. exact Va. }
286
+ rewrite !wl_cell by cells. rewrite !wl_neg by cells.
287
+ set (f1 := wnext we cEOT (wget we cEQ && wget we (DEST w))).
288
+ assert (Lf1 : length f1 = W) by (unfold f1; rewrite length_wnext; exact Le).
289
+ assert (F1 : forall x, wget f1 x = if Nat.eqb x cEOT then eotv ww else wget we x).
290
+ { intro x. unfold f1. rewrite wget_set by (cells || (rewrite Le; cells)). rewrite Veq, Dst. reflexivity. }
291
+ rewrite !(F1 cWR), !(F1 (DEST w)), (proj2 (Nat.eqb_neq cWR cEOT)), (proj2 (Nat.eqb_neq (DEST w) cEOT)) by cells.
292
+ rewrite Wr, Dst.
293
+ set (f2 := wnext f1 cCA (wrv ww && negb (destv ww))).
294
+ assert (Lf2 : length f2 = W) by (unfold f2; rewrite length_wnext; exact Lf1).
295
+ assert (F2 : forall x, wget f2 x = if Nat.eqb x cCA then cav ww else wget f1 x).
296
+ { intro x. unfold f2. rewrite wget_set by (cells || (rewrite Lf1; cells)). reflexivity. }
297
+ assert (G1 : wget f2 cWR = wrv ww).
298
+ { rewrite F2, F1, (proj2 (Nat.eqb_neq cWR cCA)), (proj2 (Nat.eqb_neq cWR cEOT)) by cells. exact Wr. }
299
+ assert (G2 : wget f2 (DEST w) = destv ww).
300
+ { rewrite F2, F1, (proj2 (Nat.eqb_neq (DEST w) cCA)), (proj2 (Nat.eqb_neq (DEST w) cEOT)) by cells. exact Dst. }
301
+ rewrite G1, G2.
302
+ set (f3 := wnext f2 cCC (wrv ww && destv ww)).
303
+ assert (F3 : forall x, wget f3 x = if Nat.eqb x cCC then ccv ww else wget f2 x).
304
+ { intro x. unfold f3. rewrite wget_set by (cells || (rewrite Lf2; cells)). reflexivity. }
305
+ split; [unfold f3; rewrite length_wnext; exact Lf2|].
306
+ assert (Old : forall x, x <> cCC -> x <> cCA -> x <> cEOT -> wget f3 x = wget we x).
307
+ { intros x H1 H2 H3. rewrite F3, F2, F1. rewrite (proj2 (Nat.eqb_neq _ _) H1), (proj2 (Nat.eqb_neq _ _) H2),
308
+ (proj2 (Nat.eqb_neq _ _) H3). reflexivity. }
309
+ split; [rewrite Old by cells; exact Wr|].
310
+ split; [rewrite Old by cells; rewrite Rd by (try (intros; cells); cells); rewrite Uc by cells; exact Vb|].
311
+ split; [rewrite Old by cells; rewrite Rd by (try (intros; cells); cells); exact Vc|].
312
+ split; [rewrite F3, F2, F1, (proj2 (Nat.eqb_neq cEOT cCC)), (proj2 (Nat.eqb_neq cEOT cCA)), Nat.eqb_refl by cells; reflexivity|].
313
+ split; [rewrite F3, F2, (proj2 (Nat.eqb_neq cCA cCC)), Nat.eqb_refl by cells; reflexivity|].
314
+ split; [rewrite F3, Nat.eqb_refl; reflexivity|].
315
+ intros x Hx. rewrite Old by cells. rewrite Rd by (try (intros; cells); cells). apply Uabc; cells.
316
+ Qed.
317
+
318
+ (* ---- the low byte of R_out under the arm or under the copy head --------------------------------------- *)
319
+ Definition Ebody (k : nat) : list rec :=
320
+ gMUX A w nu lvs cCA (MBc (rout A) (7 - k), true) (ARM, true) ARM ++ [gCOPY (cCA, true) AA]
321
+ ++ gMUX A w nu lvs cCC (MBc (rout A) (7 - k), true) (CPY, true) CPY ++ [gCOPY (cCC, true) AC].
322
+
323
+ Lemma tape_same : forall t, mkT (upd (td t) (th t) (tget t)) (th t) = t.
324
+ Proof. intros [d h]. unfold tget. cbn [td th]. rewrite upd_same. reflexivity. Qed.
325
+
326
+ Lemma win_set : forall v x c b, HO < c -> c < length (vw v) -> wget (upd (vw v) c b) x = if Nat.eqb x c then b else wget (vw v) x.
327
+ Proof. intros v x c b H1 H2. rewrite wget_upd, (proj2 (Nat.ltb_lt _ _) H2), andb_true_r. reflexivity. Qed.
328
+
329
+ Lemma Ebody_run : forall k v, k < 8 -> reqclear (vw v) -> length (vw v) = W ->
330
+ let ca := wget (vw v) cCA in let cc := wget (vw v) cCC in let b := wget (vw v) (MBc (rout A) (7 - k)) in
331
+ let v' := vrun Lb L (Ebody k) v in
332
+ reqclear (vw v') /\ length (vw v') = W /\ (forall x, x <> m0 -> x <> m1 -> wget (vw v') x = wget (vw v) x)
333
+ /\ vr v' = vr v /\ va v' = (if ca then wstep Lb b (va v) else va v)
334
+ /\ vc v' = (if cc then wstep L b (vc v) else vc v) /\ vho v' = vho v.
335
+ Proof.
336
+ intros k v Hk Hq Hl ca cc b. cbv zeta. unfold Ebody, gMUX. cbn [app vrun].
337
+ pose proof (io_lt) as (_ & _ & _ & _ & _ & Hro).
338
+ assert (Hrt : HO < MBc (rout A) (7 - k) /\ MBc (rout A) (7 - k) < DB A w nu lvs)
339
+ by (pose proof (MB_range (rout A) (7 - k) Hro ltac:(lia)); pose proof (DB_gt (rout A) (7 - k) Hro ltac:(lia)); split; cells).
340
+ (* the arm *)
341
+ rewrite (vexec_cell Lb L _ v Hq) by (cbn [ao_of gAND]; cells).
342
+ rewrite rval_and, !lv_win by (cbn [fst]; cells || lia). cbn [ao_of gAND]. fold ca b.
343
+ set (v1 := mkV (upd (vw v) m0 (ca && b)) (vr v) (va v) (vc v) (vho v)).
344
+ assert (Q1 : reqclear (vw v1)) by (apply reqclear_upd; [cells | exact Hq]).
345
+ assert (L1 : length (vw v1) = W) by (cbn [vw v1]; rewrite upd_length; exact Hl).
346
+ assert (W1 : forall x, wget (vw v1) x = if Nat.eqb x m0 then ca && b else wget (vw v) x)
347
+ by (intro x; cbn [vw v1]; apply win_set; [cells | rewrite Hl; cells]).
348
+ rewrite (vexec_cell Lb L _ v1 Q1) by (cbn [ao_of gAND]; cells).
349
+ rewrite rval_and. unfold lv. cbn [fst snd]. rewrite (vcell_win v1 cCA) by cells.
350
+ rewrite W1, (proj2 (Nat.eqb_neq cCA m0)) by cells. fold ca.
351
+ assert (Ha1 : vcell v1 ARM = tget (va v)) by reflexivity. rewrite Ha1. cbn [ao_of gAND].
352
+ set (v2 := mkV (upd (vw v1) m1 (negb ca && tget (va v))) (vr v1) (va v1) (vc v1) (vho v1)).
353
+ assert (Q2 : reqclear (vw v2)) by (apply reqclear_upd; [cells | exact Q1]).
354
+ assert (L2 : length (vw v2) = W) by (cbn [vw v2]; rewrite upd_length; exact L1).
355
+ assert (W2 : forall x, wget (vw v2) x = if Nat.eqb x m1 then negb ca && tget (va v) else wget (vw v1) x)
356
+ by (intro x; cbn [vw v2]; apply win_set; [cells | rewrite L1; cells]).
357
+ rewrite (vexec_arm Lb L _ v2 Q2) by reflexivity.
358
+ rewrite rval_or. unfold lv. cbn [fst snd]. rewrite !vcell_win by cells.
359
+ rewrite (W2 m0), (proj2 (Nat.eqb_neq m0 m1)), W1, Nat.eqb_refl, W2, Nat.eqb_refl by cells.
360
+ cbn [va v2 v1 vw vr vc vho].
361
+ set (xa := ca && b || negb ca && tget (va v)).
362
+ set (v3 := mkV (vw v2) (vr v) (mkT (upd (td (va v)) (th (va v)) xa) (th (va v))) (vc v) (vho v)).
363
+ assert (Q3 : reqclear (vw v3)) by exact Q2.
364
+ rewrite (vexec_req Lb L _ v3 Q3) by (cbn [ao_of gCOPY]; unfold AR, AA, HO; lia || (cbn [vw v3]; rewrite L2; unfold AA; cells)).
365
+ rewrite rval_copy. unfold lv. cbn [fst snd]. rewrite vcell_win by cells. cbn [vw v3].
366
+ rewrite W2, (proj2 (Nat.eqb_neq cCA m1)), W1, (proj2 (Nat.eqb_neq cCA m0)) by cells. fold ca.
367
+ set (v4 := if ca then vact Lb L (ao_of (gCOPY (cCA, true) AA)) v3 else v3).
368
+ assert (V4 : vw v4 = vw v2 /\ vr v4 = vr v /\ va v4 = (if ca then wstep Lb b (va v) else va v) /\ vc v4 = vc v
369
+ /\ vho v4 = vho v).
370
+ { unfold v4, v3, xa. destruct ca; cbn [ao_of gCOPY AA vact vw vr va vc vho negb andb orb].
371
+ - rewrite orb_false_r. unfold wstep. repeat split.
372
+ - repeat split. apply tape_same. }
373
+ destruct V4 as (V4w & V4r & V4a & V4c & V4h).
374
+ assert (Q4 : reqclear (vw v4)) by (rewrite V4w; exact Q2).
375
+ (* the copy head *)
376
+ rewrite (vexec_cell Lb L _ v4 Q4) by (cbn [ao_of gAND]; cells).
377
+ rewrite rval_and, !lv_win by (cbn [fst]; cells || lia). cbn [ao_of gAND]. rewrite V4w.
378
+ rewrite W2, (proj2 (Nat.eqb_neq cCC m1)), W1, (proj2 (Nat.eqb_neq cCC m0)) by cells. fold cc.
379
+ rewrite W2, (proj2 (Nat.eqb_neq (MBc (rout A) (7 - k)) m1)), W1, (proj2 (Nat.eqb_neq (MBc (rout A) (7 - k)) m0)) by cells.
380
+ fold b.
381
+ set (v5 := mkV (upd (vw v2) m0 (cc && b)) (vr v4) (va v4) (vc v4) (vho v4)).
382
+ assert (Q5 : reqclear (vw v5)) by (apply reqclear_upd; [cells | exact Q2]).
383
+ assert (L5 : length (vw v5) = W) by (cbn [vw v5]; rewrite upd_length; exact L2).
384
+ assert (W5 : forall x, wget (vw v5) x = if Nat.eqb x m0 then cc && b else wget (vw v2) x)
385
+ by (intro x; cbn [vw v5]; apply win_set; [cells | rewrite L2; cells]).
386
+ rewrite (vexec_cell Lb L _ v5 Q5) by (cbn [ao_of gAND]; cells).
387
+ rewrite rval_and. unfold lv. cbn [fst snd]. rewrite (vcell_win v5 cCC) by cells.
388
+ rewrite W5, (proj2 (Nat.eqb_neq cCC m0)), W2, (proj2 (Nat.eqb_neq cCC m1)), W1, (proj2 (Nat.eqb_neq cCC m0)) by cells.
389
+ fold cc.
390
+ assert (Hc5 : vcell v5 CPY = tget (vc v)) by (change (vcell v5 CPY) with (tget (vc v4)); rewrite V4c; reflexivity).
391
+ rewrite Hc5. cbn [ao_of gAND].
392
+ set (v6 := mkV (upd (vw v5) m1 (negb cc && tget (vc v))) (vr v5) (va v5) (vc v5) (vho v5)).
393
+ assert (Q6 : reqclear (vw v6)) by (apply reqclear_upd; [cells | exact Q5]).
394
+ assert (L6 : length (vw v6) = W) by (cbn [vw v6]; rewrite upd_length; exact L5).
395
+ assert (W6 : forall x, wget (vw v6) x = if Nat.eqb x m1 then negb cc && tget (vc v) else wget (vw v5) x)
396
+ by (intro x; cbn [vw v6]; apply win_set; [cells | rewrite L5; cells]).
397
+ rewrite (vexec_cpy Lb L _ v6 Q6) by reflexivity.
398
+ rewrite rval_or. unfold lv. cbn [fst snd]. rewrite !vcell_win by cells.
399
+ rewrite (W6 m0), (proj2 (Nat.eqb_neq m0 m1)), W5, Nat.eqb_refl, W6, Nat.eqb_refl by cells.
400
+ cbn [vc v6 v5 vw vr va vho]. rewrite V4c.
401
+ set (xc := cc && b || negb cc && tget (vc v)).
402
+ set (v7 := mkV (vw v6) (vr v4) (va v4) (mkT (upd (td (vc v)) (th (vc v)) xc) (th (vc v))) (vho v4)).
403
+ assert (Q7 : reqclear (vw v7)) by exact Q6.
404
+ rewrite (vexec_req Lb L _ v7 Q7) by (cbn [ao_of gCOPY]; unfold AR, AC, HO; lia || (cbn [vw v7]; rewrite L6; unfold AC; cells)).
405
+ rewrite rval_copy. unfold lv. cbn [fst snd]. rewrite vcell_win by cells. cbn [vw v7].
406
+ rewrite W6, (proj2 (Nat.eqb_neq cCC m1)), W5, (proj2 (Nat.eqb_neq cCC m0)), W2, (proj2 (Nat.eqb_neq cCC m1)), W1,
407
+ (proj2 (Nat.eqb_neq cCC m0)) by cells. fold cc.
408
+ assert (Fin : forall x, x <> m0 -> x <> m1 -> wget (vw v7) x = wget (vw v) x).
409
+ { intros x X0 X1. cbn [vw v7]. rewrite W6, (proj2 (Nat.eqb_neq x m1) X1), W5, (proj2 (Nat.eqb_neq x m0) X0), W2,
410
+ (proj2 (Nat.eqb_neq x m1) X1), W1, (proj2 (Nat.eqb_neq x m0) X0). reflexivity. }
411
+ destruct cc eqn:Ecc; cbn [ao_of gCOPY AC vact vw vr va vc vho v7 negb andb orb].
412
+ - refine (conj Q6 (conj L6 (conj Fin (conj V4r (conj V4a (conj _ V4h)))))). unfold xc, wstep.
413
+ rewrite orb_false_r. reflexivity.
414
+ - refine (conj Q6 (conj L6 (conj Fin (conj V4r (conj V4a (conj _ V4h)))))). unfold xc. apply tape_same.
415
+ Qed.
416
+
417
+ Lemma wseq_snoc : forall Lt bs b t, wseq Lt (bs ++ [b]) t = wstep Lt b (wseq Lt bs t).
418
+ Proof. intros. unfold wseq. rewrite fold_left_app. reflexivity. Qed.
419
+
420
+ Theorem segE_run : forall k v, k <= 8 -> reqclear (vw v) -> length (vw v) = W ->
421
+ let ca := wget (vw v) cCA in let cc := wget (vw v) cCC in
422
+ let bits := map (fun k' => wget (vw v) (MBc (rout A) (7 - k'))) (seq 0 k) in
423
+ let v' := vrun Lb L (concat (map Ebody (seq 0 k))) v in
424
+ reqclear (vw v') /\ length (vw v') = W /\ (forall x, x <> m0 -> x <> m1 -> wget (vw v') x = wget (vw v) x)
425
+ /\ vr v' = vr v /\ va v' = (if ca then wseq Lb bits (va v) else va v)
426
+ /\ vc v' = (if cc then wseq L bits (vc v) else vc v) /\ vho v' = vho v.
427
+ Proof.
428
+ induction k as [|k IH]; intros v Hk Hq Hl; cbv zeta.
429
+ - cbn [seq map concat vrun]. refine (conj Hq (conj Hl (conj (fun _ _ _ => eq_refl) (conj eq_refl (conj _ (conj _ eq_refl)))))).
430
+ + destruct (wget (vw v) cCA); reflexivity.
431
+ + destruct (wget (vw v) cCC); reflexivity.
432
+ - rewrite seq_S, map_app, concat_app, vrun_app, map_app. cbn [map concat]. rewrite app_nil_r, Nat.add_0_l.
433
+ destruct (IH v ltac:(lia) Hq Hl) as (Q1 & L1 & U1 & R1 & A1 & C1 & H1). cbv zeta in Q1, L1, U1, R1, A1, C1, H1.
434
+ set (v1 := vrun Lb L (concat (map Ebody (seq 0 k))) v) in *.
435
+ destruct (Ebody_run k v1 ltac:(lia) Q1 L1) as (Q2 & L2 & U2 & R2 & A2 & C2 & H2). cbv zeta in Q2, L2, U2, R2, A2, C2, H2.
436
+ pose proof io_lt as (_ & _ & _ & _ & _ & Hro).
437
+ assert (Eca : wget (vw v1) cCA = wget (vw v) cCA) by (apply U1; cells).
438
+ assert (Ecc : wget (vw v1) cCC = wget (vw v) cCC) by (apply U1; cells).
439
+ assert (Eb : wget (vw v1) (MBc (rout A) (7 - k)) = wget (vw v) (MBc (rout A) (7 - k)))
440
+ by (pose proof (DB_gt (rout A) (7 - k) Hro ltac:(lia)); apply U1; cells).
441
+ rewrite Eca, Ecc, Eb in *.
442
+ refine (conj Q2 (conj L2 (conj _ (conj _ (conj _ (conj _ _)))))).
443
+ + intros x X0 X1. rewrite (U2 x X0 X1). apply U1; assumption.
444
+ + rewrite R2. exact R1.
445
+ + rewrite A2, A1. destruct (wget (vw v) cCA); [rewrite wseq_snoc; reflexivity | reflexivity].
446
+ + rewrite C2, C1. destruct (wget (vw v) cCC); [rewrite wseq_snoc; reflexivity | reflexivity].
447
+ + rewrite H2. exact H1.
448
+ Qed.
449
+
450
+ (* ---- the byte under the read head into R_in -------------------------------------------------------------- *)
451
+ Definition Hbody (k : nat) : list rec :=
452
+ gMUX A w nu lvs cG (RD, true) (MBc (rin A) (7 - k), true) (MBc (rin A) (7 - k)) ++ [gCOPY (cG, true) AR].
453
+
454
+ Lemma Hbody_run : forall k v, k < 8 -> reqclear (vw v) -> length (vw v) = W ->
455
+ let g := wget (vw v) cG in
456
+ let v' := vrun Lb L (Hbody k) v in
457
+ reqclear (vw v') /\ length (vw v') = W
458
+ /\ wget (vw v') (MBc (rin A) (7 - k)) = (if g then tget (vr v) else wget (vw v) (MBc (rin A) (7 - k)))
459
+ /\ (forall x, x <> m0 -> x <> m1 -> x <> MBc (rin A) (7 - k) -> wget (vw v') x = wget (vw v) x)
460
+ /\ vr v' = (if g then mkT (td (vr v)) (succ_mod L (th (vr v))) else vr v) /\ va v' = va v /\ vc v' = vc v
461
+ /\ vho v' = vho v.
462
+ Proof.
463
+ intros k v Hk Hq Hl g. cbv zeta. unfold Hbody, gMUX. cbn [app vrun].
464
+ pose proof io_lt as (_ & _ & _ & _ & Hri & _).
465
+ set (c := MBc (rin A) (7 - k)).
466
+ assert (Hc : HO < c /\ c < DB A w nu lvs)
467
+ by (unfold c; pose proof (MB_range (rin A) (7 - k) Hri ltac:(lia)); pose proof (DB_gt (rin A) (7 - k) Hri ltac:(lia)); split; cells).
468
+ rewrite (vexec_cell Lb L _ v Hq) by (cbn [ao_of gAND]; cells).
469
+ rewrite rval_and. rewrite (lv_win v cG true) by cells.
470
+ assert (Hrd : ViewOps.lv v (RD, true) = tget (vr v)) by reflexivity. rewrite Hrd. cbn [ao_of gAND]. fold g.
471
+ set (v1 := mkV (upd (vw v) m0 (g && tget (vr v))) (vr v) (va v) (vc v) (vho v)).
472
+ assert (Q1 : reqclear (vw v1)) by (apply reqclear_upd; [cells | exact Hq]).
473
+ assert (L1 : length (vw v1) = W) by (cbn [vw v1]; rewrite upd_length; exact Hl).
474
+ assert (W1 : forall x, wget (vw v1) x = if Nat.eqb x m0 then g && tget (vr v) else wget (vw v) x)
475
+ by (intro x; cbn [vw v1]; apply win_set; [cells | rewrite Hl; cells]).
476
+ rewrite (vexec_cell Lb L _ v1 Q1) by (cbn [ao_of gAND]; cells).
477
+ rewrite rval_and, (lv_win v1 cG false), (lv_win v1 c true) by cells.
478
+ rewrite !W1, (proj2 (Nat.eqb_neq cG m0)), (proj2 (Nat.eqb_neq c m0)) by cells. fold g. cbn [ao_of gAND].
479
+ set (v2 := mkV (upd (vw v1) m1 (negb g && wget (vw v) c)) (vr v1) (va v1) (vc v1) (vho v1)).
480
+ assert (Q2 : reqclear (vw v2)) by (apply reqclear_upd; [cells | exact Q1]).
481
+ assert (L2 : length (vw v2) = W) by (cbn [vw v2]; rewrite upd_length; exact L1).
482
+ assert (W2 : forall x, wget (vw v2) x = if Nat.eqb x m1 then negb g && wget (vw v) c else wget (vw v1) x)
483
+ by (intro x; cbn [vw v2]; apply win_set; [cells | rewrite L1; cells]).
484
+ rewrite (vexec_cell Lb L _ v2 Q2) by (cbn [ao_of gOR]; cells).
485
+ rewrite rval_or, (lv_win v2 m0 true), (lv_win v2 m1 true) by cells.
486
+ rewrite (W2 m0), (proj2 (Nat.eqb_neq m0 m1)), W1, Nat.eqb_refl, W2, Nat.eqb_refl by cells. cbn [ao_of gOR].
487
+ set (x3 := g && tget (vr v) || negb g && wget (vw v) c).
488
+ set (v3 := mkV (upd (vw v2) c x3) (vr v2) (va v2) (vc v2) (vho v2)).
489
+ assert (Q3 : reqclear (vw v3)) by (apply reqclear_upd; [cells | exact Q2]).
490
+ assert (L3 : length (vw v3) = W) by (cbn [vw v3]; rewrite upd_length; exact L2).
491
+ assert (W3 : forall x, wget (vw v3) x = if Nat.eqb x c then x3 else wget (vw v2) x)
492
+ by (intro x; cbn [vw v3]; apply win_set; [cells | rewrite L2; cells]).
493
+ rewrite (vexec_req Lb L _ v3 Q3) by (cbn [ao_of gCOPY]; unfold AR, HO; lia || (rewrite L3; unfold AR; cells)).
494
+ rewrite rval_copy, (lv_win v3 cG true) by cells.
495
+ rewrite W3, (proj2 (Nat.eqb_neq cG c)), W2, (proj2 (Nat.eqb_neq cG m1)), W1, (proj2 (Nat.eqb_neq cG m0)) by cells. fold g.
496
+ assert (Fx3 : x3 = if g then tget (vr v) else wget (vw v) c) by (unfold x3; destruct g; cbn [andb orb negb]; [rewrite orb_false_r|]; reflexivity).
497
+ assert (Fin : forall x, x <> m0 -> x <> m1 -> x <> c -> wget (vw v3) x = wget (vw v) x).
498
+ { intros x X0 X1 Xc. rewrite W3, (proj2 (Nat.eqb_neq x c) Xc), W2, (proj2 (Nat.eqb_neq x m1) X1), W1,
499
+ (proj2 (Nat.eqb_neq x m0) X0). reflexivity. }
500
+ assert (Vc : wget (vw v3) c = if g then tget (vr v) else wget (vw v) c) by (rewrite W3, Nat.eqb_refl; exact Fx3).
501
+ destruct g eqn:Eg; cbn [ao_of gCOPY AR vact vw vr va vc vho v3 v2 v1].
502
+ - refine (conj Q3 (conj L3 (conj Vc (conj Fin (conj eq_refl (conj eq_refl (conj eq_refl eq_refl))))))).
503
+ - refine (conj Q3 (conj L3 (conj Vc (conj Fin (conj eq_refl (conj eq_refl (conj eq_refl eq_refl))))))).
504
+ Qed.
505
+
506
+ Theorem segH_run : forall k v, k <= 8 -> reqclear (vw v) -> length (vw v) = W ->
507
+ let g := wget (vw v) cG in
508
+ let v' := vrun Lb L (concat (map Hbody (seq 0 k))) v in
509
+ reqclear (vw v') /\ length (vw v') = W
510
+ /\ (forall i, i < k -> wget (vw v') (MBc (rin A) (7 - i))
511
+ = (if g then nth (adv L i (th (vr v))) (td (vr v)) false else wget (vw v) (MBc (rin A) (7 - i))))
512
+ /\ (forall x, x <> m0 -> x <> m1 -> (forall i, i < k -> x <> MBc (rin A) (7 - i)) -> wget (vw v') x = wget (vw v) x)
513
+ /\ vr v' = (if g then mkT (td (vr v)) (adv L k (th (vr v))) else vr v) /\ va v' = va v /\ vc v' = vc v
514
+ /\ vho v' = vho v.
515
+ Proof.
516
+ induction k as [|k IH]; intros v Hk Hq Hl; cbv zeta.
517
+ - cbn [seq map concat vrun]. refine (conj Hq (conj Hl (conj _ (conj (fun _ _ _ _ => eq_refl) (conj _ (conj eq_refl (conj eq_refl eq_refl))))))).
518
+ + intros; lia.
519
+ + destruct (wget (vw v) cG); [destruct (vr v); reflexivity | reflexivity].
520
+ - rewrite seq_S, map_app, concat_app, vrun_app. cbn [map concat]. rewrite app_nil_r, Nat.add_0_l.
521
+ destruct (IH v ltac:(lia) Hq Hl) as (Q1 & L1 & V1 & U1 & R1 & A1 & C1 & H1). cbv zeta in Q1, L1, V1, U1, R1, A1, C1, H1.
522
+ set (v1 := vrun Lb L (concat (map Hbody (seq 0 k))) v) in *.
523
+ destruct (Hbody_run k v1 ltac:(lia) Q1 L1) as (Q2 & L2 & V2 & U2 & R2 & A2 & C2 & H2). cbv zeta in Q2, L2, V2, U2, R2, A2, C2, H2.
524
+ pose proof io_lt as (_ & _ & _ & _ & Hri & _).
525
+ assert (Eg : wget (vw v1) cG = wget (vw v) cG).
526
+ { apply U1; [cells | cells |]. intros i Hi. pose proof (DB_gt (rin A) (7 - i) Hri ltac:(lia)). cells. }
527
+ rewrite Eg in *.
528
+ assert (Neq : forall i j, i < 8 -> j < 8 -> i <> j -> MBc (rin A) (7 - i) <> MBc (rin A) (7 - j)).
529
+ { intros i j Hi Hj Hij E. apply MB_inj in E as [_ E]; [lia | exact Hri | exact Hri | lia | lia]. }
530
+ refine (conj Q2 (conj L2 (conj _ (conj _ (conj _ (conj _ (conj _ _))))))).
531
+ + intros i Hi. destruct (Nat.eq_dec i k) as [->|Hik].
532
+ * rewrite V2. destruct (wget (vw v) cG); [|rewrite U1 by (try (intros j Hj; apply Neq; lia); cells); reflexivity].
533
+ rewrite R1. unfold tget. reflexivity.
534
+ * rewrite U2 by (try (apply Neq; lia); cells). apply V1. lia.
535
+ + intros x X0 X1 Xi. rewrite U2 by (try exact X0; try exact X1; apply Xi; lia). apply U1; [exact X0 | exact X1 |].
536
+ intros i Hi. apply Xi. lia.
537
+ + rewrite R2, R1. destruct (wget (vw v) cG); reflexivity.
538
+ + rewrite A2. exact A1.
539
+ + rewrite C2. exact C1.
540
+ + rewrite H2. exact H1.
541
+ Qed.
542
+
543
+ (* ---- R_out cleared on a write, and whether a byte is read ---------------------------------------------- *)
544
+ Lemma reads_gate : forall x y d, reads_of (gAND x y d) = [fst x; fst y] /\ reads_of (gOR x y d) = [fst x; fst y].
545
+ Proof. intros [a p] [c q] d. unfold reads_of, gAND, gOR, pm. cbn [fst snd]. destruct p, q; split; reflexivity. Qed.
546
+
547
+ Theorem chunk2_run : forall ww, length ww = W ->
548
+ let ww' := wrun (segF ++ segG) ww in
549
+ length ww' = W
550
+ /\ (forall t, t < A -> wget ww' (MBc (rout A) t) = wget ww (MBc (rout A) t) && negb (wget ww cWR))
551
+ /\ wget ww' cG = wget ww cRD && negb (wget ww cEOT)
552
+ /\ (forall x, x <> cG -> (forall t, t < A -> x <> MBc (rout A) t) -> wget ww' x = wget ww x).
553
+ Proof.
554
+ intros ww Hl. cbv zeta. rewrite wrun_app.
555
+ pose proof io_lt as (_ & _ & _ & _ & _ & Hro).
556
+ assert (Hcell : forall t, t < A -> HO < MBc (rout A) t /\ MBc (rout A) t < DB A w nu lvs)
557
+ by (intros t Ht; pose proof (MB_range (rout A) t Hro Ht); pose proof (DB_gt (rout A) t Hro Ht); split; cells).
558
+ destruct (wrun_par segF ww) as [P1 P2].
559
+ - unfold segF. rewrite map_map. cbn [ao_of gAND]. apply nodup_map_seq_inj.
560
+ intros i j Hi Hj E. apply MB_inj in E as [_ E]; [lia | exact Hro | exact Hro | lia | lia].
561
+ - intros r Hr. unfold segF in Hr. apply in_map_iff in Hr as (t & <- & Ht). apply in_seq in Ht. cbn [ao_of gAND].
562
+ destruct (Hcell t ltac:(lia)). split; [lia | rewrite Hl; cells].
563
+ - intros r r' Hr Hr' Hin. unfold segF in Hr, Hr'. apply in_map_iff in Hr as (t & <- & Ht). apply in_map_iff in Hr' as (t' & <- & Ht').
564
+ apply in_seq in Ht, Ht'. rewrite (proj1 (reads_gate _ _ _)) in Hin. cbn [ao_of gAND fst] in *.
565
+ destruct Hin as [E|[E|[]]]; [exact (eq_sym E)|]. exfalso. pose proof (DB_gt (rout A) t' Hro ltac:(lia)). cells.
566
+ - set (w1 := wrun segF ww) in *.
567
+ assert (Lw1 : length w1 = W) by (unfold w1; rewrite length_wrun; exact Hl).
568
+ assert (R1 : forall t, t < A -> wget w1 (MBc (rout A) t) = wget ww (MBc (rout A) t) && negb (wget ww cWR)).
569
+ { intros t Ht. assert (Hr : In (gAND (MBc (rout A) t, true) (cWR, false) (MBc (rout A) t)) segF)
570
+ by (unfold segF; apply in_map_iff; exists t; split; [reflexivity | apply in_seq; lia]).
571
+ pose proof (P1 _ Hr) as E. cbn [ao_of gAND] in E. rewrite E, wval_and.
572
+ destruct (Hcell t Ht). rewrite wl_cell, wl_neg by cells. reflexivity. }
573
+ assert (U1 : forall x, (forall t, t < A -> x <> MBc (rout A) t) -> wget w1 x = wget ww x).
574
+ { intros x Hx. apply P2. intro Hin. unfold segF in Hin. rewrite map_map in Hin. apply in_map_iff in Hin as (t & E & Ht).
575
+ apply in_seq in Ht. cbn [ao_of gAND] in E. apply (Hx t); [lia | symmetry; exact E]. }
576
+ unfold segG. cbn [wrun]. unfold wexec. cbn [ao_of gAND]. rewrite wval_and, wl_cell, wl_neg by cells.
577
+ assert (Hd : forall t, t < A -> cRD <> MBc (rout A) t /\ cEOT <> MBc (rout A) t /\ cWR <> MBc (rout A) t /\ cG <> MBc (rout A) t)
578
+ by (intros t Ht; destruct (Hcell t Ht); repeat split; cells).
579
+ rewrite !U1 by (intros t Ht; apply Hd; exact Ht).
580
+ split; [rewrite length_wnext; exact Lw1|]. split.
581
+ + intros t Ht. rewrite wget_set by (cells || (rewrite Lw1; cells)).
582
+ rewrite (proj2 (Nat.eqb_neq (MBc (rout A) t) cG)) by (intro E; apply (proj2 (proj2 (proj2 (Hd t Ht)))); auto).
583
+ apply R1. exact Ht.
584
+ + split.
585
+ * rewrite wget_set by (cells || (rewrite Lw1; cells)). rewrite Nat.eqb_refl. reflexivity.
586
+ * intros x Xg Xr. rewrite wget_set by (cells || (rewrite Lw1; cells)). rewrite (proj2 (Nat.eqb_neq _ _) Xg).
587
+ apply U1. exact Xr.
588
+ Qed.
589
+
590
+ (* ---- the sign of R_in, the end of the tape, the carries and the count ------------------------------------ *)
591
+ Lemma m01 : HO < m0 /\ HO < m1 /\ m0 <> m1 /\ m0 < W /\ m1 < W.
592
+ Proof. repeat split; cells. Qed.
593
+
594
+ Lemma mux_win : forall s a b d ww, length ww = W -> HO < d -> d < m0 -> HO < s -> s < m0 ->
595
+ HO < fst a -> fst a < m0 -> HO < fst b -> fst b < m0 ->
596
+ let ww' := wrun (gMUX A w nu lvs s a b d) ww in
597
+ length ww' = W /\ wget ww' d = (if wget ww s then wl ww a else wl ww b)
598
+ /\ (forall c, c <> m0 -> c <> m1 -> c <> d -> wget ww' c = wget ww c).
599
+ Proof.
600
+ intros s a b d ww Hl Hd1 Hd2 Hs1 Hs2 Ha1 Ha2 Hb1 Hb2. cbv zeta. unfold gMUX.
601
+ pose proof m01 as (H0 & H1 & H01 & L0 & L1).
602
+ destruct (wrun_mux m0 m1 s a b d ww H0 H1 H01 ltac:(rewrite Hl; exact L0) ltac:(rewrite Hl; exact L1) Hd1
603
+ ltac:(rewrite Hl; lia) Hs1 ltac:(lia) ltac:(lia) ltac:(lia) ltac:(cells))
604
+ as (LL & VV & UU).
605
+ split; [rewrite LL; exact Hl | split; [exact VV | exact UU]].
606
+ Qed.
607
+
608
+ Lemma xor_win : forall x y d ww, length ww = W -> HO < d -> d < DB A w nu lvs ->
609
+ HO < fst x -> fst x < DB A w nu lvs -> HO < fst y -> fst y < DB A w nu lvs + 7 + 2 * w ->
610
+ let ww' := wrun (gXOR A w nu lvs x y d) ww in
611
+ length ww' = W /\ wget ww' d = xorb (wl ww x) (wl ww y)
612
+ /\ (forall c, c <> m0 -> c <> m1 -> c <> d -> wget ww' c = wget ww c).
613
+ Proof.
614
+ intros x y d ww Hl Hd1 Hd2 Hx1 Hx2 Hy1 Hy2. cbv zeta. unfold gXOR.
615
+ pose proof m01 as (H0 & H1 & H01 & L0 & L1).
616
+ destruct (wrun_xor m0 m1 x y d ww H0 H1 H01 ltac:(rewrite Hl; exact L0) ltac:(rewrite Hl; exact L1) Hd1
617
+ ltac:(rewrite Hl; pose proof HW; unfold ncells in *; lia) ltac:(cells) ltac:(cells) ltac:(cells) ltac:(cells))
618
+ as (LL & VV & UU).
619
+ split; [rewrite LL; exact Hl | split; [exact VV | exact UU]].
620
+ Qed.
621
+
622
+ Lemma rin_cell : forall t, t < A -> HO < MBc (rin A) t /\ MBc (rin A) t < DB A w nu lvs.
623
+ Proof.
624
+ intros t Ht. pose proof io_lt as (_ & _ & _ & _ & Hri & _).
625
+ pose proof (MB_range (rin A) t Hri Ht). pose proof (DB_gt (rin A) t Hri Ht). split; cells.
626
+ Qed.
627
+
628
+ Lemma ceot_cell : forall t, t < A -> HO < MBc (ceot A) t /\ MBc (ceot A) t < DB A w nu lvs.
629
+ Proof.
630
+ intros t Ht. pose proof io_lt as (_ & Hce & _).
631
+ pose proof (MB_range (ceot A) t Hce Ht). pose proof (DB_gt (ceot A) t Hce Ht). split; cells.
632
+ Qed.
633
+
634
+ Theorem segI_run : forall k ww, k <= A - 8 -> length ww = W ->
635
+ let ww' := wrun (concat (map (fun t => gMUX A w nu lvs cG (MBc (rin A) 7, true) (MBc (rin A) t, true) (MBc (rin A) t))
636
+ (seq 8 k))) ww in
637
+ length ww' = W
638
+ /\ (forall t, 8 <= t < 8 + k -> wget ww' (MBc (rin A) t)
639
+ = if wget ww cG then wget ww (MBc (rin A) 7) else wget ww (MBc (rin A) t))
640
+ /\ (forall x, x <> m0 -> x <> m1 -> (forall t, 8 <= t < 8 + k -> x <> MBc (rin A) t) -> wget ww' x = wget ww x).
641
+ Proof.
642
+ pose proof io_lt as (_ & _ & _ & _ & Hri & _).
643
+ induction k as [|k IH]; intros ww Hk Hl; cbv zeta.
644
+ - split; [exact Hl | split; [intros; lia | intros; reflexivity]].
645
+ - rewrite seq_S, map_app, concat_app, wrun_app. cbn [map concat]. rewrite app_nil_r.
646
+ destruct (IH ww ltac:(lia) Hl) as (L1 & V1 & U1). cbv zeta in L1, V1, U1.
647
+ set (w1 := wrun (concat (map (fun t => gMUX A w nu lvs cG (MBc (rin A) 7, true) (MBc (rin A) t, true) (MBc (rin A) t))
648
+ (seq 8 k))) ww) in *.
649
+ destruct (rin_cell (8 + k) ltac:(lia)) as [Ht1 Ht2]. destruct (rin_cell 7 ltac:(lia)) as [H71 H72].
650
+ destruct (mux_win cG (MBc (rin A) 7, true) (MBc (rin A) (8 + k), true) (MBc (rin A) (8 + k)) w1 L1 Ht1
651
+ ltac:(cells) ltac:(cells) ltac:(cells) H71 ltac:(cbn [fst]; cells) Ht1 ltac:(cbn [fst]; cells))
652
+ as (L2 & V2 & U2).
653
+ cbv zeta in L2, V2, U2.
654
+ assert (Ne : forall t t', t < A -> t' < A -> t <> t' -> MBc (rin A) t <> MBc (rin A) t')
655
+ by (intros t t' Ht Ht' Htt E; apply MB_inj in E as [_ E]; [lia | exact Hri | exact Hri | lia | lia]).
656
+ assert (Eg : wget w1 cG = wget ww cG) by (apply U1; [cells | cells | intros t Ht; pose proof (rin_cell t ltac:(lia)); cells]).
657
+ assert (E7 : wget w1 (MBc (rin A) 7) = wget ww (MBc (rin A) 7))
658
+ by (apply U1; [cells | cells | intros t Ht; apply Ne; lia]).
659
+ split; [exact L2|]. split.
660
+ + intros t Ht. destruct (Nat.eq_dec t (8 + k)) as [->|Htk].
661
+ * rewrite V2, Eg. rewrite !wl_cell by lia. rewrite E7.
662
+ rewrite U1 by (try (intros t' Ht'; apply Ne; lia); cells). reflexivity.
663
+ * rewrite U2 by (try (apply Ne; lia); cells). apply V1. lia.
664
+ + intros x X0 X1 Xt. rewrite U2 by (try exact X0; try exact X1; apply Xt; lia). apply U1; [exact X0 | exact X1|].
665
+ intros t Ht. apply Xt. lia.
666
+ Qed.
667
+
668
+ Theorem segL_run : forall k ww, k <= w - 1 -> length ww = W ->
669
+ let ww' := wrun (map (fun i => gAND (carry A w nu lvs i, true) (CNT i, true) (cCAR (S i))) (seq 0 k)) ww in
670
+ length ww' = W
671
+ /\ (forall j, j <= k -> wget ww' (carry A w nu lvs j) = wget ww cG && forallb (fun i => wget ww (CNT i)) (seq 0 j))
672
+ /\ (forall x, (forall j, 1 <= j <= k -> x <> cCAR j) -> wget ww' x = wget ww x).
673
+ Proof.
674
+ induction k as [|k IH]; intros ww Hk Hl; cbv zeta.
675
+ - split; [exact Hl|]. split; [|intros; reflexivity].
676
+ intros j Hj. replace j with 0 by lia. cbn [seq forallb]. rewrite andb_true_r. reflexivity.
677
+ - rewrite seq_S, map_app, wrun_app. cbn [map]. rewrite Nat.add_0_l.
678
+ destruct (IH ww ltac:(lia) Hl) as (L1 & V1 & U1). cbv zeta in L1, V1, U1.
679
+ set (w1 := wrun (map (fun i => gAND (carry A w nu lvs i, true) (CNT i, true) (cCAR (S i))) (seq 0 k)) ww) in *.
680
+ cbn [wrun]. unfold wexec. cbn [ao_of gAND]. rewrite wval_and.
681
+ assert (Hck : HO < carry A w nu lvs k /\ carry A w nu lvs k < DB A w nu lvs + 7 + 2 * w).
682
+ { unfold carry. destruct (Nat.eqb k 0); split; cells. }
683
+ rewrite wl_cell by (destruct Hck; lia). rewrite wl_cell by cells.
684
+ rewrite (V1 k) by lia. rewrite (U1 (CNT k)) by (intros j Hj; cells).
685
+ set (x := wget ww cG && forallb (fun i => wget ww (CNT i)) (seq 0 k) && wget ww (CNT k)).
686
+ split; [rewrite length_wnext; exact L1|]. split.
687
+ + intros j Hj. rewrite wget_set by (cells || (rewrite L1; cells)).
688
+ destruct (Nat.eq_dec j (S k)) as [->|Hjk].
689
+ * unfold carry at 1. rewrite (proj2 (Nat.eqb_neq (S k) 0)) by lia. rewrite Nat.eqb_refl.
690
+ unfold x. rewrite seq_S, forallb_app. cbn [forallb]. rewrite andb_true_r, andb_assoc. reflexivity.
691
+ * replace (Nat.eqb (carry A w nu lvs j) (cCAR (S k))) with false.
692
+ { apply V1. lia. }
693
+ symmetry. apply Nat.eqb_neq. unfold carry. destruct (Nat.eqb_spec j 0); cells.
694
+ + intros y Hy. rewrite wget_set by (cells || (rewrite L1; cells)).
695
+ rewrite (proj2 (Nat.eqb_neq y (cCAR (S k)))) by (apply Hy; lia).
696
+ apply U1. intros j Hj. apply Hy. lia.
697
+ Qed.
698
+
699
+ Theorem segM_run : forall k ww, k <= w -> length ww = W ->
700
+ let ww' := wrun (concat (map (fun i => gXOR A w nu lvs (CNT i, true) (carry A w nu lvs i, true) (CNT i)) (seq 0 k))) ww in
701
+ length ww' = W
702
+ /\ (forall i, i < k -> wget ww' (CNT i) = xorb (wget ww (CNT i)) (wget ww (carry A w nu lvs i)))
703
+ /\ (forall x, x <> m0 -> x <> m1 -> (forall i, i < k -> x <> CNT i) -> wget ww' x = wget ww x).
704
+ Proof.
705
+ induction k as [|k IH]; intros ww Hk Hl; cbv zeta.
706
+ - split; [exact Hl | split; [intros; lia | intros; reflexivity]].
707
+ - rewrite seq_S, map_app, concat_app, wrun_app. cbn [map concat]. rewrite app_nil_r, Nat.add_0_l.
708
+ destruct (IH ww ltac:(lia) Hl) as (L1 & V1 & U1). cbv zeta in L1, V1, U1.
709
+ set (w1 := wrun (concat (map (fun i => gXOR A w nu lvs (CNT i, true) (carry A w nu lvs i, true) (CNT i)) (seq 0 k))) ww) in *.
710
+ assert (Hck : HO < carry A w nu lvs k /\ carry A w nu lvs k < DB A w nu lvs + 7 + 2 * w /\ carry A w nu lvs k <> m0
711
+ /\ carry A w nu lvs k <> m1 /\ forall i, i < w -> carry A w nu lvs k <> CNT i).
712
+ { unfold carry. destruct (Nat.eqb k 0); repeat split; try (intros i Hi); cells. }
713
+ destruct Hck as (C1 & C2 & C3 & C4 & C5).
714
+ destruct (xor_win (CNT k, true) (carry A w nu lvs k, true) (CNT k) w1 L1 ltac:(cells) ltac:(cells)
715
+ ltac:(cbn [fst]; cells) ltac:(cbn [fst]; cells) ltac:(cbn [fst]; exact C1) ltac:(cbn [fst]; exact C2))
716
+ as (L2 & V2 & U2). cbv zeta in L2, V2, U2.
717
+ split; [exact L2|]. split.
718
+ + intros i Hi. destruct (Nat.eq_dec i k) as [->|Hik].
719
+ * rewrite V2, !wl_cell by (cells || lia). rewrite !U1 by (try (intros i' Hi'; cells); try (intros i' Hi'; apply C5; lia); cells).
720
+ reflexivity.
721
+ * rewrite U2 by cells. apply V1. lia.
722
+ + intros x X0 X1 Xi. rewrite U2 by (try exact X0; try exact X1; apply Xi; lia). apply U1; [exact X0 | exact X1|].
723
+ intros i Hi. apply Xi. lia.
724
+ Qed.
725
+
726
+ Theorem segJK_run : forall ww, length ww = W ->
727
+ let ww' := wrun (segJ ++ segK) ww in
728
+ length ww' = W
729
+ /\ wget ww' (MBc (ceot A) 0) = (if wget ww cRD then wget ww cEOT else wget ww (MBc (ceot A) 0))
730
+ /\ (forall t, 1 <= t < A -> wget ww' (MBc (ceot A) t) = wget ww (MBc (ceot A) t) && negb (wget ww cRD))
731
+ /\ (forall x, x <> m0 -> x <> m1 -> (forall t, t < A -> x <> MBc (ceot A) t) -> wget ww' x = wget ww x).
732
+ Proof.
733
+ intros ww Hl. cbv zeta. rewrite wrun_app.
734
+ pose proof io_lt as (_ & Hce & _).
735
+ assert (Ne : forall t t', t < A -> t' < A -> t <> t' -> MBc (ceot A) t <> MBc (ceot A) t')
736
+ by (intros t t' Ht Ht' Htt E; apply MB_inj in E as [_ E]; [lia | exact Hce | exact Hce | lia | lia]).
737
+ destruct (ceot_cell 0 ltac:(lia)) as [C01 C02].
738
+ destruct (mux_win cRD (cEOT, true) (MBc (ceot A) 0, true) (MBc (ceot A) 0) ww Hl C01 ltac:(cells) ltac:(cells)
739
+ ltac:(cells) ltac:(cbn [fst]; cells) ltac:(cbn [fst]; cells) ltac:(cbn [fst]; cells) ltac:(cbn [fst]; cells))
740
+ as (L1 & V1 & U1). cbv zeta in L1, V1, U1. fold segJ in L1, V1, U1.
741
+ set (w1 := wrun segJ ww) in *.
742
+ rewrite !wl_cell in V1 by cells.
743
+ destruct (wrun_par segK w1) as [P1 P2].
744
+ - unfold segK. rewrite map_map. cbn [ao_of gAND]. apply nodup_map_seq_inj.
745
+ intros i j Hi Hj E. apply MB_inj in E as [_ E]; [lia | exact Hce | exact Hce | lia | lia].
746
+ - intros r Hr. unfold segK in Hr. apply in_map_iff in Hr as (t & <- & Ht). apply in_seq in Ht. cbn [ao_of gAND].
747
+ destruct (ceot_cell t ltac:(lia)). split; [lia | rewrite L1; cells].
748
+ - intros r r' Hr Hr' Hin. unfold segK in Hr, Hr'. apply in_map_iff in Hr as (t & <- & Ht). apply in_map_iff in Hr' as (t' & <- & Ht').
749
+ apply in_seq in Ht, Ht'. rewrite (proj1 (reads_gate _ _ _)) in Hin. cbn [ao_of gAND fst] in *.
750
+ destruct Hin as [E|[E|[]]]; [exact (eq_sym E)|]. exfalso. destruct (ceot_cell t' ltac:(lia)). cells.
751
+ - assert (Rk : forall t, 1 <= t < A -> wget (wrun segK w1) (MBc (ceot A) t) = wget w1 (MBc (ceot A) t) && negb (wget w1 cRD)).
752
+ { intros t Ht. assert (Hr : In (gAND (MBc (ceot A) t, true) (cRD, false) (MBc (ceot A) t)) segK)
753
+ by (unfold segK; apply in_map_iff; exists t; split; [reflexivity | apply in_seq; lia]).
754
+ pose proof (P1 _ Hr) as E. cbn [ao_of gAND] in E. rewrite E, wval_and.
755
+ destruct (ceot_cell t ltac:(lia)). rewrite wl_cell, wl_neg by cells. reflexivity. }
756
+ assert (Uk : forall x, (forall t, 1 <= t < A -> x <> MBc (ceot A) t) -> wget (wrun segK w1) x = wget w1 x).
757
+ { intros x Hx. apply P2. intro Hin. unfold segK in Hin. rewrite map_map in Hin. apply in_map_iff in Hin as (t & E & Ht).
758
+ apply in_seq in Ht. cbn [ao_of gAND] in E. apply (Hx t); [lia | symmetry; exact E]. }
759
+ assert (Erd : wget w1 cRD = wget ww cRD) by (apply U1; cells).
760
+ split; [rewrite length_wrun; exact L1|]. split.
761
+ + rewrite Uk by (intros t Ht; apply Ne; lia). rewrite V1. reflexivity.
762
+ + split.
763
+ * intros t Ht. rewrite Rk by exact Ht. rewrite Erd. rewrite U1 by (try (apply Ne; lia); destruct (ceot_cell t ltac:(lia)); cells).
764
+ reflexivity.
765
+ * intros x X0 X1 Xt. rewrite Uk by (intros t Ht; apply Xt; lia). apply U1; [exact X0 | exact X1 | apply Xt; lia].
766
+ Qed.
767
+
768
+ Definition Obody (i : nat) : list rec :=
769
+ gMUX A w nu lvs cRW (CNT i, true) (LIM w i, true) (LIM w i) ++ [gAND (CNT i, true) (cRW, false) (CNT i)].
770
+
771
+ Theorem segO_run : forall k ww, k <= w -> length ww = W ->
772
+ let rw := wget ww cRW in
773
+ let ww' := wrun (concat (map Obody (seq 0 k))) ww in
774
+ length ww' = W
775
+ /\ (forall i, i < k -> wget ww' (LIM w i) = (if rw then wget ww (CNT i) else wget ww (LIM w i))
776
+ /\ wget ww' (CNT i) = wget ww (CNT i) && negb rw)
777
+ /\ (forall x, x <> m0 -> x <> m1 -> (forall i, i < k -> x <> LIM w i /\ x <> CNT i) -> wget ww' x = wget ww x).
778
+ Proof.
779
+ induction k as [|k IH]; intros ww Hk Hl; cbv zeta.
780
+ - split; [exact Hl | split; [intros; lia | intros; reflexivity]].
781
+ - rewrite seq_S, map_app, concat_app, wrun_app. cbn [map concat]. rewrite app_nil_r, Nat.add_0_l.
782
+ destruct (IH ww ltac:(lia) Hl) as (L1 & V1 & U1). cbv zeta in L1, V1, U1.
783
+ set (w1 := wrun (concat (map Obody (seq 0 k))) ww) in *.
784
+ unfold Obody. rewrite wrun_app.
785
+ destruct (mux_win cRW (CNT k, true) (LIM w k, true) (LIM w k) w1 L1 ltac:(cells) ltac:(cells) ltac:(cells)
786
+ ltac:(cells) ltac:(cbn [fst]; cells) ltac:(cbn [fst]; cells) ltac:(cbn [fst]; cells) ltac:(cbn [fst]; cells))
787
+ as (L2 & V2 & U2). cbv zeta in L2, V2, U2.
788
+ set (w2 := wrun (gMUX A w nu lvs cRW (CNT k, true) (LIM w k, true) (LIM w k)) w1) in *.
789
+ cbn [wrun]. unfold wexec. cbn [ao_of gAND]. rewrite wval_and, wl_cell, wl_neg by cells.
790
+ assert (Erw1 : wget w1 cRW = wget ww cRW) by (apply U1; [cells | cells | intros i Hi; split; cells]).
791
+ assert (Erw2 : wget w2 cRW = wget ww cRW) by (rewrite U2 by cells; exact Erw1).
792
+ assert (Ec2 : wget w2 (CNT k) = wget ww (CNT k))
793
+ by (rewrite U2 by cells; apply U1; [cells | cells | intros i Hi; split; cells]).
794
+ rewrite Erw2, Ec2.
795
+ split; [rewrite length_wnext; exact L2|]. split.
796
+ + intros i Hi. destruct (Nat.eq_dec i k) as [->|Hik].
797
+ * split.
798
+ -- rewrite wget_set by (cells || (rewrite L2; cells)). rewrite (proj2 (Nat.eqb_neq (LIM w k) (CNT k))) by cells.
799
+ rewrite V2, Erw1, !wl_cell by cells. rewrite !U1 by (try (intros i' Hi'; split; cells); cells). reflexivity.
800
+ -- rewrite wget_set by (cells || (rewrite L2; cells)). rewrite Nat.eqb_refl. reflexivity.
801
+ * rewrite !wget_set by (cells || (rewrite L2; cells)).
802
+ rewrite (proj2 (Nat.eqb_neq (LIM w i) (CNT k))), (proj2 (Nat.eqb_neq (CNT i) (CNT k))) by cells.
803
+ rewrite !U2 by cells. apply V1. lia.
804
+ + intros x X0 X1 Xi. rewrite wget_set by (cells || (rewrite L2; cells)).
805
+ rewrite (proj2 (Nat.eqb_neq x (CNT k))) by exact (proj2 (Xi k ltac:(lia))).
806
+ rewrite U2 by (try exact X0; try exact X1; exact (proj1 (Xi k ltac:(lia)))). apply U1; [exact X0 | exact X1|].
807
+ intros i Hi. apply Xi. lia.
808
+ Qed.
809
+
810
+ Lemma req_word_cell : forall c t, (c = cwr A \/ c = crd A \/ c = crw A) -> t < A ->
811
+ HO < MBc c t /\ MBc c t < DB A w nu lvs.
812
+ Proof.
813
+ intros c t Hc Ht. pose proof io_lt as (I1 & _ & I3 & I4 & _).
814
+ assert (Hcl : c < SW A) by (destruct Hc as [->|[->| ->]]; assumption).
815
+ pose proof (MB_range c t Hcl Ht). pose proof (DB_gt c t Hcl Ht). split; cells.
816
+ Qed.
817
+
818
+ Theorem segQ_run : forall ww, length ww = W ->
819
+ let ww' := wrun segQ ww in
820
+ length ww' = W
821
+ /\ (forall c t, (c = cwr A \/ c = crd A \/ c = crw A) -> t < A -> wget ww' (MBc c t) = false)
822
+ /\ (forall x, (forall c t, (c = cwr A \/ c = crd A \/ c = crw A) -> t < A -> x <> MBc c t) -> wget ww' x = wget ww x).
823
+ Proof.
824
+ intros ww Hl. cbv zeta. pose proof io_lt as (I1 & _ & I3 & I4 & _). pose proof io_ne as (N1 & N2 & N3 & _).
825
+ assert (Hin : forall r, In r segQ -> exists c t, (c = cwr A \/ c = crd A \/ c = crw A) /\ t < A /\ r = gCONST false (MBc c t)).
826
+ { intros r Hr. unfold segQ in Hr. apply in_concat in Hr as (l & Hl' & Hr). apply in_map_iff in Hl' as (c & <- & Hc).
827
+ apply in_map_iff in Hr as (t & <- & Ht). apply in_seq in Ht. exists c, t. split; [|split; [lia | reflexivity]].
828
+ destruct Hc as [<-|[<-|[<-|[]]]]; auto. }
829
+ destruct (wrun_par segQ ww) as [P1 P2].
830
+ - unfold segQ. rewrite concat_map. cbn [map concat]. rewrite !map_map. cbn [ao_of gCONST gAND]. rewrite app_nil_r.
831
+ assert (Nd : forall c, c < SW A -> NoDup (map (fun t => MBc c t) (seq 0 A))).
832
+ { intros c Hc. apply nodup_map_seq_inj. intros i j Hi Hj E. apply MB_inj in E as [_ E]; [lia | exact Hc | exact Hc | lia | lia]. }
833
+ assert (Dj : forall c c' t t', c < SW A -> c' < SW A -> c <> c' -> t < A -> t' < A -> MBc c t <> MBc c' t')
834
+ by (intros c c' t t' Hc Hc' Hcc Ht Ht' E; apply MB_inj in E as [E _]; [lia | exact Hc | exact Hc' | exact Ht | exact Ht']).
835
+ apply NoDup_app; [apply Nd; exact I1 | apply NoDup_app; [apply Nd; exact I4 | apply Nd; exact I3 |] |].
836
+ + intros x Hx1 Hx2. apply in_map_iff in Hx1 as (t & <- & Ht). apply in_map_iff in Hx2 as (t' & E & Ht').
837
+ apply in_seq in Ht, Ht'. exact (Dj (crd A) (crw A) t t' I4 I3 N3 ltac:(lia) ltac:(lia) (eq_sym E)).
838
+ + intros x Hx1 Hx2. apply in_map_iff in Hx1 as (t & <- & Ht). apply in_seq in Ht.
839
+ apply in_app_or in Hx2 as [Hx2|Hx2]; apply in_map_iff in Hx2 as (t' & E & Ht'); apply in_seq in Ht'.
840
+ * exact (Dj (cwr A) (crd A) t t' I1 I4 N1 ltac:(lia) ltac:(lia) (eq_sym E)).
841
+ * exact (Dj (cwr A) (crw A) t t' I1 I3 N2 ltac:(lia) ltac:(lia) (eq_sym E)).
842
+ - intros r Hr. destruct (Hin r Hr) as (c & t & Hc & Ht & ->). cbn [ao_of gCONST gAND].
843
+ destruct (req_word_cell c t Hc Ht). split; [lia | rewrite Hl; cells].
844
+ - intros r r' Hr Hr' Hx. destruct (Hin r Hr) as (c & t & Hc & Ht & ->). destruct (Hin r' Hr') as (c' & t' & Hc' & Ht' & ->).
845
+ cbn [gCONST reads_of gAND pm fst snd Z.eqb] in Hx. cbn [ao_of gCONST gAND] in *.
846
+ destruct (req_word_cell c' t' Hc' Ht'). unfold SINK in Hx. destruct Hx as [E|[E|[]]]; exfalso; cells.
847
+ - split; [rewrite length_wrun; exact Hl|]. split.
848
+ + intros c t Hc Ht. assert (Hr : In (gCONST false (MBc c t)) segQ).
849
+ { unfold segQ. apply in_concat. exists (map (fun t => gCONST false (MBc c t)) (seq 0 A)).
850
+ split; [apply in_map_iff; exists c; split; [reflexivity | destruct Hc as [->|[->| ->]]; cbn [In]; tauto]
851
+ | apply in_map_iff; exists t; split; [reflexivity | apply in_seq; lia]]. }
852
+ pose proof (P1 _ Hr) as E. cbn [ao_of gCONST gAND] in E. rewrite E. reflexivity.
853
+ + intros x Hx. apply P2. intro Hin'. apply in_map_iff in Hin' as (r & E & Hr). destruct (Hin r Hr) as (c & t & Hc & Ht & ->).
854
+ cbn [ao_of gCONST gAND] in E. exact (Hx c t Hc Ht (eq_sym E)).
855
+ Qed.
856
+
857
+ Lemma MB_ne : forall j t j' t', j < SW A -> j' < SW A -> t < A -> t' < A -> j <> j' -> MBc j t <> MBc j' t'.
858
+ Proof. intros j t j' t' Hj Hj' Ht Ht' Hne E. apply MB_inj in E as [E _]; auto. Qed.
859
+
860
+ Lemma wrun_reqclear : forall rs ww, Forall wrec rs -> reqclear ww -> reqclear (wrun rs ww).
861
+ Proof.
862
+ induction rs as [|r rs IH]; intros ww Hf Hq; [exact Hq|].
863
+ apply Forall_cons_iff in Hf as [Hr Hf]. cbn [wrun]. apply IH; [exact Hf|]. unfold wexec.
864
+ apply reqclear_wnext; [exact Hq|]. destruct r as [a0 x0 a1 x1 beta ao]. apply Hr.
865
+ Qed.
866
+
867
+ (* ---- the rewind returns the read head --------------------------------------------------------------- *)
868
+ Lemma segN_run : forall v, reqclear (vw v) -> length (vw v) = W ->
869
+ vrun Lb L segN v = mkV (vw v) (if wget (vw v) cRW then mkT (td (vr v)) 0 else vr v) (va v) (vc v) (vho v).
870
+ Proof.
871
+ intros v Hq Hl. unfold segN. cbn [vrun].
872
+ rewrite (vexec_req Lb L _ v Hq) by (cbn [ao_of gCOPY]; unfold AR, RR, HO; lia || (rewrite Hl; unfold RR; cells)).
873
+ rewrite rval_copy, (lv_win v cRW true) by cells. cbn [ao_of gCOPY RR].
874
+ destruct (wget (vw v) cRW); cbn [vact]; [reflexivity | destruct v; reflexivity].
875
+ Qed.
876
+
877
+ (* ---- the sign of R_in, c_eot, the carries and the count, in one run ------------------------------------- *)
878
+ Theorem chunk3_run : forall ww, length ww = W ->
879
+ let ww' := wrun (segI ++ segJ ++ segK ++ segL ++ segM) ww in
880
+ length ww' = W
881
+ /\ (forall t, 8 <= t < A -> wget ww' (MBc (rin A) t)
882
+ = if wget ww cG then wget ww (MBc (rin A) 7) else wget ww (MBc (rin A) t))
883
+ /\ wget ww' (MBc (ceot A) 0) = (if wget ww cRD then wget ww cEOT else wget ww (MBc (ceot A) 0))
884
+ /\ (forall t, 1 <= t < A -> wget ww' (MBc (ceot A) t) = wget ww (MBc (ceot A) t) && negb (wget ww cRD))
885
+ /\ (forall i, i < w -> wget ww' (CNT i)
886
+ = xorb (wget ww (CNT i)) (wget ww cG && forallb (fun k => wget ww (CNT k)) (seq 0 i)))
887
+ /\ (forall x, x <> m0 -> x <> m1 -> (forall t, 8 <= t < A -> x <> MBc (rin A) t)
888
+ -> (forall t, t < A -> x <> MBc (ceot A) t) -> (forall j, 1 <= j < w -> x <> cCAR j)
889
+ -> (forall i, i < w -> x <> CNT i) -> wget ww' x = wget ww x).
890
+ Proof.
891
+ intros ww Hl. cbv zeta.
892
+ pose proof io_lt as (_ & Hce & _ & _ & Hri & _). pose proof io_ne as (_ & _ & _ & _ & _ & N6 & _).
893
+ assert (E : wrun (segI ++ segJ ++ segK ++ segL ++ segM) ww = wrun segM (wrun segL (wrun (segJ ++ segK) (wrun segI ww))))
894
+ by (rewrite !wrun_app; reflexivity).
895
+ rewrite E.
896
+ destruct (segI_run (A - 8) ww ltac:(lia) Hl) as (L1 & V1 & U1). cbv zeta in L1, V1, U1. fold segI in L1, V1, U1.
897
+ set (w1 := wrun segI ww) in *.
898
+ destruct (segJK_run w1 L1) as (L2 & C0 & Ct & U2). cbv zeta in L2, C0, Ct, U2.
899
+ set (w2 := wrun (segJ ++ segK) w1) in *.
900
+ destruct (segL_run (w - 1) w2 ltac:(lia) L2) as (L3 & V3 & U3). cbv zeta in L3, V3, U3. fold segL in L3, V3, U3.
901
+ set (w3 := wrun segL w2) in *.
902
+ destruct (segM_run w w3 ltac:(lia) L3) as (L4 & V4 & U4). cbv zeta in L4, V4, U4. fold segM in L4, V4, U4.
903
+ assert (Rin : forall t t', t < A -> t' < A -> t <> t' -> MBc (rin A) t <> MBc (rin A) t')
904
+ by (intros t t' Ht Ht' Htt E'; apply MB_inj in E' as [_ E']; [lia | exact Hri | exact Hri | lia | lia]).
905
+ assert (Rc : forall t t', t < A -> t' < A -> MBc (rin A) t <> MBc (ceot A) t')
906
+ by (intros t t' Ht Ht'; apply MB_ne; auto).
907
+ (* the cells the later parts read, over the earlier parts *)
908
+ assert (F12 : forall x, x <> m0 -> x <> m1 -> (forall t, 8 <= t < A -> x <> MBc (rin A) t)
909
+ -> (forall t, t < A -> x <> MBc (ceot A) t) -> wget w2 x = wget ww x).
910
+ { intros x X0 X1 Xr Xc. rewrite U2 by assumption. apply U1; [exact X0 | exact X1 | intros t Ht; apply Xr; lia]. }
911
+ assert (F3 : forall x, x <> m0 -> x <> m1 -> (forall t, 8 <= t < A -> x <> MBc (rin A) t)
912
+ -> (forall t, t < A -> x <> MBc (ceot A) t) -> (forall j, 1 <= j < w -> x <> cCAR j) -> wget w3 x = wget ww x).
913
+ { intros x X0 X1 Xr Xc Xj. rewrite U3 by (intros j Hj; apply Xj; lia). apply F12; assumption. }
914
+ assert (Hrin : forall t, t < A -> HO < MBc (rin A) t /\ MBc (rin A) t < DB A w nu lvs) by exact rin_cell.
915
+ assert (Hcet : forall t, t < A -> HO < MBc (ceot A) t /\ MBc (ceot A) t < DB A w nu lvs) by exact ceot_cell.
916
+ split; [exact L4|]. split; [|split; [|split; [|split]]].
917
+ - intros t Ht. destruct (Hrin t ltac:(lia)) as [T1 T2].
918
+ rewrite U4 by (try (intros i Hi); cells). rewrite U3 by (intros j Hj; cells).
919
+ rewrite U2 by (try (intros t' Ht'; apply Rc; lia); cells). apply V1. lia.
920
+ - destruct (Hcet 0 ltac:(lia)) as [T1 T2].
921
+ rewrite U4 by (try (intros i Hi); cells). rewrite U3 by (intros j Hj; cells). rewrite C0.
922
+ rewrite !U1 by (try (intros t Ht; first [apply not_eq_sym, Rc | destruct (Hrin t ltac:(lia))]); try lia; cells).
923
+ reflexivity.
924
+ - intros t Ht. destruct (Hcet t ltac:(lia)) as [T1 T2].
925
+ rewrite U4 by (try (intros i Hi); cells). rewrite U3 by (intros j Hj; cells). rewrite Ct by exact Ht.
926
+ rewrite !U1 by (try (intros t' Ht'; first [apply not_eq_sym, Rc | destruct (Hrin t' ltac:(lia))]); try lia; cells).
927
+ reflexivity.
928
+ - intros i Hi. rewrite V4 by exact Hi.
929
+ rewrite (F3 (CNT i)) by (try (intros t Ht; destruct (Hrin t ltac:(lia)) || destruct (Hcet t ltac:(lia))); try (intros j Hj); cells).
930
+ rewrite (V3 i) by lia.
931
+ assert (Eg : wget w2 cG = wget ww cG).
932
+ { apply F12; [cells | cells | intros t Ht; destruct (Hrin t ltac:(lia)); cells | intros t Ht; destruct (Hcet t Ht); cells]. }
933
+ rewrite Eg. f_equal. f_equal. apply forallb_ext_in'. intros k Hk. apply in_seq in Hk.
934
+ apply F12; [cells | cells | intros t Ht; destruct (Hrin t ltac:(lia)); cells | intros t Ht; destruct (Hcet t Ht); cells].
935
+ - intros x X0 X1 Xr Xc Xj Xi. rewrite U4 by assumption. apply F3; assumption.
936
+ Qed.
937
+
938
+ (* ---- the rewind on the registers and dest, and the request words cleared ----------------------------- *)
939
+ Theorem chunk4_run : forall ww, length ww = W ->
940
+ let rw := wget ww cRW in
941
+ let ww' := wrun (segO ++ segP ++ segQ) ww in
942
+ length ww' = W
943
+ /\ (forall i, i < w -> wget ww' (LIM w i) = (if rw then wget ww (CNT i) else wget ww (LIM w i))
944
+ /\ wget ww' (CNT i) = wget ww (CNT i) && negb rw)
945
+ /\ wget ww' (DEST w) = wget ww (DEST w) || rw
946
+ /\ (forall c t, (c = cwr A \/ c = crd A \/ c = crw A) -> t < A -> wget ww' (MBc c t) = false)
947
+ /\ (forall x, x <> m0 -> x <> m1 -> (forall i, i < w -> x <> LIM w i /\ x <> CNT i) -> x <> DEST w ->
948
+ (forall c t, (c = cwr A \/ c = crd A \/ c = crw A) -> t < A -> x <> MBc c t) -> wget ww' x = wget ww x).
949
+ Proof.
950
+ intros ww Hl. cbv zeta.
951
+ assert (E : wrun (segO ++ segP ++ segQ) ww = wrun segQ (wrun segP (wrun segO ww))) by (rewrite !wrun_app; reflexivity).
952
+ rewrite E.
953
+ destruct (segO_run w ww ltac:(lia) Hl) as (L1 & V1 & U1). cbv zeta in L1, V1, U1.
954
+ assert (EO : segO = concat (map Obody (seq 0 w))) by reflexivity. rewrite <- EO in L1, V1, U1.
955
+ set (w1 := wrun segO ww) in *.
956
+ assert (W2 : forall x, wget (wrun segP w1) x = if Nat.eqb x (DEST w) then wget w1 (DEST w) || wget w1 cRW else wget w1 x).
957
+ { intro x. unfold segP. rewrite wrun1. cbn [ao_of gOR]. rewrite wval_or, !wl_cell by cells.
958
+ apply wget_set; [cells | rewrite L1; cells]. }
959
+ assert (L2 : length (wrun segP w1) = W) by (rewrite length_wrun; exact L1).
960
+ set (w2 := wrun segP w1) in *.
961
+ destruct (segQ_run w2 L2) as (L3 & V3 & U3). cbv zeta in L3, V3, U3.
962
+ assert (Hreq : forall c t, (c = cwr A \/ c = crd A \/ c = crw A) -> t < A -> HO < MBc c t /\ MBc c t < DB A w nu lvs)
963
+ by exact req_word_cell.
964
+ assert (Rw1 : wget w1 cRW = wget ww cRW) by (apply U1; [cells | cells | intros i Hi; split; cells]).
965
+ split; [exact L3|]. split; [|split; [|split]].
966
+ - intros i Hi. rewrite !U3 by (intros c t Hc Ht; destruct (Hreq c t Hc Ht); cells).
967
+ rewrite !W2. rewrite (proj2 (Nat.eqb_neq (LIM w i) (DEST w))), (proj2 (Nat.eqb_neq (CNT i) (DEST w))) by cells.
968
+ apply V1. exact Hi.
969
+ - rewrite U3 by (intros c t Hc Ht; destruct (Hreq c t Hc Ht); cells). rewrite W2, Nat.eqb_refl, Rw1.
970
+ rewrite U1 by (try (intros i Hi; split); cells). reflexivity.
971
+ - exact V3.
972
+ - intros x X0 X1 Xi Xd Xc. rewrite U3 by exact Xc. rewrite W2, (proj2 (Nat.eqb_neq x (DEST w)) Xd).
973
+ apply U1; assumption.
974
+ Qed.
975
+
976
+ (* ---- the window records of the device read and write the window alone, above the requests ------------ *)
977
+ Ltac wg := first [ apply wrec_const; right; cells
978
+ | apply wrec_copy; unfold rd_ok; cbn [fst]; right; cells
979
+ | apply wrec_and; unfold rd_ok; cbn [fst]; right; cells
980
+ | apply wrec_or; unfold rd_ok; cbn [fst]; right; cells ].
981
+ Ltac fwg := repeat (apply Forall_cons; [wg|]); apply Forall_nil.
982
+
983
+ Lemma chunk1_wrec : Forall wrec (segA ++ segB ++ segC ++ segD).
984
+ Proof.
985
+ assert (Hw1 : forall j d, HO < d -> Forall wrec (word1 A w j d)).
986
+ { intros j d Hd. unfold word1. apply chain_wrec; [exact wrec_and | | exact Hd | exact Hd].
987
+ intros l [<-|Hl]; [cbn [fst]; right; cells|].
988
+ apply in_map_iff in Hl as (t & <- & Ht). apply in_seq in Ht. cbn [fst]. right. cells. }
989
+ unfold segA. rewrite !Forall_app. repeat split.
990
+ - apply Hw1. cells.
991
+ - apply Hw1. cells.
992
+ - apply Hw1. cells.
993
+ - unfold segB. apply Forall_concat, Forall_map, Forall_forall. intros i Hi. apply in_seq in Hi. fwg.
994
+ - unfold segC. apply chain_wrec; [exact wrec_and | | cells | cells].
995
+ intros l Hl. apply in_map_iff in Hl as (i & <- & Hi). apply in_seq in Hi. cbn [fst]. right. cells.
996
+ - unfold segD. fwg.
997
+ Qed.
998
+
999
+ Lemma chunk2_wrec : Forall wrec (segF ++ segG).
1000
+ Proof.
1001
+ rewrite Forall_app. split.
1002
+ - unfold segF. apply Forall_map, Forall_forall. intros t Ht. apply in_seq in Ht. wg.
1003
+ - unfold segG. fwg.
1004
+ Qed.
1005
+
1006
+ Lemma chunk3_wrec : Forall wrec (segI ++ segJ ++ segK ++ segL ++ segM).
1007
+ Proof.
1008
+ rewrite !Forall_app. repeat split.
1009
+ - unfold segI. apply Forall_concat, Forall_map, Forall_forall. intros t Ht. apply in_seq in Ht. unfold gMUX. fwg.
1010
+ - unfold segJ, gMUX. fwg.
1011
+ - unfold segK. apply Forall_map, Forall_forall. intros t Ht. apply in_seq in Ht. wg.
1012
+ - unfold segL. apply Forall_map, Forall_forall. intros i Hi. apply in_seq in Hi. unfold carry.
1013
+ destruct (Nat.eqb i 0); wg.
1014
+ - unfold segM. apply Forall_concat, Forall_map, Forall_forall. intros i Hi. apply in_seq in Hi. unfold gXOR, carry.
1015
+ destruct (Nat.eqb i 0); fwg.
1016
+ Qed.
1017
+
1018
+ Lemma chunk4_wrec : Forall wrec (segO ++ segP ++ segQ).
1019
+ Proof.
1020
+ rewrite !Forall_app. repeat split.
1021
+ - unfold segO. apply Forall_concat, Forall_map, Forall_forall. intros i Hi. apply in_seq in Hi. unfold gMUX. cbn [app]. fwg.
1022
+ - unfold segP. fwg.
1023
+ - unfold segQ. apply Forall_concat, Forall_map, Forall_forall. intros c _.
1024
+ apply Forall_map, Forall_forall. intros t Ht. apply in_seq in Ht. wg.
1025
+ Qed.
1026
+
1027
+ (* ---- the device on a view ------------------------------------------------------------------------------ *)
1028
+ (* the low byte of R_out, most significant bit first *)
1029
+ Definition outbits (ww : list bool) : list bool := map (fun k => wget ww (MBc (rout A) (7 - k))) (seq 0 8).
1030
+
1031
+ (* the cells the device writes *)
1032
+ Definition devw (x : nat) : Prop :=
1033
+ (DB A w nu lvs <= x < ncells A w nu lvs)
1034
+ \/ (exists i, i < w /\ (x = CNT i \/ x = LIM w i)) \/ x = DEST w
1035
+ \/ (exists c t, (c = cwr A \/ c = crd A \/ c = crw A \/ c = rout A \/ c = rin A \/ c = ceot A) /\ t < A /\ x = MBc c t).
1036
+
1037
+ Lemma ndevw : forall x, ~ devw x ->
1038
+ (x < DB A w nu lvs \/ ncells A w nu lvs <= x) /\ (forall i, i < w -> x <> CNT i /\ x <> LIM w i) /\ x <> DEST w
1039
+ /\ (forall c t, (c = cwr A \/ c = crd A \/ c = crw A \/ c = rout A \/ c = rin A \/ c = ceot A) -> t < A -> x <> MBc c t).
1040
+ Proof.
1041
+ intros x H. split; [|split; [|split]].
1042
+ - destruct (Nat.lt_ge_cases x (DB A w nu lvs)) as [H1|H1]; [left; exact H1|].
1043
+ destruct (Nat.lt_ge_cases x (ncells A w nu lvs)) as [H2|H2]; [|right; exact H2].
1044
+ exfalso. apply H. left. split; assumption.
1045
+ - intros i Hi. split.
1046
+ + intro E. apply H. right. left. exists i. split; [exact Hi | left; exact E].
1047
+ + intro E. apply H. right. left. exists i. split; [exact Hi | right; exact E].
1048
+ - intro E. apply H. right. right. left. exact E.
1049
+ - intros c t Hc Ht E. apply H. right. right. right. exists c, t. auto.
1050
+ Qed.
1051
+
1052
+ Ltac mbne := first
1053
+ [ apply MB_ne; first [assumption | lia | (pose proof SW8; unfold cwr, ceot, crw, crd, rin, rout; lia)]
1054
+ | let E := fresh "E" in intro E; apply MB_inj in E as [_ E];
1055
+ first [assumption | lia | (pose proof SW8; unfold cwr, ceot, crw, crd, rin, rout; lia)] ].
1056
+
1057
+ Lemma rout_cell : forall t, t < A -> HO < MBc (rout A) t /\ MBc (rout A) t < DB A w nu lvs.
1058
+ Proof.
1059
+ intros t Ht. pose proof io_lt as (_ & _ & _ & _ & _ & I6).
1060
+ pose proof (MB_range (rout A) t I6 Ht). pose proof (DB_gt (rout A) t I6 Ht). split; cells.
1061
+ Qed.
1062
+
1063
+ (* the window parts of the device as maps of views; the last also returns the read head on a rewind *)
1064
+ Definition dv1 (u : view) : view := mkV (wrun (segA ++ segB ++ segC ++ segD) (vw u)) (vr u) (va u) (vc u) (vho u).
1065
+ Definition dv3 (u : view) : view := mkV (wrun (segF ++ segG) (vw u)) (vr u) (va u) (vc u) (vho u).
1066
+ Definition dv5 (u : view) : view := mkV (wrun (segI ++ segJ ++ segK ++ segL ++ segM) (vw u)) (vr u) (va u) (vc u) (vho u).
1067
+ Definition dv6 (u : view) : view :=
1068
+ mkV (wrun (segO ++ segP ++ segQ) (vw u)) (if wget (vw u) cRW then mkT (td (vr u)) 0 else vr u) (va u) (vc u) (vho u).
1069
+
1070
+ (* the view v the device starts from, and the views u2 and u4 after the parts that move heads *)
1071
+ Section Parts.
1072
+ Variables (v u2 u4 : view).
1073
+ Hypotheses (Hq : reqclear (vw v)) (Hl : length (vw v) = W)
1074
+ (E2 : u2 = vrun Lb L (concat (map Ebody (seq 0 8))) (dv1 v))
1075
+ (E4 : u4 = vrun Lb L (concat (map Hbody (seq 0 8))) (dv3 u2)).
1076
+
1077
+ (* the requests, cnt = lim, the end of the recipe and where a write goes *)
1078
+ Lemma part1 : reqclear (vw (dv1 v)) /\ length (vw (dv1 v)) = W
1079
+ /\ wget (vw (dv1 v)) cWR = wrv (vw v) /\ wget (vw (dv1 v)) cRD = rdv (vw v) /\ wget (vw (dv1 v)) cRW = rwv (vw v)
1080
+ /\ wget (vw (dv1 v)) cEOT = eotv (vw v) /\ wget (vw (dv1 v)) cCA = cav (vw v) /\ wget (vw (dv1 v)) cCC = ccv (vw v)
1081
+ /\ (forall x, x < DB A w nu lvs \/ ncells A w nu lvs <= x -> wget (vw (dv1 v)) x = wget (vw v) x).
1082
+ Proof.
1083
+ destruct (chunk1_run (vw v) Hl) as (L1 & H1 & H2 & H3 & H4 & H5 & H6 & U1).
1084
+ exact (conj (wrun_reqclear _ _ chunk1_wrec Hq) (conj L1 (conj H1 (conj H2 (conj H3 (conj H4 (conj H5 (conj H6 U1)))))))).
1085
+ Qed.
1086
+
1087
+ (* the low byte of R_out under the arm or under the copy head *)
1088
+ Lemma part2 : reqclear (vw u2) /\ length (vw u2) = W
1089
+ /\ (forall x, x <> m0 -> x <> m1 -> wget (vw u2) x = wget (vw (dv1 v)) x)
1090
+ /\ vr u2 = vr v /\ va u2 = (if cav (vw v) then wseq Lb (outbits (vw v)) (va v) else va v)
1091
+ /\ vc u2 = (if ccv (vw v) then wseq L (outbits (vw v)) (vc v) else vc v) /\ vho u2 = vho v.
1092
+ Proof.
1093
+ rewrite E2.
1094
+ destruct part1 as (Q1 & L1 & _ & _ & _ & _ & CA1 & CC1 & U1).
1095
+ destruct (segE_run 8 (dv1 v) ltac:(lia) Q1 L1) as (Q2 & L2 & U2 & R2 & A2 & C2 & H2).
1096
+ rewrite CA1 in A2. rewrite CC1 in C2.
1097
+ assert (Eb : map (fun k' => wget (vw (dv1 v)) (MBc (rout A) (7 - k'))) (seq 0 8) = outbits (vw v)).
1098
+ { unfold outbits. apply map_ext_in. intros k Hk. apply in_seq in Hk. apply U1. left.
1099
+ destruct (rout_cell (7 - k) ltac:(lia)). lia. }
1100
+ rewrite Eb in A2, C2.
1101
+ exact (conj Q2 (conj L2 (conj U2 (conj R2 (conj A2 (conj C2 H2)))))).
1102
+ Qed.
1103
+
1104
+ (* R_out cleared on a write, and whether a byte is read *)
1105
+ Lemma part3 : reqclear (vw (dv3 u2)) /\ length (vw (dv3 u2)) = W
1106
+ /\ (forall t, t < A -> wget (vw (dv3 u2)) (MBc (rout A) t) = wget (vw v) (MBc (rout A) t) && negb (wrv (vw v)))
1107
+ /\ wget (vw (dv3 u2)) cG = gv (vw v) /\ wget (vw (dv3 u2)) cRD = rdv (vw v) /\ wget (vw (dv3 u2)) cEOT = eotv (vw v)
1108
+ /\ wget (vw (dv3 u2)) cRW = rwv (vw v)
1109
+ /\ (forall x, x < DB A w nu lvs \/ ncells A w nu lvs <= x -> (forall t, t < A -> x <> MBc (rout A) t) ->
1110
+ wget (vw (dv3 u2)) x = wget (vw v) x).
1111
+ Proof.
1112
+ destruct part1 as (_ & _ & WR1 & RD1 & RW1 & EOT1 & _ & _ & U1).
1113
+ destruct part2 as (Q2 & L2 & U2 & _).
1114
+ destruct (chunk2_run (vw u2) L2) as (L3 & R3 & G3 & U3).
1115
+ change (wrun (segF ++ segG) (vw u2)) with (vw (dv3 u2)) in L3, R3, G3, U3.
1116
+ assert (F2 : forall x, x < DB A w nu lvs \/ ncells A w nu lvs <= x -> wget (vw u2) x = wget (vw v) x).
1117
+ { intros x Hx. rewrite U2 by cells. apply U1. exact Hx. }
1118
+ assert (D3 : forall c, DB A w nu lvs <= c < ncells A w nu lvs -> c <> m0 -> c <> m1 -> c <> cG ->
1119
+ wget (vw (dv3 u2)) c = wget (vw (dv1 v)) c).
1120
+ { intros c Hc H0 H1 Hg. rewrite U3; [apply U2; assumption | exact Hg |].
1121
+ intros t Ht. destruct (rout_cell t Ht). lia. }
1122
+ refine (conj (wrun_reqclear _ _ chunk2_wrec Q2) (conj L3 (conj _ (conj _ (conj _ (conj _ (conj _ _))))))).
1123
+ - intros t Ht. destruct (rout_cell t Ht). rewrite R3 by exact Ht. rewrite F2 by (left; lia). rewrite U2 by cells.
1124
+ rewrite WR1. reflexivity.
1125
+ - rewrite G3, !U2 by cells. rewrite RD1, EOT1. reflexivity.
1126
+ - rewrite D3 by cells. exact RD1.
1127
+ - rewrite D3 by cells. exact EOT1.
1128
+ - rewrite D3 by cells. exact RW1.
1129
+ - intros x Hx Ht. rewrite U3 by (try exact Ht; cells). apply F2. exact Hx.
1130
+ Qed.
1131
+
1132
+ (* the byte under the read head into R_in *)
1133
+ Lemma part4 : reqclear (vw u4) /\ length (vw u4) = W
1134
+ /\ (forall t, t < 8 -> wget (vw u4) (MBc (rin A) t)
1135
+ = if gv (vw v) then nth (adv L (7 - t) (th (vr v))) (td (vr v)) false else wget (vw v) (MBc (rin A) t))
1136
+ /\ wget (vw u4) cG = gv (vw v) /\ wget (vw u4) cRD = rdv (vw v) /\ wget (vw u4) cEOT = eotv (vw v)
1137
+ /\ wget (vw u4) cRW = rwv (vw v)
1138
+ /\ (forall t, t < A -> wget (vw u4) (MBc (rout A) t) = wget (vw v) (MBc (rout A) t) && negb (wrv (vw v)))
1139
+ /\ (forall x, x < DB A w nu lvs \/ ncells A w nu lvs <= x -> (forall t, t < A -> x <> MBc (rout A) t) ->
1140
+ (forall i, i < 8 -> x <> MBc (rin A) (7 - i)) -> wget (vw u4) x = wget (vw v) x)
1141
+ /\ vr u4 = (if gv (vw v) then mkT (td (vr v)) (adv L 8 (th (vr v))) else vr v)
1142
+ /\ va u4 = va u2 /\ vc u4 = vc u2 /\ vho u4 = vho v.
1143
+ Proof.
1144
+ destruct part2 as (_ & _ & _ & R2 & _ & _ & H2).
1145
+ destruct part3 as (Q3 & L3 & RO3 & G3 & RD3 & EOT3 & RW3 & F3).
1146
+ rewrite E4.
1147
+ destruct (segH_run 8 (dv3 u2) ltac:(lia) Q3 L3) as (Q4 & L4 & V4 & U4 & R4 & A4 & C4 & H4).
1148
+ rewrite G3 in V4, R4. change (vr (dv3 u2)) with (vr u2) in V4, R4. rewrite R2 in V4, R4.
1149
+ assert (D4 : forall c, DB A w nu lvs <= c < ncells A w nu lvs -> c <> m0 -> c <> m1 ->
1150
+ wget (vw (vrun Lb L (concat (map Hbody (seq 0 8))) (dv3 u2))) c = wget (vw (dv3 u2)) c).
1151
+ { intros c Hc H0 H1. apply U4; [exact H0 | exact H1 |]. intros i Hi. destruct (rin_cell (7 - i) ltac:(lia)). lia. }
1152
+ refine (conj Q4 (conj L4 (conj _ (conj _ (conj _ (conj _ (conj _ (conj _ (conj _ (conj R4 (conj A4 (conj C4 _)))))))))))).
1153
+ - intros t Ht. pose proof (V4 (7 - t) ltac:(lia)) as V. replace (7 - (7 - t)) with t in V by lia. rewrite V.
1154
+ destruct (rin_cell t ltac:(lia)). rewrite F3 by (first [left; lia | intros t' Ht'; mbne]). reflexivity.
1155
+ - rewrite D4 by cells. exact G3.
1156
+ - rewrite D4 by cells. exact RD3.
1157
+ - rewrite D4 by cells. exact EOT3.
1158
+ - rewrite D4 by cells. exact RW3.
1159
+ - intros t Ht. destruct (rout_cell t Ht). rewrite U4 by (first [cells | intros i Hi; mbne]). apply RO3. exact Ht.
1160
+ - intros x Hx Ho Hr. rewrite U4 by (first [cells | exact Hr]). apply F3; assumption.
1161
+ - rewrite H4. exact H2.
1162
+ Qed.
1163
+
1164
+ (* the sign of R_in, c_eot, and the count *)
1165
+ Lemma part5 : reqclear (vw (dv5 u4)) /\ length (vw (dv5 u4)) = W
1166
+ /\ (forall t, t < A -> wget (vw (dv5 u4)) (MBc (rin A) t)
1167
+ = if gv (vw v) then nth (adv L (7 - t) (th (vr v))) (td (vr v)) false else wget (vw v) (MBc (rin A) t))
1168
+ /\ wget (vw (dv5 u4)) (MBc (ceot A) 0) = (if rdv (vw v) then eotv (vw v) else wget (vw v) (MBc (ceot A) 0))
1169
+ /\ (forall t, 1 <= t < A -> wget (vw (dv5 u4)) (MBc (ceot A) t) = wget (vw v) (MBc (ceot A) t) && negb (rdv (vw v)))
1170
+ /\ (forall i, i < w -> wget (vw (dv5 u4)) (CNT i) = cntv (vw v) i)
1171
+ /\ (forall t, t < A -> wget (vw (dv5 u4)) (MBc (rout A) t) = wget (vw v) (MBc (rout A) t) && negb (wrv (vw v)))
1172
+ /\ wget (vw (dv5 u4)) cRW = rwv (vw v)
1173
+ /\ (forall x, x < DB A w nu lvs \/ ncells A w nu lvs <= x -> (forall t, t < A -> x <> MBc (rout A) t) ->
1174
+ (forall t, t < A -> x <> MBc (rin A) t) -> (forall t, t < A -> x <> MBc (ceot A) t) ->
1175
+ (forall i, i < w -> x <> CNT i) -> wget (vw (dv5 u4)) x = wget (vw v) x).
1176
+ Proof.
1177
+ destruct part4 as (Q4 & L4 & V4 & G4 & RD4 & EOT4 & RW4 & RO4 & F4 & _).
1178
+ destruct (chunk3_run (vw u4) L4) as (L5 & I5 & E5 & T5 & C5 & U5).
1179
+ change (wrun (segI ++ segJ ++ segK ++ segL ++ segM) (vw u4)) with (vw (dv5 u4)) in L5, I5, E5, T5, C5, U5.
1180
+ refine (conj (wrun_reqclear _ _ chunk3_wrec Q4) (conj L5 (conj _ (conj _ (conj _ (conj _ (conj _ (conj _ _)))))))).
1181
+ - intros t Ht. destruct (rin_cell t Ht) as [T1 T2]. destruct (Nat.lt_ge_cases t 8) as [Hlo|Hhi].
1182
+ + rewrite U5 by (first [cells | intros t' Ht'; mbne | intros j Hj; cells | intros i Hi; cells]). apply V4. exact Hlo.
1183
+ + rewrite I5 by lia. rewrite G4. rewrite (V4 7) by lia.
1184
+ rewrite (F4 (MBc (rin A) t)) by (first [left; exact T2 | intros t' Ht'; mbne]).
1185
+ replace (7 - 7) with 0 by reflexivity. replace (7 - t) with 0 by lia. destruct (gv (vw v)); reflexivity.
1186
+ - destruct (ceot_cell 0 ltac:(lia)) as [T1 T2]. rewrite E5, RD4, EOT4.
1187
+ rewrite F4 by (first [left; exact T2 | intros t' Ht'; mbne]). reflexivity.
1188
+ - intros t Ht. destruct (ceot_cell t ltac:(lia)) as [T1 T2]. rewrite T5 by exact Ht. rewrite RD4.
1189
+ rewrite F4 by (first [left; exact T2 | intros t' Ht'; mbne]). reflexivity.
1190
+ - intros i Hi. rewrite C5 by exact Hi. unfold cntv, carryv. rewrite G4.
1191
+ rewrite (F4 (CNT i)) by (first [left; cells | intros t Ht; cells]). f_equal. f_equal.
1192
+ apply forallb_ext_in'. intros k Hk. apply in_seq in Hk. apply F4; [left; cells | intros t Ht; cells | intros t Ht; cells].
1193
+ - intros t Ht. destruct (rout_cell t Ht) as [T1 T2].
1194
+ rewrite U5 by (first [cells | intros t' Ht'; mbne | intros j Hj; cells | intros i Hi; cells]). apply RO4. exact Ht.
1195
+ - rewrite U5 by (first [cells | intros t Ht; destruct (rin_cell t ltac:(lia)); cells | intros t Ht; destruct (ceot_cell t Ht); cells
1196
+ | intros j Hj; cells | intros i Hi; cells]). exact RW4.
1197
+ - intros x Hx Ho Hr Hc Hi.
1198
+ rewrite U5 by (first [cells | intros t Ht; apply Hr; lia | exact Hc | intros j Hj; cells | exact Hi]).
1199
+ apply F4; [exact Hx | exact Ho | intros i' Hi'; apply Hr; lia].
1200
+ Qed.
1201
+
1202
+ (* the rewind, the registers, dest and the request words *)
1203
+ Lemma part6 : reqclear (vw (dv6 (dv5 u4))) /\ length (vw (dv6 (dv5 u4))) = W /\ vho (dv6 (dv5 u4)) = vho v
1204
+ /\ va (dv6 (dv5 u4)) = (if cav (vw v) then wseq Lb (outbits (vw v)) (va v) else va v)
1205
+ /\ vc (dv6 (dv5 u4)) = (if ccv (vw v) then wseq L (outbits (vw v)) (vc v) else vc v)
1206
+ /\ vr (dv6 (dv5 u4)) = mkT (td (vr v)) (if rwv (vw v) then 0 else if gv (vw v) then adv L 8 (th (vr v)) else th (vr v))
1207
+ /\ (forall t, t < A -> wget (vw (dv6 (dv5 u4))) (MBc (rout A) t) = wget (vw v) (MBc (rout A) t) && negb (wrv (vw v)))
1208
+ /\ (forall t, t < A -> wget (vw (dv6 (dv5 u4))) (MBc (rin A) t)
1209
+ = if gv (vw v) then nth (adv L (7 - t) (th (vr v))) (td (vr v)) false else wget (vw v) (MBc (rin A) t))
1210
+ /\ wget (vw (dv6 (dv5 u4))) (MBc (ceot A) 0) = (if rdv (vw v) then eotv (vw v) else wget (vw v) (MBc (ceot A) 0))
1211
+ /\ (forall t, 1 <= t < A -> wget (vw (dv6 (dv5 u4))) (MBc (ceot A) t) = wget (vw v) (MBc (ceot A) t) && negb (rdv (vw v)))
1212
+ /\ (forall c t, (c = cwr A \/ c = crd A \/ c = crw A) -> t < A -> wget (vw (dv6 (dv5 u4))) (MBc c t) = false)
1213
+ /\ (forall i, i < w -> wget (vw (dv6 (dv5 u4))) (CNT i) = cntv (vw v) i && negb (rwv (vw v))
1214
+ /\ wget (vw (dv6 (dv5 u4))) (LIM w i) = (if rwv (vw v) then cntv (vw v) i else wget (vw v) (LIM w i)))
1215
+ /\ wget (vw (dv6 (dv5 u4))) (DEST w) = destv (vw v) || rwv (vw v)
1216
+ /\ (forall x, ~ devw x -> wget (vw (dv6 (dv5 u4))) x = wget (vw v) x).
1217
+ Proof.
1218
+ destruct part2 as (_ & _ & _ & _ & A2 & C2 & _).
1219
+ destruct part4 as (_ & _ & _ & _ & _ & _ & _ & _ & _ & R4 & A4 & C4 & H4).
1220
+ destruct part5 as (Q5 & L5 & I5 & E5 & T5 & C5 & RO5 & RW5 & F5).
1221
+ destruct (chunk4_run (vw (dv5 u4)) L5) as (L7 & O7 & D7 & Z7 & U7).
1222
+ change (wrun (segO ++ segP ++ segQ) (vw (dv5 u4))) with (vw (dv6 (dv5 u4))) in L7, O7, D7, Z7, U7.
1223
+ rewrite RW5 in O7, D7.
1224
+ refine (conj (wrun_reqclear _ _ chunk4_wrec Q5) (conj L7 (conj H4 (conj _ (conj _ (conj _ (conj _ (conj _
1225
+ (conj _ (conj _ (conj Z7 (conj _ (conj _ _))))))))))))).
1226
+ - change (va (dv6 (dv5 u4))) with (va u4). rewrite A4. exact A2.
1227
+ - change (vc (dv6 (dv5 u4))) with (vc u4). rewrite C4. exact C2.
1228
+ - change (vr (dv6 (dv5 u4))) with (if wget (vw (dv5 u4)) cRW then mkT (td (vr u4)) 0 else vr u4).
1229
+ rewrite RW5, R4. destruct (rwv (vw v)), (gv (vw v)); destruct (vr v); reflexivity.
1230
+ - intros t Ht. destruct (rout_cell t Ht) as [T1 T2].
1231
+ rewrite U7 by (first [cells | intros i Hi; split; cells | intros c t' Hc Ht'; destruct Hc as [->|[->| ->]]; mbne]).
1232
+ apply RO5. exact Ht.
1233
+ - intros t Ht. destruct (rin_cell t Ht) as [T1 T2].
1234
+ rewrite U7 by (first [cells | intros i Hi; split; cells | intros c t' Hc Ht'; destruct Hc as [->|[->| ->]]; mbne]).
1235
+ apply I5. exact Ht.
1236
+ - destruct (ceot_cell 0 ltac:(lia)) as [T1 T2].
1237
+ rewrite U7 by (first [cells | intros i Hi; split; cells | intros c t' Hc Ht'; destruct Hc as [->|[->| ->]]; mbne]).
1238
+ exact E5.
1239
+ - intros t Ht. destruct (ceot_cell t ltac:(lia)) as [T1 T2].
1240
+ rewrite U7 by (first [cells | intros i Hi; split; cells | intros c t' Hc Ht'; destruct Hc as [->|[->| ->]]; mbne]).
1241
+ apply T5. exact Ht.
1242
+ - intros i Hi. destruct (O7 i Hi) as [OL OC]. rewrite OL, OC. rewrite C5 by exact Hi.
1243
+ rewrite (F5 (LIM w i)) by (first [left; cells | intros t Ht; cells | intros i' Hi'; cells]). split; reflexivity.
1244
+ - rewrite D7. rewrite F5 by (first [left; cells | intros t Ht; cells | intros i' Hi'; cells]). reflexivity.
1245
+ - intros x Hx. destruct (ndevw x Hx) as (X1 & X2 & X3 & X4). rewrite U7.
1246
+ + apply F5; [exact X1 | | | | intros i Hi; exact (proj1 (X2 i Hi))].
1247
+ * intros t Ht. apply X4; [right; right; right; left; reflexivity | exact Ht].
1248
+ * intros t Ht. apply X4; [right; right; right; right; left; reflexivity | exact Ht].
1249
+ * intros t Ht. apply X4; [right; right; right; right; right; reflexivity | exact Ht].
1250
+ + cells.
1251
+ + cells.
1252
+ + intros i Hi. destruct (X2 i Hi). split; assumption.
1253
+ + exact X3.
1254
+ + intros c t Hc Ht. apply X4; [destruct Hc as [->|[->| ->]]; auto | exact Ht].
1255
+ Qed.
1256
+
1257
+ End Parts.
1258
+
1259
+ (* the device is its parts in turn *)
1260
+ Lemma device_eq1 : forall v, reqclear (vw v) -> length (vw v) = W ->
1261
+ vrun Lb L (Stored.device A w nu lvs) v
1262
+ = vrun Lb L (segO ++ segP ++ segQ) (vrun Lb L segN (vrun Lb L (segI ++ segJ ++ segK ++ segL ++ segM)
1263
+ (vrun Lb L segH (vrun Lb L (segF ++ segG) (vrun Lb L (concat (map Ebody (seq 0 8))) (dv1 v)))))).
1264
+ Proof.
1265
+ intros v Hq Hl.
1266
+ assert (E : vrun Lb L (Stored.device A w nu lvs) v
1267
+ = vrun Lb L (segO ++ segP ++ segQ) (vrun Lb L segN (vrun Lb L (segI ++ segJ ++ segK ++ segL ++ segM)
1268
+ (vrun Lb L segH (vrun Lb L (segF ++ segG) (vrun Lb L segE (vrun Lb L (segA ++ segB ++ segC ++ segD) v)))))))
1269
+ by (rewrite device_split, !vrun_app; reflexivity).
1270
+ rewrite E. rewrite (vrun_wrun Lb L _ v chunk1_wrec Hq).
1271
+ change (mkV (wrun (segA ++ segB ++ segC ++ segD) (vw v)) (vr v) (va v) (vc v) (vho v)) with (dv1 v).
1272
+ reflexivity.
1273
+ Qed.
1274
+
1275
+ Lemma device_eq2 : forall v, reqclear (vw v) -> length (vw v) = W ->
1276
+ vrun Lb L (Stored.device A w nu lvs) v
1277
+ = vrun Lb L (segO ++ segP ++ segQ) (vrun Lb L segN (vrun Lb L (segI ++ segJ ++ segK ++ segL ++ segM)
1278
+ (vrun Lb L segH (dv3 (vrun Lb L (concat (map Ebody (seq 0 8))) (dv1 v)))))).
1279
+ Proof.
1280
+ intros v Hq Hl. rewrite (device_eq1 v Hq Hl).
1281
+ remember (vrun Lb L (concat (map Ebody (seq 0 8))) (dv1 v)) as X2 eqn:EX2.
1282
+ destruct (part2 v X2 Hq Hl EX2) as (Q2 & _).
1283
+ rewrite (vrun_wrun Lb L _ X2 chunk2_wrec Q2).
1284
+ change (mkV (wrun (segF ++ segG) (vw X2)) (vr X2) (va X2) (vc X2) (vho X2)) with (dv3 X2).
1285
+ reflexivity.
1286
+ Qed.
1287
+
1288
+ Lemma device_eq3 : forall v X2 X4, reqclear (vw v) -> length (vw v) = W ->
1289
+ X2 = vrun Lb L (concat (map Ebody (seq 0 8))) (dv1 v) -> X4 = vrun Lb L (concat (map Hbody (seq 0 8))) (dv3 X2) ->
1290
+ vrun Lb L (segO ++ segP ++ segQ) (vrun Lb L segN (vrun Lb L (segI ++ segJ ++ segK ++ segL ++ segM) X4)) = dv6 (dv5 X4).
1291
+ Proof.
1292
+ intros v X2 X4 Hq Hl EX2 EX4.
1293
+ destruct (part4 v X2 X4 Hq Hl EX2 EX4) as (Q4 & _).
1294
+ rewrite (vrun_wrun Lb L _ X4 chunk3_wrec Q4).
1295
+ change (mkV (wrun (segI ++ segJ ++ segK ++ segL ++ segM) (vw X4)) (vr X4) (va X4) (vc X4) (vho X4)) with (dv5 X4).
1296
+ destruct (part5 v X2 X4 Hq Hl EX2 EX4) as (Q5 & L5 & _).
1297
+ rewrite (segN_run (dv5 X4) Q5 L5).
1298
+ rewrite (vrun_wrun Lb L _ (mkV (vw (dv5 X4)) (if wget (vw (dv5 X4)) cRW then mkT (td (vr (dv5 X4))) 0 else vr (dv5 X4))
1299
+ (va (dv5 X4)) (vc (dv5 X4)) (vho (dv5 X4))) chunk4_wrec Q5).
1300
+ reflexivity.
1301
+ Qed.
1302
+
1303
+ Lemma device_eq : forall v, reqclear (vw v) -> length (vw v) = W ->
1304
+ vrun Lb L (Stored.device A w nu lvs) v
1305
+ = dv6 (dv5 (vrun Lb L (concat (map Hbody (seq 0 8))) (dv3 (vrun Lb L (concat (map Ebody (seq 0 8))) (dv1 v))))).
1306
+ Proof.
1307
+ intros v Hq Hl. rewrite (device_eq2 v Hq Hl).
1308
+ assert (EH : segH = concat (map Hbody (seq 0 8))) by reflexivity. rewrite EH.
1309
+ exact (device_eq3 v _ _ Hq Hl eq_refl eq_refl).
1310
+ Qed.
1311
+
1312
+ Theorem device_run : forall v, reqclear (vw v) -> length (vw v) = W ->
1313
+ let w0 := vw v in
1314
+ let v' := vrun Lb L (Stored.device A w nu lvs) v in
1315
+ reqclear (vw v') /\ length (vw v') = W /\ vho v' = vho v
1316
+ /\ va v' = (if cav w0 then wseq Lb (outbits w0) (va v) else va v)
1317
+ /\ vc v' = (if ccv w0 then wseq L (outbits w0) (vc v) else vc v)
1318
+ /\ vr v' = mkT (td (vr v)) (if rwv w0 then 0 else if gv w0 then adv L 8 (th (vr v)) else th (vr v))
1319
+ /\ (forall t, t < A -> wget (vw v') (MBc (rout A) t) = wget w0 (MBc (rout A) t) && negb (wrv w0))
1320
+ /\ (forall t, t < A -> wget (vw v') (MBc (rin A) t)
1321
+ = if gv w0 then nth (adv L (7 - t) (th (vr v))) (td (vr v)) false else wget w0 (MBc (rin A) t))
1322
+ /\ wget (vw v') (MBc (ceot A) 0) = (if rdv w0 then eotv w0 else wget w0 (MBc (ceot A) 0))
1323
+ /\ (forall t, 1 <= t < A -> wget (vw v') (MBc (ceot A) t) = wget w0 (MBc (ceot A) t) && negb (rdv w0))
1324
+ /\ (forall c t, (c = cwr A \/ c = crd A \/ c = crw A) -> t < A -> wget (vw v') (MBc c t) = false)
1325
+ /\ (forall i, i < w -> wget (vw v') (CNT i) = cntv w0 i && negb (rwv w0)
1326
+ /\ wget (vw v') (LIM w i) = (if rwv w0 then cntv w0 i else wget w0 (LIM w i)))
1327
+ /\ wget (vw v') (DEST w) = destv w0 || rwv w0
1328
+ /\ (forall x, ~ devw x -> wget (vw v') x = wget w0 x).
1329
+ Proof.
1330
+ intros v Hq Hl. cbv zeta. rewrite (device_eq v Hq Hl). exact (part6 v _ _ Hq Hl eq_refl eq_refl).
1331
+ Qed.
1332
+
1333
+ End Dev.
rocq/StoredImage.v ADDED
@@ -0,0 +1,151 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* The image of the stored host as a byte string, and recipes of byte strings by literal tokens (Lemma 3.2): the
2
+ records of S_{A,w} fill whole bytes, and every byte string has a recipe of at most twice its length plus one. *)
3
+ From Stdlib Require Import List Bool Arith ZArith Lia.
4
+ Import ListNotations.
5
+ From TH Require Import TwoHead Net Abstract Indep Run PhysSem View Stored Host Device Pstar StoredPass.
6
+
7
+ (* ---- bits and bytes --------------------------------------------------------------------------------------- *)
8
+ Lemma nat2bits_bits2nat : forall l, nat2bits (length l) (bits2nat l) = l.
9
+ Proof.
10
+ intro l. apply (nth_ext _ _ false false); [apply length_nat2bits|]. intros t Ht. rewrite length_nat2bits in Ht.
11
+ rewrite nth_nat2bits by exact Ht. apply testbit_bits2nat. exact Ht.
12
+ Qed.
13
+
14
+ (* q bytes from 8 q bits, the most significant bit of each byte first *)
15
+ Fixpoint bytes_of (q : nat) (l : list bool) : list nat :=
16
+ match q with O => [] | S q' => bits2nat (firstn 8 l) :: bytes_of q' (skipn 8 l) end.
17
+
18
+ Lemma bbits_bytes : forall q l, length l = 8 * q -> bbits (bytes_of q l) = l.
19
+ Proof.
20
+ induction q as [|q IH]; intros l Hl.
21
+ - destruct l; [reflexivity | cbn in Hl; lia].
22
+ - cbn [bytes_of]. unfold bbits. cbn [map concat]. fold (bbits (bytes_of q (skipn 8 l))).
23
+ rewrite IH by (rewrite length_skipn; lia).
24
+ assert (Hf : length (firstn 8 l) = 8) by (rewrite length_firstn; lia).
25
+ rewrite <- Hf at 1. rewrite nat2bits_bits2nat. apply firstn_skipn.
26
+ Qed.
27
+
28
+ Lemma bytes_lt : forall q l, Forall (fun x => x < 256) (bytes_of q l).
29
+ Proof.
30
+ induction q as [|q IH]; intro l; cbn [bytes_of]; constructor; [|apply IH].
31
+ pose proof (bits2nat_lt (firstn 8 l)) as H. rewrite length_firstn in H.
32
+ assert (Hp : 2 ^ Nat.min 8 (length l) <= 2 ^ 8) by (apply Nat.pow_le_mono_r; lia).
33
+ change (2 ^ 8) with 256 in Hp. lia.
34
+ Qed.
35
+
36
+ Lemma length_bytes : forall q l, length (bytes_of q l) = q.
37
+ Proof. induction q as [|q IH]; intro l; cbn [bytes_of length]; [reflexivity | rewrite IH; reflexivity]. Qed.
38
+
39
+ (* ---- the image fills whole bytes --------------------------------------------------------------------------- *)
40
+ Lemma padn_spec : forall al len, (recw al * (len + 4 + padn al len)) mod 8 = 0.
41
+ Proof.
42
+ intros al len. unfold padn.
43
+ destruct (find (fun p => Nat.eqb ((recw al * (len + 4 + p)) mod 8) 0) (seq 0 8)) as [p|] eqn:E.
44
+ - apply find_some in E as [_ E]. apply Nat.eqb_eq in E. exact E.
45
+ - exfalso. pose proof (Nat.mod_upper_bound (len + 4) 8 ltac:(lia)) as Hr.
46
+ pose proof (Nat.div_mod_eq (len + 4) 8) as Hq.
47
+ set (r := (len + 4) mod 8) in *. set (q := (len + 4) / 8) in *.
48
+ set (p := (8 - r) mod 8).
49
+ assert (Hp8 : (len + 4 + p) mod 8 = 0).
50
+ { destruct (Nat.eq_dec r 0) as [E0|E0].
51
+ - unfold p. rewrite E0, Nat.sub_0_r, Nat.Div0.mod_same, Nat.add_0_r. fold r. exact E0.
52
+ - assert (Ep : p = 8 - r) by (unfold p; apply Nat.mod_small; lia). rewrite Ep.
53
+ replace (len + 4 + (8 - r)) with ((q + 1) * 8) by lia. apply Nat.Div0.mod_mul. }
54
+ assert (Hp : In p (seq 0 8)) by (apply in_seq; pose proof (Nat.mod_upper_bound (8 - r) 8 ltac:(lia)); unfold p; lia).
55
+ pose proof (find_none _ _ E p Hp) as F. cbv beta in F. apply Nat.eqb_neq in F. apply F.
56
+ rewrite Nat.Div0.mul_mod, Hp8, Nat.mul_0_r. reflexivity.
57
+ Qed.
58
+
59
+ Lemma image_whole : forall A w, (recw (alS A w) * length (stored A w)) mod 8 = 0.
60
+ Proof.
61
+ intros A w. rewrite (stored_split A w), !length_app, repeat_length. unfold handover. cbn [length].
62
+ rewrite !Nat.add_assoc.
63
+ set (len := length (startup A w (image A (progPstar A)))
64
+ + length (step_go A w (length (host_units A)) 0 (host_units A)
65
+ (next_tbl (nH A) (length (host_units A)) (host_next A)))
66
+ + length (Stored.device A w (length (host_units A)) (levels (host_units A)))).
67
+ pose proof (padn_spec (alS A w) len) as H.
68
+ replace (len + padn (alS A w) len + 4) with (len + 4 + padn (alS A w) len) by lia. exact H.
69
+ Qed.
70
+
71
+ (* the image of S_{A,w} as bytes *)
72
+ Definition image_bytes (A w : nat) : list nat :=
73
+ bytes_of (recw (alS A w) * length (stored A w) / 8) (encA (alS A w) (stored A w)).
74
+
75
+ Lemma bbits_image : forall A w, bbits (image_bytes A w) = encA (alS A w) (stored A w).
76
+ Proof.
77
+ intros A w. unfold image_bytes. apply bbits_bytes. rewrite length_encA.
78
+ pose proof (image_whole A w) as H. pose proof (Nat.div_mod_eq (recw (alS A w) * length (stored A w)) 8). lia.
79
+ Qed.
80
+
81
+ Lemma image_bytes_lt : forall A w, Forall (fun x => x < 256) (image_bytes A w).
82
+ Proof. intros A w. apply bytes_lt. Qed.
83
+
84
+ Lemma length_image_bytes : forall A w, length (image_bytes A w) <= recw (alS A w) * length (stored A w).
85
+ Proof. intros A w. unfold image_bytes. rewrite length_bytes. apply Nat.Div0.div_le_upper_bound. lia. Qed.
86
+
87
+ (* ---- recipes of literal tokens: Lemma 3.2 ------------------------------------------------------------------- *)
88
+ Fixpoint chunks (fuel : nat) (f : list nat) : list (list nat) :=
89
+ match fuel with
90
+ | O => []
91
+ | S k => match f with [] => [] | _ :: _ => firstn 127 f :: chunks k (skipn 127 f) end
92
+ end.
93
+
94
+ Lemma chunks_concat : forall fuel f, length f <= 127 * fuel -> concat (chunks fuel f) = f.
95
+ Proof.
96
+ induction fuel as [|k IH]; intros f Hf; [destruct f; [reflexivity | cbn in Hf; lia]|].
97
+ destruct f as [|x f']; [reflexivity|]. cbn [chunks concat]. rewrite IH by (rewrite length_skipn; cbn [length] in *; lia).
98
+ apply firstn_skipn.
99
+ Qed.
100
+
101
+ Lemma chunks_ok : forall fuel f c, In c (chunks fuel f) -> 1 <= length c <= 127 /\ (forall x, In x c -> In x f).
102
+ Proof.
103
+ induction fuel as [|k IH]; intros f c Hc; [destruct Hc|].
104
+ destruct f as [|x f']; [destruct Hc|]. cbn [chunks In] in Hc. destruct Hc as [<-|Hc].
105
+ - rewrite length_firstn. cbn [length]. split; [lia|]. intros y Hy.
106
+ rewrite <- (firstn_skipn 127 (x :: f')). apply in_or_app. left. exact Hy.
107
+ - destruct (IH _ c Hc) as [Hl Hi]. split; [exact Hl|]. intros y Hy.
108
+ rewrite <- (firstn_skipn 127 (x :: f')). apply in_or_app. right. apply Hi. exact Hy.
109
+ Qed.
110
+
111
+ Lemma length_concat_chunks : forall fuel f, length (chunks fuel f) <= length (concat (chunks fuel f)).
112
+ Proof.
113
+ induction fuel as [|k IH]; intro f; [reflexivity|]. destruct f as [|x f']; [reflexivity|].
114
+ cbn [chunks concat length]. rewrite length_app, length_firstn. cbn [length]. specialize (IH (skipn 127 (x :: f'))). lia.
115
+ Qed.
116
+
117
+ Definition lits (f : list nat) : list token := map (fun c => Lit (map nu c)) (chunks (length f) f).
118
+
119
+ Lemma nu_nu : forall b, b < 256 -> nu (nu b) = b.
120
+ Proof.
121
+ intros b Hb. unfold nu. destruct (Nat.eq_dec b 0) as [->|E]; [reflexivity|].
122
+ rewrite (Nat.mod_small (256 - b)) by lia. rewrite Nat.mod_small by lia. lia.
123
+ Qed.
124
+
125
+ Lemma nu_lt : forall b, nu b < 256.
126
+ Proof. intro b. unfold nu. apply Nat.mod_upper_bound. lia. Qed.
127
+
128
+ Lemma lits_ok : forall f, Forall tok_ok (lits f).
129
+ Proof.
130
+ intro f. unfold lits. apply Forall_map, Forall_forall. intros c Hc. destruct (chunks_ok _ _ _ Hc) as [Hl _].
131
+ cbn [tok_ok]. rewrite length_map. split; [exact Hl|]. apply Forall_map, Forall_forall. intros x _. apply nu_lt.
132
+ Qed.
133
+
134
+ Lemma delta_lits : forall f, Forall (fun x => x < 256) f -> delta (lits f) = f.
135
+ Proof.
136
+ intros f Hf. unfold delta, lits. rewrite map_map. cbn [dec].
137
+ transitivity (concat (chunks (length f) f)); [|apply chunks_concat; lia].
138
+ f_equal. rewrite <- (map_id (chunks (length f) f)) at 2. apply map_ext_in. intros c Hc.
139
+ rewrite map_map. rewrite <- (map_id c) at 2. apply map_ext_in. intros x Hx. apply nu_nu.
140
+ rewrite Forall_forall in Hf. apply Hf. exact (proj2 (chunks_ok _ _ _ Hc) x Hx).
141
+ Qed.
142
+
143
+ Lemma length_recipe_lits : forall f, length (recipe (lits f)) <= 2 * length f + 1.
144
+ Proof.
145
+ intro f. unfold recipe, lits. rewrite length_app. cbn [length].
146
+ assert (E : length (concat (map enc (map (fun c => Lit (map nu c)) (chunks (length f) f))))
147
+ = length (chunks (length f) f) + length (concat (chunks (length f) f))).
148
+ { generalize (chunks (length f) f). induction l as [|c l IH]; [reflexivity|].
149
+ cbn [map concat enc]. rewrite !length_app. cbn [length]. rewrite length_map, IH. lia. }
150
+ rewrite E. pose proof (length_concat_chunks (length f) f) as H. rewrite chunks_concat in * by lia. lia.
151
+ Qed.
rocq/StoredMain.v ADDED
@@ -0,0 +1,320 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* Theorem 8.7 for the stored host S_{A,w}, every A >= 8: run on a recipe of its own image it rebuilds itself in
2
+ the next bank and copies the recipe onto the next tape in every generation, the copies accumulate until every
3
+ bank holds one, and from the K-th generation on the state of the ring machine, and of the network, repeats
4
+ every K generations. *)
5
+ From Stdlib Require Import List Bool Arith ZArith Lia.
6
+ Import ListNotations.
7
+ From TH Require Import TwoHead Net Abstract Indep Run PhysSem PhysMain View Stored WinRun ViewOps Host HostSem
8
+ Device Pstar StoredStep StoredBoot StoredPass StoredRun StoredWbr.
9
+
10
+ Section Ring.
11
+ Variables (A w K S0 L : nat) (ks : list token).
12
+ Hypotheses (HA : 8 <= A) (Hw : 1 <= w) (HK : 2 <= K) (HS : length (stored A w) <= S0) (HL : 1 <= L)
13
+ (Hks : Forall tok_ok ks) (Ht1 : 8 * length (recipe ks) <= L) (Ht2 : length (recipe ks) < 2 ^ w)
14
+ (Hd : bbits (delta ks) = encA (alS A w) (stored A w)).
15
+
16
+ Local Notation al := (alS A w).
17
+ Local Notation rs := (stored A w).
18
+ Local Notation G := (length (stored A w)).
19
+ Local Notation Lb := (S0 * recw (alS A w)).
20
+ Local Notation tau := (recipe ks).
21
+
22
+ (* a generation, the tape that holds the recipe, the cells a pass reads or writes, and the other cells *)
23
+ Definition T : nat := (NN ks - 1) * S0 + G.
24
+ Definition dz : list bool := bbits tau ++ repeat false (L - 8 * length tau).
25
+ Definition D1 (c : nat) : Prop := D0 A w c \/ wrt rs c.
26
+ Definition outside (c : nat) : Prop := c <= CPY \/ ~ D1 c.
27
+
28
+ (* a state from which a generation starts: Theorem 8.6's hypothesis *)
29
+ Definition start (s : st) : Prop := ready A w K S0 L ks s.
30
+
31
+ Lemma Hd8 : 8 * length (delta ks) <= Lb.
32
+ Proof. rewrite <- length_bbits, Hd, length_encA. nia. Qed.
33
+
34
+ Lemma new_img : bbits (delta ks) ++ repeat false (Lb - 8 * length (delta ks)) = img A w S0.
35
+ Proof. unfold img. rewrite <- length_bbits, Hd, length_encA. do 2 f_equal. rewrite Nat.mul_sub_distr_r. lia. Qed.
36
+
37
+ (* ---- two runs of a generation agree on the cells a pass reads or writes ------------------------------------- *)
38
+ Lemma D1_req : forall c, AR <= c <= HO -> D1 c.
39
+ Proof. intros c Hc. left. exact (req_D0 A w HA Hw c Hc). Qed.
40
+
41
+ Lemma wbr_D1 : wbr D1 rs.
42
+ Proof. apply (wbr_mono _ (D0 A w)); [intros c Hc; left; exact Hc | exact (wbr_stored A w HA Hw)]. Qed.
43
+
44
+ Lemma pass_agree : forall v1 v2, vagree D1 v1 v2 -> vagree D1 (vrun Lb L rs v1) (vrun Lb L rs v2).
45
+ Proof.
46
+ intros v1 v2 H. refine (vagree_mono _ _ _ _ _ (vrun_agree Lb L rs D1 v1 v2 D1_req wbr_D1 H)).
47
+ intros c Hc. left. exact Hc.
48
+ Qed.
49
+
50
+ (* the first pass loads the same state into every window with booted clear *)
51
+ Lemma first_agree : forall v1 v2, reqclear (vw v1) -> reqclear (vw v2) -> length (vw v1) = 2 ^ al ->
52
+ length (vw v2) = 2 ^ al -> wget (vw v1) BOOT = false -> wget (vw v2) BOOT = false -> vho v1 = vho v2 ->
53
+ td (vr v1) = td (vr v2) -> vagree D1 (vrun Lb L rs v1) (vrun Lb L rs v2).
54
+ Proof.
55
+ intros v1 v2 Q1 Q2 L1 L2 B1 B2 Hh Ht. rewrite (stored_rest A w), !vrun_app.
56
+ pose proof (startup_run A w (2 ^ al) Lb L (image A (progPstar A)) ltac:(lia) (length_image A) (HWs A w HA Hw)
57
+ v1 Q1 L1) as U1.
58
+ pose proof (startup_run A w (2 ^ al) Lb L (image A (progPstar A)) ltac:(lia) (length_image A) (HWs A w HA Hw)
59
+ v2 Q2 L2) as U2.
60
+ cbv zeta in U1, U2.
61
+ destruct U1 as (Q1' & L1' & BB1 & S1 & R1 & E1 & _ & VR1 & VA1 & VC1 & VH1).
62
+ destruct U2 as (Q2' & L2' & BB2 & S2 & R2 & E2 & _ & VR2 & VA2 & VC2 & VH2).
63
+ rewrite B1 in S1, R1, E1, VR1, VA1, VC1. rewrite B2 in S2, R2, E2, VR2, VA2, VC2.
64
+ set (u1 := vrun Lb L (startup A w (image A (progPstar A))) v1) in *.
65
+ set (u2 := vrun Lb L (startup A w (image A (progPstar A))) v2) in *.
66
+ assert (H0 : vagree (D0 A w) u1 u2).
67
+ { refine (conj _ (conj _ (conj _ (conj _ (conj _ _))))).
68
+ - rewrite VR1, VR2, Ht. reflexivity.
69
+ - rewrite VA1, VA2. reflexivity.
70
+ - rewrite VC1, VC2. reflexivity.
71
+ - rewrite VH1, VH2. exact Hh.
72
+ - rewrite L1', L2'. reflexivity.
73
+ - intros c Hc Hd0. unfold D0 in Hd0.
74
+ destruct (Nat.le_gt_cases c HO) as [H1|H1].
75
+ { rewrite (Q1' c), (Q2' c) by (unfold AR, CPY in *; lia). reflexivity. }
76
+ destruct (Nat.eq_dec c BOOT) as [->|H2]; [rewrite BB1, BB2; reflexivity|].
77
+ destruct (Nat.lt_ge_cases c (14 + w)) as [H3|H3].
78
+ { replace c with (CNT (c - 14)) by (unfold CNT, BOOT, HO in *; lia).
79
+ rewrite (proj1 (R1 (c - 14) ltac:(unfold BOOT, HO in *; lia))),
80
+ (proj1 (R2 (c - 14) ltac:(unfold BOOT, HO in *; lia))), !andb_false_r. reflexivity. }
81
+ destruct (Nat.eq_dec c (14 + w)) as [->|H4].
82
+ { change (14 + w) with (DEST w). rewrite E1, E2, !andb_false_r. reflexivity. }
83
+ destruct (Nat.lt_ge_cases c (15 + 2 * w)) as [H5|H5].
84
+ { replace c with (LIM w (c - 15 - w)) by (unfold LIM; lia).
85
+ rewrite (proj2 (R1 (c - 15 - w) ltac:(lia))), (proj2 (R2 (c - 15 - w) ltac:(lia))), !andb_false_r.
86
+ reflexivity. }
87
+ unfold ST in Hd0. replace c with (ST w (c - 15 - 2 * w)) by (unfold ST; lia).
88
+ rewrite (S1 (c - 15 - 2 * w) ltac:(lia)), (S2 (c - 15 - 2 * w) ltac:(lia)). reflexivity. }
89
+ pose proof (vrun_agree Lb L (rest A w) (D0 A w) u1 u2 (req_D0 A w HA Hw) (wbr_rest A w HA Hw) H0) as H1.
90
+ refine (vagree_mono _ _ _ _ _ H1). intros c [Hc|Hc]; [left; exact Hc|].
91
+ rewrite (stored_rest A w) in Hc. unfold wrt in Hc. rewrite map_app in Hc. apply in_app_or in Hc as [Hc|Hc].
92
+ - left. exact (wrt_startup A w HA Hw c Hc).
93
+ - right. exact Hc.
94
+ Qed.
95
+
96
+ Lemma vpass_agree : forall n v1 v2, 1 <= n -> reqclear (vw v1) -> reqclear (vw v2) -> length (vw v1) = 2 ^ al ->
97
+ length (vw v2) = 2 ^ al -> wget (vw v1) BOOT = false -> wget (vw v2) BOOT = false -> vho v1 = vho v2 ->
98
+ td (vr v1) = td (vr v2) -> vagree D1 (vpass A w S0 L n v1) (vpass A w S0 L n v2).
99
+ Proof.
100
+ induction n as [|n IH]; intros v1 v2 Hn Q1 Q2 L1 L2 B1 B2 Hh Ht; [lia|]. cbn [vpass].
101
+ destruct n as [|n]; [apply first_agree; assumption|].
102
+ apply pass_agree. apply IH; [lia | assumption..].
103
+ Qed.
104
+
105
+ (* the cells outside D1 keep their values *)
106
+ Lemma vpass_frame : forall n v c, outside c -> wget (vw (vpass A w S0 L n v)) c = wget (vw v) c.
107
+ Proof.
108
+ induction n as [|n IH]; intros v c Hc; [reflexivity|]. cbn [vpass]. rewrite vrun_frame; [apply IH; exact Hc|].
109
+ destruct Hc as [Hc|Hc]; [left; exact Hc | right; split].
110
+ - assert (H0 : ~ D0 A w c) by (intro E; apply Hc; left; exact E). unfold D0, ST in H0. unfold HO. lia.
111
+ - intro E. apply Hc. right. exact E.
112
+ Qed.
113
+
114
+ (* ---- one generation --------------------------------------------------------------------------------------- *)
115
+ Lemma gen : forall s, start s ->
116
+ let s' := itern al K S0 L T s in
117
+ start s' /\ kap s' = succ_mod K (kap s)
118
+ /\ nth (succ_mod K (kap s)) (banks s') bank0 = mkB (img A w S0) 0 0
119
+ /\ nth (succ_mod K (kap s)) (tapes s') tape0 = mkT dz 0
120
+ /\ nth (kap s) (banks s') bank0 = mkB (img A w S0) (G mod S0) (bj (nth (kap s) (banks s) bank0))
121
+ /\ nth (kap s) (tapes s') tape0 = mkT dz ((8 * length tau) mod L)
122
+ /\ (forall x, x < K -> x <> kap s -> x <> succ_mod K (kap s) ->
123
+ nth x (banks s') bank0 = nth x (banks s) bank0 /\ nth x (tapes s') tape0 = nth x (tapes s) tape0)
124
+ /\ (forall c, outside c -> wget (win s') c = wget (win s) c)
125
+ /\ win s' = vw (vpass A w S0 L (NN ks) (view0 al K s)).
126
+ Proof.
127
+ intros s Hs s'. pose proof Hs as (Hf & Hb & Hsl & Hq & Hboot & Htd).
128
+ pose proof (stored_construct A w K S0 L ks HA Hw HK HS HL Hks Ht1 Ht2 Hd8 s Hs) as SC. cbv zeta in SC.
129
+ change (itern al K S0 L ((NN ks - 1) * S0 + G) s) with s' in SC.
130
+ destruct SC as (Hf' & Hk' & HI & HC & HA' & HR & Hq' & Hb' & Hw' & Ho).
131
+ rewrite new_img in HI.
132
+ refine (conj _ (conj Hk' (conj HI (conj HC (conj HA' (conj _ (conj Ho (conj _ Hw')))))))).
133
+ - unfold start, ready. rewrite Hk', HI, HC. cbn [bq bs td].
134
+ exact (conj Hf' (conj eq_refl (conj eq_refl (conj Hq' (conj Hb' eq_refl))))).
135
+ - rewrite HR, Htd. reflexivity.
136
+ - intros c Hc. rewrite Hw'. rewrite vpass_frame by exact Hc. reflexivity.
137
+ Qed.
138
+
139
+ (* the window after a generation depends only on the cells outside D1 of the window it started from *)
140
+ Lemma gen_window : forall s1 s2, start s1 -> start s2 -> (forall c, outside c -> wget (win s1) c = wget (win s2) c) ->
141
+ win (itern al K S0 L T s1) = win (itern al K S0 L T s2).
142
+ Proof.
143
+ intros s1 s2 H1 H2 Ho.
144
+ pose proof (gen s1 H1) as G1. pose proof (gen s2 H2) as G2. cbv zeta in G1, G2.
145
+ destruct G1 as (((Hl1' & _) & _) & _ & _ & _ & _ & _ & _ & Fx1 & W1).
146
+ destruct G2 as (((Hl2' & _) & _) & _ & _ & _ & _ & _ & _ & Fx2 & W2).
147
+ destruct H1 as ((Hl1 & _) & _ & _ & Q1 & B1 & T1). destruct H2 as ((Hl2 & _) & _ & _ & Q2 & B2 & T2).
148
+ assert (Ag : vagree D1 (vpass A w S0 L (NN ks) (view0 al K s1)) (vpass A w S0 L (NN ks) (view0 al K s2))).
149
+ { apply vpass_agree; [unfold NN; lia | exact Q1 | exact Q2 | exact Hl1 | exact Hl2 | exact B1 | exact B2
150
+ | reflexivity | cbn [view0 vr]; rewrite T1, T2; reflexivity]. }
151
+ destruct Ag as (_ & _ & _ & _ & _ & Ag).
152
+ apply (nth_ext _ _ false false); [rewrite Hl1', Hl2'; reflexivity|]. intros c _.
153
+ change (wget (win (itern al K S0 L T s1)) c = wget (win (itern al K S0 L T s2)) c).
154
+ assert (Out : outside c -> wget (win (itern al K S0 L T s1)) c = wget (win (itern al K S0 L T s2)) c)
155
+ by (intro Hc; rewrite (Fx1 c Hc), (Fx2 c Hc); apply Ho; exact Hc).
156
+ destruct (Nat.le_gt_cases c CPY) as [Hc|Hc]; [apply Out; left; exact Hc|].
157
+ assert (In1 : D1 c -> wget (win (itern al K S0 L T s1)) c = wget (win (itern al K S0 L T s2)) c)
158
+ by (intro Hd1; rewrite W1, W2; exact (Ag c Hc Hd1)).
159
+ destruct (Nat.lt_ge_cases c (ST w (nH A))) as [Hd0|Hd0]; [apply In1; left; exact Hd0|].
160
+ destruct (in_dec Nat.eq_dec c (map ao_of rs)) as [Hr|Hr]; [apply In1; right; exact Hr|].
161
+ apply Out. right. intros [E|E]; [unfold D0 in E; lia | exact (Hr E)].
162
+ Qed.
163
+
164
+ (* ---- generations since a bank was active ------------------------------------------------------------------- *)
165
+ Definition ago (k x : nat) : nat := if x <=? k then k - x else k + K - x.
166
+
167
+ Lemma ago_zero : forall k x, k < K -> x < K -> ago k x = 0 -> x = k.
168
+ Proof. intros k x Hk Hx. unfold ago. destruct (Nat.leb_spec x k); lia. Qed.
169
+
170
+ Lemma ago_self : forall k, ago k k = 0.
171
+ Proof. intro k. unfold ago. rewrite Nat.leb_refl. lia. Qed.
172
+
173
+ Lemma ago_lt : forall k x, k < K -> x < K -> ago k x < K.
174
+ Proof. intros k x Hk Hx. unfold ago. destruct (Nat.leb_spec x k); lia. Qed.
175
+
176
+ Lemma ago_succ : forall k x, k < K -> x < K ->
177
+ ago (succ_mod K k) x = if Nat.eqb x (succ_mod K k) then 0 else S (ago k x).
178
+ Proof.
179
+ intros k x Hk Hx. unfold ago, succ_mod.
180
+ destruct (Nat.eqb_spec (S k) K) as [E|E].
181
+ - destruct (Nat.eqb_spec x 0) as [->|E0]; [reflexivity|].
182
+ destruct (Nat.leb_spec x 0), (Nat.leb_spec x k); lia.
183
+ - destruct (Nat.eqb_spec x (S k)) as [->|E1]; [rewrite Nat.leb_refl; lia|].
184
+ destruct (Nat.leb_spec x (S k)), (Nat.leb_spec x k); lia.
185
+ Qed.
186
+
187
+ Lemma succ_plus : forall k0 g, succ_mod K ((k0 + g) mod K) = (k0 + S g) mod K.
188
+ Proof. intros k0 g. rewrite succ_mod_mod by lia. f_equal. lia. Qed.
189
+
190
+ Lemma kap_lt : forall s, start s -> kap s < K.
191
+ Proof. intros s ((_ & H & _) & _). exact H. Qed.
192
+
193
+ (* ---- the state after g generations -------------------------------------------------------------------------- *)
194
+ (* After g >= 1 generations from x0: a start state again; the bank active for the last time a generations ago
195
+ holds the image, at slot G mod S0 if a > 0, and the tape read then the recipe; the banks and tapes not yet
196
+ reached are those of x0; the cells outside D1 are those of x0, and the window is the one after the first
197
+ generation. *)
198
+ Definition after (x0 : st) (g : nat) (s : st) : Prop :=
199
+ start s /\ kap s = (kap x0 + g) mod K
200
+ /\ (forall c, outside c -> wget (win s) c = wget (win x0) c)
201
+ /\ win s = win (itern al K S0 L T x0)
202
+ /\ (forall x, x < K ->
203
+ (ago (kap s) x = 0 -> nth x (banks s) bank0 = mkB (img A w S0) 0 0 /\ nth x (tapes s) tape0 = mkT dz 0)
204
+ /\ (0 < ago (kap s) x < g -> nth x (banks s) bank0 = mkB (img A w S0) (G mod S0) 0
205
+ /\ nth x (tapes s) tape0 = mkT dz ((8 * length tau) mod L))
206
+ /\ (ago (kap s) x = g -> nth x (banks s) bank0 = mkB (img A w S0) (G mod S0) (bj (nth (kap x0) (banks x0) bank0))
207
+ /\ nth x (tapes s) tape0 = mkT dz ((8 * length tau) mod L))
208
+ /\ (g < ago (kap s) x -> nth x (banks s) bank0 = nth x (banks x0) bank0
209
+ /\ nth x (tapes s) tape0 = nth x (tapes x0) tape0)).
210
+
211
+ Lemma after_1 : forall x0, start x0 -> after x0 1 (itern al K S0 L T x0).
212
+ Proof.
213
+ intros x0 Hs. pose proof (gen x0 Hs) as G0. cbv zeta in G0.
214
+ destruct G0 as (Hs' & Hk & HI & HC & HA' & HR & Ho & Hfx & _).
215
+ pose proof (kap_lt x0 Hs) as Hk0.
216
+ set (s1 := itern al K S0 L T x0) in *.
217
+ refine (conj Hs' (conj _ (conj Hfx (conj eq_refl _)))).
218
+ - rewrite Hk, <- (Nat.mod_small (kap x0) K Hk0) at 1. rewrite succ_mod_mod by lia. f_equal. lia.
219
+ - intros x Hx. rewrite Hk, (ago_succ (kap x0) x Hk0 Hx).
220
+ destruct (Nat.eqb_spec x (succ_mod K (kap x0))) as [->|E1].
221
+ + refine (conj (fun _ => conj HI HC) (conj _ (conj _ _))); intros; lia.
222
+ + destruct (Nat.eq_dec x (kap x0)) as [->|E0].
223
+ * rewrite ago_self. refine (conj _ (conj _ (conj (fun _ => conj HA' HR) _))); intros; lia.
224
+ * pose proof (Ho x Hx E0 E1) as [B Tp].
225
+ assert (ago (kap x0) x <> 0) by (intro Z; apply E0; exact (ago_zero _ _ Hk0 Hx Z)).
226
+ refine (conj _ (conj _ (conj _ (fun _ => conj B Tp)))); intros; lia.
227
+ Qed.
228
+
229
+ Lemma after_S : forall x0 g s, start x0 -> 1 <= g -> after x0 g s -> after x0 (S g) (itern al K S0 L T s).
230
+ Proof.
231
+ intros x0 g s Hs0 Hg (Hs & Hkap & Hfx0 & Hw0 & Hb0).
232
+ pose proof (gen s Hs) as G0. cbv zeta in G0.
233
+ destruct G0 as (Hs' & Hk & HI & HC & HA' & HR & Ho & Hfx & _).
234
+ pose proof (kap_lt s Hs) as Hkl.
235
+ refine (conj Hs' (conj _ (conj _ (conj _ _)))).
236
+ - rewrite Hk, Hkap. apply succ_plus.
237
+ - intros c Hc. rewrite (Hfx c Hc). exact (Hfx0 c Hc).
238
+ - apply gen_window; [exact Hs | exact Hs0 | exact Hfx0].
239
+ - intros x Hx. rewrite Hk, (ago_succ (kap s) x Hkl Hx).
240
+ destruct (Hb0 (kap s) Hkl) as (Hact & _). rewrite ago_self in Hact. destruct (Hact eq_refl) as [Bk Tk].
241
+ destruct (Nat.eqb_spec x (succ_mod K (kap s))) as [->|E1].
242
+ + refine (conj (fun _ => conj HI HC) (conj _ (conj _ _))); intros; lia.
243
+ + destruct (Nat.eq_dec x (kap s)) as [->|E0].
244
+ * rewrite ago_self. rewrite Bk in HA'. cbn [bj] in HA'.
245
+ refine (conj _ (conj (fun _ => conj HA' HR) (conj _ _))); intros; lia.
246
+ * pose proof (Ho x Hx E0 E1) as [B Tp]. rewrite B, Tp.
247
+ assert (Ha : ago (kap s) x <> 0) by (intro Z; apply E0; exact (ago_zero _ _ Hkl Hx Z)).
248
+ destruct (Hb0 x Hx) as (_ & Hmid & Heq & Hgt).
249
+ refine (conj _ (conj _ (conj _ _))); intros; [lia | apply Hmid; lia | apply Heq; lia | apply Hgt; lia].
250
+ Qed.
251
+
252
+ Theorem reproduces : forall x0, start x0 -> forall g, 1 <= g -> after x0 g (itern al K S0 L (g * T) x0).
253
+ Proof.
254
+ intros x0 Hs g Hg. induction g as [|g IH]; [lia|].
255
+ destruct (Nat.eq_dec g 0) as [->|E].
256
+ - replace (1 * T) with T by lia. exact (after_1 x0 Hs).
257
+ - replace (S g * T) with (g * T + T) by lia. rewrite itern_add.
258
+ apply after_S; [exact Hs | lia | apply IH; lia].
259
+ Qed.
260
+
261
+ (* After g >= 1 generations, every bank active within the last g generations, and the one active now, holds the
262
+ image of the stored host, and its tape the recipe: min(g + 1, K) copies. *)
263
+ Corollary copies : forall x0, start x0 -> forall g x, 1 <= g -> x < K ->
264
+ ago (kap (itern al K S0 L (g * T) x0)) x <= g ->
265
+ bq (nth x (banks (itern al K S0 L (g * T) x0)) bank0) = img A w S0
266
+ /\ td (nth x (tapes (itern al K S0 L (g * T) x0)) tape0) = dz.
267
+ Proof.
268
+ intros x0 Hs g x Hg Hx Ha.
269
+ destruct (reproduces x0 Hs g Hg) as (_ & _ & _ & _ & Hb). destruct (Hb x Hx) as (H0 & Hmid & Heq & _).
270
+ destruct (Nat.eq_dec (ago (kap (itern al K S0 L (g * T) x0)) x) 0) as [Z|Z];
271
+ [destruct (H0 Z) as [B Tp] |
272
+ destruct (Nat.eq_dec (ago (kap (itern al K S0 L (g * T) x0)) x) g) as [Q|Q];
273
+ [destruct (Heq Q) as [B Tp] | destruct (Hmid ltac:(lia)) as [B Tp]]];
274
+ rewrite B, Tp; split; reflexivity.
275
+ Qed.
276
+
277
+ (* From the K-th generation on, the whole state of the machine repeats every K generations. *)
278
+ Theorem periodic : forall x0, start x0 -> forall g, K <= g ->
279
+ itern al K S0 L ((g + K) * T) x0 = itern al K S0 L (g * T) x0.
280
+ Proof.
281
+ intros x0 Hs g Hg.
282
+ destruct (reproduces x0 Hs g ltac:(lia)) as (Hs1 & Hk1 & _ & Hw1 & Hb1).
283
+ destruct (reproduces x0 Hs (g + K) ltac:(lia)) as (Hs2 & Hk2 & _ & Hw2 & Hb2).
284
+ set (s1 := itern al K S0 L (g * T) x0) in *. set (s2 := itern al K S0 L ((g + K) * T) x0) in *.
285
+ assert (Hk : kap s2 = kap s1).
286
+ { rewrite Hk1, Hk2. replace (kap x0 + (g + K)) with (kap x0 + g + 1 * K) by lia. apply Nat.Div0.mod_add. }
287
+ destruct Hs1 as ((_ & Hkl1 & HB1 & HT1 & _) & _). destruct Hs2 as ((_ & Hkl2 & HB2 & HT2 & _) & _).
288
+ assert (Hnth : forall x, x < K -> nth x (banks s2) bank0 = nth x (banks s1) bank0
289
+ /\ nth x (tapes s2) tape0 = nth x (tapes s1) tape0).
290
+ { intros x Hx. pose proof (ago_lt (kap s1) x Hkl1 Hx) as Ha.
291
+ destruct (Hb1 x Hx) as (A0 & A1 & _). destruct (Hb2 x Hx) as (B0 & B1 & _). rewrite Hk in B0, B1.
292
+ destruct (Nat.eq_dec (ago (kap s1) x) 0) as [Z|Z].
293
+ - destruct (A0 Z) as [P Q]. destruct (B0 Z) as [P' Q']. split; congruence.
294
+ - destruct (A1 ltac:(lia)) as [P Q]. destruct (B1 ltac:(lia)) as [P' Q']. split; congruence. }
295
+ assert (Hwin : win s2 = win s1) by (rewrite Hw1, Hw2; reflexivity).
296
+ destruct s1 as [w1 k1 b1 t1], s2 as [w2 k2 b2 t2]. cbn [win kap banks tapes] in *.
297
+ rewrite Hwin, Hk. f_equal.
298
+ - apply (nth_ext b2 b1 bank0 bank0); [congruence|]. intros x Hx. rewrite HB2 in Hx. exact (proj1 (Hnth x Hx)).
299
+ - apply (nth_ext t2 t1 tape0 tape0); [congruence|]. intros x Hx. rewrite HT2 in Hx. exact (proj2 (Hnth x Hx)).
300
+ Qed.
301
+
302
+ (* ---- the network ----------------------------------------------------------------------------------------- *)
303
+ Theorem network_reproduces : forall x0, start x0 -> forall g, 1 <= g ->
304
+ netiter al K S0 L (g * T) (encode al K S0 L x0) = encode al K S0 L (itern al K S0 L (g * T) x0)
305
+ /\ after x0 g (itern al K S0 L (g * T) x0).
306
+ Proof.
307
+ intros x0 Hs g Hg. split; [|exact (reproduces x0 Hs g Hg)].
308
+ destruct Hs as (Hf & _).
309
+ exact (network_orbit al K S0 L (g * T) x0 (al4 A w K S0 L HA Hw HK HS HL) HK (S0_pos A w K S0 L HA Hw HK HS HL) HL Hf).
310
+ Qed.
311
+
312
+ Theorem network_periodic : forall x0, start x0 -> forall g, K <= g ->
313
+ netiter al K S0 L ((g + K) * T) (encode al K S0 L x0) = netiter al K S0 L (g * T) (encode al K S0 L x0).
314
+ Proof.
315
+ intros x0 Hs g Hg. pose proof Hs as (Hf & _).
316
+ rewrite !(network_orbit al K S0 L _ x0 (al4 A w K S0 L HA Hw HK HS HL) HK (S0_pos A w K S0 L HA Hw HK HS HL) HL Hf).
317
+ rewrite (periodic x0 Hs g Hg). reflexivity.
318
+ Qed.
319
+
320
+ End Ring.
rocq/StoredOk.v ADDED
@@ -0,0 +1,213 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* The records of the stored host fit their code: weights in {-1, 0, 1}, a bias in [-8, 7] and addresses
2
+ below the window of 2^alS cells, so a bank holding their codes holds them. *)
3
+ From Stdlib Require Import List Bool Arith ZArith Lia.
4
+ Import ListNotations.
5
+ From TH Require Import TwoHead Net Abstract Indep Run View Stored WinRun Host HostIP Device StoredStep StoredDev StoredPass.
6
+
7
+ (* ---- gates ---------------------------------------------------------------------------------------------- *)
8
+ (* the record fits the code of a window of more than its addresses *)
9
+ Definition rok (N : nat) (r : rec) : Prop :=
10
+ match r with
11
+ | Rec a0 w0 a1 w1 beta ao =>
12
+ (w0 = 1 \/ w0 = 0 \/ w0 = -1)%Z /\ (w1 = 1 \/ w1 = 0 \/ w1 = -1)%Z /\ (-8 <= beta <= 7)%Z
13
+ /\ a0 < N /\ a1 < N /\ ao < N
14
+ end.
15
+
16
+ Lemma rok_rec_ok : forall al r, rok (2 ^ al) r -> rec_ok al r.
17
+ Proof. intros al [a0 w0 a1 w1 beta ao] H. exact H. Qed.
18
+
19
+ Lemma pm_ok : forall b, (pm b = 1 \/ pm b = 0 \/ pm b = -1)%Z.
20
+ Proof. intros [|]; cbn; auto. Qed.
21
+
22
+ Lemma rok_and : forall N x y d, fst x < N -> fst y < N -> d < N -> rok N (gAND x y d).
23
+ Proof.
24
+ intros N [a p] [c q] d Ha Hc Hd. cbn [fst] in *. unfold rok, gAND. cbn [fst snd].
25
+ refine (conj (pm_ok p) (conj (pm_ok q) (conj _ (conj Ha (conj Hc Hd))))). destruct p, q; cbn; lia.
26
+ Qed.
27
+
28
+ Lemma rok_or : forall N x y d, fst x < N -> fst y < N -> d < N -> rok N (gOR x y d).
29
+ Proof.
30
+ intros N [a p] [c q] d Ha Hc Hd. cbn [fst] in *. unfold rok, gOR. cbn [fst snd].
31
+ refine (conj (pm_ok p) (conj (pm_ok q) (conj _ (conj Ha (conj Hc Hd))))). destruct p, q; cbn; lia.
32
+ Qed.
33
+
34
+ Lemma rok_copy : forall N x d, 0 < N -> fst x < N -> d < N -> rok N (gCOPY x d).
35
+ Proof.
36
+ intros N [a p] d H0 Ha Hd. cbn [fst] in *. unfold rok, gCOPY. cbn [fst snd].
37
+ refine (conj (pm_ok p) (conj _ (conj _ (conj Ha (conj H0 Hd))))); [auto | destruct p; lia].
38
+ Qed.
39
+
40
+ Lemma rok_const : forall N b d, 0 < N -> d < N -> rok N (gCONST b d).
41
+ Proof. intros N [|] d H0 Hd; [apply rok_or | apply rok_and]; cbn [fst]; unfold SINK; lia. Qed.
42
+
43
+ Lemma rok_empty : forall N, 0 < N -> rok N EMPTY.
44
+ Proof. intros N H. unfold rok, EMPTY. lia. Qed.
45
+
46
+ Lemma chain_rok : forall N g ls d acc,
47
+ (forall x y d', fst x < N -> fst y < N -> d' < N -> rok N (g x y d')) -> 0 < N ->
48
+ (forall l, In l ls -> fst l < N) -> d < N -> acc < N -> Forall (rok N) (chain g ls d acc).
49
+ Proof.
50
+ intros N g ls d acc Hg H0 Hl Hd Ha.
51
+ assert (T : forall l t, (forall l', In l' (l :: t) -> fst l' < N) -> Forall (rok N) (chain_tail g acc l t d)).
52
+ { intros l t. revert l. induction t as [|l' t IH]; intros l H; cbn [chain_tail].
53
+ - constructor; [apply Hg; [exact Ha | apply H; left; reflexivity | exact Hd] | constructor].
54
+ - constructor; [apply Hg; [exact Ha | apply H; left; reflexivity | exact Ha]|].
55
+ apply IH. intros l'' Hin. apply H. right. exact Hin. }
56
+ destruct ls as [|l0 [|l1 [|l2 t]]]; cbn [chain].
57
+ - constructor.
58
+ - constructor; [apply rok_copy; [exact H0 | apply Hl; left; reflexivity | exact Hd] | constructor].
59
+ - constructor; [apply Hg; [apply Hl; left; reflexivity | apply Hl; right; left; reflexivity | exact Hd] | constructor].
60
+ - constructor; [apply Hg; [apply Hl; left; reflexivity | apply Hl; right; left; reflexivity | exact Ha]|].
61
+ apply T. intros l' Hin. apply Hl. right. right. exact Hin.
62
+ Qed.
63
+
64
+ (* the compiled threshold unit uses its levels of cells below LV *)
65
+ Lemma ucomp_rok : forall N LV (xc : nat -> nat -> nat), (forall j k, j < LV -> k < 3 -> xc j k < N) -> 0 < N ->
66
+ forall ls t d acc lev, d < N -> acc < N -> (forall l, In l ls -> fst l < N) ->
67
+ ((1 < t < Z.of_nat (length ls))%Z -> lev + length ls <= LV + 2) -> Forall (rok N) (ucomp xc t ls d acc lev).
68
+ Proof.
69
+ intros N LV xc Hx H0. induction ls as [|l0 rest IH]; intros t d acc lev Hd Ha Hl Hlev; cbn [ucomp].
70
+ - cbn [length]. destruct (Z.leb t 0); [constructor; [apply rok_const; assumption | constructor]|].
71
+ destruct (Z.ltb (Z.of_nat 0) t); [constructor; [apply rok_const; assumption | constructor]|].
72
+ destruct (Z.eqb t 1); [cbn [chain]; constructor|].
73
+ destruct (Z.eqb t (Z.of_nat 0)); cbn [chain]; constructor.
74
+ - destruct (Z.leb_spec t 0); [constructor; [apply rok_const; assumption | constructor]|].
75
+ destruct (Z.ltb_spec (Z.of_nat (length (l0 :: rest))) t); [constructor; [apply rok_const; assumption | constructor]|].
76
+ destruct (Z.eqb_spec t 1); [apply chain_rok; [exact (rok_or N) | exact H0 | exact Hl | exact Hd | exact Ha]|].
77
+ destruct (Z.eqb_spec t (Z.of_nat (length (l0 :: rest))));
78
+ [apply chain_rok; [exact (rok_and N) | exact H0 | exact Hl | exact Hd | exact Ha]|].
79
+ cbn [length] in *. assert (Hlv : lev < LV) by (specialize (Hlev ltac:(lia)); lia).
80
+ assert (Hlev' : forall t', (1 < t' < Z.of_nat (length rest))%Z -> S lev + length rest <= LV + 2)
81
+ by (intros t' Ht'; specialize (Hlev ltac:(lia)); lia).
82
+ apply Forall_app. split; [apply IH; [apply Hx; lia | apply Hx; lia | intros l Hin; apply Hl; right; exact Hin
83
+ | apply Hlev']|].
84
+ apply Forall_app. split; [apply IH; [apply Hx; lia | apply Hx; lia | intros l Hin; apply Hl; right; exact Hin
85
+ | apply Hlev']|].
86
+ constructor; [apply rok_and; [apply Hl; left; reflexivity | cbn [fst]; apply Hx; lia | apply Hx; lia]|].
87
+ constructor; [apply rok_or; [cbn [fst]; apply Hx; lia | cbn [fst]; apply Hx; lia | exact Hd] | constructor].
88
+ Qed.
89
+
90
+ (* ---- the records of the stored host --------------------------------------------------------------------- *)
91
+ Section Ok.
92
+ Variables (A w : nat).
93
+ Hypotheses (HA : 8 <= A) (Hw : 1 <= w).
94
+
95
+ Local Notation nu := (length (host_units A)).
96
+ Local Notation lvs := (levels (host_units A)).
97
+ Local Notation n := (nH A).
98
+ Local Notation N := (ncells A w nu lvs).
99
+ Local Notation m := (image A (progPstar A)).
100
+
101
+ Lemma N_pos : 0 < N.
102
+ Proof. unfold ncells. lia. Qed.
103
+
104
+ Ltac cl := unfold dCAR, dG, dCC, dCA, dEOT, dEQ, dE, dRW, dRD, dWR, M0, M1, ncells, carry in *;
105
+ unfold DB, XC, UC, MB in *; unfold ST, CNT, LIM, DEST, BOOT, nh, nH in *;
106
+ unfold HO, CPY, AR, AA, AC, RR, RA, RC, CB, CT, ARM, RD, SINK, cwr, crd, crw, ceot, rin, rout in *;
107
+ first [lia | nia].
108
+
109
+ Lemma MB_lt : forall j t, j < SW A -> t < A -> MB A w j t < N.
110
+ Proof.
111
+ intros j t Hj Ht. pose proof (DB_gt A w N HA Hw (le_n _) j t Hj Ht). unfold ncells. lia.
112
+ Qed.
113
+
114
+ Lemma step_rok : Forall (rok N) (step_go A w nu 0 (host_units A) (next_tbl n nu (host_next A))).
115
+ Proof.
116
+ assert (G : forall k u, u + k = nu ->
117
+ Forall (rok N) (step_go A w nu u (skipn u (host_units A)) (skipn u (next_tbl n nu (host_next A))))).
118
+ { induction k as [|k IH]; intros u Hk.
119
+ - rewrite Nat.add_0_r in Hk. subst u. rewrite step_go_end. constructor.
120
+ - rewrite (step_go_unit A w N ltac:(lia) (le_n _) (repeat false N) (repeat_length _ _) u ltac:(lia)).
121
+ apply Forall_app. split; [|apply IH; lia].
122
+ set (U := nth u (host_units A) tu0).
123
+ assert (HUin : In U (host_units A)) by (apply nth_In; lia).
124
+ unfold unit_recs. fold U.
125
+ apply (ucomp_rok N lvs); [intros j k' Hj Hk'; cl | exact N_pos | | cl | |].
126
+ + destruct (nth u (next_tbl n nu (host_next A)) None) as [i|] eqn:Eo; [|cl].
127
+ destruct (nt_some A ltac:(lia) u i ltac:(lia) Eo) as [Hi _]. cl.
128
+ + intros l Hl. apply in_map_iff in Hl as ([i wt] & <- & Hin). unfold lit_of. cbn [fst].
129
+ pose proof (host_reads_below A ltac:(lia) u ltac:(lia) i wt Hin) as Hr.
130
+ destruct (Nat.ltb_spec i (nh A)); cl.
131
+ + intros [H1 H2]. rewrite length_map in *.
132
+ assert (Ht : thr_unit U = true) by (unfold thr_unit; apply andb_true_intro; split; apply Z.ltb_lt; lia).
133
+ pose proof (lv_bound A w N ltac:(lia) (le_n _) (repeat false N) (repeat_length _ _) U HUin Ht). lia. }
134
+ exact (G nu 0 eq_refl).
135
+ Qed.
136
+
137
+ Ltac rg := first [ apply rok_const; cl | apply rok_copy; cbn [fst]; cl | apply rok_and; cbn [fst]; cl
138
+ | apply rok_or; cbn [fst]; cl ].
139
+ Ltac frg := repeat (apply Forall_cons; [rg|]); apply Forall_nil.
140
+
141
+ Lemma startup_rok : Forall (rok N) (startup A w m).
142
+ Proof.
143
+ pose proof N_pos as H0. unfold startup. rewrite !Forall_app. repeat split.
144
+ - apply Forall_concat, Forall_map, Forall_forall. intros [j v] Hjv. cbn [fst snd].
145
+ pose proof (in_combine_l _ _ _ _ Hjv) as Hj. apply in_seq in Hj.
146
+ unfold boot_word. apply Forall_map, Forall_forall. intros t Ht. apply in_seq in Ht.
147
+ pose proof (MB_lt j t ltac:(lia) ltac:(lia)).
148
+ destruct (Nat.testbit v t); [apply rok_or | apply rok_and]; cbn [fst]; cl.
149
+ - apply Forall_map, Forall_forall. intros t Ht. apply in_seq in Ht. apply rok_and; cbn [fst]; cl.
150
+ - constructor; [apply rok_and; cbn [fst]; cl | constructor].
151
+ - apply Forall_concat, Forall_map, Forall_forall. intros i Hi. apply in_seq in Hi.
152
+ constructor; [apply rok_and; cbn [fst]; cl | constructor; [apply rok_and; cbn [fst]; cl | constructor]].
153
+ - constructor; [apply rok_and; cbn [fst]; cl | constructor].
154
+ - cbn [map]. frg.
155
+ - constructor; [apply rok_const; cl | constructor].
156
+ Qed.
157
+
158
+ Lemma handover_rok : Forall (rok N) (handover A w).
159
+ Proof.
160
+ unfold handover. repeat (apply Forall_cons; [first [apply rok_and | apply rok_copy]; cbn [fst]; cl|]). apply Forall_nil.
161
+ Qed.
162
+
163
+ Lemma device_rok : Forall (rok N) (Stored.device A w nu lvs).
164
+ Proof.
165
+ pose proof N_pos as H0. pose proof (io_lt A w N HA Hw (le_n _)) as (I1 & I2 & I3 & I4 & I5 & I6).
166
+ assert (Hw1 : forall j d, j < SW A -> d < N -> Forall (rok N) (word1 A w j d)).
167
+ { intros j d Hj Hd. unfold word1. apply chain_rok; [exact (rok_and N) | exact H0 | | exact Hd | exact Hd].
168
+ intros l [<-|Hl]; [cbn [fst]; apply MB_lt; lia|].
169
+ apply in_map_iff in Hl as (t & <- & Ht). apply in_seq in Ht. cbn [fst]. apply MB_lt; lia. }
170
+ rewrite device_split. unfold segA. rewrite !Forall_app. repeat split.
171
+ - apply Hw1; [exact I1 | cl].
172
+ - apply Hw1; [exact I4 | cl].
173
+ - apply Hw1; [exact I3 | cl].
174
+ - unfold segB. apply Forall_concat, Forall_map, Forall_forall. intros i Hi. apply in_seq in Hi. frg.
175
+ - unfold segC. apply chain_rok; [exact (rok_and N) | exact H0 | | cl | cl].
176
+ intros l Hl. apply in_map_iff in Hl as (i & <- & Hi). apply in_seq in Hi. cbn [fst]. cl.
177
+ - unfold segD. frg.
178
+ - unfold segE. apply Forall_concat, Forall_map, Forall_forall. intros k Hk. apply in_seq in Hk.
179
+ pose proof (MB_lt (rout A) (7 - k) I6 ltac:(lia)). unfold gMUX. cbn [app]. frg.
180
+ - unfold segF. apply Forall_map, Forall_forall. intros t Ht. apply in_seq in Ht. pose proof (MB_lt (rout A) t I6 ltac:(lia)). rg.
181
+ - unfold segG. frg.
182
+ - unfold segH. apply Forall_concat, Forall_map, Forall_forall. intros k Hk. apply in_seq in Hk.
183
+ pose proof (MB_lt (rin A) (7 - k) I5 ltac:(lia)). unfold gMUX. cbn [app]. frg.
184
+ - unfold segI. apply Forall_concat, Forall_map, Forall_forall. intros t Ht. apply in_seq in Ht.
185
+ pose proof (MB_lt (rin A) t I5 ltac:(lia)). pose proof (MB_lt (rin A) 7 I5 ltac:(lia)). unfold gMUX. frg.
186
+ - unfold segJ, gMUX. pose proof (MB_lt (ceot A) 0 I2 ltac:(lia)). frg.
187
+ - unfold segK. apply Forall_map, Forall_forall. intros t Ht. apply in_seq in Ht. pose proof (MB_lt (ceot A) t I2 ltac:(lia)). rg.
188
+ - unfold segL. apply Forall_map, Forall_forall. intros i Hi. apply in_seq in Hi. unfold carry.
189
+ destruct (Nat.eqb i 0); rg.
190
+ - unfold segM. apply Forall_concat, Forall_map, Forall_forall. intros i Hi. apply in_seq in Hi. unfold gXOR, carry.
191
+ destruct (Nat.eqb i 0); frg.
192
+ - unfold segN. frg.
193
+ - unfold segO. apply Forall_concat, Forall_map, Forall_forall. intros i Hi. apply in_seq in Hi. unfold gMUX. cbn [app]. frg.
194
+ - unfold segP. frg.
195
+ - unfold segQ. apply Forall_concat, Forall_map, Forall_forall. intros c Hc.
196
+ assert (Hcl : c < SW A) by (destruct Hc as [<-|[<-|[<-|[]]]]; assumption).
197
+ apply Forall_map, Forall_forall. intros t Ht. apply in_seq in Ht. pose proof (MB_lt c t Hcl ltac:(lia)). rg.
198
+ Qed.
199
+
200
+ (* every record of the image fits the code of the window of 2^alS cells *)
201
+ Theorem stored_ok : Forall (rec_ok (alS A w)) (stored A w).
202
+ Proof.
203
+ apply Forall_forall. intros r Hr. apply rok_rec_ok.
204
+ assert (Hr' : Forall (rok N) (stored A w)).
205
+ { rewrite (stored_split A w). rewrite !Forall_app. refine (conj startup_rok (conj step_rok (conj device_rok (conj _ handover_rok)))).
206
+ apply Forall_forall. intros x Hx. apply repeat_spec in Hx. subst x. apply rok_empty, N_pos. }
207
+ rewrite Forall_forall in Hr'. pose proof (Hr' r Hr) as Hrk. pose proof (HW A w HA Hw) as Hb.
208
+ destruct r as [a0 w0 a1 w1 beta ao]. unfold rok in Hrk |- *.
209
+ destruct Hrk as (H1 & H2 & H3 & H4 & H5 & H6).
210
+ refine (conj H1 (conj H2 (conj H3 (conj _ (conj _ _))))); eapply Nat.lt_le_trans; eassumption.
211
+ Qed.
212
+
213
+ End Ok.
rocq/StoredPass.v ADDED
@@ -0,0 +1,674 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* One pass of the stored host against one step of the transducer of Definition 8.4: the records of H_A,
2
+ the device and the hand-over carry the window, the read tape, the arm and the copy tape of a
3
+ configuration of SUBLEQ_A with its device to those of the next configuration, for every A >= 8. *)
4
+ From Stdlib Require Import List Bool Arith ZArith Lia.
5
+ Import ListNotations.
6
+ From TH Require Import TwoHead Net Abstract Indep Decoder Run PhysSem View Stored WinRun WinPar ViewOps Host HostWF
7
+ HostSem HostIP Device Pstar StoredStep StoredBoot StoredDev.
8
+
9
+ (* ---- bits of numbers --------------------------------------------------------------------------------- *)
10
+ Lemma forallb_seq_S0 : forall (f : nat -> bool) k, forallb f (seq 0 (S k)) = f 0 && forallb (fun j => f (S j)) (seq 0 k).
11
+ Proof. intros f k. cbn [seq forallb]. f_equal. rewrite <- seq_shift, forallb_map'. reflexivity. Qed.
12
+
13
+ (* the bits of c + 1: bit i flips when the bits below it are all 1 *)
14
+ Lemma testbit_succ : forall c i, Nat.testbit (S c) i = xorb (Nat.testbit c i) (forallb (Nat.testbit c) (seq 0 i)).
15
+ Proof.
16
+ intros c i. revert c. induction i as [|i IH]; intro c.
17
+ - cbn [seq forallb]. rewrite xorb_true_r, !Nat.bit0_odd, Nat.odd_succ, Nat.negb_odd. reflexivity.
18
+ - rewrite forallb_seq_S0. destruct (Nat.Even_or_Odd c) as [[k ->]|[k ->]].
19
+ + replace (S (2 * k)) with (2 * k + 1) by lia.
20
+ rewrite Nat.testbit_odd_succ, Nat.testbit_even_succ, Nat.testbit_even_0 by lia. cbn [andb]. rewrite xorb_false_r.
21
+ reflexivity.
22
+ + replace (S (2 * k + 1)) with (2 * S k) by lia.
23
+ rewrite Nat.testbit_even_succ, Nat.testbit_odd_succ, Nat.testbit_odd_0 by lia. cbn [andb].
24
+ rewrite IH. f_equal. apply forallb_ext_in'. intros j _. symmetry. apply Nat.testbit_odd_succ. lia.
25
+ Qed.
26
+
27
+ Lemma testbit_lt_false : forall b k, b < 2 ^ k -> Nat.testbit b k = false.
28
+ Proof.
29
+ intros b k H. rewrite <- (Nat.add_0_l k), <- Nat.div_pow2_bits, Nat.div_small by exact H. reflexivity.
30
+ Qed.
31
+
32
+ (* a byte with its sign bit copied into the bits above the eighth *)
33
+ Lemma testbit_sext : forall A b t, 8 <= A -> b < 256 -> t < A ->
34
+ Nat.testbit (sext A b) t = Nat.testbit b (7 - (7 - t)).
35
+ Proof.
36
+ intros A b t HA Hb Ht. unfold sext. destruct (Nat.ltb_spec b 128) as [Hs|Hs].
37
+ - destruct (Nat.lt_ge_cases t 8) as [Hlo|Hhi]; [f_equal; lia|].
38
+ replace (7 - (7 - t)) with 7 by lia.
39
+ rewrite (testbit_lt_false b 7) by (cbn; lia). apply testbit_lt_false.
40
+ apply (Nat.lt_le_trans _ (2 ^ 8)); [cbn; lia | apply Nat.pow_le_mono_r; lia].
41
+ - assert (E : b + SW A - 256 = b + (2 ^ (A - 8) - 1) * 2 ^ 8).
42
+ { unfold SW. replace A with ((A - 8) + 8) at 1 by lia. rewrite Nat.pow_add_r.
43
+ pose proof (Nat.pow_nonzero 2 (A - 8) ltac:(lia)). change (2 ^ 8) with 256. nia. }
44
+ rewrite E. destruct (Nat.lt_ge_cases t 8) as [Hlo|Hhi].
45
+ + rewrite <- (Nat.mod_pow2_bits_low _ 8 t) by exact Hlo. rewrite Nat.Div0.mod_add, Nat.mod_small by (cbn; lia).
46
+ f_equal. lia.
47
+ + replace t with ((t - 8) + 8) at 1 by lia. rewrite <- Nat.div_pow2_bits.
48
+ rewrite Nat.div_add, Nat.div_small, Nat.add_0_l by (cbn; lia).
49
+ replace (2 ^ (A - 8) - 1) with (Nat.ones (A - 8)) by (rewrite Nat.ones_equiv; lia).
50
+ rewrite Nat.ones_spec_low by lia. replace (7 - (7 - t)) with 7 by lia.
51
+ symmetry. rewrite <- (Nat.add_0_l 7), <- Nat.div_pow2_bits.
52
+ replace (b / 2 ^ 7) with 1 by (apply Nat.div_unique with (r := b - 128); cbn; lia). reflexivity.
53
+ Qed.
54
+
55
+ (* a word of A bits that holds 1 *)
56
+ Lemma bits_one : forall A x, 1 <= A -> x < 2 ^ A ->
57
+ Nat.testbit x 0 && forallb (fun t => negb (Nat.testbit x t)) (seq 1 (A - 1)) = Nat.eqb x 1.
58
+ Proof.
59
+ intros A x HA Hx. rewrite <- (testbits_eqb A x 1 Hx) by (apply (Nat.lt_le_trans _ (2 ^ 1)); [cbn; lia
60
+ | apply Nat.pow_le_mono_r; lia]).
61
+ replace (seq 0 A) with (0 :: seq 1 (A - 1)) by (replace A with (S (A - 1)) at 2 by lia; reflexivity).
62
+ cbn [forallb]. change (Nat.testbit 1 0) with true. f_equal.
63
+ - destruct (Nat.testbit x 0); reflexivity.
64
+ - apply forallb_ext_in'. intros t Ht. apply in_seq in Ht.
65
+ rewrite (testbit_lt_false 1 t) by (apply (Nat.lt_le_trans _ (2 ^ 1)); [cbn; lia | apply Nat.pow_le_mono_r; lia]).
66
+ destruct (Nat.testbit x t); reflexivity.
67
+ Qed.
68
+
69
+ (* ---- bytes on a tape, most significant bit first ------------------------------------------------------ *)
70
+ Definition bbits (o : list nat) : list bool := concat (map (nat2bits 8) o).
71
+
72
+ (* the bytes o followed by blank cells, the head on cell 8 k *)
73
+ Definition obt (Lt : nat) (o : list nat) (k : nat) : tape := mkT (bbits o ++ repeat false (Lt - 8 * length o)) ((8 * k) mod Lt).
74
+
75
+ Lemma length_bbits : forall o, length (bbits o) = 8 * length o.
76
+ Proof.
77
+ intro o. unfold bbits. rewrite (length_concat_const _ _ 8).
78
+ - rewrite length_map. lia.
79
+ - apply Forall_forall. intros l Hl. apply in_map_iff in Hl as (x & <- & _). apply length_nat2bits.
80
+ Qed.
81
+
82
+ Lemma bbits_app : forall o1 o2, bbits (o1 ++ o2) = bbits o1 ++ bbits o2.
83
+ Proof. intros o1 o2. unfold bbits. rewrite map_app, concat_app. reflexivity. Qed.
84
+
85
+ Lemma nth_bbits : forall o k j, k < length o -> j < 8 -> nth (8 * k + j) (bbits o) false = Nat.testbit (nth k o 0) (7 - j).
86
+ Proof.
87
+ intros o k j Hk Hj. unfold bbits.
88
+ rewrite (nth_concat_const _ false (map (nat2bits 8) o) 8 k j).
89
+ - rewrite (nth_map_d _ _ (nat2bits 8) o k [] 0) by exact Hk. rewrite nth_nat2bits by exact Hj. reflexivity.
90
+ - apply Forall_forall. intros l Hl. apply in_map_iff in Hl as (x & <- & _). apply length_nat2bits.
91
+ - rewrite length_map. exact Hk.
92
+ - exact Hj.
93
+ Qed.
94
+
95
+ Lemma nat2bits_map : forall k x, nat2bits k x = map (fun j => Nat.testbit x (k - 1 - j)) (seq 0 k).
96
+ Proof.
97
+ intros k x. apply (nth_ext _ _ false false); [rewrite length_nat2bits, length_map, length_seq; reflexivity|].
98
+ intros j Hj. rewrite length_nat2bits in Hj. rewrite nth_nat2bits by exact Hj.
99
+ rewrite (nth_map_seq _ (fun j => Nat.testbit x (k - 1 - j)) k j false Hj). reflexivity.
100
+ Qed.
101
+
102
+ Lemma nat2bits_mod : forall x, nat2bits 8 (x mod 256) = nat2bits 8 x.
103
+ Proof.
104
+ intro x. rewrite !nat2bits_map. apply map_ext_in. intros j Hj. apply in_seq in Hj.
105
+ change 256 with (2 ^ 8). apply Nat.mod_pow2_bits_low. lia.
106
+ Qed.
107
+
108
+ Lemma adv_mod : forall Lt k x, 1 <= Lt -> adv Lt k (x mod Lt) = (x + k) mod Lt.
109
+ Proof.
110
+ intros Lt k x H. induction k as [|k IH]; cbn [adv]; [rewrite Nat.add_0_r; reflexivity|].
111
+ rewrite IH, succ_mod_mod by exact H. f_equal. lia.
112
+ Qed.
113
+
114
+ Lemma wseq_cons : forall Lt b bs t, wseq Lt (b :: bs) t = wseq Lt bs (wstep Lt b t).
115
+ Proof. reflexivity. Qed.
116
+
117
+ (* bits written one after another from the first blank cell *)
118
+ Lemma wseq_fill : forall Lt bs pre, length pre + length bs <= Lt ->
119
+ wseq Lt bs (mkT (pre ++ repeat false (Lt - length pre)) (length pre mod Lt))
120
+ = mkT (pre ++ bs ++ repeat false (Lt - length pre - length bs)) ((length pre + length bs) mod Lt).
121
+ Proof.
122
+ induction bs as [|b bs IH]; intros pre H.
123
+ - cbn [length]. rewrite app_nil_l, Nat.add_0_r, Nat.sub_0_r. reflexivity.
124
+ - rewrite wseq_cons. cbn [length] in H.
125
+ assert (Hp : length pre < Lt) by lia.
126
+ assert (E : wstep Lt b (mkT (pre ++ repeat false (Lt - length pre)) (length pre mod Lt))
127
+ = mkT ((pre ++ [b]) ++ repeat false (Lt - length (pre ++ [b]))) (length (pre ++ [b]) mod Lt)).
128
+ { unfold wstep. cbn [td th]. rewrite succ_mod_mod by lia. rewrite (Nat.mod_small (length pre) Lt Hp).
129
+ replace (Lt - length pre) with (S (Lt - length pre - 1)) by lia. cbn [repeat].
130
+ rewrite upd_app_cons, <- app_assoc, length_app. cbn [app length]. f_equal; [do 3 f_equal; lia | f_equal; lia]. }
131
+ rewrite E, IH by (rewrite length_app; cbn [length]; lia).
132
+ rewrite <- app_assoc, length_app. cbn [app length]. f_equal; [do 4 f_equal; lia | f_equal; lia].
133
+ Qed.
134
+
135
+ (* a byte written under a head on the first blank cell *)
136
+ Lemma wseq_byte : forall Lt o x, 8 * S (length o) <= Lt ->
137
+ wseq Lt (nat2bits 8 x) (obt Lt o (length o)) = obt Lt (o ++ [x mod 256]) (length (o ++ [x mod 256])).
138
+ Proof.
139
+ intros Lt o x H. unfold obt. rewrite <- (length_bbits o).
140
+ rewrite wseq_fill by (rewrite length_nat2bits, length_bbits; lia).
141
+ rewrite bbits_app, length_app, length_nat2bits, length_bbits. cbn [length]. unfold bbits at 3. cbn [map concat].
142
+ rewrite nat2bits_mod, app_nil_r, <- app_assoc. f_equal; [do 3 f_equal; lia | f_equal; lia].
143
+ Qed.
144
+
145
+ (* a bit of the byte under the read head *)
146
+ Lemma read_bit : forall tau Lt h t, 8 * length tau <= Lt -> h < length tau ->
147
+ nth (adv Lt (7 - t) ((8 * h) mod Lt)) (bbits tau ++ repeat false (Lt - 8 * length tau)) false
148
+ = Nat.testbit (nth h tau 0) (7 - (7 - t)).
149
+ Proof.
150
+ intros tau Lt h t H1 H2. rewrite adv_mod by lia. rewrite Nat.mod_small by lia.
151
+ rewrite app_nth1 by (rewrite length_bbits; lia). rewrite nth_bbits by lia. reflexivity.
152
+ Qed.
153
+
154
+ (* ---- states of the host ------------------------------------------------------------------------------- *)
155
+ Section States.
156
+ Variable A : nat.
157
+ Hypothesis HA : 8 <= A.
158
+
159
+ Lemma subleq_valid : forall s, hvalid A s -> hvalid A (subleq A s).
160
+ Proof.
161
+ intros s (Hp & Hl & Hf). pose proof (SW256 A HA) as HS. rewrite Forall_forall in Hf.
162
+ assert (Hm : forall j, j < SW A -> memv s j < SW A) by (intros j Hj; unfold memv; apply Hf, nth_In; lia).
163
+ unfold subleq. destruct (hhalt s); [refine (conj Hp (conj Hl _)); apply Forall_forall; exact Hf|].
164
+ cbv zeta. unfold hvalid. cbn [hpc hmem]. split; [|split].
165
+ - destruct (_ || _); [apply Hm, Nat.mod_upper_bound; lia | apply Nat.mod_upper_bound; lia].
166
+ - rewrite length_map, length_seq. reflexivity.
167
+ - apply Forall_forall. intros x Hx. apply in_map_iff in Hx as (j & <- & Hj). apply in_seq in Hj.
168
+ destruct (Nat.eqb j _); [apply Nat.mod_upper_bound; lia | apply Hm; lia].
169
+ Qed.
170
+
171
+ Lemma setm_valid : forall s c v, hvalid A s -> v < SW A -> hvalid A (setm A s c v).
172
+ Proof.
173
+ intros s c v (Hp & Hl & Hf) Hv. unfold setm, hvalid. cbn [hpc hmem]. split; [exact Hp|].
174
+ split; [rewrite length_map, length_seq; reflexivity|].
175
+ apply Forall_forall. intros x Hx. apply in_map_iff in Hx as (j & <- & Hj). apply in_seq in Hj.
176
+ destruct (Nat.eqb j c); [exact Hv|]. unfold memv. rewrite Forall_forall in Hf. apply Hf, nth_In. lia.
177
+ Qed.
178
+
179
+ Lemma device_valid : forall s d, hvalid A s -> Forall (fun x => x < 256) (dtape d) -> hvalid A (fst (device A s d)).
180
+ Proof.
181
+ intros s d Hv Hb. pose proof (SW256 A HA) as HS. unfold device. cbv zeta. cbn [fst].
182
+ rewrite Forall_forall in Hb.
183
+ repeat apply setm_valid; try lia.
184
+ destruct (Nat.eqb (memv s (crd A)) 1); [destruct (Nat.ltb (dhead d) (length (dtape d))) eqn:Ok|];
185
+ repeat apply setm_valid; try lia;
186
+ try (destruct (Nat.eqb (memv s (cwr A)) 1); [apply setm_valid; [exact Hv | lia] | exact Hv]).
187
+ apply sext_lt; [exact HA|]. apply Nat.ltb_lt in Ok.
188
+ destruct (Nat.lt_ge_cases (dhead d) (length (dtape d))) as [H|H]; [apply Hb, nth_In, H | lia].
189
+ Qed.
190
+
191
+ Lemma device_pc : forall s d, hpc (fst (device A s d)) = hpc s /\ hhalt (fst (device A s d)) = hhalt s
192
+ /\ length (hmem (fst (device A s d))) = SW A.
193
+ Proof.
194
+ intros s d. unfold device. cbv zeta. cbn [fst]. split; [|split; [|apply setm_len]];
195
+ unfold setm; cbn [hpc hhalt];
196
+ destruct (Nat.eqb (memv s (crd A)) 1), (Nat.ltb (dhead d) (length (dtape d))), (Nat.eqb (memv s (cwr A)) 1);
197
+ reflexivity.
198
+ Qed.
199
+
200
+ (* the words of memory after the device *)
201
+ Lemma memv_device : forall s d j, j < SW A ->
202
+ memv (fst (device A s d)) j =
203
+ if Nat.eqb j (cwr A) || Nat.eqb j (crd A) || Nat.eqb j (crw A) then 0
204
+ else if Nat.eqb j (rout A) then (if Nat.eqb (memv s (cwr A)) 1 then 0 else memv s j)
205
+ else if Nat.eqb j (rin A) then
206
+ (if Nat.eqb (memv s (crd A)) 1 && Nat.ltb (dhead d) (length (dtape d))
207
+ then sext A (nth (dhead d) (dtape d) 0) else memv s j)
208
+ else if Nat.eqb j (ceot A) then
209
+ (if Nat.eqb (memv s (crd A)) 1 then (if Nat.ltb (dhead d) (length (dtape d)) then 0 else 1) else memv s j)
210
+ else memv s j.
211
+ Proof.
212
+ intros s d j Hj. pose proof (SW256 A HA) as HS. unfold device. cbv zeta. cbn [fst].
213
+ rewrite !setm_mem by exact Hj.
214
+ destruct (Nat.eqb (memv s (crd A)) 1), (Nat.ltb (dhead d) (length (dtape d))), (Nat.eqb (memv s (cwr A)) 1);
215
+ cbn [andb]; rewrite ?setm_mem by exact Hj;
216
+ unfold cwr, crd, crw, rout, rin, ceot in *;
217
+ repeat match goal with |- context [Nat.eqb ?x ?y] => destruct (Nat.eqb_spec x y) end;
218
+ cbn [orb]; try lia; reflexivity.
219
+ Qed.
220
+
221
+ (* the initial memory image holds words *)
222
+ Lemma prog_lt : forall a b c, In (a, b, c) (progPstar A) -> a < SW A /\ b < SW A /\ c < SW A.
223
+ Proof.
224
+ intros a b c H. pose proof (SW256 A HA). unfold progPstar, decode_loop in H. cbn [app In] in H.
225
+ repeat (destruct H as [H|H];
226
+ [injection H as <- <- <-; unfold t1c, t2c, zc, rin, rout, eokc, ceot, cwr, crd, crw, neg1c, onec, haltc; lia|]).
227
+ destruct H.
228
+ Qed.
229
+
230
+ Lemma img0_lt : forall j, img0 A (progPstar A) j < SW A.
231
+ Proof.
232
+ intro j. pose proof (SW256 A HA). unfold img0. destruct (j <? _).
233
+ - unfold word. destruct (nth (j / 3) (progPstar A) (0, 0, 0)) as [[a b] c] eqn:E.
234
+ destruct (Nat.lt_ge_cases (j / 3) (length (progPstar A))) as [Hl|Hl].
235
+ + pose proof (nth_In (progPstar A) (0, 0, 0) Hl) as Hin. rewrite E in Hin.
236
+ destruct (prog_lt a b c Hin) as (Ha & Hb & Hc). destruct (j mod 3) as [|[|]]; assumption.
237
+ + rewrite nth_overflow in E by exact Hl. injection E as <- <- <-. destruct (j mod 3) as [|[|]]; lia.
238
+ - destruct (Nat.eqb j _); [lia|]. destruct (Nat.eqb j _); [lia|]. destruct (Nat.eqb j _); lia.
239
+ Qed.
240
+
241
+ Lemma init_valid : hvalid A (x0m (image A (progPstar A))).
242
+ Proof.
243
+ unfold hvalid, x0m, image. cbn [hpc hmem]. split; [pose proof (SW256 A HA); lia|].
244
+ split; [rewrite length_map, length_seq; reflexivity|].
245
+ apply Forall_forall. intros v Hv. apply in_map_iff in Hv as (j & <- & _). apply img0_lt.
246
+ Qed.
247
+
248
+ End States.
249
+
250
+ Definition isnil (l : list nat) : bool := match l with [] => true | _ => false end.
251
+
252
+ (* ---- a pass on a view ------------------------------------------------------------------------------------ *)
253
+ Section Pass.
254
+ Variables (A w Lb L : nat).
255
+ Hypotheses (HA : 8 <= A) (Hw : 1 <= w).
256
+
257
+ Local Notation nu := (length (host_units A)).
258
+ Local Notation lvs := (levels (host_units A)).
259
+ Local Notation n := (nH A).
260
+ Local Notation nt := (next_tbl (nH A) (length (host_units A)) (host_next A)).
261
+ Local Notation W := (2 ^ alS A w).
262
+
263
+ Lemma alS_eq : alS A w = Nat.log2_up (ncells A w nu lvs).
264
+ Proof. reflexivity. Qed.
265
+
266
+ Lemma HW : ncells A w nu lvs <= W.
267
+ Proof.
268
+ rewrite alS_eq. destruct (Nat.log2_up_spec (ncells A w nu lvs)) as [_ H]; [unfold ncells, DB; lia | exact H].
269
+ Qed.
270
+
271
+ (* the state bits of the window hold the state s of the host *)
272
+ Definition holds (ww : list bool) (s : hst) : Prop := forall i, i < n -> wget ww (ST w i) = nth i (encodeH A s) false.
273
+
274
+ Lemma holds_MB : forall ww s j t, holds ww s -> length (hmem s) = SW A -> j < SW A -> t < A ->
275
+ wget ww (MB A w j t) = Nat.testbit (memv s j) t.
276
+ Proof.
277
+ intros ww s j t H Hl Hj Ht. unfold MB. rewrite H by (unfold nH; nia).
278
+ replace (A + 1 + A * j + (A - 1 - t)) with (A + 1 + j * A + (A - 1 - t)) by lia.
279
+ rewrite nth_encodeH_mem by (assumption || lia). unfold bitof. f_equal. lia.
280
+ Qed.
281
+
282
+ Lemma holds_of : forall ww s, length (hmem s) = SW A ->
283
+ (forall i, i < A -> wget ww (ST w i) = bitof A (hpc s) i) -> wget ww (ST w A) = hhalt s ->
284
+ (forall j t, j < SW A -> t < A -> wget ww (MB A w j t) = Nat.testbit (memv s j) t) -> holds ww s.
285
+ Proof.
286
+ intros ww s Hl Hp Hh Hm i Hi. destruct (Nat.lt_ge_cases i A) as [H1|H1].
287
+ - rewrite nth_encodeH_pc by exact H1. apply Hp. exact H1.
288
+ - destruct (Nat.eq_dec i A) as [->|H2]; [rewrite nth_encodeH_halt; exact Hh|].
289
+ set (j := (i - A - 1) / A). set (k := (i - A - 1) mod A).
290
+ assert (Hk : k < A) by (apply Nat.mod_upper_bound; lia).
291
+ assert (Hji : i = A + 1 + j * A + k) by (pose proof (Nat.div_mod_eq (i - A - 1) A); unfold j, k; lia).
292
+ assert (Hj : j < SW A) by (unfold nH in Hi; nia).
293
+ rewrite Hji at 2. rewrite nth_encodeH_mem by assumption. unfold bitof.
294
+ pose proof (Hm j (A - 1 - k) Hj ltac:(lia)) as E. unfold MB in E.
295
+ replace (A + 1 + A * j + (A - 1 - (A - 1 - k))) with i in E by lia. rewrite E; reflexivity.
296
+ Qed.
297
+
298
+ (* a view at the start of a pass, h after the hand-over, against a configuration c of the transducer: the
299
+ window holds the state of the host, cnt the head, lim the head of the last rewind and dest whether one was
300
+ requested; the read tape holds the tape of c, and the arm and the copy tape the bytes o1 and o2 emitted
301
+ before and after the rewind *)
302
+ Definition Rv (h : bool) (c : hst * dev) (o1 o2 : list nat) (v : view) : Prop :=
303
+ reqclear (vw v) /\ length (vw v) = W /\ vho v = h /\ wget (vw v) BOOT = negb h
304
+ /\ holds (vw v) (fst c) /\ hvalid A (fst c)
305
+ /\ (forall i, i < w -> wget (vw v) (CNT i) = Nat.testbit (dhead (snd c)) i)
306
+ /\ (forall i, i < w -> wget (vw v) (LIM w i) = Nat.testbit (last (drew (snd c)) 0) i)
307
+ /\ wget (vw v) (DEST w) = negb (isnil (drew (snd c)))
308
+ /\ vr v = obt L (dtape (snd c)) (dhead (snd c))
309
+ /\ va v = obt Lb o1 (if h then 0 else length o1)
310
+ /\ vc v = obt L o2 (if h then 0 else length o2)
311
+ /\ dout (snd c) = o1 ++ o2 /\ (isnil (drew (snd c)) = true -> o2 = []).
312
+
313
+ (* ---- the step block ---------------------------------------------------------------------------------------- *)
314
+ Lemma step_view : forall v s, reqclear (vw v) -> length (vw v) = W -> holds (vw v) s -> hvalid A s ->
315
+ let v' := vrun Lb L (step_go A w nu 0 (host_units A) nt) v in
316
+ reqclear (vw v') /\ length (vw v') = W /\ holds (vw v') (subleq A s)
317
+ /\ (forall c, c < ST w 0 \/ DB A w nu lvs <= c -> wget (vw v') c = wget (vw v) c)
318
+ /\ vr v' = vr v /\ va v' = va v /\ vc v' = vc v /\ vho v' = vho v.
319
+ Proof.
320
+ intros v s Hq Hl Hh Hv v'. unfold v'.
321
+ rewrite (vrun_wrun Lb L _ v (step_wrec A w W ltac:(lia) HW (vw v) Hl) Hq). cbn [vw vr va vc vho].
322
+ destruct (step_run A w W ltac:(lia) HW (vw v) Hl Hq) as (L1 & Q1 & _ & S1 & U1).
323
+ refine (conj Q1 (conj L1 (conj _ (conj U1 (conj eq_refl (conj eq_refl (conj eq_refl eq_refl))))))).
324
+ intros i Hi. rewrite S1 by exact Hi. pose proof (host_next_range A ltac:(lia) i Hi) as Hr.
325
+ rewrite (proj2 (Nat.ltb_lt _ _)) by lia.
326
+ assert (Ex : xbits A w (vw v) = encodeH A s).
327
+ { destruct Hv as (_ & Hlen & _). apply (nth_ext _ _ false false).
328
+ - rewrite length_encodeH by exact Hlen. unfold xbits. rewrite length_map, length_seq. reflexivity.
329
+ - intros j Hj. unfold xbits in *. rewrite length_map, length_seq in Hj.
330
+ rewrite (nth_map_seq _ (fun i => wget (vw v) (ST w i)) n j false Hj). apply Hh. exact Hj. }
331
+ unfold E, X. rewrite Ex.
332
+ pose proof (host_step A s ltac:(lia) Hv) as Hs. unfold netstep in Hs. cbv zeta in Hs.
333
+ rewrite <- Hs. rewrite (nth_map_d _ _ _ (host_next A) i false 0) by (rewrite length_host_next; exact Hi).
334
+ reflexivity.
335
+ Qed.
336
+
337
+ (* ---- the startup ------------------------------------------------------------------------------------------- *)
338
+ Local Notation m := (image A (progPstar A)).
339
+
340
+ Lemma length_image : length m = SW A.
341
+ Proof. unfold image. rewrite length_map, length_seq. reflexivity. Qed.
342
+
343
+ Lemma HWs : 15 + 2 * w + n <= W.
344
+ Proof. pose proof HW. unfold ncells, DB, nh in *. lia. Qed.
345
+
346
+ Lemma view_eta : forall u : view, u = mkV (vw u) (vr u) (va u) (vc u) (vho u).
347
+ Proof. intros [? ? ? ? ?]. reflexivity. Qed.
348
+
349
+ (* once booted, the startup changes nothing *)
350
+ Lemma startup_booted : forall v, reqclear (vw v) -> length (vw v) = W -> wget (vw v) BOOT = true ->
351
+ vrun Lb L (startup A w m) v = v.
352
+ Proof.
353
+ intros v Hq Hl Hb.
354
+ destruct (startup_run A w W Lb L m ltac:(lia) length_image HWs v Hq Hl)
355
+ as (Q & L1 & B1 & S1 & R1 & D1 & U1 & VR & VA & VC & VH).
356
+ cbv zeta in *. rewrite Hb in S1, R1, D1, VR, VA, VC.
357
+ transitivity (mkV (vw v) (vr v) (va v) (vc v) (vho v)); [|symmetry; apply view_eta].
358
+ rewrite (view_eta (vrun Lb L (startup A w m) v)). rewrite VR, VA, VC, VH.
359
+ f_equal. apply (nth_ext _ _ false false); [congruence|]. intros i Hi.
360
+ change (wget (vw (vrun Lb L (startup A w m) v)) i = wget (vw v) i).
361
+ destruct (Nat.lt_ge_cases i BOOT) as [H1|H1]; [apply U1; left; exact H1|].
362
+ destruct (Nat.eq_dec i BOOT) as [->|H2]; [rewrite B1; symmetry; exact Hb|].
363
+ destruct (Nat.lt_ge_cases i (14 + w)) as [H3|H3].
364
+ { replace i with (CNT (i - 14)) by (unfold CNT, BOOT in *; lia). rewrite (proj1 (R1 (i - 14) ltac:(unfold BOOT in *; lia))).
365
+ apply andb_true_r. }
366
+ destruct (Nat.eq_dec i (14 + w)) as [->|H4]; [change (14 + w) with (DEST w); rewrite D1; apply andb_true_r|].
367
+ destruct (Nat.lt_ge_cases i (15 + 2 * w)) as [H5|H5].
368
+ { replace i with (LIM w (i - 15 - w)) by (unfold LIM; lia). rewrite (proj2 (R1 (i - 15 - w) ltac:(lia))).
369
+ apply andb_true_r. }
370
+ destruct (Nat.lt_ge_cases i (15 + 2 * w + n)) as [H6|H6]; [|apply U1; right; exact H6].
371
+ replace i with (ST w (i - 15 - 2 * w)) by (unfold ST; lia). apply S1. lia.
372
+ Qed.
373
+
374
+ (* the first pass of a generation loads the initial state of the transducer *)
375
+ Lemma startup_first : forall v tau, reqclear (vw v) -> length (vw v) = W -> wget (vw v) BOOT = false -> vho v = false ->
376
+ td (vr v) = bbits tau ++ repeat false (L - 8 * length tau) ->
377
+ Rv false (init A (progPstar A) tau) [] [] (vrun Lb L (startup A w m) v).
378
+ Proof.
379
+ intros v tau Hq Hl Hb Hh Ht.
380
+ destruct (startup_run A w W Lb L m ltac:(lia) length_image HWs v Hq Hl)
381
+ as (Q & L1 & B1 & S1 & R1 & D1 & U1 & VR & VA & VC & VH).
382
+ cbv zeta in *. rewrite Hb in S1, R1, D1, VR, VA, VC.
383
+ unfold Rv, init. cbn [fst snd dhead drew dtape dout last isnil negb].
384
+ refine (conj Q (conj L1 (conj _ (conj B1 (conj _ (conj (init_valid A HA) (conj _ (conj _ (conj _ (conj _
385
+ (conj _ (conj _ (conj eq_refl (fun _ => eq_refl)))))))))))))).
386
+ - rewrite VH. exact Hh.
387
+ - intros i Hi. rewrite S1 by exact Hi. reflexivity.
388
+ - intros i Hi. rewrite (proj1 (R1 i Hi)), andb_false_r, Nat.bits_0. reflexivity.
389
+ - intros i Hi. rewrite (proj2 (R1 i Hi)), andb_false_r, Nat.bits_0. reflexivity.
390
+ - rewrite D1, andb_false_r. reflexivity.
391
+ - rewrite VR. unfold obt. rewrite Ht, Nat.mul_0_r, Nat.Div0.mod_0_l. reflexivity.
392
+ - rewrite VA. unfold obt. cbn [length bbits map concat app]. rewrite Nat.mul_0_r, Nat.sub_0_r, Nat.Div0.mod_0_l.
393
+ reflexivity.
394
+ - rewrite VC. unfold obt. cbn [length bbits map concat app]. rewrite Nat.mul_0_r, Nat.sub_0_r, Nat.Div0.mod_0_l.
395
+ reflexivity.
396
+ Qed.
397
+
398
+ (* ---- the values the device reads from a window that holds a state -------------------------------------- *)
399
+ Lemma word1v_holds : forall ww s j, holds ww s -> hvalid A s -> j < SW A -> word1v A w ww j = Nat.eqb (memv s j) 1.
400
+ Proof.
401
+ intros ww s j Hh Hv Hj. destruct Hv as (_ & Hl & Hf).
402
+ assert (Hm : memv s j < 2 ^ A) by (unfold memv; rewrite Forall_forall in Hf; apply Hf, nth_In; lia).
403
+ unfold word1v. rewrite (holds_MB ww s j 0 Hh Hl Hj ltac:(lia)).
404
+ rewrite <- (bits_one A (memv s j) ltac:(lia) Hm). f_equal.
405
+ apply forallb_ext_in'. intros t Ht. apply in_seq in Ht. rewrite (holds_MB ww s j t Hh Hl Hj ltac:(lia)). reflexivity.
406
+ Qed.
407
+
408
+ Lemma regs_eq : forall ww h lim, h < 2 ^ w -> lim < 2 ^ w ->
409
+ (forall i, i < w -> wget ww (CNT i) = Nat.testbit h i) -> (forall i, i < w -> wget ww (LIM w i) = Nat.testbit lim i) ->
410
+ eqv w ww = Nat.eqb h lim.
411
+ Proof.
412
+ intros ww h lim Hh Hlim Hc Hl. unfold eqv. rewrite <- (testbits_eqb w h lim Hh Hlim).
413
+ apply forallb_ext_in'. intros i Hi. apply in_seq in Hi. rewrite Hc, Hl by lia. reflexivity.
414
+ Qed.
415
+
416
+ Lemma cntv_eq : forall ww h, (forall i, i < w -> wget ww (CNT i) = Nat.testbit h i) ->
417
+ forall i, i < w -> cntv A w ww i = Nat.testbit (if gv A w ww then S h else h) i.
418
+ Proof.
419
+ intros ww h Hc i Hi. unfold cntv, carryv. rewrite Hc by exact Hi.
420
+ destruct (gv A w ww); cbn [andb].
421
+ - rewrite testbit_succ. f_equal. apply forallb_ext_in'. intros k Hk. apply in_seq in Hk. apply Hc. lia.
422
+ - rewrite xorb_false_r. reflexivity.
423
+ Qed.
424
+
425
+ Lemma outbits_eq : forall ww s, holds ww s -> length (hmem s) = SW A -> rout A < SW A ->
426
+ outbits A w ww = nat2bits 8 (memv s (rout A)).
427
+ Proof.
428
+ intros ww s Hh Hl Hr. unfold outbits. rewrite nat2bits_map. apply map_ext_in. intros k Hk. apply in_seq in Hk.
429
+ rewrite (holds_MB ww s (rout A) (7 - k) Hh Hl Hr ltac:(lia)). reflexivity.
430
+ Qed.
431
+
432
+ (* the cells of the counter, the halt bit and the words the device does not touch *)
433
+ Lemma ST_ndevw : forall i, i <= A -> ~ devw A w (ST w i).
434
+ Proof.
435
+ intros i Hi H. destruct H as [H|[(j & Hj & [E|E])|[E|(c0 & t & _ & Ht & E)]]];
436
+ unfold MB, DB, ST, CNT, LIM, DEST, nh, nH in *; nia.
437
+ Qed.
438
+
439
+ Lemma MB_ndevw : forall j t, j < SW A -> t < A -> j <> cwr A -> j <> crd A -> j <> crw A -> j <> rout A -> j <> rin A ->
440
+ j <> ceot A -> ~ devw A w (MB A w j t).
441
+ Proof.
442
+ intros j t Hj Ht N1 N2 N3 N4 N5 N6 H. pose proof (io_lt A w W HA Hw HW) as (I1 & I2 & I3 & I4 & I5 & I6).
443
+ pose proof (MB_range A w W HA Hw HW j t Hj Ht). pose proof (DB_gt A w W HA Hw HW j t Hj Ht).
444
+ destruct H as [H|[(i & Hi & [E|E])|[E|(c0 & t0 & Hc & Ht0 & E)]]]; [lia | unfold CNT in E; lia | unfold LIM in E; lia
445
+ | unfold DEST in E; lia |].
446
+ assert (Hc0 : c0 < SW A) by (destruct Hc as [->|[->|[->|[->|[->| ->]]]]]; assumption).
447
+ apply (MB_inj A w W HA Hw HW) in E as [E _]; [|assumption | assumption | assumption | assumption].
448
+ destruct Hc as [->|[->|[->|[->|[->| ->]]]]]; contradiction.
449
+ Qed.
450
+
451
+ (* ---- one step of the transducer: the records of H_A, the device, the padding and the hand-over ------------- *)
452
+ Theorem pass_step : forall c o1 o2 v p, Rv false c o1 o2 v -> hhalt (fst c) = false ->
453
+ Forall (fun x => x < 256) (dtape (snd c)) -> 8 * length (dtape (snd c)) <= L -> length (dtape (snd c)) < 2 ^ w ->
454
+ dhead (snd c) <= length (dtape (snd c)) ->
455
+ (isnil (drew (snd c)) = false -> last (drew (snd c)) 0 = length (dtape (snd c))) ->
456
+ (memv (subleq A (fst c)) (crd A) = 1 -> isnil (drew (snd c)) = true -> dhead (snd c) < length (dtape (snd c))) ->
457
+ (memv (subleq A (fst c)) (cwr A) = 1 -> isnil (drew (snd c)) = true -> 8 * S (length o1) <= Lb) ->
458
+ (memv (subleq A (fst c)) (cwr A) = 1 -> isnil (drew (snd c)) = false -> 8 * S (length o2) <= L) ->
459
+ 1 <= Lb -> 1 <= L ->
460
+ let s1 := subleq A (fst c) in
461
+ let x := memv s1 (rout A) mod 256 in
462
+ let wr := Nat.eqb (memv s1 (cwr A)) 1 in
463
+ let o1' := if wr && isnil (drew (snd c)) then o1 ++ [x] else o1 in
464
+ let o2' := if wr && negb (isnil (drew (snd c))) then o2 ++ [x] else o2 in
465
+ let c' := tstep A c in
466
+ Rv (hhalt (fst c')) c' o1' o2'
467
+ (vrun Lb L (step_go A w nu 0 (host_units A) nt ++ Stored.device A w nu lvs ++ repeat EMPTY p ++ handover A w) v).
468
+ Proof.
469
+ intros c o1 o2 v p HR Hh Hb8 HtL Htw Hhd Hlim Hlate Hca Hcc HLb HL. cbv zeta.
470
+ destruct c as [s d]. unfold tstep.
471
+ destruct HR as (Q0 & L0 & H0 & B0 & Hs & Hv & C0 & M0 & D0 & R0 & A0 & V0 & O0 & N0). cbn [negb] in B0.
472
+ cbn [fst snd] in *.
473
+ pose proof (SW256 A HA) as HS. pose proof (io_lt A w W HA Hw HW) as (I1 & I2 & I3 & I4 & I5 & I6).
474
+ set (s1 := subleq A s) in *.
475
+ assert (Hv1 : hvalid A s1) by (apply subleq_valid; assumption).
476
+ pose proof Hv1 as (_ & Hl1 & _).
477
+ rewrite !vrun_app.
478
+ (* the step of H_A *)
479
+ destruct (step_view v s Q0 L0 Hs Hv) as (Q1 & L1 & S1 & U1 & R1 & A1 & V1 & H1).
480
+ set (v1 := vrun Lb L (step_go A w nu 0 (host_units A) nt) v) in *.
481
+ assert (C1 : forall i, i < w -> wget (vw v1) (CNT i) = Nat.testbit (dhead d) i)
482
+ by (intros i Hi; rewrite U1 by (left; unfold CNT, ST; lia); apply C0, Hi).
483
+ assert (M1 : forall i, i < w -> wget (vw v1) (LIM w i) = Nat.testbit (last (drew d) 0) i)
484
+ by (intros i Hi; rewrite U1 by (left; unfold LIM, ST; lia); apply M0, Hi).
485
+ assert (D1 : wget (vw v1) (DEST w) = negb (isnil (drew d))) by (rewrite U1 by (left; unfold DEST, ST; lia); exact D0).
486
+ assert (B1 : wget (vw v1) BOOT = true) by (rewrite U1 by (left; unfold BOOT, ST; lia); exact B0).
487
+ (* what the device reads *)
488
+ set (rdb := Nat.eqb (memv s1 (crd A)) 1). set (okb := Nat.ltb (dhead d) (length (dtape d))).
489
+ set (rwb := Nat.eqb (memv s1 (crw A)) 1). set (wrb := Nat.eqb (memv s1 (cwr A)) 1).
490
+ assert (WR : wrv A w (vw v1) = wrb) by (apply word1v_holds; assumption).
491
+ assert (RD : rdv A w (vw v1) = rdb) by (apply word1v_holds; assumption).
492
+ assert (RW : rwv A w (vw v1) = rwb) by (apply word1v_holds; assumption).
493
+ assert (Hlim2 : last (drew d) 0 < 2 ^ w).
494
+ { destruct (isnil (drew d)) eqn:En; [|rewrite Hlim by reflexivity; exact Htw].
495
+ destruct (drew d); [|discriminate]. cbn [last]. pose proof (Nat.pow_nonzero 2 w ltac:(lia)). lia. }
496
+ assert (EQ : eqv w (vw v1) = Nat.eqb (dhead d) (last (drew d) 0)) by (apply regs_eq; try assumption; lia).
497
+ assert (G : gv A w (vw v1) = rdb && okb).
498
+ { unfold gv, eotv, destv. rewrite RD, EQ, D1.
499
+ destruct (isnil (drew d)) eqn:En; cbn [negb andb].
500
+ - rewrite andb_false_r. cbn [negb]. rewrite andb_true_r.
501
+ destruct rdb eqn:Er; [|reflexivity]. symmetry. apply Nat.ltb_lt.
502
+ apply Hlate; [apply Nat.eqb_eq; exact Er | first [exact En | reflexivity]].
503
+ - rewrite andb_true_r, Hlim by (first [exact En | reflexivity]). unfold okb. f_equal.
504
+ destruct (Nat.eqb_spec (dhead d) (length (dtape d))), (Nat.ltb_spec (dhead d) (length (dtape d))); cbn [negb]; lia. }
505
+ assert (EOT : rdb = true -> eotv w (vw v1) = negb okb).
506
+ { intro Er. unfold eotv, destv. rewrite EQ, D1. destruct (isnil (drew d)) eqn:En; cbn [negb andb].
507
+ - rewrite andb_false_r. unfold okb. rewrite (proj2 (Nat.ltb_lt _ _)); [reflexivity|].
508
+ apply Hlate; [apply Nat.eqb_eq; exact Er | first [exact En | reflexivity]].
509
+ - rewrite andb_true_r, Hlim by (first [exact En | reflexivity]). unfold okb.
510
+ destruct (Nat.eqb_spec (dhead d) (length (dtape d))), (Nat.ltb_spec (dhead d) (length (dtape d))); cbn [negb]; lia. }
511
+ assert (CA : cav A w (vw v1) = wrb && isnil (drew d)) by (unfold cav, destv; rewrite WR, D1, negb_involutive; reflexivity).
512
+ assert (CC : ccv A w (vw v1) = wrb && negb (isnil (drew d))) by (unfold ccv, destv; rewrite WR, D1; reflexivity).
513
+ assert (CN : forall i, i < w -> cntv A w (vw v1) i = Nat.testbit (if rdb && okb then S (dhead d) else dhead d) i)
514
+ by (intros i Hi; rewrite (cntv_eq (vw v1) (dhead d) C1 i Hi), G; reflexivity).
515
+ assert (OB : outbits A w (vw v1) = nat2bits 8 (memv s1 (rout A))) by (apply outbits_eq; assumption).
516
+ (* the device *)
517
+ destruct (device_run A w W Lb L HA Hw HW v1 Q1 L1)
518
+ as (Q2 & L2 & H2 & A2 & C2 & R2 & RO2 & RI2 & CE02 & CE2 & RQ2 & CL2 & D2 & U2).
519
+ cbv zeta in Q2, L2, H2, A2, C2, R2, RO2, RI2, CE02, CE2, RQ2, CL2, D2, U2.
520
+ set (v2 := vrun Lb L (Stored.device A w nu lvs) v1) in *.
521
+ rewrite (pad_run Lb L p v2 Q2).
522
+ (* the hand-over *)
523
+ assert (HWh : 15 + 2 * w + A < W) by (pose proof HWs; unfold nH in *; nia).
524
+ destruct (handover_run A w W Lb L HWh v2 Q2 L2) as (Q3 & L3 & U3 & R3 & A3 & C3 & H3).
525
+ cbv zeta in Q3, L3, U3, R3, A3, C3, H3.
526
+ set (v3 := vrun Lb L (handover A w) v2) in *.
527
+ assert (Hh3 : wget (vw v2) (ST w A) = hhalt s1).
528
+ { rewrite U2 by (apply ST_ndevw; lia). rewrite S1 by (unfold nH; lia). apply nth_encodeH_halt. }
529
+ rewrite Hh3 in U3, A3, C3, H3.
530
+ assert (W3 : forall y, y <> BOOT -> wget (vw v3) y = wget (vw v2) y)
531
+ by (intros y Hy; rewrite U3, (proj2 (Nat.eqb_neq _ _) Hy); reflexivity).
532
+ destruct (device_pc A s1 d) as (Dp & Dh & Dl).
533
+ set (d' := snd (device A s1 d)).
534
+ assert (Hd' : dtape d' = dtape d
535
+ /\ dhead d' = (if rwb then 0 else if rdb && okb then S (dhead d) else dhead d)
536
+ /\ drew d' = (if rwb then drew d ++ [if rdb && okb then S (dhead d) else dhead d] else drew d)
537
+ /\ dout d' = (if wrb then dout d ++ [memv s1 (rout A) mod 256] else dout d))
538
+ by (unfold d', device; cbv zeta; cbn [snd dtape dhead drew dout]; repeat split).
539
+ destruct Hd' as (Td & Hdh & Hdr & Hdo).
540
+ rewrite Dh. unfold Rv. fold d'. rewrite Td, Hdh, Hdr, Hdo.
541
+ refine (conj Q3 (conj L3 (conj _ (conj _ (conj _ (conj (device_valid A HA s1 d Hv1 Hb8) (conj _ (conj _ (conj _
542
+ (conj _ (conj _ (conj _ (conj _ _))))))))))))).
543
+ - (* the hand-over flag *) rewrite H3, H2, H1, H0. reflexivity.
544
+ - (* booted *) rewrite U3, Nat.eqb_refl. rewrite U2 by (unfold devw; intro H; unfold BOOT, DB, CNT, LIM, DEST, MB, ST in *;
545
+ destruct H as [H|[(j & Hj & [E|E])|[E|(c0 & t & _ & Ht & E)]]]; lia). rewrite B1. reflexivity.
546
+ - (* the state of the host *)
547
+ apply holds_of; [exact Dl | | |].
548
+ + intros i Hi. rewrite W3 by (unfold ST, BOOT; lia). rewrite U2 by (apply ST_ndevw; lia).
549
+ rewrite S1 by (unfold nH; lia). rewrite nth_encodeH_pc by exact Hi. rewrite Dp. reflexivity.
550
+ + rewrite W3 by (unfold ST, BOOT; lia). rewrite Hh3. symmetry. apply Dh.
551
+ + intros j t Hj Ht. rewrite W3 by (pose proof (MB_range A w W HA Hw HW j t Hj Ht); unfold BOOT; lia).
552
+ rewrite (memv_device A HA s1 d j Hj). fold rdb okb wrb.
553
+ destruct (Nat.eqb_spec j (cwr A)) as [->|N1].
554
+ { cbn [orb]. rewrite RQ2 by (auto; lia). rewrite Nat.bits_0. reflexivity. }
555
+ destruct (Nat.eqb_spec j (crd A)) as [->|N2].
556
+ { cbn [orb]. rewrite RQ2 by (auto; lia). rewrite Nat.bits_0. reflexivity. }
557
+ destruct (Nat.eqb_spec j (crw A)) as [->|N3].
558
+ { cbn [orb]. rewrite RQ2 by (auto; lia). rewrite Nat.bits_0. reflexivity. }
559
+ cbn [orb].
560
+ destruct (Nat.eqb_spec j (rout A)) as [->|N4].
561
+ { rewrite RO2 by exact Ht. rewrite (holds_MB (vw v1) s1 (rout A) t S1 Hl1 I6 Ht), WR.
562
+ destruct wrb; cbn [negb]; [rewrite andb_false_r, Nat.bits_0 | rewrite andb_true_r]; reflexivity. }
563
+ destruct (Nat.eqb_spec j (rin A)) as [->|N5].
564
+ { rewrite RI2 by exact Ht. rewrite G, R1, R0.
565
+ destruct (rdb && okb) eqn:Eg.
566
+ - apply andb_prop in Eg as [_ Eo]. apply Nat.ltb_lt in Eo. unfold obt. cbn [td th].
567
+ rewrite read_bit by assumption.
568
+ rewrite testbit_sext by (try assumption; rewrite Forall_forall in Hb8; apply Hb8, nth_In; exact Eo).
569
+ reflexivity.
570
+ - apply (holds_MB (vw v1) s1 (rin A) t S1 Hl1 I5 Ht). }
571
+ destruct (Nat.eqb_spec j (ceot A)) as [->|N6].
572
+ { destruct (Nat.eq_dec t 0) as [->|Ht0].
573
+ - rewrite CE02, RD. destruct rdb eqn:Er.
574
+ + rewrite (EOT eq_refl). destruct okb; reflexivity.
575
+ + apply (holds_MB (vw v1) s1 (ceot A) 0 S1 Hl1 I2 Ht).
576
+ - rewrite CE2 by lia. rewrite RD, (holds_MB (vw v1) s1 (ceot A) t S1 Hl1 I2 Ht).
577
+ destruct rdb; cbn [negb]; [rewrite andb_false_r | rewrite andb_true_r; reflexivity].
578
+ destruct okb; [rewrite Nat.bits_0; reflexivity|]. symmetry. apply testbit_lt_false.
579
+ apply (Nat.lt_le_trans _ (2 ^ 1)); [cbn; lia | apply Nat.pow_le_mono_r; lia]. }
580
+ rewrite U2 by (apply MB_ndevw; assumption). apply holds_MB; assumption.
581
+ - (* the count *)
582
+ intros i Hi. rewrite W3 by (unfold CNT, BOOT; lia). rewrite (proj1 (CL2 i Hi)), CN, RW by exact Hi.
583
+ destruct rwb; cbn [negb]; [rewrite andb_false_r, Nat.bits_0 | rewrite andb_true_r]; reflexivity.
584
+ - (* the limit *)
585
+ intros i Hi. rewrite W3 by (unfold LIM, BOOT; lia). rewrite (proj2 (CL2 i Hi)), RW.
586
+ destruct rwb; [rewrite last_last; apply CN; exact Hi | apply M1; exact Hi].
587
+ - (* dest *)
588
+ rewrite W3 by (unfold DEST, BOOT; lia). rewrite D2. unfold destv. rewrite D1, RW.
589
+ destruct rwb; [rewrite orb_true_r; destruct (drew d); reflexivity | apply orb_false_r].
590
+ - (* the read tape *)
591
+ rewrite R3, R2, R1, R0, RW, G. unfold obt. cbn [td th]. f_equal.
592
+ destruct rwb; [symmetry; apply Nat.Div0.mod_0_l|].
593
+ destruct (rdb && okb); [|reflexivity]. rewrite adv_mod by exact HL. f_equal. lia.
594
+ - (* the arm *)
595
+ rewrite A3, A2, A1, A0, CA, OB. cbn [orb].
596
+ assert (Ea : (if wrb && isnil (drew d) then wseq Lb (nat2bits 8 (memv s1 (rout A))) (obt Lb o1 (length o1))
597
+ else obt Lb o1 (length o1))
598
+ = obt Lb (if wrb && isnil (drew d) then o1 ++ [memv s1 (rout A) mod 256] else o1)
599
+ (length (if wrb && isnil (drew d) then o1 ++ [memv s1 (rout A) mod 256] else o1))).
600
+ { destruct (wrb && isnil (drew d)) eqn:Ew; [|reflexivity].
601
+ apply andb_prop in Ew as [Ew En]. apply wseq_byte. apply Hca; [apply Nat.eqb_eq; exact Ew | exact En]. }
602
+ rewrite Ea. destruct (hhalt s1); [|reflexivity]. unfold obt. cbn [td]. rewrite Nat.mul_0_r, Nat.Div0.mod_0_l.
603
+ reflexivity.
604
+ - (* the copy tape *)
605
+ rewrite C3, C2, V1, V0, CC, OB. cbn [orb].
606
+ assert (Ec : (if wrb && negb (isnil (drew d)) then wseq L (nat2bits 8 (memv s1 (rout A))) (obt L o2 (length o2))
607
+ else obt L o2 (length o2))
608
+ = obt L (if wrb && negb (isnil (drew d)) then o2 ++ [memv s1 (rout A) mod 256] else o2)
609
+ (length (if wrb && negb (isnil (drew d)) then o2 ++ [memv s1 (rout A) mod 256] else o2))).
610
+ { destruct (wrb && negb (isnil (drew d))) eqn:Ew; [|reflexivity].
611
+ apply andb_prop in Ew as [Ew En]. apply wseq_byte. apply Hcc; [apply Nat.eqb_eq; exact Ew | destruct (isnil (drew d)); [discriminate | reflexivity]]. }
612
+ rewrite Ec. destruct (hhalt s1); [|reflexivity]. unfold obt. cbn [td]. rewrite Nat.mul_0_r, Nat.Div0.mod_0_l.
613
+ reflexivity.
614
+ - (* the output *)
615
+ rewrite O0. destruct wrb; [|reflexivity]. cbn [andb].
616
+ destruct (isnil (drew d)) eqn:En; cbn [negb].
617
+ + rewrite (N0 ltac:(first [exact En | reflexivity])), !app_nil_r. reflexivity.
618
+ + rewrite <- app_assoc. reflexivity.
619
+ - (* nothing after a rewind before one is requested *)
620
+ destruct rwb; [destruct (drew d); discriminate|]. intro En. rewrite (N0 En), En. destruct wrb; reflexivity.
621
+ Qed.
622
+
623
+ (* ---- a pass of the whole image ------------------------------------------------------------------------------- *)
624
+ Lemma stored_split : stored A w = startup A w m ++ step_go A w nu 0 (host_units A) nt ++ Stored.device A w nu lvs
625
+ ++ repeat EMPTY (padn (alS A w) (length (startup A w m ++ step_go A w nu 0 (host_units A) nt ++ Stored.device A w nu lvs)))
626
+ ++ handover A w.
627
+ Proof. unfold stored, alS, stored_of. cbv zeta. cbn [fst snd]. rewrite <- !app_assoc. reflexivity. Qed.
628
+
629
+ (* the conditions under which a pass carries out the step from c *)
630
+ Definition step_ok (c : hst * dev) (o1 o2 : list nat) : Prop :=
631
+ hhalt (fst c) = false /\ Forall (fun x => x < 256) (dtape (snd c)) /\ 8 * length (dtape (snd c)) <= L
632
+ /\ length (dtape (snd c)) < 2 ^ w /\ dhead (snd c) <= length (dtape (snd c))
633
+ /\ (isnil (drew (snd c)) = false -> last (drew (snd c)) 0 = length (dtape (snd c)))
634
+ /\ (memv (subleq A (fst c)) (crd A) = 1 -> isnil (drew (snd c)) = true -> dhead (snd c) < length (dtape (snd c)))
635
+ /\ (memv (subleq A (fst c)) (cwr A) = 1 -> isnil (drew (snd c)) = true -> 8 * S (length o1) <= Lb)
636
+ /\ (memv (subleq A (fst c)) (cwr A) = 1 -> isnil (drew (snd c)) = false -> 8 * S (length o2) <= L)
637
+ /\ 1 <= Lb /\ 1 <= L.
638
+
639
+ (* the bytes emitted under the arm and under the copy head by the step from c *)
640
+ Definition out1 (c : hst * dev) (o1 : list nat) : list nat :=
641
+ if Nat.eqb (memv (subleq A (fst c)) (cwr A)) 1 && isnil (drew (snd c))
642
+ then o1 ++ [memv (subleq A (fst c)) (rout A) mod 256] else o1.
643
+ Definition out2 (c : hst * dev) (o2 : list nat) : list nat :=
644
+ if Nat.eqb (memv (subleq A (fst c)) (cwr A)) 1 && negb (isnil (drew (snd c)))
645
+ then o2 ++ [memv (subleq A (fst c)) (rout A) mod 256] else o2.
646
+
647
+ Lemma pass_rest : forall c o1 o2 v p, Rv false c o1 o2 v -> step_ok c o1 o2 ->
648
+ Rv (hhalt (fst (tstep A c))) (tstep A c) (out1 c o1) (out2 c o2)
649
+ (vrun Lb L (step_go A w nu 0 (host_units A) nt ++ Stored.device A w nu lvs ++ repeat EMPTY p ++ handover A w) v).
650
+ Proof.
651
+ intros c o1 o2 v p HR (H1 & H2 & H3 & H4 & H5 & H6 & H7 & H8 & H9 & H10 & H11).
652
+ exact (pass_step c o1 o2 v p HR H1 H2 H3 H4 H5 H6 H7 H8 H9 H10 H11).
653
+ Qed.
654
+
655
+ (* a pass once booted *)
656
+ Theorem pass_next : forall c o1 o2 v, Rv false c o1 o2 v -> step_ok c o1 o2 ->
657
+ Rv (hhalt (fst (tstep A c))) (tstep A c) (out1 c o1) (out2 c o2) (vrun Lb L (stored A w) v).
658
+ Proof.
659
+ intros c o1 o2 v HR Hok. pose proof HR as (Q & Hl & _ & B & _).
660
+ rewrite stored_split, vrun_app, (startup_booted v Q Hl B). apply pass_rest; assumption.
661
+ Qed.
662
+
663
+ (* the first pass of a generation: the startup loads the initial state of the transducer on the tape, which
664
+ it then steps *)
665
+ Theorem pass_first : forall v tau, reqclear (vw v) -> length (vw v) = W -> wget (vw v) BOOT = false -> vho v = false ->
666
+ td (vr v) = bbits tau ++ repeat false (L - 8 * length tau) -> step_ok (init A (progPstar A) tau) [] [] ->
667
+ Rv (hhalt (fst (tstep A (init A (progPstar A) tau)))) (tstep A (init A (progPstar A) tau))
668
+ (out1 (init A (progPstar A) tau) []) (out2 (init A (progPstar A) tau) []) (vrun Lb L (stored A w) v).
669
+ Proof.
670
+ intros v tau Hq Hl Hb Hh Ht Hok. rewrite stored_split, vrun_app. apply pass_rest; [|exact Hok].
671
+ apply startup_first; assumption.
672
+ Qed.
673
+
674
+ End Pass.
rocq/StoredRun.v ADDED
@@ -0,0 +1,565 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* The stored host runs P* on a recipe by the dynamics of the ring machine (Theorem 8.6): a pass of its records
2
+ for each step of the transducer, the bytes it decodes written under the arm and the recipe under the copy
3
+ head, and the hand-over at the halt. *)
4
+ From Stdlib Require Import List Bool Arith ZArith Lia.
5
+ Import ListNotations.
6
+ From TH Require Import TwoHead Net Abstract Indep Run PhysSem PhysMain View Stored WinRun ViewOps Host HostSem
7
+ Device Pstar StoredStep StoredBoot StoredDev StoredPass StoredOk.
8
+
9
+ (* ---- lists that grow at their end ------------------------------------------------------------------------ *)
10
+ Definition prefix (a b : list nat) : Prop := exists o, b = a ++ o.
11
+
12
+ Lemma prefix_refl : forall a, prefix a a.
13
+ Proof. intro a. exists []. rewrite app_nil_r. reflexivity. Qed.
14
+
15
+ Lemma prefix_trans : forall a b c, prefix a b -> prefix b c -> prefix a c.
16
+ Proof. intros a b c [o1 ->] [o2 ->]. exists (o1 ++ o2). rewrite app_assoc. reflexivity. Qed.
17
+
18
+ Lemma prefix_length : forall a b, prefix a b -> length a <= length b.
19
+ Proof. intros a b [o ->]. rewrite length_app. lia. Qed.
20
+
21
+ Lemma prefix_nil : forall a, prefix a [] -> a = [].
22
+ Proof. intros a [o E]. destruct a; [reflexivity | discriminate]. Qed.
23
+
24
+ Lemma prefix_app : forall a b c, prefix (a ++ b) (a ++ c) -> prefix b c.
25
+ Proof. intros a b c [o E]. exists o. rewrite <- app_assoc in E. apply app_inv_head in E. exact E. Qed.
26
+
27
+ Lemma prefix_antisym : forall a b, prefix a b -> prefix b a -> a = b.
28
+ Proof.
29
+ intros a b [o1 E1] [o2 E2]. rewrite E1, <- app_assoc in E2.
30
+ assert (Hl : length (o1 ++ o2) = 0) by (apply (f_equal (@length nat)) in E2; rewrite length_app in E2; lia).
31
+ destruct o1; [rewrite app_nil_r in E1; symmetry; exact E1 | cbn in Hl; lia].
32
+ Qed.
33
+
34
+ (* ---- the device along a run ---------------------------------------------------------------------------------- *)
35
+ Section Dev.
36
+ Variable A : nat.
37
+
38
+ Lemma tstep_snd : forall c,
39
+ dtape (snd (tstep A c)) = dtape (snd c)
40
+ /\ dout (snd (tstep A c)) = (if Nat.eqb (memv (subleq A (fst c)) (cwr A)) 1
41
+ then dout (snd c) ++ [memv (subleq A (fst c)) (rout A) mod 256] else dout (snd c))
42
+ /\ prefix (drew (snd c)) (drew (snd (tstep A c)))
43
+ /\ dlate (snd (tstep A c)) = dlate (snd c) || (Nat.eqb (memv (subleq A (fst c)) (crd A)) 1
44
+ && negb (Nat.ltb (dhead (snd c)) (length (dtape (snd c)))) && isnil (drew (snd c)))
45
+ /\ (dhead (snd c) <= length (dtape (snd c)) -> dhead (snd (tstep A c)) <= length (dtape (snd c))).
46
+ Proof.
47
+ intro c. unfold tstep, device. cbv zeta. cbn [snd dtape dout drew dlate dhead].
48
+ refine (conj eq_refl (conj eq_refl (conj _ (conj _ _)))).
49
+ - destruct (Nat.eqb (memv (subleq A (fst c)) (crw A)) 1); [eexists; reflexivity | apply prefix_refl].
50
+ - unfold isnil. reflexivity.
51
+ - intro H. destruct (Nat.eqb (memv (subleq A (fst c)) (crw A)) 1); [lia|].
52
+ destruct (_ && _) eqn:E; [|exact H]. apply andb_prop in E as [_ E]. apply Nat.ltb_lt in E. lia.
53
+ Qed.
54
+
55
+ Lemma trun_snd : forall n c,
56
+ dtape (snd (trun A n c)) = dtape (snd c) /\ prefix (dout (snd c)) (dout (snd (trun A n c)))
57
+ /\ prefix (drew (snd c)) (drew (snd (trun A n c))) /\ (dlate (snd c) = true -> dlate (snd (trun A n c)) = true)
58
+ /\ (dhead (snd c) <= length (dtape (snd c)) -> dhead (snd (trun A n c)) <= length (dtape (snd c))).
59
+ Proof.
60
+ induction n as [|n IH]; intro c; cbn [trun].
61
+ - exact (conj eq_refl (conj (prefix_refl _) (conj (prefix_refl _) (conj (fun H => H) (fun H => H))))).
62
+ - destruct (tstep_snd c) as (T1 & O1 & R1 & D1 & H1). destruct (IH (tstep A c)) as (T2 & O2 & R2 & D2 & H2).
63
+ rewrite T1 in T2, H2. refine (conj T2 (conj _ (conj (prefix_trans _ _ _ R1 R2) (conj _ _)))).
64
+ + eapply prefix_trans; [|exact O2]. rewrite O1. destruct (_ =? 1); [eexists; reflexivity | apply prefix_refl].
65
+ + intro H. apply D2. rewrite D1, H. reflexivity.
66
+ + intro H. apply H2, H1, H.
67
+ Qed.
68
+
69
+ Lemma trun_S : forall n c, trun A (S n) c = tstep A (trun A n c).
70
+ Proof. intros n c. replace (S n) with (n + 1) by lia. rewrite trun_add. reflexivity. Qed.
71
+
72
+ End Dev.
73
+
74
+ (* ---- the run of P* on a recipe, in three phases ---------------------------------------------------------- *)
75
+ Section Phases.
76
+ Variables (A : nat) (ks : list token).
77
+ Hypotheses (HA : 8 <= A) (Hks : Forall tok_ok ks).
78
+
79
+ Local Notation tau := (recipe ks).
80
+ Definition c0 : hst * dev := init A (progPstar A) (recipe ks).
81
+ Definition n0 : nat := dsteps ks + 7.
82
+ Definition NN : nat := dsteps ks + 7 + 1 + (6 * length (recipe ks) + 2).
83
+ Definition cr (t : nat) : hst * dev := trun A t c0.
84
+
85
+ Lemma Htl : length (tailS A) <= 7.
86
+ Proof. cbn. lia. Qed.
87
+
88
+ (* the decoding: the decoded bytes emitted and the head at the end of the recipe *)
89
+ Lemma phase_A : Reach A c0 n0 (fun c => At A (tailS A) tau c 60 (V 0 0 0 0 0 1 0) (length tau) (delta ks) false []).
90
+ Proof.
91
+ destruct (end_At A HA (tailS A) Htl tau ks eq_refl) as (E1 & E2 & E3).
92
+ assert (Hs : skipn 0 tau = concat (map enc ks) ++ [0]) by reflexivity.
93
+ unfold n0, c0. rewrite E3.
94
+ apply (reach_seq A _ (dsteps ks) 7
95
+ (fun c => exists t1 t2 r e, At A (tailS A) tau c 0 (V t1 t2 0 r 0 1 e) (length (concat (map enc ks))) (delta ks) false [])).
96
+ - eapply reach_mono; [exact (decode A HA (tailS A) Htl tau ks _ 0 0 0 0 1 0 [] false [] [0] Hks
97
+ (init_At A HA (tailS A) Htl tau) Hs)|].
98
+ intros c (t1 & t2 & r & e & St). exists t1, t2, r, e. exact St.
99
+ - intros c (t1 & t2 & r & e & St). exact (end_tok A HA (tailS A) Htl tau c t1 t2 r e 1 _ (delta ks) false [] St E1 E2).
100
+ Qed.
101
+
102
+ (* the rewind *)
103
+ Lemma phase_R : Reach A c0 (S n0) (fun c => At A (tailS A) tau c 63 (V 0 0 0 0 0 1 0) 0 (delta ks) false [length tau]).
104
+ Proof.
105
+ replace (S n0) with (n0 + 1) by lia. apply (reach_seq A _ n0 1 _ _ phase_A).
106
+ intros c St. exact (rew_S A HA (tailS A) Htl tau eq_refl c _ _ _ _ _ St).
107
+ Qed.
108
+
109
+ (* the copy *)
110
+ Lemma phase_B : Reach A c0 NN (fun c => hhalt (fst c) = true
111
+ /\ snd c = mkD tau (length tau) (delta ks ++ tau) false [length tau]).
112
+ Proof.
113
+ unfold NN. replace (dsteps ks + 7 + 1 + (6 * length tau + 2)) with (S n0 + (6 * length tau + 2)) by (unfold n0; lia).
114
+ apply (reach_seq A _ (S n0) _ _ _ phase_R). intros c St.
115
+ apply (copy_loop A HA (tailS A) Htl tau eq_refl tau c 0 0 0 0 0 (delta ks) [length tau] St); [reflexivity | lia | discriminate|].
116
+ apply recipe_bytes. exact Hks.
117
+ Qed.
118
+
119
+ Lemma not_halted : forall t, t < NN -> hhalt (fst (cr t)) = false.
120
+ Proof. intros t Ht. exact (proj1 phase_B t Ht). Qed.
121
+
122
+ Lemma at_n0 : snd (cr n0) = mkD tau (length tau) (delta ks) false [].
123
+ Proof. destruct (proj2 phase_A) as (_ & _ & _ & _ & _ & E). exact E. Qed.
124
+
125
+ Lemma at_n1 : snd (cr (S n0)) = mkD tau 0 (delta ks) false [length tau].
126
+ Proof. destruct (proj2 phase_R) as (_ & _ & _ & _ & _ & E). exact E. Qed.
127
+
128
+ Lemma at_NN : hhalt (fst (cr NN)) = true /\ snd (cr NN) = mkD tau (length tau) (delta ks ++ tau) false [length tau].
129
+ Proof. exact (proj2 phase_B). Qed.
130
+
131
+ Lemma n0_NN : S n0 < NN.
132
+ Proof. unfold n0, NN. lia. Qed.
133
+
134
+ Lemma cr_S : forall t, cr (S t) = tstep A (cr t).
135
+ Proof. intro t. unfold cr. apply trun_S. Qed.
136
+
137
+ Lemma cr_add : forall t k, cr (t + k) = trun A k (cr t).
138
+ Proof. intros t k. unfold cr. apply trun_add. Qed.
139
+
140
+ (* ---- the device along the run ----------------------------------------------------------------------------- *)
141
+ Lemma inv_tape : forall t, dtape (snd (cr t)) = tau.
142
+ Proof. intro t. unfold cr. rewrite (proj1 (trun_snd A t c0)). reflexivity. Qed.
143
+
144
+ Lemma inv_head : forall t, dhead (snd (cr t)) <= length tau.
145
+ Proof.
146
+ intro t. unfold cr. destruct (trun_snd A t c0) as (_ & _ & _ & _ & H). apply H. cbn. lia.
147
+ Qed.
148
+
149
+ Lemma inv_early : forall t, t <= n0 -> drew (snd (cr t)) = [] /\ prefix (dout (snd (cr t))) (delta ks).
150
+ Proof.
151
+ intros t Ht. pose proof (cr_add t (n0 - t)) as E. replace (t + (n0 - t)) with n0 in E by lia.
152
+ destruct (trun_snd A (n0 - t) (cr t)) as (_ & O & R & _ & _). rewrite <- E, at_n0 in O, R. cbn [drew dout] in O, R.
153
+ split; [apply prefix_nil, R | exact O].
154
+ Qed.
155
+
156
+ Lemma inv_late : forall t, S n0 <= t <= NN ->
157
+ drew (snd (cr t)) = [length tau] /\ exists o, dout (snd (cr t)) = delta ks ++ o /\ prefix o tau.
158
+ Proof.
159
+ intros t Ht. pose proof (cr_add (S n0) (t - S n0)) as E1. replace (S n0 + (t - S n0)) with t in E1 by lia.
160
+ pose proof (cr_add t (NN - t)) as E2. replace (t + (NN - t)) with NN in E2 by lia.
161
+ destruct (trun_snd A (t - S n0) (cr (S n0))) as (_ & O1 & R1 & _ & _). rewrite <- E1, at_n1 in O1, R1.
162
+ destruct (trun_snd A (NN - t) (cr t)) as (_ & O2 & R2 & _ & _). rewrite <- E2, (proj2 at_NN) in O2, R2.
163
+ cbn [drew dout] in O1, R1, O2, R2. split; [exact (eq_sym (prefix_antisym _ _ R1 R2))|].
164
+ destruct O1 as [o Eo]. exists o. split; [exact Eo|]. rewrite Eo in O2. exact (prefix_app _ _ _ O2).
165
+ Qed.
166
+
167
+ Lemma inv_nolate : forall t, t <= NN -> dlate (snd (cr t)) = false.
168
+ Proof.
169
+ intros t Ht. pose proof (cr_add t (NN - t)) as E. replace (t + (NN - t)) with NN in E by lia.
170
+ destruct (dlate (snd (cr t))) eqn:D; [|reflexivity].
171
+ destruct (trun_snd A (NN - t) (cr t)) as (_ & _ & _ & L & _). specialize (L D). rewrite <- E, (proj2 at_NN) in L.
172
+ discriminate.
173
+ Qed.
174
+
175
+ (* no byte is requested at the end of the tape before the rewind *)
176
+ Lemma inv_read : forall t, t < NN -> memv (subleq A (fst (cr t))) (crd A) = 1 -> isnil (drew (snd (cr t))) = true ->
177
+ dhead (snd (cr t)) < length (dtape (snd (cr t))).
178
+ Proof.
179
+ intros t Ht Hrd Hn. destruct (Nat.ltb_spec (dhead (snd (cr t))) (length (dtape (snd (cr t))))) as [H|H]; [exact H|].
180
+ exfalso. pose proof (inv_nolate (S t) ltac:(lia)) as L. rewrite cr_S in L.
181
+ destruct (tstep_snd A (cr t)) as (_ & _ & _ & D & _). rewrite D, Hrd, Hn in L. cbn [Nat.eqb andb orb] in L.
182
+ rewrite (proj2 (Nat.ltb_ge _ _) H) in L. rewrite orb_true_r in L. discriminate.
183
+ Qed.
184
+
185
+ (* ---- the bytes written under the arm and under the copy head ----------------------------------------------- *)
186
+ Fixpoint outs (t : nat) : list nat * list nat :=
187
+ match t with
188
+ | O => ([], [])
189
+ | S t' => (out1 A (cr t') (fst (outs t')), out2 A (cr t') (snd (outs t')))
190
+ end.
191
+
192
+ Lemma outs_early : forall t, t <= S n0 -> fst (outs t) = dout (snd (cr t)) /\ snd (outs t) = [].
193
+ Proof.
194
+ induction t as [|t IH]; intro Ht; [split; reflexivity|].
195
+ destruct (IH ltac:(lia)) as [O1 O2]. destruct (inv_early t ltac:(lia)) as [Rn _].
196
+ cbn [outs fst snd]. unfold out1, out2. rewrite Rn, O1, O2. cbn [isnil negb]. rewrite andb_false_r, andb_true_r.
197
+ split; [|reflexivity]. rewrite cr_S. destruct (tstep_snd A (cr t)) as (_ & Eo & _). rewrite Eo. reflexivity.
198
+ Qed.
199
+
200
+ Lemma outs_late : forall t, S n0 <= t <= NN -> fst (outs t) = delta ks /\ dout (snd (cr t)) = delta ks ++ snd (outs t).
201
+ Proof.
202
+ intros t Ht. induction t as [|t IH]; [lia|].
203
+ destruct (Nat.eq_dec (S t) (S n0)) as [E|E].
204
+ - injection E as ->. destruct (outs_early (S n0) (le_n _)) as [O1 O2]. rewrite O1, O2, at_n1. cbn [dout].
205
+ rewrite app_nil_r. split; reflexivity.
206
+ - destruct (IH ltac:(lia)) as [O1 O2]. destruct (inv_late t ltac:(lia)) as [Rn _].
207
+ cbn [outs fst snd]. unfold out1, out2. rewrite Rn, O1. cbn [isnil negb]. rewrite andb_false_r, andb_true_r.
208
+ split; [reflexivity|]. rewrite cr_S. destruct (tstep_snd A (cr t)) as (_ & Eo & _). rewrite Eo, O2.
209
+ destruct (_ =? 1); [rewrite app_assoc|]; reflexivity.
210
+ Qed.
211
+
212
+ Lemma cap1 : forall t, t < NN -> memv (subleq A (fst (cr t))) (cwr A) = 1 -> isnil (drew (snd (cr t))) = true ->
213
+ S (length (fst (outs t))) <= length (delta ks).
214
+ Proof.
215
+ intros t Ht Hwr Hn. destruct (Nat.le_gt_cases t n0) as [H|H].
216
+ 2:{ rewrite (proj1 (inv_late t ltac:(lia))) in Hn. discriminate. }
217
+ destruct (outs_early (S t) ltac:(lia)) as [O1 _]. cbn [outs fst] in O1. unfold out1 in O1. rewrite Hn, Hwr in O1.
218
+ cbn [Nat.eqb andb] in O1. apply (f_equal (@length nat)) in O1. rewrite length_app in O1. cbn [length] in O1.
219
+ rewrite Nat.add_1_r in O1. rewrite O1.
220
+ destruct (Nat.eq_dec (S t) (S n0)) as [E|E].
221
+ - rewrite E, at_n1. cbn [dout]. lia.
222
+ - apply prefix_length. exact (proj2 (inv_early (S t) ltac:(lia))).
223
+ Qed.
224
+
225
+ Lemma cap2 : forall t, t < NN -> memv (subleq A (fst (cr t))) (cwr A) = 1 -> isnil (drew (snd (cr t))) = false ->
226
+ S (length (snd (outs t))) <= length tau.
227
+ Proof.
228
+ intros t Ht Hwr Hn. destruct (Nat.le_gt_cases t n0) as [H|H].
229
+ { rewrite (proj1 (inv_early t H)) in Hn. discriminate. }
230
+ destruct (outs_late (S t) ltac:(lia)) as [_ O2]. destruct (inv_late (S t) ltac:(lia)) as [_ (o & Eo & Po)].
231
+ rewrite Eo in O2. apply app_inv_head in O2. cbn [outs snd] in O2. unfold out2 in O2. rewrite Hn, Hwr in O2.
232
+ cbn [Nat.eqb negb andb] in O2. apply prefix_length in Po. rewrite O2, length_app in Po. cbn [length] in Po. lia.
233
+ Qed.
234
+
235
+ End Phases.
236
+
237
+ (* ---- the hand-over request ------------------------------------------------------------------------------------ *)
238
+ Section Ho.
239
+ Variables (Lb L : nat).
240
+
241
+ Lemma vexec_vho_mono : forall r v, vho v = true -> vho (vexec Lb L r v) = true.
242
+ Proof. intros r v H. unfold vexec, vput. cbn [vho]. rewrite H. reflexivity. Qed.
243
+
244
+ Lemma vrun_vho_mono : forall l v, vho v = true -> vho (vrun Lb L l v) = true.
245
+ Proof. induction l as [|r l IH]; intros v H; [exact H|]. cbn [vrun]. apply IH, vexec_vho_mono, H. Qed.
246
+
247
+ Lemma vexec_noho : forall r v, reqclear (vw v) -> ao_of r <> HO ->
248
+ vho (vexec Lb L r v) = vho v /\ reqclear (vw (vexec Lb L r v)).
249
+ Proof.
250
+ intros r v Hq Ho. unfold vexec, vput. cbn [vho vw]. split.
251
+ - unfold wnext. destruct (Nat.leb (ao_of r) CPY); [rewrite (Hq HO) by (unfold AR, HO; lia)|].
252
+ + apply orb_false_r.
253
+ + rewrite wget_upd. replace (Nat.eqb HO (ao_of r)) with false by (symmetry; apply Nat.eqb_neq; congruence).
254
+ rewrite (Hq HO) by (unfold AR, HO; lia). apply orb_false_r.
255
+ - intros c Hc. apply wget_clearq_req. exact Hc.
256
+ Qed.
257
+
258
+ Lemma vrun_noho : forall l v, reqclear (vw v) -> Forall (fun r => ao_of r <> HO) l -> vho (vrun Lb L l v) = vho v.
259
+ Proof.
260
+ induction l as [|r l IH]; intros v Hq Hf; [reflexivity|]. apply Forall_cons_iff in Hf as [Hr Hf].
261
+ cbn [vrun]. destruct (vexec_noho r v Hq Hr) as [E Q]. rewrite IH by assumption. exact E.
262
+ Qed.
263
+
264
+ End Ho.
265
+
266
+ Lemma Forall_firstn' : forall (T : Type) (P : T -> Prop) l j, Forall P l -> Forall P (firstn j l).
267
+ Proof. intros T P l j H. rewrite <- (firstn_skipn j l) in H. apply Forall_app in H. exact (proj1 H). Qed.
268
+
269
+ Lemma wrec_noho : forall r, wrec r -> ao_of r <> HO.
270
+ Proof. intros [a0 w0 a1 w1 beta ao] (_ & _ & H). cbn [ao_of]. unfold SINK, HO in *. lia. Qed.
271
+
272
+ (* ---- the records of the stored host but the last request no hand-over --------------------------------------- *)
273
+ Section Body.
274
+ Variables (A w : nat).
275
+ Hypotheses (HA : 8 <= A) (Hw : 1 <= w).
276
+
277
+ Local Notation nu := (length (host_units A)).
278
+ Local Notation lvs := (levels (host_units A)).
279
+ Local Notation m := (image A (progPstar A)).
280
+
281
+ Definition body : list rec :=
282
+ startup A w m ++ step_go A w nu 0 (host_units A) (next_tbl (nH A) nu (host_next A)) ++ Stored.device A w nu lvs
283
+ ++ repeat EMPTY (padn (alS A w) (length (startup A w m ++ step_go A w nu 0 (host_units A) (next_tbl (nH A) nu (host_next A))
284
+ ++ Stored.device A w nu lvs)))
285
+ ++ [gAND (BOOT, true) (ST w A, false) BOOT; gCOPY (ST w A, true) RA; gCOPY (ST w A, true) RC].
286
+
287
+ Lemma stored_body : stored A w = body ++ [gCOPY (ST w A, true) HO].
288
+ Proof. rewrite (stored_split A w). unfold body, handover. rewrite <- !app_assoc. reflexivity. Qed.
289
+
290
+ Lemma body_noho : Forall (fun r => ao_of r <> HO) body.
291
+ Proof.
292
+ pose proof (HWs A w HA Hw) as HW'. pose proof (HW A w HA Hw) as HWn.
293
+ unfold body. rewrite !Forall_app. refine (conj _ (conj _ (conj _ (conj _ _)))).
294
+ - rewrite (startup_split A w m (length_image A)). rewrite !Forall_app. refine (conj _ (conj _ _)).
295
+ + apply Forall_forall. intros r Hr. pose proof (wpart_ao_range A w _ m ltac:(lia) (length_image A) HW' r Hr).
296
+ unfold HO. lia.
297
+ + unfold req_recs. cbn [map]. repeat constructor; cbn [ao_of gCOPY]; unfold RR, CB, RA, CT, RC, HO; lia.
298
+ + constructor; [cbn [ao_of gCONST gOR]; unfold BOOT, HO; lia | constructor].
299
+ - eapply Forall_impl; [exact wrec_noho|]. exact (step_wrec A w _ ltac:(lia) HWn (repeat false _) (repeat_length _ _)).
300
+ - rewrite device_split.
301
+ assert (Hm0 : M0 A w nu lvs <> HO /\ M1 A w nu lvs <> HO) by (unfold M0, M1, DB, HO; lia). destruct Hm0 as [Hm0 Hm1].
302
+ apply Forall_app; split; [|apply Forall_app; split; [|apply Forall_app; split; [|apply Forall_app; split;
303
+ [|apply Forall_app; split; [|apply Forall_app; split]]]]].
304
+ + eapply Forall_impl; [exact wrec_noho | exact (chunk1_wrec A w _ HA Hw HWn)].
305
+ + unfold segE. apply Forall_concat, Forall_map, Forall_forall. intros k _. unfold gMUX. cbn [app].
306
+ repeat constructor; cbn [ao_of gAND gOR gCOPY]; first [exact Hm0 | exact Hm1 | unfold ARM, AA, CPY, AC, HO; lia].
307
+ + eapply Forall_impl; [exact wrec_noho | exact (chunk2_wrec A w _ HA Hw HWn)].
308
+ + unfold segH. apply Forall_concat, Forall_map, Forall_forall. intros k Hk. apply in_seq in Hk. unfold gMUX. cbn [app].
309
+ pose proof (io_lt A w _ HA Hw HWn) as (_ & _ & _ & _ & Hri & _).
310
+ pose proof (MB_range A w _ HA Hw HWn (rin A) (7 - k) Hri ltac:(lia)).
311
+ repeat constructor; cbn [ao_of gAND gOR gCOPY]; first [exact Hm0 | exact Hm1 | unfold AR, HO in *; lia].
312
+ + eapply Forall_impl; [exact wrec_noho | exact (chunk3_wrec A w _ HA Hw HWn)].
313
+ + unfold segN. repeat constructor. cbn [ao_of gCOPY]. unfold RR, HO. lia.
314
+ + eapply Forall_impl; [exact wrec_noho | exact (chunk4_wrec A w _ HA Hw HWn)].
315
+ - apply Forall_forall. intros r Hr. apply repeat_spec in Hr. subst r. cbn. unfold HO. lia.
316
+ - repeat constructor; cbn [ao_of gAND gCOPY]; unfold BOOT, RA, RC, HO; lia.
317
+ Qed.
318
+
319
+ End Body.
320
+
321
+ (* ---- a pass of the machine ------------------------------------------------------------------------------------- *)
322
+ Section Mach.
323
+ Variables (A w K S0 L : nat).
324
+ Hypotheses (HA : 8 <= A) (Hw : 1 <= w) (HK : 2 <= K) (HS : length (stored A w) <= S0) (HL : 1 <= L).
325
+
326
+ Local Notation al := (alS A w).
327
+ Local Notation rs := (stored A w).
328
+ Local Notation G := (length (stored A w)).
329
+ Local Notation Lb := (S0 * recw (alS A w)).
330
+
331
+ Lemma al4 : 4 <= al.
332
+ Proof.
333
+ pose proof (HW A w HA Hw) as H.
334
+ assert (Hn : 16 <= ncells A w (length (host_units A)) (levels (host_units A))) by (unfold ncells, DB; lia).
335
+ destruct (Nat.le_gt_cases 4 al) as [E|E]; [exact E|]. exfalso.
336
+ assert (Hp : 2 ^ al <= 2 ^ 3) by (apply Nat.pow_le_mono_r; lia). change (2 ^ 3) with 8 in Hp. lia.
337
+ Qed.
338
+
339
+ Lemma G_ge : 4 <= G.
340
+ Proof. rewrite (stored_body A w). rewrite length_app. unfold body. rewrite !length_app. cbn [length]. lia. Qed.
341
+
342
+ Lemma S0_pos : 1 <= S0.
343
+ Proof. pose proof G_ge. lia. Qed.
344
+
345
+ Lemma Lb_pos : 1 <= Lb.
346
+ Proof. pose proof S0_pos. unfold recw. nia. Qed.
347
+
348
+ Lemma nat2bits_0 : forall k, nat2bits k 0 = repeat false k.
349
+ Proof. induction k as [|k IH]; [reflexivity|]. cbn [nat2bits repeat]. rewrite IH, Nat.bits_0. reflexivity. Qed.
350
+
351
+ Lemma enc_empty : enc_recA al EMPTY = repeat false (recw al).
352
+ Proof.
353
+ unfold enc_recA, EMPTY, enc_w. cbn [Z.eqb]. change (Z.to_nat (0 mod 16)) with 0. rewrite !nat2bits_0.
354
+ change [false; false] with (repeat false 2). rewrite <- !repeat_app. f_equal; unfold recw; lia.
355
+ Qed.
356
+
357
+ Lemma encA_repeat : forall k, encA al (repeat EMPTY k) = repeat false (k * recw al).
358
+ Proof.
359
+ induction k as [|k IH]; [reflexivity|]. cbn [repeat]. unfold encA in *. cbn [map concat].
360
+ rewrite IH, enc_empty, <- repeat_app. f_equal; lia.
361
+ Qed.
362
+
363
+ (* the active bank holds the image from its first slot, followed by empty slots *)
364
+ Definition img : list bool := encA al rs ++ repeat false ((S0 - G) * recw al).
365
+
366
+ Lemma img_pad : encA al (rs ++ repeat EMPTY (S0 - G)) = img ++ [].
367
+ Proof. rewrite encA_app, encA_repeat, app_nil_r. reflexivity. Qed.
368
+
369
+ Lemma ok_pad : Forall (rec_ok al) (rs ++ repeat EMPTY (S0 - G)).
370
+ Proof.
371
+ apply Forall_app. split; [exact (stored_ok A w HA Hw)|]. apply Forall_forall. intros r Hr. apply repeat_spec in Hr.
372
+ subst r. pose proof (Nat.pow_nonzero 2 al ltac:(lia)). unfold rec_ok, EMPTY. lia.
373
+ Qed.
374
+
375
+ (* a pass: the records of the image, in G steps if they hand over and otherwise in S0 *)
376
+ Lemma machine_pass : forall s0 h c o1 o2,
377
+ fits al K S0 L s0 -> bq (nth (kap s0) (banks s0) bank0) = img -> bs (nth (kap s0) (banks s0) bank0) = 0 ->
378
+ reqclear (win s0) -> Rv A w Lb L h c o1 o2 (vrun Lb L rs (view0 al K s0)) ->
379
+ View.mv al K S0 L s0 (if h then G else S0) (itern al K S0 L (if h then G else S0) s0) (vrun Lb L rs (view0 al K s0)).
380
+ Proof.
381
+ intros s0 h c o1 o2 Hf Hb Hs Hq HR. destruct HR as (Q & _ & Hh & _).
382
+ pose proof al4 as Hal. pose proof S0_pos as HS0.
383
+ assert (Hq0 : reqclear (vw (view0 al K s0))) by exact Hq.
384
+ destruct h.
385
+ - pose proof (seg_run al K S0 L s0 Hal HK HS0 HL Hf rs (repeat false ((S0 - G) * recw al)) Hb Hs HS
386
+ (stored_ok A w HA Hw)) as SR.
387
+ assert (Hho : forall j, 1 <= j < G -> vho (vrun (S0 * recw al) L (firstn j rs) (view0 al K s0)) = false).
388
+ { intros j Hj. rewrite (stored_body A w), firstn_app.
389
+ replace (j - length (body A w)) with 0 by (rewrite (stored_body A w), length_app in Hj; cbn [length] in Hj; lia).
390
+ rewrite firstn_O, app_nil_r. rewrite vrun_noho by (try exact Hq0; apply Forall_firstn', (body_noho A w HA Hw)).
391
+ reflexivity. }
392
+ pose proof (SR Hho G (le_n _)) as M. rewrite firstn_all in M. exact M.
393
+ - pose proof (seg_run al K S0 L s0 Hal HK HS0 HL Hf (rs ++ repeat EMPTY (S0 - G)) [] ltac:(rewrite img_pad, !app_nil_r; exact Hb) Hs
394
+ ltac:(rewrite length_app, repeat_length; lia) ok_pad) as SR.
395
+ assert (Hfull : vrun Lb L (rs ++ repeat EMPTY (S0 - G)) (view0 al K s0) = vrun Lb L rs (view0 al K s0))
396
+ by (rewrite vrun_app; apply pad_run, Q).
397
+ assert (Hho : forall j, 1 <= j < length (rs ++ repeat EMPTY (S0 - G)) ->
398
+ vho (vrun (S0 * recw al) L (firstn j (rs ++ repeat EMPTY (S0 - G))) (view0 al K s0)) = false).
399
+ { intros j _. destruct (vho (vrun (S0 * recw al) L (firstn j (rs ++ repeat EMPTY (S0 - G))) (view0 al K s0))) eqn:E;
400
+ [|reflexivity].
401
+ exfalso. pose proof (vrun_vho_mono Lb L (skipn j (rs ++ repeat EMPTY (S0 - G))) _ E) as E'.
402
+ rewrite <- vrun_app, firstn_skipn, Hfull, Hh in E'. discriminate. }
403
+ pose proof (SR Hho S0 ltac:(rewrite length_app, repeat_length; lia)) as M.
404
+ rewrite firstn_all2 in M by (rewrite length_app, repeat_length; lia). rewrite Hfull in M. exact M.
405
+ Qed.
406
+
407
+ (* a pass that does not hand over leaves the state it started from but for the window, the idle bank and the
408
+ copy tape, and the view it ends in is the view of the next pass *)
409
+ Lemma bank_eta0 : forall q, bs q = 0 -> mkB (bq q) 0 (bj q) = q.
410
+ Proof. intros [q s j] H. cbn in H. subst s. reflexivity. Qed.
411
+
412
+ Lemma mv_next : forall s0 s v, bs (nth (kap s0) (banks s0) bank0) = 0 ->
413
+ View.mv al K S0 L s0 S0 s v -> vho v = false ->
414
+ fits al K S0 L s /\ kap s = kap s0 /\ nth (kap s0) (banks s) bank0 = nth (kap s0) (banks s0) bank0
415
+ /\ (forall x, x < K -> x <> kap s0 -> x <> succ_mod K (kap s0) ->
416
+ nth x (banks s) bank0 = nth x (banks s0) bank0 /\ nth x (tapes s) tape0 = nth x (tapes s0) tape0)
417
+ /\ view0 al K s = v.
418
+ Proof.
419
+ intros s0 s v Hb0 (Hf & Hwn & Hk & Ha & HI & HR & HC & Ho) Hh. rewrite Hh in Hk.
420
+ refine (conj Hf (conj Hk (conj _ (conj Ho _)))).
421
+ - rewrite Ha, Hb0, Nat.add_0_l, Nat.Div0.mod_same. apply bank_eta0. exact Hb0.
422
+ - unfold view0. rewrite Hk, Hwn, HR, HC, HI. transitivity (mkV (vw v) (vr v) (va v) (vc v) (vho v));
423
+ [rewrite Hh; reflexivity | symmetry; apply view_eta].
424
+ Qed.
425
+
426
+ End Mach.
427
+
428
+ (* ---- the passes of a generation: Theorem 8.6 ------------------------------------------------------------------ *)
429
+ Section Gen.
430
+ Variables (A w K S0 L : nat) (ks : list token).
431
+ Hypotheses (HA : 8 <= A) (Hw : 1 <= w) (HK : 2 <= K) (HS : length (stored A w) <= S0) (HL : 1 <= L)
432
+ (Hks : Forall tok_ok ks) (Ht1 : 8 * length (recipe ks) <= L) (Ht2 : length (recipe ks) < 2 ^ w)
433
+ (Hd : 8 * length (delta ks) <= S0 * recw (alS A w)).
434
+
435
+ Local Notation al := (alS A w).
436
+ Local Notation rs := (stored A w).
437
+ Local Notation G := (length (stored A w)).
438
+ Local Notation Lb := (S0 * recw (alS A w)).
439
+ Local Notation tau := (recipe ks).
440
+
441
+ (* the views the passes start from *)
442
+ Fixpoint vpass (n : nat) (v : view) : view := match n with O => v | S n' => vrun Lb L rs (vpass n' v) end.
443
+
444
+ Lemma ok_at : forall t, t < NN ks -> step_ok A w Lb L (cr A ks t) (fst (outs A ks t)) (snd (outs A ks t)).
445
+ Proof.
446
+ intros t Ht. pose proof (Lb_pos A w K S0 L HA Hw HK HS HL) as HLb.
447
+ unfold step_ok. rewrite (inv_tape A ks t).
448
+ refine (conj (not_halted A ks HA Hks t Ht) (conj (recipe_bytes ks Hks) (conj Ht1 (conj Ht2
449
+ (conj (inv_head A ks HA t) (conj _ (conj _ (conj _ (conj _ (conj HLb HL)))))))))).
450
+ - intro Hn. destruct (Nat.le_gt_cases t (n0 ks)) as [H|H].
451
+ + rewrite (proj1 (inv_early A ks HA Hks t H)) in Hn. discriminate.
452
+ + rewrite (proj1 (inv_late A ks HA Hks t ltac:(lia))). reflexivity.
453
+ - intros Hrd Hn. pose proof (inv_read A ks HA Hks t Ht Hrd Hn) as R. rewrite (inv_tape A ks t) in R. exact R.
454
+ - intros Hwr Hn. pose proof (cap1 A ks HA Hks t Ht Hwr Hn). lia.
455
+ - intros Hwr Hn. pose proof (cap2 A ks HA Hks t Ht Hwr Hn). lia.
456
+ Qed.
457
+
458
+ (* the state t passes into a generation started from s0 *)
459
+ Definition PI (s0 : st) (t : nat) (s : st) : Prop :=
460
+ fits al K S0 L s /\ kap s = kap s0 /\ nth (kap s0) (banks s) bank0 = nth (kap s0) (banks s0) bank0
461
+ /\ (forall x, x < K -> x <> kap s0 -> x <> succ_mod K (kap s0) ->
462
+ nth x (banks s) bank0 = nth x (banks s0) bank0 /\ nth x (tapes s) tape0 = nth x (tapes s0) tape0)
463
+ /\ view0 al K s = vpass t (view0 al K s0)
464
+ /\ Rv A w Lb L false (cr A ks t) (fst (outs A ks t)) (snd (outs A ks t)) (view0 al K s).
465
+
466
+ (* the hypothesis of Theorem 8.6: the image in the active bank from its first slot, the slot head there, the
467
+ recipe on the read tape from its first cell, booted clear and the requests clear *)
468
+ Definition ready (s0 : st) : Prop :=
469
+ fits al K S0 L s0 /\ bq (nth (kap s0) (banks s0) bank0) = img A w S0 /\ bs (nth (kap s0) (banks s0) bank0) = 0
470
+ /\ reqclear (win s0) /\ wget (win s0) BOOT = false
471
+ /\ td (nth (kap s0) (tapes s0) tape0) = bbits tau ++ repeat false (L - 8 * length tau).
472
+
473
+ Lemma passes : forall s0, ready s0 -> forall t, 1 <= t < NN ks -> PI s0 t (itern al K S0 L (t * S0) s0).
474
+ Proof.
475
+ intros s0 (Hf & Hb & Hs & Hq & Hboot & Htd) t. induction t as [|t IH]; intro Ht; [lia|].
476
+ destruct (Nat.eq_dec t 0) as [->|Ht0].
477
+ - set (v0 := view0 al K s0).
478
+ assert (Hl0 : length (vw v0) = 2 ^ al) by (destruct Hf as (Hl & _); exact Hl).
479
+ pose proof (pass_first A w Lb L HA Hw v0 tau Hq Hl0 Hboot eq_refl Htd (ok_at 0 ltac:(lia))) as R1.
480
+ assert (E1 : cr A ks 1 = tstep A (init A (progPstar A) tau)) by reflexivity.
481
+ rewrite <- E1, (not_halted A ks HA Hks 1 ltac:(lia)) in R1.
482
+ change (out1 A (init A (progPstar A) tau) []) with (fst (outs A ks 1)) in R1.
483
+ change (out2 A (init A (progPstar A) tau) []) with (snd (outs A ks 1)) in R1.
484
+ pose proof (machine_pass A w K S0 L HA Hw HK HS HL s0 false _ _ _ Hf Hb Hs Hq R1) as M. cbn iota in M.
485
+ destruct (mv_next A w K S0 L s0 _ _ Hs M (proj1 (proj2 (proj2 R1))))
486
+ as (Hf1 & Hk1 & Hb1 & Ho1 & Hv1).
487
+ replace (1 * S0) with S0 by lia.
488
+ refine (conj Hf1 (conj Hk1 (conj Hb1 (conj Ho1 (conj Hv1 _))))). rewrite Hv1. exact R1.
489
+ - destruct (IH ltac:(lia)) as (Hf' & Hk' & Hb' & Ho' & Hv' & HR').
490
+ set (s := itern al K S0 L (t * S0) s0) in *.
491
+ pose proof (pass_next A w Lb L HA Hw _ _ _ _ HR' (ok_at t ltac:(lia))) as R1.
492
+ rewrite <- (cr_S A ks t), (not_halted A ks HA Hks (S t) ltac:(lia)) in R1.
493
+ change (out1 A (cr A ks t) (fst (outs A ks t))) with (fst (outs A ks (S t))) in R1.
494
+ change (out2 A (cr A ks t) (snd (outs A ks t))) with (snd (outs A ks (S t))) in R1.
495
+ assert (Hbs : bq (nth (kap s) (banks s) bank0) = img A w S0 /\ bs (nth (kap s) (banks s) bank0) = 0)
496
+ by (rewrite Hk', Hb'; split; assumption).
497
+ pose proof (machine_pass A w K S0 L HA Hw HK HS HL s false _ _ _ Hf' (proj1 Hbs) (proj2 Hbs)
498
+ (proj1 HR') R1) as M. cbn iota in M.
499
+ destruct (mv_next A w K S0 L s _ _ (proj2 Hbs) M (proj1 (proj2 (proj2 R1))))
500
+ as (Hf1 & Hk1 & Hb1 & Ho1 & Hv1).
501
+ replace (S t * S0) with (t * S0 + S0) by lia. rewrite itern_add. fold s.
502
+ rewrite Hk' in Hk1, Hb1, Ho1. rewrite Hb' in Hb1.
503
+ refine (conj Hf1 (conj Hk1 (conj Hb1 (conj _ (conj _ _))))).
504
+ + intros x Hx E1 E2. destruct (Ho1 x Hx E1 E2) as [B T]. destruct (Ho' x Hx E1 E2) as [B' T'].
505
+ split; congruence.
506
+ + rewrite Hv1, Hv'. reflexivity.
507
+ + rewrite Hv1. exact R1.
508
+ Qed.
509
+
510
+ (* Theorem 8.6: after NN passes, each of S0 steps but the last, which has G, the next bank holds the decoded bytes
511
+ from its first slot and the next tape the recipe from its first cell, both with their heads at their origins;
512
+ the active bank and the read tape keep the image and the recipe, booted and the requests are clear, no other
513
+ bank or tape has changed, and the bank index has moved on *)
514
+ Theorem stored_construct : forall s0, ready s0 ->
515
+ let s := itern al K S0 L ((NN ks - 1) * S0 + G) s0 in
516
+ fits al K S0 L s /\ kap s = succ_mod K (kap s0)
517
+ /\ nth (succ_mod K (kap s0)) (banks s) bank0 = mkB (bbits (delta ks) ++ repeat false (Lb - 8 * length (delta ks))) 0 0
518
+ /\ nth (succ_mod K (kap s0)) (tapes s) tape0 = mkT (bbits tau ++ repeat false (L - 8 * length tau)) 0
519
+ /\ nth (kap s0) (banks s) bank0 = mkB (img A w S0) (G mod S0) (bj (nth (kap s0) (banks s0) bank0))
520
+ /\ nth (kap s0) (tapes s) tape0 = mkT (td (nth (kap s0) (tapes s0) tape0)) ((8 * length tau) mod L)
521
+ /\ reqclear (win s) /\ wget (win s) BOOT = false
522
+ /\ win s = vw (vpass (NN ks) (view0 al K s0))
523
+ /\ (forall x, x < K -> x <> kap s0 -> x <> succ_mod K (kap s0) ->
524
+ nth x (banks s) bank0 = nth x (banks s0) bank0 /\ nth x (tapes s) tape0 = nth x (tapes s0) tape0).
525
+ Proof.
526
+ intros s0 Hr s. pose proof Hr as (Hf & Hb & Hs & Hq & Hboot & Htd).
527
+ assert (HN : 2 <= NN ks) by (unfold NN; lia).
528
+ destruct (passes s0 Hr (NN ks - 1) ltac:(lia)) as (Hf' & Hk' & Hb' & Ho' & Hv' & HR').
529
+ set (s' := itern al K S0 L ((NN ks - 1) * S0) s0) in *.
530
+ assert (Es : s = itern al K S0 L G s') by (unfold s, s'; apply itern_add).
531
+ pose proof (pass_next A w Lb L HA Hw _ _ _ _ HR' (ok_at (NN ks - 1) ltac:(lia))) as R1.
532
+ rewrite <- (cr_S A ks), (Nat.sub_1_r (NN ks)), (Nat.succ_pred_pos (NN ks) ltac:(lia)) in R1.
533
+ rewrite (proj1 (at_NN A ks HA Hks)) in R1.
534
+ assert (EO : forall t, out1 A (cr A ks t) (fst (outs A ks t)) = fst (outs A ks (S t))
535
+ /\ out2 A (cr A ks t) (snd (outs A ks t)) = snd (outs A ks (S t))) by (intro t; split; reflexivity).
536
+ rewrite (proj1 (EO _)), (proj2 (EO _)), (Nat.succ_pred_pos (NN ks) ltac:(lia)) in R1.
537
+ assert (Hbs : bq (nth (kap s') (banks s') bank0) = img A w S0 /\ bs (nth (kap s') (banks s') bank0) = 0)
538
+ by (rewrite Hk', Hb'; split; assumption).
539
+ pose proof (machine_pass A w K S0 L HA Hw HK HS HL s' true _ _ _ Hf' (proj1 Hbs) (proj2 Hbs) (proj1 HR') R1) as M.
540
+ cbn iota in M. rewrite <- Es in M. clear EO.
541
+ destruct (outs_late A ks HA Hks (NN ks) ltac:(unfold NN, n0; lia)) as [O1 O2].
542
+ rewrite (proj2 (at_NN A ks HA Hks)) in O2. cbn [dout] in O2. apply app_inv_head in O2.
543
+ destruct R1 as (Q & _ & Hh & Hbt & _ & _ & _ & _ & _ & VR & VA & VC & _).
544
+ rewrite (proj2 (at_NN A ks HA Hks)) in VR. cbn [dtape dhead] in VR.
545
+ rewrite O1 in VA. rewrite <- O2 in VC.
546
+ destruct M as (Hfs & Hws & Hks' & Has & His & Hrs & Hcs & Hos). rewrite Hh in Hks'. rewrite Hk' in *.
547
+ pose proof (Hfs) as (_ & _ & _ & _ & HB & _).
548
+ refine (conj Hfs (conj Hks' (conj _ (conj _ (conj _ (conj _ (conj _ (conj _ (conj _ _))))))))).
549
+ - rewrite VA in His. unfold obt, lin in His.
550
+ pose proof (f_equal td His) as Eq. pose proof (f_equal th His) as Ep. cbn [td th] in Eq, Ep.
551
+ assert (Hk0 : succ_mod K (kap s0) < K)
552
+ by (destruct Hf as (_ & Hk0 & _); unfold succ_mod; destruct (Nat.eqb_spec (S (kap s0)) K); lia).
553
+ destruct (HB _ Hk0) as (_ & _ & Hj).
554
+ rewrite Nat.mul_0_r, Nat.Div0.mod_0_l in Ep. rewrite <- (eta_bank (nth _ (banks s) bank0)), Eq.
555
+ assert (Hr8 : 1 <= recw al) by (unfold recw; lia). f_equal; nia.
556
+ - rewrite Hcs, VC. unfold obt. rewrite Nat.mul_0_r, Nat.Div0.mod_0_l. reflexivity.
557
+ - rewrite Has, Hb', Hs, Hb, Nat.add_0_l. reflexivity.
558
+ - rewrite Hrs, VR. unfold obt. f_equal. rewrite Hv' in HR'. rewrite Htd. reflexivity.
559
+ - rewrite Hws. exact Q.
560
+ - rewrite Hws. rewrite Hbt. reflexivity.
561
+ - assert (EN : NN ks = S (NN ks - 1)) by lia. rewrite Hws, Hv'. rewrite EN at 2. reflexivity.
562
+ - intros x Hx E1 E2. destruct (Hos x Hx E1 E2) as [B T]. destruct (Ho' x Hx E1 E2) as [B' T']. split; congruence.
563
+ Qed.
564
+
565
+ End Gen.
rocq/StoredStep.v ADDED
@@ -0,0 +1,362 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* The step block of the stored host: evaluated in the order of the netlist, each unit of H_A into its
2
+ own cell, the unit of each next value into its state bit, the records leave in the state bits the next
3
+ state of H_A, from every window and for every A >= 3. *)
4
+ From Stdlib Require Import List Bool Arith ZArith Lia.
5
+ Import ListNotations.
6
+ From TH Require Import TwoHead Net Abstract Indep Run View Stored WinRun Host HostWF HostSem HostIP.
7
+
8
+ (* ---- a unit of weights 1 and -1 fires when at least tval of its literals hold -------------------------- *)
9
+ Definition litE (E : nat -> bool) (p : nat * Z) : bool := if Z.ltb 0 (snd p) then E (fst p) else negb (E (fst p)).
10
+
11
+ Lemma wsum_count : forall ins E, (forall i w, In (i, w) ins -> w = 1%Z \/ w = (-1)%Z) ->
12
+ wsum ins E = (Z.of_nat (length (filter (litE E) ins)) - Z.of_nat (length (filter (fun p => Z.ltb (snd p) 0) ins)))%Z.
13
+ Proof.
14
+ induction ins as [|[i w] t IH]; intros E H; [reflexivity|].
15
+ cbn [wsum filter]. rewrite IH by (intros i' w' Hin; apply (H i' w'); right; exact Hin).
16
+ destruct (H i w (or_introl eq_refl)) as [->| ->]; unfold litE; cbn [fst snd Z.ltb Z.compare];
17
+ destruct (E i); cbn [negb length b2z]; rewrite ?Nat2Z.inj_succ; lia.
18
+ Qed.
19
+
20
+ Lemma fire_count : forall u E, (forall i w, In (i, w) (tin u) -> w = 1%Z \/ w = (-1)%Z) ->
21
+ fire u E = Z.leb (tval u) (Z.of_nat (length (filter (litE E) (tin u)))).
22
+ Proof.
23
+ intros u E H. unfold fire, tval. rewrite (wsum_count _ E H).
24
+ destruct (Z.leb_spec 0 (Net.tb u + (Z.of_nat (length (filter (litE E) (tin u)))
25
+ - Z.of_nat (length (filter (fun p => Z.ltb (snd p) 0) (tin u)))))),
26
+ (Z.leb_spec (Z.of_nat (length (filter (fun p => Z.ltb (snd p) 0) (tin u))) - Net.tb u)
27
+ (Z.of_nat (length (filter (litE E) (tin u))))); lia.
28
+ Qed.
29
+
30
+ (* ---- the table of next values ---------------------------------------------------------------------- *)
31
+ Lemma length_setopt : forall l k x, length (setopt l k x) = length l.
32
+ Proof. induction l as [|y l IH]; intros [|k] x; cbn [setopt length]; try rewrite IH; reflexivity. Qed.
33
+
34
+ Lemma nth_setopt : forall l k x u, nth u (setopt l k x) None = if Nat.eqb u k && Nat.ltb k (length l) then Some x else nth u l None.
35
+ Proof.
36
+ induction l as [|y l IH]; intros k x u.
37
+ - cbn [setopt nth length]. destruct (Nat.ltb_spec k 0); [lia|]. rewrite andb_false_r. destruct u; reflexivity.
38
+ - destruct k as [|k], u as [|u]; cbn [setopt nth length]; try reflexivity.
39
+ rewrite IH. reflexivity.
40
+ Qed.
41
+
42
+ Lemma find_none_of : forall (T : Type) (f : T -> bool) l, (forall x, In x l -> f x = false) -> find f l = None.
43
+ Proof.
44
+ intros T f l. induction l as [|x l IH]; intro H; [reflexivity|]. cbn [find].
45
+ rewrite (H x (or_introl eq_refl)). apply IH. intros y Hy. apply H. right. exact Hy.
46
+ Qed.
47
+
48
+ Lemma fold_setopt : forall n ps tbl, NoDup (map snd ps) -> (forall p, In p ps -> n <= snd p < n + length tbl) ->
49
+ length (fold_left (fun tb p => setopt tb (snd p - n) (fst p)) ps tbl) = length tbl
50
+ /\ forall u, u < length tbl -> nth u (fold_left (fun tb p => setopt tb (snd p - n) (fst p)) ps tbl) None
51
+ = match find (fun p => Nat.eqb (snd p) (n + u)) ps with Some p => Some (fst p) | None => nth u tbl None end.
52
+ Proof.
53
+ intros n. induction ps as [|p ps IH]; intros tbl Hnd Hr; [split; [reflexivity | intros u Hu; reflexivity]|].
54
+ cbn [fold_left find]. inversion Hnd as [|? ? Hni Hnd']; subst.
55
+ assert (Hr' : forall q, In q ps -> n <= snd q < n + length (setopt tbl (snd p - n) (fst p)))
56
+ by (intros q Hq; rewrite length_setopt; apply Hr; right; exact Hq).
57
+ destruct (IH (setopt tbl (snd p - n) (fst p)) Hnd' Hr') as [L E]. rewrite length_setopt in L.
58
+ split; [exact L|]. intros u Hu. rewrite E by (rewrite length_setopt; exact Hu).
59
+ pose proof (Hr p (or_introl eq_refl)) as Hp.
60
+ rewrite nth_setopt. destruct (Nat.eqb_spec (snd p) (n + u)) as [Ep|Ep].
61
+ - assert (Hf : find (fun q => Nat.eqb (snd q) (n + u)) ps = None).
62
+ { apply find_none_of. intros q Hq. apply Nat.eqb_neq. intro Eq. apply Hni. rewrite Ep, <- Eq.
63
+ apply in_map. exact Hq. }
64
+ rewrite Hf. replace (Nat.eqb u (snd p - n)) with true by (symmetry; apply Nat.eqb_eq; lia).
65
+ rewrite (proj2 (Nat.ltb_lt _ _)) by lia. reflexivity.
66
+ - destruct (find (fun q => Nat.eqb (snd q) (n + u)) ps); [reflexivity|].
67
+ replace (Nat.eqb u (snd p - n)) with false by (symmetry; apply Nat.eqb_neq; lia). reflexivity.
68
+ Qed.
69
+
70
+ Lemma in_combine_seq : forall (l : list nat) p, In p (combine (seq 0 (length l)) l) ->
71
+ fst p < length l /\ snd p = nth (fst p) l 0.
72
+ Proof.
73
+ intros l p Hin. destruct p as [i x]. cbn [fst snd].
74
+ pose proof (in_combine_l _ _ _ _ Hin) as Hi. apply in_seq in Hi.
75
+ assert (G : forall m (l' : list nat), In (i, x) (combine (seq m (length l')) l') -> m <= i /\ x = nth (i - m) l' 0).
76
+ { intros m l'. revert m. induction l' as [|y l' IHl]; intros m H; [destruct H|].
77
+ cbn [length seq combine In] in H. destruct H as [H|H].
78
+ - injection H as <- <-. rewrite Nat.sub_diag. split; [lia | reflexivity].
79
+ - destruct (IHl (S m) H) as [H1 H2]. split; [lia|]. replace (i - m) with (S (i - S m)) by lia. exact H2. }
80
+ destruct (G 0 l Hin) as [_ H]. rewrite Nat.sub_0_r in H. split; [lia | exact H].
81
+ Qed.
82
+
83
+ Lemma map_snd_combine : forall (a b : list nat), length a = length b -> map snd (combine a b) = b.
84
+ Proof.
85
+ induction a as [|x a IH]; intros [|y b] H; cbn in H |- *; try reflexivity; try discriminate.
86
+ rewrite IH by lia. reflexivity.
87
+ Qed.
88
+
89
+ Section Tbl.
90
+ Variable A : nat.
91
+ Hypothesis HA : 3 <= A.
92
+
93
+ Local Notation us := (host_units A).
94
+ Local Notation n := (nH A).
95
+ Local Notation nt := (next_tbl (nH A) (length (host_units A)) (host_next A)).
96
+
97
+ Lemma nodup_next : NoDup (host_next A).
98
+ Proof.
99
+ apply (NoDup_nth (host_next A) 0). intros i i' Hi Hi' E. rewrite length_host_next in Hi, Hi'.
100
+ exact (host_next_inj A HA i i' Hi Hi' E).
101
+ Qed.
102
+
103
+ Lemma nt_spec : length nt = length us
104
+ /\ forall u, u < length us -> nth u nt None
105
+ = match find (fun p => Nat.eqb (snd p) (n + u)) (combine (seq 0 n) (host_next A)) with
106
+ | Some p => Some (fst p) | None => None end.
107
+ Proof.
108
+ assert (Hm : map snd (combine (seq 0 n) (host_next A)) = host_next A)
109
+ by (apply map_snd_combine; rewrite length_seq, length_host_next; reflexivity).
110
+ assert (Hnd : NoDup (map snd (combine (seq 0 n) (host_next A)))) by (rewrite Hm; exact nodup_next).
111
+ assert (Hr : forall p, In p (combine (seq 0 n) (host_next A)) -> n <= snd p < n + length (repeat (@None nat) (length us))).
112
+ { intros p Hp. rewrite repeat_length. rewrite <- length_host_next in Hp.
113
+ destruct (in_combine_seq (host_next A) p Hp) as [H1 H2]. rewrite H2.
114
+ rewrite length_host_next in H1. exact (host_next_range A HA (fst p) H1). }
115
+ destruct (fold_setopt n _ _ Hnd Hr) as [L E]. rewrite repeat_length in L.
116
+ split; [exact L|]. intros u Hu. unfold next_tbl. rewrite E by (rewrite repeat_length; exact Hu).
117
+ destruct (find _ _); [reflexivity|]. apply nth_repeat.
118
+ Qed.
119
+
120
+ Lemma nt_some : forall u i, u < length us -> nth u nt None = Some i -> i < n /\ nth i (host_next A) 0 = n + u.
121
+ Proof.
122
+ intros u i Hu E. rewrite (proj2 nt_spec u Hu) in E.
123
+ destruct (find _ _) as [p|] eqn:Ef; [|discriminate]. injection E as <-.
124
+ apply find_some in Ef as [Hin Hp]. apply Nat.eqb_eq in Hp.
125
+ assert (Hin' : In p (combine (seq 0 (length (host_next A))) (host_next A))) by (rewrite length_host_next; exact Hin).
126
+ destruct (in_combine_seq _ _ Hin') as [H1 H2]. rewrite length_host_next in H1.
127
+ split; [exact H1 | rewrite <- H2; exact Hp].
128
+ Qed.
129
+
130
+ Lemma in_combine_at : forall m (l : list nat) j, j < length l -> In (m + j, nth j l 0) (combine (seq m (length l)) l).
131
+ Proof.
132
+ intros m l. revert m. induction l as [|y l IHl]; intros m j Hj; cbn [length] in Hj; [lia|].
133
+ cbn [length seq combine In]. destruct j as [|j]; [left; rewrite Nat.add_0_r; reflexivity|].
134
+ right. replace (m + S j) with (S m + j) by lia. apply IHl. lia.
135
+ Qed.
136
+
137
+ Lemma nt_none : forall u, u < length us -> nth u nt None = None -> forall i, i < n -> nth i (host_next A) 0 <> n + u.
138
+ Proof.
139
+ intros u Hu E i Hi Hni. rewrite (proj2 nt_spec u Hu) in E.
140
+ destruct (find _ _) as [p|] eqn:Ef; [discriminate|].
141
+ pose proof (in_combine_at 0 (host_next A) i ltac:(rewrite length_host_next; exact Hi)) as Hin.
142
+ rewrite length_host_next in Hin.
143
+ pose proof (find_none _ _ Ef _ Hin) as Hf. cbn [snd] in Hf. rewrite Hni, Nat.eqb_refl in Hf. discriminate.
144
+ Qed.
145
+
146
+ End Tbl.
147
+
148
+ (* ---- the step block ---------------------------------------------------------------------------------- *)
149
+ Section Step.
150
+ Variables (A w W : nat).
151
+ Hypothesis HA : 3 <= A.
152
+
153
+ Local Notation us := (host_units A).
154
+ Local Notation nu := (length (host_units A)).
155
+ Local Notation lv := (levels (host_units A)).
156
+ Local Notation n := (nH A).
157
+ Local Notation nt := (next_tbl (nH A) (length (host_units A)) (host_next A)).
158
+
159
+ Hypothesis HW : ncells A w nu lv <= W.
160
+
161
+ (* the window at the start of the block, its state bits, and the values of the netlist on them *)
162
+ Variable w0 : list bool.
163
+ Hypotheses (Hw0 : length w0 = W) (Hq0 : reqclear w0).
164
+
165
+ Definition xbits : list bool := map (fun i => wget w0 (ST w i)) (seq 0 n).
166
+ Definition X (i : nat) : bool := nth i xbits false.
167
+ Definition E : nat -> bool := run us n X.
168
+
169
+ Definition unit_recs (u : nat) : list rec :=
170
+ ucomp (XC A w nu) (tval (nth u us tu0)) (map (lit_of A w) (tin (nth u us tu0)))
171
+ (match nth u nt None with Some i => ST w i | None => UC A w u end) (UC A w u) 0.
172
+
173
+ Definition Inv (u : nat) (w' : list bool) : Prop :=
174
+ length w' = W /\ reqclear w'
175
+ /\ (forall v, v < u -> nth v nt None = None -> wget w' (UC A w v) = E (n + v))
176
+ /\ (forall i, i < n -> wget w' (ST w i)
177
+ = if Nat.ltb (nth i (host_next A) 0) (n + u) then E (nth i (host_next A) 0) else X i)
178
+ /\ (forall c, c < ST w 0 \/ DB A w nu lv <= c -> wget w' c = wget w0 c).
179
+
180
+ Lemma X_eq : forall i, i < n -> X i = wget w0 (ST w i).
181
+ Proof. intros i Hi. unfold X, xbits. rewrite (nth_map_seq _ (fun i => wget w0 (ST w i)) n i false Hi). reflexivity. Qed.
182
+
183
+ Lemma E_low : forall i, i < n -> E i = X i.
184
+ Proof. intros i Hi. unfold E. apply run_prefix. exact Hi. Qed.
185
+
186
+ Lemma Inv_0 : Inv 0 w0.
187
+ Proof.
188
+ refine (conj Hw0 (conj Hq0 (conj _ (conj _ _)))).
189
+ - intros v Hv. lia.
190
+ - intros i Hi. pose proof (host_next_range A HA i Hi) as Hr.
191
+ replace (Nat.ltb (nth i (host_next A) 0) (n + 0)) with false by (symmetry; apply Nat.ltb_ge; lia).
192
+ rewrite X_eq by exact Hi. reflexivity.
193
+ - intros c _. reflexivity.
194
+ Qed.
195
+
196
+ Lemma max_fold : forall l a x, In x l \/ x <= a -> x <= fold_left Nat.max l a.
197
+ Proof.
198
+ induction l as [|y l IH]; intros a x H; cbn [fold_left]; [destruct H as [[]|H]; exact H|].
199
+ apply IH. destruct H as [[<-|H]|H]; [right; lia | left; exact H | right; lia].
200
+ Qed.
201
+
202
+ Lemma lv_bound : forall U, In U us -> thr_unit U = true -> length (tin U) - 2 <= lv.
203
+ Proof.
204
+ intros U Hin Ht. unfold levels. apply max_fold. left.
205
+ apply in_map_iff. exists U. split; [rewrite Ht; reflexivity | exact Hin].
206
+ Qed.
207
+
208
+ Lemma xc_gt : forall j k, k < 3 -> HO < XC A w nu j k.
209
+ Proof. intros. unfold XC, HO. lia. Qed.
210
+
211
+ Lemma xc_lt : forall j k, j < lv -> k < 3 -> XC A w nu j k < W.
212
+ Proof. intros j k Hj Hk. unfold ncells, DB in HW. unfold XC, nh in *. lia. Qed.
213
+
214
+ Lemma xc_inj : forall j k j' k', k < 3 -> k' < 3 -> XC A w nu j k = XC A w nu j' k' -> j = j' /\ k = k'.
215
+ Proof. intros j k j' k' Hk Hk' E. unfold XC in E. lia. Qed.
216
+
217
+ Lemma not_scr : forall c lev, c < XC A w nu 0 0 -> ~ scr lv (XC A w nu) lev c.
218
+ Proof. intros c lev Hc (j & k & _ & _ & ->). unfold XC in Hc. lia. Qed.
219
+
220
+ Lemma scr_db : forall c lev, DB A w nu lv <= c -> ~ scr lv (XC A w nu) lev c.
221
+ Proof. intros c lev Hc (j & k & Hj & Hk & ->). unfold XC, DB in *. lia. Qed.
222
+
223
+ Lemma ntrue_lits : forall w' U, (forall p, In p (tin U) -> wl w' (lit_of A w p) = litE E p) ->
224
+ ntrue w' (map (lit_of A w) (tin U)) = length (filter (litE E) (tin U)).
225
+ Proof.
226
+ intros w' U H. unfold ntrue. induction (tin U) as [|p t IH]; [reflexivity|].
227
+ cbn [map filter]. rewrite (H p (or_introl eq_refl)).
228
+ assert (IH' : length (filter (wl w') (map (lit_of A w) t)) = length (filter (litE E) t))
229
+ by (apply IH; intros q Hq; apply H; right; exact Hq).
230
+ destruct (litE E p); cbn [length]; rewrite IH'; reflexivity.
231
+ Qed.
232
+
233
+ Theorem unit_step : forall u w', u < nu -> Inv u w' -> Inv (S u) (wrun (unit_recs u) w').
234
+ Proof.
235
+ intros u w' Hu (Hl & Hq & Hun & Hst & Hfix).
236
+ set (U := nth u us tu0).
237
+ assert (HUin : In U us) by (apply nth_In; exact Hu).
238
+ assert (Hwt : forall i wt, In (i, wt) (tin U) -> wt = 1%Z \/ wt = (-1)%Z)
239
+ by (intros i wt Hin; exact (host_weights A HA u i wt Hu Hin)).
240
+ assert (Hrb : forall i wt, In (i, wt) (tin U) -> i < n + u)
241
+ by (intros i wt Hin; exact (host_reads_below A HA u Hu i wt Hin)).
242
+ (* every literal holds the value of the netlist *)
243
+ assert (Hlit : forall p, In p (tin U) -> wl w' (lit_of A w p) = litE E p).
244
+ { intros [i wt] Hin. unfold lit_of, litE, wl, nh. cbn [fst snd].
245
+ assert (Ev : wcell w' (if i <? n then ST w i else UC A w (i - n)) = E i).
246
+ { unfold wcell. replace (Nat.eqb (if i <? n then ST w i else UC A w (i - n)) SINK) with false
247
+ by (symmetry; apply Nat.eqb_neq; destruct (i <? n); unfold ST, UC, SINK; lia).
248
+ destruct (Nat.ltb_spec i n) as [Hi|Hi].
249
+ - rewrite Hst by exact Hi.
250
+ pose proof (host_in_before A HA u i wt Hu Hin Hi) as Hb.
251
+ replace (Nat.ltb (nth i (host_next A) 0) (n + u)) with false by (symmetry; apply Nat.ltb_ge; lia).
252
+ rewrite E_low by exact Hi. reflexivity.
253
+ - pose proof (Hrb i wt Hin) as Hlt.
254
+ assert (Hnone : nth (i - n) nt None = None).
255
+ { destruct (nth (i - n) nt None) as [i'|] eqn:Ei; [|reflexivity]. exfalso.
256
+ destruct (nt_some A HA (i - n) i' ltac:(lia) Ei) as [Hi' Ei'].
257
+ apply (host_no_out A HA u i wt Hu Hin i' Hi'). lia. }
258
+ rewrite Hun by (lia || exact Hnone). f_equal. lia. }
259
+ rewrite Ev. reflexivity. }
260
+ assert (Hval : Z.leb (tval U) (Z.of_nat (ntrue w' (map (lit_of A w) (tin U)))) = E (n + u)).
261
+ { rewrite (ntrue_lits w' U Hlit), <- (fire_count U E Hwt).
262
+ unfold E. rewrite run_at; [reflexivity | exact Hu | intros k Hk; exact (host_reads_below A HA k Hk)]. }
263
+ assert (Hlits : forall l, In l (map (lit_of A w) (tin U)) -> fst l <> UC A w u /\ ~ scr lv (XC A w nu) 0 (fst l)).
264
+ { intros l Hl'. apply in_map_iff in Hl' as ([i wt] & <- & Hin). unfold lit_of, nh. cbn [fst].
265
+ pose proof (Hrb i wt Hin). split.
266
+ - destruct (Nat.ltb_spec i n); unfold ST, UC, nh; lia.
267
+ - apply not_scr. destruct (Nat.ltb_spec i n); unfold ST, UC, XC, nh; lia. }
268
+ assert (Hlev : (1 < tval U < Z.of_nat (length (map (lit_of A w) (tin U))))%Z ->
269
+ 0 + length (map (lit_of A w) (tin U)) <= lv + 2).
270
+ { intros [H1 H2]. rewrite length_map in *.
271
+ assert (Ht : thr_unit U = true) by (unfold thr_unit; apply andb_true_intro; split; apply Z.ltb_lt; lia).
272
+ pose proof (lv_bound U HUin Ht). lia. }
273
+ assert (HUC : UC A w u < W) by (unfold ncells, DB in HW; unfold UC, nh in *; lia).
274
+ assert (Hacc : ok_cell W (UC A w u)) by (split; [unfold UC, HO; lia | exact HUC]).
275
+ assert (Hsacc : ~ scr lv (XC A w nu) 0 (UC A w u)) by (apply not_scr; unfold UC, XC, nh; lia).
276
+ unfold unit_recs. fold U.
277
+ destruct (nth u nt None) as [i0|] eqn:Eo.
278
+ - (* the unit of the next value of state bit i0 writes that bit *)
279
+ destruct (nt_some A HA u i0 Hu Eo) as [Hi0 Ei0].
280
+ assert (Hd : ok_cell W (ST w i0)) by (split; [unfold ST, HO; lia | unfold ncells, DB in HW; unfold ST, nh in *; lia]).
281
+ assert (Hsd : ~ scr lv (XC A w nu) 0 (ST w i0)) by (apply not_scr; unfold ST, XC, nh; lia).
282
+ destruct (ucomp_run W lv (XC A w nu) xc_gt xc_lt xc_inj (map (lit_of A w) (tin U)) (tval U) (ST w i0)
283
+ (UC A w u) 0 w' Hl Hd Hacc Hsd Hsacc Hlits Hlev) as (L1 & V1 & U1).
284
+ rewrite Hval in V1.
285
+ refine (conj L1 (conj _ (conj _ (conj _ _)))).
286
+ + intros c Hc. rewrite U1; [apply Hq; exact Hc | unfold ST, AR, HO in *; lia | unfold UC, AR, HO in *; lia
287
+ | apply not_scr; unfold XC, AR, HO in *; lia].
288
+ + intros v Hv Hnv. destruct (Nat.eq_dec v u) as [->|Hvu]; [rewrite Eo in Hnv; discriminate|].
289
+ rewrite U1; [apply Hun; [lia | exact Hnv] | unfold ST, UC, nh in *; lia | unfold UC; lia
290
+ | apply not_scr; unfold UC, XC, nh; lia].
291
+ + intros i Hi. destruct (Nat.eq_dec i i0) as [->|Hii].
292
+ * rewrite V1, Ei0. replace (Nat.ltb (n + u) (n + S u)) with true by (symmetry; apply Nat.ltb_lt; lia).
293
+ reflexivity.
294
+ * rewrite U1; [|unfold ST; lia | unfold ST, UC, nh; lia | apply not_scr; unfold ST, XC, nh; lia].
295
+ rewrite Hst by exact Hi.
296
+ assert (Hne : nth i (host_next A) 0 <> n + u).
297
+ { intro E1. apply Hii. apply (host_next_inj A HA i i0 Hi Hi0). rewrite E1, Ei0. reflexivity. }
298
+ destruct (Nat.ltb_spec (nth i (host_next A) 0) (n + u)), (Nat.ltb_spec (nth i (host_next A) 0) (n + S u));
299
+ try reflexivity; lia.
300
+ + intros c Hc. rewrite U1; [apply Hfix; exact Hc
301
+ | unfold ST, DB, nh in *; lia | unfold UC, DB, ST, nh in *; lia|].
302
+ destruct Hc as [Hc|Hc]; [apply not_scr; unfold ST, XC, nh in *; lia | apply scr_db; exact Hc].
303
+ - (* any other unit writes its own cell *)
304
+ destruct (ucomp_run W lv (XC A w nu) xc_gt xc_lt xc_inj (map (lit_of A w) (tin U)) (tval U) (UC A w u)
305
+ (UC A w u) 0 w' Hl Hacc Hacc Hsacc Hsacc Hlits Hlev) as (L1 & V1 & U1).
306
+ rewrite Hval in V1.
307
+ refine (conj L1 (conj _ (conj _ (conj _ _)))).
308
+ + intros c Hc. rewrite U1; [apply Hq; exact Hc | unfold UC, AR, HO in *; lia | unfold UC, AR, HO in *; lia
309
+ | apply not_scr; unfold XC, AR, HO in *; lia].
310
+ + intros v Hv Hnv. destruct (Nat.eq_dec v u) as [->|Hvu]; [exact V1|].
311
+ rewrite U1; [apply Hun; [lia | exact Hnv] | unfold UC; lia | unfold UC; lia
312
+ | apply not_scr; unfold UC, XC, nh; lia].
313
+ + intros i Hi. rewrite U1; [|unfold ST, UC, nh; lia | unfold ST, UC, nh; lia | apply not_scr; unfold ST, XC, nh; lia].
314
+ rewrite Hst by exact Hi.
315
+ pose proof (nt_none A HA u Hu Eo i Hi) as Hne.
316
+ destruct (Nat.ltb_spec (nth i (host_next A) 0) (n + u)), (Nat.ltb_spec (nth i (host_next A) 0) (n + S u));
317
+ try reflexivity; lia.
318
+ + intros c Hc. rewrite U1; [apply Hfix; exact Hc | unfold UC, DB, ST, nh in *; lia | unfold UC, DB, ST, nh in *; lia|].
319
+ destruct Hc as [Hc|Hc]; [apply not_scr; unfold ST, XC, nh in *; lia | apply scr_db; exact Hc].
320
+ Qed.
321
+
322
+ Lemma skipn_cons_nth : forall (T : Type) (l : list T) k d, k < length l -> skipn k l = nth k l d :: skipn (S k) l.
323
+ Proof.
324
+ intros T l. induction l as [|x l IH]; intros [|k] d Hk; cbn [length] in Hk; try lia; [reflexivity|].
325
+ cbn [skipn nth]. apply IH. lia.
326
+ Qed.
327
+
328
+ Lemma step_go_unit : forall u, u < nu ->
329
+ step_go A w nu u (skipn u us) (skipn u nt) = unit_recs u ++ step_go A w nu (S u) (skipn (S u) us) (skipn (S u) nt).
330
+ Proof.
331
+ intros u Hu. rewrite (skipn_cons_nth _ us u tu0 Hu).
332
+ rewrite (skipn_cons_nth _ nt u None) by (rewrite (proj1 (nt_spec A HA)); exact Hu).
333
+ reflexivity.
334
+ Qed.
335
+
336
+ Lemma step_go_end : step_go A w nu nu (skipn nu us) (skipn nu nt) = [].
337
+ Proof. rewrite skipn_all. reflexivity. Qed.
338
+
339
+ Theorem step_run : Inv nu (wrun (step_go A w nu 0 us nt) w0).
340
+ Proof.
341
+ assert (G : forall k u w', u + k = nu -> Inv u w' -> Inv nu (wrun (step_go A w nu u (skipn u us) (skipn u nt)) w')).
342
+ { induction k as [|k IH]; intros u w' Hk Hi.
343
+ - rewrite Nat.add_0_r in Hk. subst u. rewrite step_go_end. exact Hi.
344
+ - rewrite step_go_unit by lia. rewrite wrun_app. apply IH; [lia|]. apply unit_step; [lia | exact Hi]. }
345
+ exact (G nu 0 w0 eq_refl Inv_0).
346
+ Qed.
347
+
348
+ (* the block's records read and write only the window, above the requests *)
349
+ Theorem step_wrec : Forall wrec (step_go A w nu 0 us nt).
350
+ Proof.
351
+ assert (G : forall L NT u, Forall wrec (step_go A w nu u L NT)).
352
+ { induction L as [|U L IH]; intros [|o NT] u; cbn [step_go]; try constructor.
353
+ apply Forall_app. split; [|apply IH].
354
+ apply (ucomp_wrec (XC A w nu) xc_gt).
355
+ - destruct o; unfold ST, UC, HO; lia.
356
+ - unfold UC, HO; lia.
357
+ - intros l Hl. apply in_map_iff in Hl as ([i wt] & <- & _). unfold lit_of, rd_ok. cbn [fst]. right.
358
+ destruct (i <? nh A); unfold ST, UC, CPY; lia. }
359
+ apply G.
360
+ Qed.
361
+
362
+ End Step.
rocq/StoredWbr.v ADDED
@@ -0,0 +1,639 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* Every cell that a pass of the stored host reads, other than the sink and the cells under the heads, holds the
2
+ state of the host, a register, booted or a request, or is written earlier in the pass. Two views that agree on
3
+ those cells and on the heads therefore agree after the pass on them and on every cell the pass writes, whatever
4
+ the other cells of the window hold; the cells no record writes keep their values. *)
5
+ From Stdlib Require Import List Bool Arith ZArith Lia.
6
+ Import ListNotations.
7
+ From TH Require Import TwoHead Net Abstract Indep Run View Stored WinRun ViewOps Host HostIP Device StoredStep.
8
+
9
+ (* ---- reads of cells written before ------------------------------------------------------------------------- *)
10
+ Definition cok (D : nat -> Prop) (c : nat) : Prop := c <= CPY \/ D c.
11
+
12
+ Definition rdw (D : nat -> Prop) (a : nat) (wt : Z) : Prop := wt = 0%Z \/ cok D a.
13
+
14
+ Definition rdr (D : nat -> Prop) (r : rec) : Prop :=
15
+ match r with Rec a0 w0 a1 w1 _ _ => rdw D a0 w0 /\ rdw D a1 w1 end.
16
+
17
+ (* the records of rs read, of the window cells from 4 on, only those in D and those written before them *)
18
+ Fixpoint wbr (D : nat -> Prop) (rs : list rec) : Prop :=
19
+ match rs with
20
+ | [] => True
21
+ | r :: t => rdr D r /\ wbr (fun c => D c \/ c = ao_of r) t
22
+ end.
23
+
24
+ Definition wrt (rs : list rec) (c : nat) : Prop := In c (map ao_of rs).
25
+
26
+ Lemma cok_mono : forall (D D' : nat -> Prop) c, (forall x, D x -> D' x) -> cok D c -> cok D' c.
27
+ Proof. intros D D' c H [Hc|Hc]; [left; exact Hc | right; apply H; exact Hc]. Qed.
28
+
29
+ Lemma rdr_mono : forall (D D' : nat -> Prop) r, (forall c, D c -> D' c) -> rdr D r -> rdr D' r.
30
+ Proof.
31
+ intros D D' [a0 w0 a1 w1 beta ao] H [H0 H1].
32
+ split; [destruct H0 as [H0|H0] | destruct H1 as [H1|H1]];
33
+ solve [left; exact H0 | left; exact H1 | right; exact (cok_mono D D' _ H H0) | right; exact (cok_mono D D' _ H H1)].
34
+ Qed.
35
+
36
+ Lemma wbr_mono : forall rs (D D' : nat -> Prop), (forall c, D c -> D' c) -> wbr D rs -> wbr D' rs.
37
+ Proof.
38
+ induction rs as [|r rs IH]; intros D D' H Hw; [exact I|]. destruct Hw as [Hr Hw].
39
+ split; [exact (rdr_mono D D' r H Hr)|].
40
+ apply (IH (fun c => D c \/ c = ao_of r)); [|exact Hw].
41
+ intros c [Hc|Hc]; [left; apply H; exact Hc | right; exact Hc].
42
+ Qed.
43
+
44
+ Lemma wbr_app : forall a b (D D' : nat -> Prop), wbr D a -> (forall c, D' c -> D c \/ wrt a c) -> wbr D' b ->
45
+ wbr D (a ++ b).
46
+ Proof.
47
+ induction a as [|r a IH]; intros b D D' Ha HD Hb.
48
+ - cbn [app]. apply (wbr_mono b D'); [|exact Hb]. intros c Hc. destruct (HD c Hc) as [H|[]]. exact H.
49
+ - destruct Ha as [Hr Ha]. cbn [app wbr]. split; [exact Hr|]. apply (IH b _ D' Ha); [|exact Hb].
50
+ intros c Hc. destruct (HD c Hc) as [H|H]; [left; left; exact H|].
51
+ unfold wrt in H. cbn [map In] in H. destruct H as [H|H]; [left; right; symmetry; exact H | right; exact H].
52
+ Qed.
53
+
54
+ Lemma wbr_all : forall rs (D : nat -> Prop), Forall (rdr D) rs -> wbr D rs.
55
+ Proof.
56
+ induction rs as [|r rs IH]; intros D H; [exact I|]. apply Forall_cons_iff in H as [Hr Hrs].
57
+ split; [exact Hr|]. apply IH. eapply Forall_impl; [|exact Hrs].
58
+ intros r' Hr'. apply (rdr_mono D); [|exact Hr']. intros c Hc. left. exact Hc.
59
+ Qed.
60
+
61
+ Lemma wbr_concat_map : forall (f : nat -> list rec) l (D : nat -> Prop), (forall i, In i l -> wbr D (f i)) ->
62
+ wbr D (concat (map f l)).
63
+ Proof.
64
+ intros f l. induction l as [|i l IH]; intros D H; [exact I|]. cbn [map concat].
65
+ apply (wbr_app _ _ D D); [apply H; left; reflexivity | intros c Hc; left; exact Hc |].
66
+ apply IH. intros j Hj. apply H. right. exact Hj.
67
+ Qed.
68
+
69
+ Lemma wrt_app_l : forall a b c, wrt a c -> wrt (a ++ b) c.
70
+ Proof. intros a b c H. unfold wrt in *. rewrite map_app. apply in_or_app. left. exact H. Qed.
71
+
72
+ Lemma wrt_app_r : forall a b c, wrt b c -> wrt (a ++ b) c.
73
+ Proof. intros a b c H. unfold wrt in *. rewrite map_app. apply in_or_app. right. exact H. Qed.
74
+
75
+ Lemma wrt_concat_map : forall (f : nat -> list rec) l i c, In i l -> wrt (f i) c -> wrt (concat (map f l)) c.
76
+ Proof.
77
+ intros f l i c Hi H. unfold wrt in *. apply in_map_iff in H as (r & Hr & Hin).
78
+ apply in_map_iff. exists r. split; [exact Hr|]. apply in_concat. exists (f i). split; [apply in_map; exact Hi | exact Hin].
79
+ Qed.
80
+
81
+ Lemma wrt_map : forall (f : nat -> rec) l i, In i l -> wrt (map f l) (ao_of (f i)).
82
+ Proof. intros f l i Hi. unfold wrt. rewrite map_map. apply (in_map (fun x => ao_of (f x))). exact Hi. Qed.
83
+
84
+ (* ---- the gates ----------------------------------------------------------------------------------------------- *)
85
+ Lemma rdr_and : forall (D : nat -> Prop) x y d, cok D (fst x) -> cok D (fst y) -> rdr D (gAND x y d).
86
+ Proof. intros D x y d Hx Hy. split; right; assumption. Qed.
87
+
88
+ Lemma rdr_or : forall (D : nat -> Prop) x y d, cok D (fst x) -> cok D (fst y) -> rdr D (gOR x y d).
89
+ Proof. intros D x y d Hx Hy. split; right; assumption. Qed.
90
+
91
+ Lemma rdr_copy : forall (D : nat -> Prop) x d, cok D (fst x) -> rdr D (gCOPY x d).
92
+ Proof. intros D x d Hx. split; [right; exact Hx | left; reflexivity]. Qed.
93
+
94
+ Lemma rdr_const : forall (D : nat -> Prop) b d, rdr D (gCONST b d).
95
+ Proof. intros D [|] d; split; right; left; unfold SINK, CPY; cbn; lia. Qed.
96
+
97
+ Lemma rdr_empty : forall (D : nat -> Prop), rdr D EMPTY.
98
+ Proof. intro D. split; left; reflexivity. Qed.
99
+
100
+ Section Chains.
101
+ Variable g : nat * bool -> nat * bool -> nat -> rec.
102
+ Hypotheses (Hg : forall (D : nat -> Prop) x y d, cok D (fst x) -> cok D (fst y) -> rdr D (g x y d))
103
+ (Hgo : forall x y d, ao_of (g x y d) = d).
104
+
105
+ Lemma wbr_chain_tail : forall ls (D : nat -> Prop) acc l d, D acc -> cok D (fst l) ->
106
+ (forall l', In l' ls -> cok D (fst l')) -> wbr D (chain_tail g acc l ls d).
107
+ Proof.
108
+ induction ls as [|l' ls IH]; intros D acc l d Ha Hl Hls; cbn [chain_tail wbr].
109
+ - split; [apply Hg; [right; exact Ha | exact Hl] | exact I].
110
+ - split; [apply Hg; [right; exact Ha | exact Hl]|]. rewrite Hgo.
111
+ apply IH; [left; exact Ha | |].
112
+ + apply (cok_mono D); [intros c Hc; left; exact Hc | apply Hls; left; reflexivity].
113
+ + intros l'' Hl''. apply (cok_mono D); [intros c Hc; left; exact Hc | apply Hls; right; exact Hl''].
114
+ Qed.
115
+
116
+ Lemma wbr_chain : forall ls (D : nat -> Prop) d acc, (forall l, In l ls -> cok D (fst l)) -> wbr D (chain g ls d acc).
117
+ Proof.
118
+ intros [|l0 [|l1 [|l2 t]]] D d acc H; cbn [chain wbr].
119
+ - exact I.
120
+ - split; [apply rdr_copy, H; left; reflexivity | exact I].
121
+ - split; [apply Hg; apply H; [left | right; left]; reflexivity | exact I].
122
+ - split; [apply Hg; apply H; [left | right; left]; reflexivity|]. rewrite Hgo.
123
+ apply wbr_chain_tail; [right; reflexivity | |].
124
+ + apply (cok_mono D); [intros c Hc; left; exact Hc | apply H; right; right; left; reflexivity].
125
+ + intros l' Hl'. apply (cok_mono D); [intros c Hc; left; exact Hc | apply H; right; right; right; exact Hl'].
126
+ Qed.
127
+
128
+ Lemma chain_tail_writes : forall ls acc l d, wrt (chain_tail g acc l ls d) d.
129
+ Proof.
130
+ induction ls as [|l' ls IH]; intros acc l d; cbn [chain_tail]; unfold wrt; cbn [map In].
131
+ - left. apply Hgo.
132
+ - right. apply IH.
133
+ Qed.
134
+
135
+ Lemma chain_writes : forall ls d acc, ls <> [] -> wrt (chain g ls d acc) d.
136
+ Proof.
137
+ intros [|l0 [|l1 [|l2 t]]] d acc Hne; [contradiction Hne; reflexivity | | |]; unfold wrt; cbn [chain map In].
138
+ - left. reflexivity.
139
+ - left. apply Hgo.
140
+ - right. apply chain_tail_writes.
141
+ Qed.
142
+
143
+ End Chains.
144
+
145
+ Lemma wbr_chain_and : forall ls (D : nat -> Prop) d acc, (forall l, In l ls -> cok D (fst l)) ->
146
+ wbr D (chain gAND ls d acc).
147
+ Proof. apply wbr_chain; [exact rdr_and | reflexivity]. Qed.
148
+
149
+ Lemma wbr_chain_or : forall ls (D : nat -> Prop) d acc, (forall l, In l ls -> cok D (fst l)) ->
150
+ wbr D (chain gOR ls d acc).
151
+ Proof. apply wbr_chain; [exact rdr_or | reflexivity]. Qed.
152
+
153
+ (* ---- a unit: the cells of its levels are written before they are read ---------------------------------------- *)
154
+ Section Ucomp.
155
+ Variable xc : nat -> nat -> nat.
156
+
157
+ Lemma ucomp_eq : forall t ls d acc lev, ucomp xc t ls d acc lev =
158
+ if Z.leb t 0 then [gCONST true d]
159
+ else if Z.ltb (Z.of_nat (length ls)) t then [gCONST false d]
160
+ else if Z.eqb t 1 then chain gOR ls d acc
161
+ else if Z.eqb t (Z.of_nat (length ls)) then chain gAND ls d acc
162
+ else match ls with
163
+ | [] => []
164
+ | l0 :: rest =>
165
+ ucomp xc t rest (xc lev 0) (xc lev 0) (S lev) ++ ucomp xc (t - 1) rest (xc lev 1) (xc lev 1) (S lev)
166
+ ++ [gAND l0 (xc lev 1, true) (xc lev 2); gOR (xc lev 0, true) (xc lev 2, true) d]
167
+ end.
168
+ Proof. intros t [|l0 rest] d acc lev; reflexivity. Qed.
169
+
170
+ Lemma ucomp_writes : forall ls t d acc lev, wrt (ucomp xc t ls d acc lev) d.
171
+ Proof.
172
+ intros ls t d acc lev. rewrite ucomp_eq.
173
+ destruct (Z.leb_spec t 0); [unfold wrt; cbn [map In]; left; reflexivity|].
174
+ destruct (Z.ltb_spec (Z.of_nat (length ls)) t); [unfold wrt; cbn [map In]; left; reflexivity|].
175
+ destruct (Z.eqb_spec t 1).
176
+ { apply (chain_writes gOR (fun _ _ _ => eq_refl)). intro E. subst ls. cbn in *. lia. }
177
+ destruct (Z.eqb_spec t (Z.of_nat (length ls))).
178
+ { apply (chain_writes gAND (fun _ _ _ => eq_refl)). intro E. subst ls. cbn in *. lia. }
179
+ destruct ls as [|l0 rest]; [cbn in *; lia|].
180
+ apply wrt_app_r, wrt_app_r. unfold wrt. cbn [map In]. right. left. reflexivity.
181
+ Qed.
182
+
183
+ Lemma wbr_ucomp : forall ls t d acc lev (D : nat -> Prop), (forall l, In l ls -> cok D (fst l)) ->
184
+ wbr D (ucomp xc t ls d acc lev).
185
+ Proof.
186
+ induction ls as [|l0 rest IH]; intros t d acc lev D H; rewrite ucomp_eq.
187
+ - destruct (Z.leb t 0); [exact (conj (rdr_const D true d) I)|].
188
+ destruct (Z.ltb _ t); [exact (conj (rdr_const D false d) I)|].
189
+ destruct (Z.eqb t 1); [apply wbr_chain_or; exact H|].
190
+ destruct (Z.eqb t _); [apply wbr_chain_and; exact H | exact I].
191
+ - destruct (Z.leb t 0); [exact (conj (rdr_const D true d) I)|].
192
+ destruct (Z.ltb _ t); [exact (conj (rdr_const D false d) I)|].
193
+ destruct (Z.eqb t 1); [apply wbr_chain_or; exact H|].
194
+ destruct (Z.eqb t _); [apply wbr_chain_and; exact H|].
195
+ assert (Hr : forall l, In l rest -> cok D (fst l)) by (intros l Hl; apply H; right; exact Hl).
196
+ set (U1 := ucomp xc t rest (xc lev 0) (xc lev 0) (S lev)).
197
+ set (U2 := ucomp xc (t - 1) rest (xc lev 1) (xc lev 1) (S lev)).
198
+ apply (wbr_app U1 _ D (fun c => D c \/ c = xc lev 0)); [apply IH; exact Hr | |].
199
+ { intros c [Hc|Hc]; [left; exact Hc | right; subst c; apply ucomp_writes]. }
200
+ apply (wbr_app U2 _ _ (fun c => (D c \/ c = xc lev 0) \/ c = xc lev 1)).
201
+ { apply IH. intros l Hl. apply (cok_mono D); [intros c Hc; left; exact Hc | apply Hr; exact Hl]. }
202
+ { intros c [Hc|Hc]; [left; exact Hc | right; subst c; apply ucomp_writes]. }
203
+ cbn [wbr]. split; [|split; [|exact I]].
204
+ + apply rdr_and; [|right; right; reflexivity].
205
+ apply (cok_mono D); [intros c Hc; left; left; exact Hc | apply H; left; reflexivity].
206
+ + apply rdr_or; right; [left; left; right; reflexivity | right; reflexivity].
207
+ Qed.
208
+
209
+ End Ucomp.
210
+
211
+ (* ---- two views that agree on the cells read ------------------------------------------------------------------ *)
212
+ Definition vagree (D : nat -> Prop) (v1 v2 : view) : Prop :=
213
+ vr v1 = vr v2 /\ va v1 = va v2 /\ vc v1 = vc v2 /\ vho v1 = vho v2 /\ length (vw v1) = length (vw v2)
214
+ /\ (forall c, CPY < c -> D c -> wget (vw v1) c = wget (vw v2) c).
215
+
216
+ Lemma vagree_mono : forall (D D' : nat -> Prop) v1 v2, (forall c, D' c -> D c) -> vagree D v1 v2 -> vagree D' v1 v2.
217
+ Proof.
218
+ intros D D' v1 v2 H (HR & HA & HC & HH & Hl & HW).
219
+ refine (conj HR (conj HA (conj HC (conj HH (conj Hl _))))). intros c Hc Hd. apply HW; [exact Hc | apply H; exact Hd].
220
+ Qed.
221
+
222
+ Section Agree.
223
+ Variables (Lb L : nat).
224
+
225
+ Lemma vcell_agree : forall (D : nat -> Prop) v1 v2 a wt, vagree D v1 v2 -> rdw D a wt ->
226
+ (wt * b2z (vcell v1 a) = wt * b2z (vcell v2 a))%Z.
227
+ Proof.
228
+ intros D v1 v2 a wt (HR & HA & HC & _ & _ & HW) Hrd. destruct Hrd as [->|[Ha|Ha]]; [reflexivity| |].
229
+ - assert (Hc : a = SINK \/ a = RD \/ a = ARM \/ a = CPY) by (unfold SINK, RD, ARM, CPY in *; lia).
230
+ unfold vcell. rewrite HR, HA, HC. destruct Hc as [->|[->|[->| ->]]]; reflexivity.
231
+ - destruct (Nat.leb_spec a CPY) as [Hle|Hgt].
232
+ + assert (Hc : a = SINK \/ a = RD \/ a = ARM \/ a = CPY) by (unfold SINK, RD, ARM, CPY in *; lia).
233
+ unfold vcell. rewrite HR, HA, HC. destruct Hc as [->|[->|[->| ->]]]; reflexivity.
234
+ + unfold vcell.
235
+ replace (Nat.eqb a SINK) with false by (symmetry; apply Nat.eqb_neq; unfold SINK, CPY in *; lia).
236
+ replace (Nat.eqb a RD) with false by (symmetry; apply Nat.eqb_neq; unfold RD, CPY in *; lia).
237
+ replace (Nat.eqb a ARM) with false by (symmetry; apply Nat.eqb_neq; unfold ARM, CPY in *; lia).
238
+ replace (Nat.eqb a CPY) with false by (symmetry; apply Nat.eqb_neq; lia).
239
+ rewrite (HW a Hgt Ha). reflexivity.
240
+ Qed.
241
+
242
+ Lemma rval_agree : forall (D : nat -> Prop) v1 v2 r, vagree D v1 v2 -> rdr D r -> rval v1 r = rval v2 r.
243
+ Proof.
244
+ intros D v1 v2 [a0 w0 a1 w1 beta ao] H [H0 H1]. unfold rval.
245
+ rewrite (vcell_agree D v1 v2 a0 w0 H H0), (vcell_agree D v1 v2 a1 w1 H H1). reflexivity.
246
+ Qed.
247
+
248
+ Lemma vexec_agree : forall (D : nat -> Prop) v1 v2 r, (forall c, AR <= c <= HO -> D c) -> vagree D v1 v2 -> rdr D r ->
249
+ vagree (fun c => D c \/ c = ao_of r) (vexec Lb L r v1) (vexec Lb L r v2).
250
+ Proof.
251
+ intros D v1 v2 r Hreq H Hr. pose proof (rval_agree D v1 v2 r H Hr) as Ex.
252
+ destruct H as (HR & HA & HC & HH & Hl & HW).
253
+ unfold vexec. rewrite Ex. set (x := rval v2 r). set (ao := ao_of r).
254
+ assert (Hn : forall c, CPY < c -> D c \/ c = ao -> wget (wnext (vw v1) ao x) c = wget (wnext (vw v2) ao x) c).
255
+ { intros c Hc Hd. unfold wnext. destruct (Nat.leb_spec ao CPY) as [Ha|Ha].
256
+ - destruct Hd as [Hd|Hd]; [exact (HW c Hc Hd) | lia].
257
+ - rewrite !wget_upd, Hl. destruct (Nat.eqb c ao && Nat.ltb ao (length (vw v2))) eqn:E; [reflexivity|].
258
+ destruct Hd as [Hd|Hd]; [exact (HW c Hc Hd)|]. subst c.
259
+ rewrite Nat.eqb_refl in E. cbn [andb] in E. apply Nat.ltb_ge in E.
260
+ unfold wget. rewrite !nth_overflow by lia. reflexivity. }
261
+ assert (Hq : forall c, AR <= c <= HO -> wget (wnext (vw v1) ao x) c = wget (wnext (vw v2) ao x) c)
262
+ by (intros c Hc; apply Hn; [unfold AR, CPY in *; lia | left; apply Hreq; exact Hc]).
263
+ unfold vput. cbv zeta. unfold vagree. cbn [vr va vc vho vw].
264
+ rewrite (Hq RR), (Hq AR), (Hq CB), (Hq RA), (Hq AA), (Hq CT), (Hq RC), (Hq AC), (Hq HO)
265
+ by (unfold AR, RR, CB, RA, AA, CT, RC, AC, HO; lia).
266
+ rewrite HR, HA, HC, HH.
267
+ refine (conj eq_refl (conj eq_refl (conj eq_refl (conj eq_refl (conj _ _))))).
268
+ - rewrite !length_clearq, !length_wnext. exact Hl.
269
+ - intros c Hc Hd. destruct (Nat.le_gt_cases c HO) as [H1|H1].
270
+ + rewrite !wget_clearq_req by (unfold AR, CPY in *; lia). reflexivity.
271
+ + rewrite !wget_clearq_out by (right; exact H1). exact (Hn c Hc Hd).
272
+ Qed.
273
+
274
+ Lemma vrun_agree : forall rs (D : nat -> Prop) v1 v2, (forall c, AR <= c <= HO -> D c) -> wbr D rs -> vagree D v1 v2 ->
275
+ vagree (fun c => D c \/ wrt rs c) (vrun Lb L rs v1) (vrun Lb L rs v2).
276
+ Proof.
277
+ induction rs as [|r rs IH]; intros D v1 v2 Hreq Hw H.
278
+ - cbn [vrun]. apply (vagree_mono D); [intros c [Hc|[]]; exact Hc | exact H].
279
+ - destruct Hw as [Hr Hw]. cbn [vrun].
280
+ pose proof (vexec_agree D v1 v2 r Hreq H Hr) as H1.
281
+ pose proof (IH _ _ _ (fun c Hc => or_introl (Hreq c Hc)) Hw H1) as H2.
282
+ refine (vagree_mono _ _ _ _ _ H2).
283
+ intros c [Hc|Hc]; [left; left; exact Hc|]. unfold wrt in Hc. cbn [map In] in Hc.
284
+ destruct Hc as [Hc|Hc]; [left; right; symmetry; exact Hc | right; exact Hc].
285
+ Qed.
286
+
287
+ (* the cells under the heads and the cells from the requests on that no record writes keep their values *)
288
+ Lemma vexec_frame : forall r v c, c <= CPY \/ (HO < c /\ c <> ao_of r) -> wget (vw (vexec Lb L r v)) c = wget (vw v) c.
289
+ Proof.
290
+ intros r v c Hc. unfold vexec, vput. cbv zeta. cbn [vw].
291
+ rewrite wget_clearq_out by (destruct Hc as [Hc|[Hc _]]; [left; unfold AR, CPY in *; lia | right; exact Hc]).
292
+ unfold wnext. destruct (Nat.leb_spec (ao_of r) CPY); [reflexivity|].
293
+ rewrite wget_upd. replace (Nat.eqb c (ao_of r)) with false; [reflexivity|].
294
+ symmetry. apply Nat.eqb_neq. destruct Hc as [Hc|[_ Hc]]; [lia | exact Hc].
295
+ Qed.
296
+
297
+ Lemma vrun_frame : forall rs v c, c <= CPY \/ (HO < c /\ ~ wrt rs c) -> wget (vw (vrun Lb L rs v)) c = wget (vw v) c.
298
+ Proof.
299
+ induction rs as [|r rs IH]; intros v c Hc; [reflexivity|]. cbn [vrun].
300
+ rewrite IH; [apply vexec_frame|].
301
+ - destruct Hc as [Hc|[Hc Hn]]; [left; exact Hc | right; split; [exact Hc|]].
302
+ intro E. apply Hn. unfold wrt. cbn [map In]. left. symmetry. exact E.
303
+ - destruct Hc as [Hc|[Hc Hn]]; [left; exact Hc | right; split; [exact Hc|]].
304
+ intro E. apply Hn. unfold wrt. cbn [map In]. right. exact E.
305
+ Qed.
306
+
307
+ End Agree.
308
+
309
+ (* ---- the stored host ----------------------------------------------------------------------------------------- *)
310
+ Section Host.
311
+ Variables (A w : nat).
312
+ Hypotheses (HA : 8 <= A) (Hw : 1 <= w).
313
+
314
+ Local Notation n := (nH A).
315
+ Local Notation us := (host_units A).
316
+ Local Notation nu := (length (host_units A)).
317
+ Local Notation lv := (levels (host_units A)).
318
+ Local Notation nt := (next_tbl (nH A) (length (host_units A)) (host_next A)).
319
+
320
+ (* the cells a pass reads before it writes them: the requests, booted, the registers and the state of the host *)
321
+ Definition D0 (c : nat) : Prop := c < ST w n.
322
+
323
+ Lemma SW8 : 256 <= SW A.
324
+ Proof.
325
+ unfold SW. replace A with (8 + (A - 8)) by lia. rewrite Nat.pow_add_r. change (2 ^ 8) with 256.
326
+ pose proof (Nat.pow_nonzero 2 (A - 8) ltac:(lia)). lia.
327
+ Qed.
328
+
329
+ Lemma MB_D0 : forall j t, j < SW A -> t < A -> D0 (MB A w j t).
330
+ Proof. intros j t Hj Ht. unfold D0, MB, ST, nH. nia. Qed.
331
+
332
+ Lemma ST_D0 : forall i, i < n -> D0 (ST w i).
333
+ Proof. intros i Hi. unfold D0, ST. lia. Qed.
334
+
335
+ Lemma reg_D0 : forall i, i < w -> D0 (CNT i) /\ D0 (LIM w i).
336
+ Proof. intros i Hi. unfold D0, CNT, LIM, ST. lia. Qed.
337
+
338
+ Lemma CNT_D0 : forall i, i < w -> D0 (CNT i).
339
+ Proof. intros i Hi. exact (proj1 (reg_D0 i Hi)). Qed.
340
+
341
+ Lemma LIM_D0 : forall i, i < w -> D0 (LIM w i).
342
+ Proof. intros i Hi. exact (proj2 (reg_D0 i Hi)). Qed.
343
+
344
+ Lemma DEST_D0 : D0 (DEST w).
345
+ Proof. unfold D0, DEST, ST. lia. Qed.
346
+
347
+ Lemma BOOT_D0 : D0 BOOT.
348
+ Proof. unfold D0, BOOT, ST. lia. Qed.
349
+
350
+ Lemma req_D0 : forall c, AR <= c <= HO -> D0 c.
351
+ Proof. intros c Hc. unfold D0, ST, AR, HO in *. lia. Qed.
352
+
353
+ Lemma dev_lt : cwr A < SW A /\ crd A < SW A /\ crw A < SW A /\ rout A < SW A /\ rin A < SW A /\ ceot A < SW A.
354
+ Proof. pose proof SW8. unfold cwr, crd, crw, rout, rin, ceot. lia. Qed.
355
+
356
+ (* the startup reads only its own cells and booted *)
357
+ Lemma wbr_startup : forall m, length m = SW A -> wbr D0 (startup A w m).
358
+ Proof.
359
+ intros m Hm. apply wbr_all. unfold startup. rewrite !Forall_app. pose proof BOOT_D0 as HB.
360
+ refine (conj _ (conj _ (conj _ (conj _ (conj _ (conj _ _)))))).
361
+ - apply Forall_concat, Forall_map, Forall_forall. intros [j v] Hp. apply in_combine_l in Hp. apply in_seq in Hp.
362
+ cbn [fst snd]. unfold boot_word. apply Forall_map, Forall_forall. intros t Ht. apply in_seq in Ht.
363
+ destruct (Nat.testbit v t); [apply rdr_or | apply rdr_and]; right; cbn [fst];
364
+ first [exact HB | apply MB_D0; lia].
365
+ - apply Forall_map, Forall_forall. intros t Ht. apply in_seq in Ht.
366
+ apply rdr_and; right; cbn [fst]; [apply ST_D0; unfold nH; lia | exact HB].
367
+ - apply Forall_cons; [|apply Forall_nil]. apply rdr_and; right; cbn [fst]; [apply ST_D0; unfold nH; lia | exact HB].
368
+ - apply Forall_concat, Forall_map, Forall_forall. intros i Hi. apply in_seq in Hi.
369
+ destruct (reg_D0 i ltac:(lia)) as [H1 H2].
370
+ apply Forall_cons; [|apply Forall_cons; [|apply Forall_nil]]; apply rdr_and; right; cbn [fst]; assumption.
371
+ - apply Forall_cons; [|apply Forall_nil]. apply rdr_and; right; cbn [fst]; [exact DEST_D0 | exact HB].
372
+ - cbn [map]. repeat (apply Forall_cons; [apply rdr_copy; right; exact HB|]). apply Forall_nil.
373
+ - apply Forall_cons; [apply rdr_const | apply Forall_nil].
374
+ Qed.
375
+
376
+ (* the step: every input of a unit is a state bit, or a unit before it whose cell it writes *)
377
+ Definition Du (u : nat) (c : nat) : Prop := D0 c \/ exists v, v < u /\ nth v nt None = None /\ c = UC A w v.
378
+
379
+ Lemma lit_Du : forall u, u < nu -> forall p, In p (tin (nth u us tu0)) -> cok (Du u) (fst (lit_of A w p)).
380
+ Proof.
381
+ intros u Hu [i wt] Hin. right. unfold lit_of, nh. cbn [fst].
382
+ destruct (Nat.ltb_spec i n) as [Hi|Hi]; [left; apply ST_D0; exact Hi|].
383
+ right. pose proof (host_reads_below A ltac:(lia) u Hu i wt Hin) as Hlt.
384
+ exists (i - n). split; [lia|]. split; [|reflexivity].
385
+ destruct (nth (i - n) nt None) as [i'|] eqn:Ei; [|reflexivity]. exfalso.
386
+ destruct (nt_some A ltac:(lia) (i - n) i' ltac:(lia) Ei) as [Hi' Ei'].
387
+ apply (host_no_out A ltac:(lia) u i wt Hu Hin i' Hi'). lia.
388
+ Qed.
389
+
390
+ Lemma skipn_nth' : forall (T : Type) (l : list T) k d, k < length l -> skipn k l = nth k l d :: skipn (S k) l.
391
+ Proof.
392
+ intros T l. induction l as [|x l IH]; intros [|k] d Hk; cbn [length] in Hk; try lia; [reflexivity|].
393
+ cbn [skipn nth]. apply IH. lia.
394
+ Qed.
395
+
396
+ Lemma step_go_cons : forall u, u < nu ->
397
+ step_go A w nu u (skipn u us) (skipn u nt) = unit_recs A w u ++ step_go A w nu (S u) (skipn (S u) us) (skipn (S u) nt).
398
+ Proof.
399
+ intros u Hu. rewrite (skipn_nth' _ us u tu0 Hu).
400
+ rewrite (skipn_nth' _ nt u None) by (rewrite (proj1 (nt_spec A ltac:(lia))); exact Hu).
401
+ reflexivity.
402
+ Qed.
403
+
404
+ Lemma wbr_step : wbr D0 (step_go A w nu 0 us nt).
405
+ Proof.
406
+ assert (G : forall k u, u + k = nu -> wbr (Du u) (step_go A w nu u (skipn u us) (skipn u nt))).
407
+ { induction k as [|k IH]; intros u Hk.
408
+ - rewrite Nat.add_0_r in Hk. subst u. rewrite skipn_all. exact I.
409
+ - rewrite step_go_cons by lia. apply (wbr_app _ _ _ (Du (S u))).
410
+ + unfold unit_recs. apply wbr_ucomp. intros l Hl. apply in_map_iff in Hl as (p & <- & Hp).
411
+ apply lit_Du; [lia | exact Hp].
412
+ + intros c [Hc|(v & Hv & Hn & ->)]; [left; left; exact Hc|].
413
+ destruct (Nat.eq_dec v u) as [->|Hvu]; [right | left; right; exists v; split; [lia | split; [exact Hn | reflexivity]]].
414
+ unfold unit_recs. rewrite Hn. apply ucomp_writes.
415
+ + apply IH. lia. }
416
+ apply (wbr_mono _ (Du 0)); [|exact (G nu 0 eq_refl)].
417
+ intros c [Hc|(v & Hv & _)]; [exact Hc | lia].
418
+ Qed.
419
+
420
+ (* the device: its temporaries are written in order, each before its first read *)
421
+ Local Notation dWR := (dWR A w nu lv).
422
+ Local Notation dRD := (dRD A w nu lv).
423
+ Local Notation dRW := (dRW A w nu lv).
424
+ Local Notation dE := (dE A w nu lv).
425
+ Local Notation dEQ := (dEQ A w nu lv).
426
+ Local Notation dEOT := (dEOT A w nu lv).
427
+ Local Notation dCA := (dCA A w nu lv).
428
+ Local Notation dCC := (dCC A w nu lv).
429
+ Local Notation dG := (dG A w nu lv).
430
+ Local Notation dCAR := (dCAR A w nu lv).
431
+
432
+ Definition Tn (j c : nat) : Prop :=
433
+ match j with
434
+ | 1 => c = dWR | 2 => c = dRD | 3 => c = dRW | 4 => exists i, i < w /\ c = dE i | 5 => c = dEQ
435
+ | 6 => c = dEOT \/ c = dCA \/ c = dCC | 7 => c = dG | 8 => exists j, 1 <= j < w /\ c = dCAR j
436
+ | _ => False
437
+ end.
438
+
439
+ Fixpoint Td (k c : nat) : Prop := match k with O => D0 c | S k' => Td k' c \/ Tn k c end.
440
+
441
+ Lemma Td_mono : forall k k' c, k <= k' -> Td k c -> Td k' c.
442
+ Proof.
443
+ intros k k' c Hk. induction k' as [|k' IH]; intro H.
444
+ - assert (k = 0) by lia. subst k. exact H.
445
+ - destruct (Nat.eq_dec k (S k')) as [->|E]; [exact H|]. left. apply IH; [lia | exact H].
446
+ Qed.
447
+
448
+ Lemma td_D0 : forall k c, D0 c -> Td k c.
449
+ Proof. intros k c H. apply (Td_mono 0); [lia | exact H]. Qed.
450
+
451
+ Lemma td_new : forall j k c, 1 <= j <= k -> Tn j c -> Td k c.
452
+ Proof. intros j k c Hj H. apply (Td_mono j); [lia|]. destruct j as [|j]; [lia|]. right. exact H. Qed.
453
+
454
+ Lemma td_up : forall k (s : list rec), (forall c, Tn (S k) c -> wrt s c) -> forall c, Td (S k) c -> Td k c \/ wrt s c.
455
+ Proof. intros k s H c [Hc|Hc]; [left; exact Hc | right; apply H; exact Hc]. Qed.
456
+
457
+ Lemma td_same : forall k (s : list rec) c, Td k c -> Td k c \/ wrt s c.
458
+ Proof. intros k s c Hc. left. exact Hc. Qed.
459
+
460
+ Ltac tdc :=
461
+ match goal with
462
+ | |- cok _ (Stored.dWR _ _ _ _) => right; apply (td_new 1); [lia | reflexivity]
463
+ | |- cok _ (Stored.dRD _ _ _ _) => right; apply (td_new 2); [lia | reflexivity]
464
+ | |- cok _ (Stored.dRW _ _ _ _) => right; apply (td_new 3); [lia | reflexivity]
465
+ | |- cok _ (Stored.dE _ _ _ _ _) => right; apply (td_new 4); [lia | eexists; split; [|reflexivity]; lia]
466
+ | |- cok _ (Stored.dEQ _ _ _ _) => right; apply (td_new 5); [lia | reflexivity]
467
+ | |- cok _ (Stored.dEOT _ _ _ _) => right; apply (td_new 6); [lia | left; reflexivity]
468
+ | |- cok _ (Stored.dCA _ _ _ _) => right; apply (td_new 6); [lia | right; left; reflexivity]
469
+ | |- cok _ (Stored.dCC _ _ _ _) => right; apply (td_new 6); [lia | right; right; reflexivity]
470
+ | |- cok _ (Stored.dG _ _ _ _) => right; apply (td_new 7); [lia | reflexivity]
471
+ | |- cok _ (Stored.dCAR _ _ _ _ _) => right; apply (td_new 8); [lia | eexists; split; [|reflexivity]; lia]
472
+ | |- cok _ (MB _ _ _ _) => right; apply td_D0, MB_D0; destruct dev_lt as (? & ? & ? & ? & ? & ?); lia
473
+ | |- cok _ (CNT _) => right; apply td_D0, CNT_D0; lia
474
+ | |- cok _ (LIM _ _) => right; apply td_D0, LIM_D0; lia
475
+ | |- cok _ (DEST _) => right; apply td_D0; exact DEST_D0
476
+ | |- cok _ _ => left; unfold SINK, RD, ARM, CPY; lia
477
+ end.
478
+
479
+ Lemma wbr_tri : forall (D : nat -> Prop) x y x' y' d, cok D (fst x) -> cok D (fst y) -> cok D (fst x') -> cok D (fst y') ->
480
+ wbr D [gAND x y (M0 A w nu lv); gAND x' y' (M1 A w nu lv); gOR (M0 A w nu lv, true) (M1 A w nu lv, true) d].
481
+ Proof.
482
+ intros D x y x' y' d Hx Hy Hx' Hy'. cbn [wbr]. split; [apply rdr_and; assumption|]. split.
483
+ - apply rdr_and; apply (cok_mono D); try (intros c Hc; left; exact Hc); assumption.
484
+ - split; [|exact I]. apply rdr_or; right; [left; right; reflexivity | right; reflexivity].
485
+ Qed.
486
+
487
+ Lemma wbr_mux : forall k s a b d, cok (Td k) s -> cok (Td k) (fst a) -> cok (Td k) (fst b) ->
488
+ wbr (Td k) (gMUX A w nu lv s a b d).
489
+ Proof. intros k s a b d Hs Ha Hb. apply wbr_tri; assumption. Qed.
490
+
491
+ Lemma wbr_xor : forall k x y d, cok (Td k) (fst x) -> cok (Td k) (fst y) -> wbr (Td k) (gXOR A w nu lv x y d).
492
+ Proof.
493
+ intros k x y d Hx Hy. unfold gXOR. cbn [wbr]. split; [apply rdr_or; assumption|]. split.
494
+ - apply rdr_or; apply (cok_mono (Td k)); try (intros c Hc; left; exact Hc); assumption.
495
+ - split; [|exact I]. apply rdr_and; right; [left; right; reflexivity | right; reflexivity].
496
+ Qed.
497
+
498
+ Lemma wbr_word1 : forall k j d, j < SW A -> wbr (Td k) (word1 A w j d).
499
+ Proof.
500
+ intros k j d Hj. unfold word1. apply wbr_chain_and. intros l [<-|Hl]; [cbn [fst]; tdc|].
501
+ apply in_map_iff in Hl as (t & <- & Ht). apply in_seq in Ht. cbn [fst]. right. apply td_D0, MB_D0; lia.
502
+ Qed.
503
+
504
+ Lemma word1_writes : forall j d, wrt (word1 A w j d) d.
505
+ Proof. intros j d. unfold word1. apply (chain_writes gAND (fun _ _ _ => eq_refl)). discriminate. Qed.
506
+
507
+ Lemma wbr_carries : forall len k (D : nat -> Prop), k + len <= w - 1 -> (forall c, Td 7 c -> D c) ->
508
+ (forall j, 1 <= j <= k -> D (dCAR j)) ->
509
+ wbr D (map (fun i => gAND (carry A w nu lv i, true) (CNT i, true) (dCAR (S i))) (seq k len)).
510
+ Proof.
511
+ induction len as [|len IH]; intros k D Hk H7 Hc; [exact I|]. cbn [seq map wbr]. split.
512
+ - apply rdr_and; right; cbn [fst].
513
+ + unfold carry. destruct (Nat.eqb_spec k 0) as [->|E]; [apply H7; apply (td_new 7); [lia | reflexivity]|].
514
+ apply Hc. lia.
515
+ + apply H7, td_D0. apply (proj1 (reg_D0 k ltac:(lia))).
516
+ - apply IH; [lia | intros c Hc'; left; apply H7; exact Hc' |].
517
+ intros j Hj. destruct (Nat.eq_dec j (S k)) as [->|E]; [right; reflexivity | left; apply Hc; lia].
518
+ Qed.
519
+
520
+ Lemma wbr_device : wbr D0 (Stored.device A w nu lv).
521
+ Proof.
522
+ pose proof dev_lt as (Hwr & Hrd & Hrw & Hro & Hri & Heo).
523
+ apply (wbr_mono _ (Td 0)); [intros c Hc; exact Hc|]. unfold Stored.device.
524
+ apply (wbr_app _ _ _ (Td 1)); [apply wbr_word1; exact Hwr | apply td_up; intros c ->; apply word1_writes|].
525
+ apply (wbr_app _ _ _ (Td 2)); [apply wbr_word1; exact Hrd | apply td_up; intros c ->; apply word1_writes|].
526
+ apply (wbr_app _ _ _ (Td 3)); [apply wbr_word1; exact Hrw | apply td_up; intros c ->; apply word1_writes|].
527
+ apply (wbr_app _ _ _ (Td 4)).
528
+ { apply wbr_concat_map. intros i Hi. apply in_seq in Hi. apply wbr_tri; cbn [fst]; tdc. }
529
+ { apply td_up. intros c (i & Hi & ->). apply (wrt_concat_map _ _ i); [apply in_seq; lia|].
530
+ unfold wrt. cbn [map In]. right. right. left. reflexivity. }
531
+ apply (wbr_app _ _ _ (Td 5)).
532
+ { apply wbr_chain_and. intros l Hl. apply in_map_iff in Hl as (i & <- & Hi). apply in_seq in Hi. cbn [fst]. tdc. }
533
+ { apply td_up. intros c ->. apply (chain_writes gAND (fun _ _ _ => eq_refl)).
534
+ destruct w as [|w']; [lia | discriminate]. }
535
+ apply (wbr_app _ _ _ (Td 6)).
536
+ { apply wbr_all. do 3 (apply Forall_cons; [apply rdr_and; cbn [fst]; tdc|]). apply Forall_nil. }
537
+ { apply td_up. intros c [->|[->| ->]]; unfold wrt; cbn [map In]; [left | right; left | right; right; left];
538
+ reflexivity. }
539
+ apply (wbr_app _ _ _ (Td 6)).
540
+ { apply wbr_concat_map. intros k Hk. apply in_seq in Hk.
541
+ apply (wbr_app _ _ _ (Td 6)); [apply wbr_mux; cbn [fst]; tdc | intros c Hc; left; exact Hc|].
542
+ apply (wbr_app _ _ _ (Td 6)); [(split; [apply rdr_copy; cbn [fst]; tdc | exact I])
543
+ | intros c Hc; left; exact Hc |].
544
+ apply (wbr_app _ _ _ (Td 6)); [apply wbr_mux; cbn [fst]; tdc | intros c Hc; left; exact Hc|].
545
+ (split; [apply rdr_copy; cbn [fst]; tdc | exact I]). }
546
+ { apply td_same. }
547
+ apply (wbr_app _ _ _ (Td 6)).
548
+ { apply wbr_all, Forall_map, Forall_forall. intros t Ht. apply in_seq in Ht. apply rdr_and; cbn [fst]; tdc. }
549
+ { apply td_same. }
550
+ apply (wbr_app _ _ _ (Td 7)).
551
+ { (split; [apply rdr_and; cbn [fst]; tdc | exact I]). }
552
+ { apply td_up. intros c ->. unfold wrt. cbn [map In]. left. reflexivity. }
553
+ apply (wbr_app _ _ _ (Td 7)).
554
+ { apply wbr_concat_map. intros k Hk. apply in_seq in Hk.
555
+ apply (wbr_app _ _ _ (Td 7)); [apply wbr_mux; cbn [fst]; tdc | intros c Hc; left; exact Hc|].
556
+ (split; [apply rdr_copy; cbn [fst]; tdc | exact I]). }
557
+ { apply td_same. }
558
+ apply (wbr_app _ _ _ (Td 7)).
559
+ { apply wbr_concat_map. intros t Ht. apply in_seq in Ht. apply wbr_mux; cbn [fst]; tdc. }
560
+ { apply td_same. }
561
+ apply (wbr_app _ _ _ (Td 7)); [apply wbr_mux; cbn [fst]; tdc | apply td_same|].
562
+ apply (wbr_app _ _ _ (Td 7)).
563
+ { apply wbr_all, Forall_map, Forall_forall. intros t Ht. apply in_seq in Ht. apply rdr_and; cbn [fst]; tdc. }
564
+ { apply td_same. }
565
+ apply (wbr_app _ _ _ (Td 8)).
566
+ { apply wbr_carries; [lia | intros c Hc; exact Hc | intros j Hj; lia]. }
567
+ { apply td_up. intros c (j & Hj & ->).
568
+ assert (E : dCAR j = dCAR (S (j - 1))) by (f_equal; lia). rewrite E.
569
+ apply (wrt_map (fun i => gAND (carry A w nu lv i, true) (CNT i, true) (dCAR (S i))) _ (j - 1)).
570
+ apply in_seq. lia. }
571
+ apply (wbr_app _ _ _ (Td 8)).
572
+ { apply wbr_concat_map. intros i Hi. apply in_seq in Hi. apply wbr_xor; cbn [fst]; [tdc|].
573
+ unfold carry. destruct (Nat.eqb_spec i 0) as [->|E]; tdc. }
574
+ { apply td_same. }
575
+ apply (wbr_app _ _ _ (Td 8)); [(split; [apply rdr_copy; cbn [fst]; tdc | exact I]) | apply td_same|].
576
+ apply (wbr_app _ _ _ (Td 8)).
577
+ { apply wbr_concat_map. intros i Hi. apply in_seq in Hi.
578
+ apply (wbr_app _ _ _ (Td 8)); [apply wbr_mux; cbn [fst]; tdc | intros c Hc; left; exact Hc|].
579
+ (split; [apply rdr_and; cbn [fst]; tdc | exact I]). }
580
+ { apply td_same. }
581
+ apply (wbr_app _ _ _ (Td 8)).
582
+ { split; [apply rdr_or; cbn [fst]; tdc | exact I]. }
583
+ { apply td_same. }
584
+ apply wbr_concat_map. intros c Hc. apply wbr_all, Forall_map, Forall_forall. intros t _. apply rdr_const.
585
+ Qed.
586
+
587
+ (* the whole image: each block reads only the cells of D0 and its own *)
588
+ Local Notation m := (image A (progPstar A)).
589
+
590
+ Lemma length_m : length m = SW A.
591
+ Proof. unfold image. rewrite length_map, length_seq. reflexivity. Qed.
592
+
593
+ Definition rest : list rec :=
594
+ step_go A w nu 0 us nt ++ Stored.device A w nu lv
595
+ ++ repeat EMPTY (padn (alS A w) (length (startup A w m ++ step_go A w nu 0 us nt ++ Stored.device A w nu lv)))
596
+ ++ handover A w.
597
+
598
+ Lemma stored_rest : stored A w = startup A w m ++ rest.
599
+ Proof. unfold stored, stored_of, rest. cbv zeta. cbn [fst]. rewrite <- !app_assoc. reflexivity. Qed.
600
+
601
+ Lemma wbr_rest : wbr D0 rest.
602
+ Proof.
603
+ unfold rest.
604
+ apply (wbr_app _ _ _ D0); [exact wbr_step | intros c Hc; left; exact Hc|].
605
+ apply (wbr_app _ _ _ D0); [exact wbr_device | intros c Hc; left; exact Hc|].
606
+ apply (wbr_app _ _ _ D0); [apply wbr_all, Forall_forall; intros r Hr; apply repeat_spec in Hr; subst r; apply rdr_empty
607
+ | intros c Hc; left; exact Hc|].
608
+ apply wbr_all. unfold handover. pose proof BOOT_D0 as HB. pose proof (ST_D0 A ltac:(unfold nH; lia)) as HS.
609
+ apply Forall_cons; [apply rdr_and; right; assumption|].
610
+ do 3 (apply Forall_cons; [apply rdr_copy; right; assumption|]). apply Forall_nil.
611
+ Qed.
612
+
613
+ Lemma wrt_startup : forall c, wrt (startup A w m) c -> D0 c.
614
+ Proof.
615
+ intros c Hc. unfold wrt, startup in Hc. rewrite !map_app in Hc.
616
+ repeat (apply in_app_or in Hc as [Hc|Hc]).
617
+ - apply in_map_iff in Hc as (r & <- & Hr). apply in_concat in Hr as (l & Hl & Hr).
618
+ apply in_map_iff in Hl as ([j v] & <- & Hp). apply in_combine_l in Hp. apply in_seq in Hp.
619
+ unfold boot_word in Hr. apply in_map_iff in Hr as (t & <- & Ht). apply in_seq in Ht. cbn [fst snd].
620
+ destruct (Nat.testbit v t); apply MB_D0; lia.
621
+ - apply in_map_iff in Hc as (r & <- & Hr). apply in_map_iff in Hr as (t & <- & Ht). apply in_seq in Ht.
622
+ apply ST_D0. unfold nH. lia.
623
+ - destruct Hc as [<-|[]]. apply ST_D0. unfold nH. lia.
624
+ - apply in_map_iff in Hc as (r & <- & Hr). apply in_concat in Hr as (l & Hl & Hr).
625
+ apply in_map_iff in Hl as (i & <- & Hi). apply in_seq in Hi.
626
+ destruct Hr as [<-|[<-|[]]]; [exact (proj1 (reg_D0 i ltac:(lia))) | exact (proj2 (reg_D0 i ltac:(lia)))].
627
+ - destruct Hc as [<-|[]]. exact DEST_D0.
628
+ - destruct Hc as [<-|[<-|[<-|[<-|[<-|[]]]]]]; cbn [ao_of gCOPY]; apply req_D0; unfold AR, HO, RR, CB, RA, CT, RC;
629
+ lia.
630
+ - destruct Hc as [<-|[]]. exact BOOT_D0.
631
+ Qed.
632
+
633
+ Theorem wbr_stored : wbr D0 (stored A w).
634
+ Proof.
635
+ rewrite stored_rest. apply (wbr_app _ _ _ D0); [exact (wbr_startup m length_m) | intros c Hc; left; exact Hc |].
636
+ exact wbr_rest.
637
+ Qed.
638
+
639
+ End Host.
rocq/StoredWidth.v ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* Theorem 8.8: for every word width A >= 8 there is a counter width w >= 20 for which the recipe of literal tokens
2
+ of the image of S_{A,w} is shorter than 2^w, so that Theorems 8.6 and 8.7 apply to S_{A,w}: its records grow
3
+ linearly in w and its window logarithmically, while 2^w grows exponentially. *)
4
+ From Stdlib Require Import List Bool Arith ZArith Lia.
5
+ Import ListNotations.
6
+ From TH Require Import TwoHead Net Abstract Indep Run PhysSem View Stored Host Device Pstar StoredPass StoredWbr
7
+ StoredImage.
8
+
9
+ (* ---- the number of records ------------------------------------------------------------------------------- *)
10
+ Lemma length_cmk : forall (S T : Type) (f : S -> list T) l k, (forall x, length (f x) = k) ->
11
+ length (concat (map f l)) = k * length l.
12
+ Proof. intros S T f l k H. induction l as [|x l IH]; cbn [map concat length]; [lia|]. rewrite length_app, H, IH. lia. Qed.
13
+
14
+ Lemma length_chain_tail : forall (g : nat * bool -> nat * bool -> nat -> rec) acc ls l d,
15
+ length (chain_tail g acc l ls d) = S (length ls).
16
+ Proof.
17
+ intros g acc ls. induction ls as [|l' ls IH]; intros l d; cbn [chain_tail length]; [reflexivity|].
18
+ rewrite IH. reflexivity.
19
+ Qed.
20
+
21
+ Lemma length_chain : forall g ls d acc, length (chain g ls d acc) <= length ls.
22
+ Proof. intros g [|l0 [|l1 [|l2 t]]] d acc; cbn [chain length]; try lia. rewrite length_chain_tail. lia. Qed.
23
+
24
+ Lemma length_ucomp : forall xc ls t d acc lev, length (ucomp xc t ls d acc lev) <= 2 ^ (length ls + 2) - 2.
25
+ Proof.
26
+ intros xc. induction ls as [|l0 rest IH]; intros t d acc lev; rewrite ucomp_eq.
27
+ - destruct (Z.leb t 0); [cbn; lia|]. destruct (Z.ltb _ t); [cbn; lia|].
28
+ destruct (Z.eqb t 1); [pose proof (length_chain gOR [] d acc); cbn in *; lia|].
29
+ destruct (Z.eqb t _); [pose proof (length_chain gAND [] d acc); cbn in *; lia | cbn; lia].
30
+ - cbn [length]. rewrite Nat.add_succ_l, Nat.pow_succ_r'.
31
+ assert (Hp : 4 <= 2 ^ (length rest + 2)) by (change 4 with (2 ^ 2); apply Nat.pow_le_mono_r; lia).
32
+ pose proof (Nat.pow_gt_lin_r 2 (length rest + 2) ltac:(lia)) as Hl.
33
+ destruct (Z.leb t 0); [cbn [length]; lia|]. destruct (Z.ltb _ t); [cbn [length]; lia|].
34
+ destruct (Z.eqb t 1); [pose proof (length_chain gOR (l0 :: rest) d acc) as H; cbn [length] in H; lia|].
35
+ destruct (Z.eqb t _); [pose proof (length_chain gAND (l0 :: rest) d acc) as H; cbn [length] in H; lia|].
36
+ rewrite !length_app. cbn [length].
37
+ pose proof (IH t (xc lev 0) (xc lev 0) (S lev)). pose proof (IH (t - 1)%Z (xc lev 1) (xc lev 1) (S lev)). lia.
38
+ Qed.
39
+
40
+ Definition sbound (us : list tu) : nat := fold_right (fun U acc => 2 ^ (length (tin U) + 2) + acc) 0 us.
41
+
42
+ Lemma length_step_go : forall A w nu us nt u, length (step_go A w nu u us nt) <= sbound us.
43
+ Proof.
44
+ intros A w nu us. induction us as [|U us IH]; intros nt u; [cbn; lia|].
45
+ destruct nt as [|o nt]; [cbn [step_go length]; lia|]. cbn [step_go sbound fold_right]. rewrite length_app.
46
+ pose proof (length_ucomp (XC A w nu) (map (lit_of A w) (tin U)) (tval U)
47
+ (match o with Some i => ST w i | None => UC A w u end) (UC A w u) 0) as H.
48
+ rewrite length_map in H. specialize (IH nt (S u)). fold (sbound us). lia.
49
+ Qed.
50
+
51
+ Lemma length_startup : forall A w m, length m = SW A -> length (startup A w m) = SW A * A + A + 2 * w + 8.
52
+ Proof.
53
+ intros A w m Hm. unfold startup. rewrite !length_app, !length_map, !length_seq. cbn [length].
54
+ rewrite (length_cmk _ _ _ _ A) by (intros [j v]; unfold boot_word; rewrite length_map, length_seq; reflexivity).
55
+ rewrite (length_cmk _ _ _ _ 2) by (intro; reflexivity).
56
+ rewrite length_combine, length_seq, Hm, Nat.min_id, length_seq. lia.
57
+ Qed.
58
+
59
+ Lemma length_word1 : forall A w j d, 1 <= A -> length (word1 A w j d) <= A.
60
+ Proof.
61
+ intros A w j d HA. unfold word1. eapply Nat.le_trans; [apply length_chain|]. cbn [length].
62
+ rewrite length_map, length_seq. lia.
63
+ Qed.
64
+
65
+ Lemma length_device : forall A w nu lv, 8 <= A -> length (Stored.device A w nu lv) <= 11 * A + 12 * w + 120.
66
+ Proof.
67
+ intros A w nu lv HA.
68
+ pose proof (length_word1 A w (cwr A) (dWR A w nu lv) ltac:(lia)) as C1.
69
+ pose proof (length_word1 A w (crd A) (dRD A w nu lv) ltac:(lia)) as C2.
70
+ pose proof (length_word1 A w (crw A) (dRW A w nu lv) ltac:(lia)) as C3.
71
+ pose proof (length_chain gAND (map (fun i => (dE A w nu lv i, true)) (seq 0 w)) (dEQ A w nu lv) (dEQ A w nu lv))
72
+ as C4.
73
+ rewrite length_map, length_seq in C4.
74
+ unfold Stored.device. rewrite !length_app.
75
+ rewrite (length_cmk _ _ _ _ 3) by (intro; reflexivity).
76
+ rewrite (length_cmk _ _ _ _ 8) by (intro; reflexivity).
77
+ rewrite (length_cmk _ _ _ _ 4) by (intro; reflexivity).
78
+ rewrite (length_cmk _ _ _ _ 3) by (intro; reflexivity).
79
+ rewrite (length_cmk _ _ _ _ 3) by (intro; reflexivity).
80
+ rewrite (length_cmk _ _ _ _ 4) by (intro; reflexivity).
81
+ rewrite (length_cmk _ _ _ _ A) by (intro; rewrite length_map, length_seq; reflexivity).
82
+ rewrite !length_map, !length_seq. unfold gMUX. cbn [length]. lia.
83
+ Qed.
84
+
85
+ Lemma padn_lt : forall al len, padn al len < 8.
86
+ Proof.
87
+ intros al len. unfold padn. destruct (find _ (seq 0 8)) as [p|] eqn:E; [|lia].
88
+ apply find_some in E as [E _]. apply in_seq in E. lia.
89
+ Qed.
90
+
91
+ Lemma length_stored : forall A w, 8 <= A ->
92
+ length (stored A w) <= SW A * A + 12 * A + sbound (host_units A) + 14 * w + 139.
93
+ Proof.
94
+ intros A w HA. rewrite (stored_split A w), !length_app, repeat_length. unfold handover. cbn [length].
95
+ rewrite (length_startup A w _ (length_image A)).
96
+ pose proof (length_step_go A w (length (host_units A)) (host_units A)
97
+ (next_tbl (nH A) (length (host_units A)) (host_next A)) 0).
98
+ pose proof (length_device A w (length (host_units A)) (levels (host_units A)) HA).
99
+ match goal with |- context [padn ?a ?b] => pose proof (padn_lt a b) end.
100
+ lia.
101
+ Qed.
102
+
103
+ Lemma alS_le : forall A w, alS A w <= nH A + length (host_units A) + 3 * levels (host_units A) + 24 + 4 * w.
104
+ Proof.
105
+ intros A w. unfold alS, stored_of. cbv zeta. cbn [snd].
106
+ eapply Nat.le_trans; [apply Nat.log2_up_le_lin; lia|]. unfold ncells, DB, nh. lia.
107
+ Qed.
108
+
109
+ (* ---- 2^w outgrows every polynomial of degree two in w -------------------------------------------------------- *)
110
+ Lemma cube_pow : forall w, 11 <= w -> (w + 1) * (w + 1) * (w + 1) < 2 ^ w.
111
+ Proof.
112
+ induction w as [|w IH]; intro Hw; [lia|].
113
+ destruct (Nat.eq_dec w 10) as [->|E]; [change (2 ^ 11) with 2048; lia|].
114
+ assert (IH' : (w + 1) * (w + 1) * (w + 1) < 2 ^ w) by (apply IH; lia).
115
+ assert (H1 : (S w + 1) * (S w + 1) * (S w + 1) <= 2 * ((w + 1) * (w + 1) * (w + 1))) by nia.
116
+ rewrite Nat.pow_succ_r'. lia.
117
+ Qed.
118
+
119
+ (* Theorem 8.8: a counter width for every word width, with room for every recipe of at most 2B + 1 bytes *)
120
+ Theorem width_exists : forall A, 8 <= A ->
121
+ exists w, 20 <= w /\ 2 * length (image_bytes A w) + 1 < 2 ^ w.
122
+ Proof.
123
+ intros A HA.
124
+ set (c0 := SW A * A + 12 * A + sbound (host_units A) + 139).
125
+ set (c1 := nH A + length (host_units A) + 3 * levels (host_units A) + 24).
126
+ set (a := 8 + 3 * c1 + 12). set (b := c0 + 14). set (C := 2 * a * b + 1).
127
+ exists (C + 20). split; [lia|]. set (w := C + 20).
128
+ pose proof (length_image_bytes A w) as B.
129
+ pose proof (length_stored A w HA) as G. fold c0 in G.
130
+ pose proof (alS_le A w) as Hal. fold c1 in Hal.
131
+ assert (HX : recw (alS A w) <= a * (w + 1)) by (unfold recw, a; nia).
132
+ assert (HY : length (stored A w) <= b * (w + 1)) by (unfold b; nia).
133
+ assert (HXY : recw (alS A w) * length (stored A w) <= (a * (w + 1)) * (b * (w + 1)))
134
+ by (apply Nat.mul_le_mono; assumption).
135
+ assert (HC : C * ((w + 1) * (w + 1)) <= (w + 1) * (w + 1) * (w + 1)).
136
+ { replace ((w + 1) * (w + 1) * (w + 1)) with ((w + 1) * ((w + 1) * (w + 1))) by ring.
137
+ apply Nat.mul_le_mono_r. unfold w. lia. }
138
+ pose proof (cube_pow w ltac:(unfold w; lia)) as P.
139
+ assert (Hab : 2 * ((a * (w + 1)) * (b * (w + 1))) + 1 <= C * ((w + 1) * (w + 1))).
140
+ { unfold C. replace (2 * (a * (w + 1) * (b * (w + 1)))) with (2 * a * b * ((w + 1) * (w + 1))) by ring.
141
+ assert (1 * 1 <= (w + 1) * (w + 1)) by (apply Nat.mul_le_mono; lia). lia. }
142
+ lia.
143
+ Qed.
144
+
145
+ (* the hypotheses of Theorem 8.7 hold for the recipe of literal tokens of the image, at every such w *)
146
+ Corollary recipe_of_image : forall A w, 2 * length (image_bytes A w) + 1 < 2 ^ w ->
147
+ Forall tok_ok (lits (image_bytes A w)) /\ bbits (delta (lits (image_bytes A w))) = encA (alS A w) (stored A w)
148
+ /\ length (recipe (lits (image_bytes A w))) < 2 ^ w.
149
+ Proof.
150
+ intros A w Hw. split; [apply lits_ok|]. split; [rewrite delta_lits by apply image_bytes_lt; apply bbits_image|].
151
+ pose proof (length_recipe_lits (image_bytes A w)). lia.
152
+ Qed.
rocq/View.v ADDED
@@ -0,0 +1,283 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* Records executed one after another on a view of the ring machine: the window, the read tape, the idle
2
+ bank read as a tape, the copy tape, and whether a record has handed over. A segment of the active bank
3
+ runs as the records it holds, whatever the width of the window. *)
4
+ From Stdlib Require Import List Bool Arith ZArith Lia.
5
+ Import ListNotations.
6
+ From TH Require Import TwoHead Net Abstract Indep Run PhysSem PhysMain.
7
+
8
+ Record view := mkV { vw : list bool; vr : tape; va : tape; vc : tape; vho : bool }.
9
+
10
+ Section View.
11
+ Variables (Lb L : nat).
12
+
13
+ Definition vcell (v : view) (a : nat) : bool :=
14
+ if Nat.eqb a SINK then false
15
+ else if Nat.eqb a RD then tget (vr v)
16
+ else if Nat.eqb a ARM then tget (va v)
17
+ else if Nat.eqb a CPY then tget (vc v)
18
+ else wget (vw v) a.
19
+
20
+ Definition rval (v : view) (r : rec) : bool :=
21
+ match r with Rec a0 w0 a1 w1 beta _ => Z.leb 0 (w0 * b2z (vcell v a0) + w1 * b2z (vcell v a1) + beta) end.
22
+
23
+ (* the value x written into cell ao, then the requests carried out and cleared *)
24
+ Definition vput (v : view) (ao : nat) (x : bool) : view :=
25
+ let wn := wnext (vw v) ao x in
26
+ let A1 := if Nat.eqb ao ARM then mkT (upd (td (va v)) (th (va v)) x) (th (va v)) else va v in
27
+ let C1 := if Nat.eqb ao CPY then mkT (upd (td (vc v)) (th (vc v)) x) (th (vc v)) else vc v in
28
+ mkV (clearq wn)
29
+ (mkT (td (vr v)) (if wget wn RR then 0 else if wget wn AR then succ_mod L (th (vr v)) else th (vr v)))
30
+ (mkT (if wget wn CB then repeat false Lb else td A1)
31
+ (if wget wn RA then 0 else if wget wn AA then succ_mod Lb (th A1) else th A1))
32
+ (mkT (if wget wn CT then repeat false L else td C1)
33
+ (if wget wn RC then 0 else if wget wn AC then succ_mod L (th C1) else th C1))
34
+ (vho v || wget wn HO).
35
+
36
+ Definition vexec (r : rec) (v : view) : view := vput v (ao_of r) (rval v r).
37
+
38
+ Fixpoint vrun (rs : list rec) (v : view) : view :=
39
+ match rs with [] => v | r :: t => vrun t (vexec r v) end.
40
+
41
+ Lemma vrun_app : forall a b v, vrun (a ++ b) v = vrun b (vrun a v).
42
+ Proof. induction a as [|r a IH]; intros b v; [reflexivity|]. cbn [app vrun]. apply IH. Qed.
43
+
44
+ End View.
45
+
46
+ (* ---- the code of a record, for every width of the window ------------------------------------------ *)
47
+ Lemma length_enc_w : forall w, length (enc_w w) = 2.
48
+ Proof. intro w. unfold enc_w. destruct (Z.eqb w 1); [|destruct (Z.eqb w (-1))]; reflexivity. Qed.
49
+
50
+ Lemma length_nat2bits : forall k v, length (nat2bits k v) = k.
51
+ Proof. induction k as [|k IH]; intro v; cbn [nat2bits length]; [reflexivity | rewrite IH; reflexivity]. Qed.
52
+
53
+ Lemma length_enc_recA : forall al r, length (enc_recA al r) = recw al.
54
+ Proof.
55
+ intros al [a0 w0 a1 w1 beta ao]. unfold enc_recA, recw.
56
+ rewrite !length_app, !length_enc_w, !length_nat2bits. lia.
57
+ Qed.
58
+
59
+ Lemma nth_nat2bits : forall k v t, t < k -> nth t (nat2bits k v) false = Nat.testbit v (k - 1 - t).
60
+ Proof.
61
+ induction k as [|k IH]; intros v t Ht; [lia|]. cbn [nat2bits].
62
+ destruct t as [|t]; cbn [nth]; [f_equal; lia|]. rewrite IH by lia. f_equal. lia.
63
+ Qed.
64
+
65
+ Lemma bits2nat_nat2bits : forall k v, v < 2 ^ k -> bits2nat (nat2bits k v) = v.
66
+ Proof.
67
+ intros k v Hv. apply (bits_eq_nat _ _ k); [|exact Hv|].
68
+ - pose proof (bits2nat_lt (nat2bits k v)) as H. rewrite length_nat2bits in H. exact H.
69
+ - intros i Hi. pose proof (testbit_bits2nat (nat2bits k v) (k - 1 - i)) as T.
70
+ rewrite length_nat2bits in T. replace (k - 1 - (k - 1 - i)) with i in T by lia.
71
+ rewrite T by lia. rewrite nth_nat2bits by lia. f_equal. lia.
72
+ Qed.
73
+
74
+ (* a record whose weights, bias and addresses fit their codes *)
75
+ Definition rec_ok (al : nat) (r : rec) : Prop :=
76
+ match r with
77
+ | Rec a0 w0 a1 w1 beta ao =>
78
+ (w0 = 1 \/ w0 = 0 \/ w0 = -1)%Z /\ (w1 = 1 \/ w1 = 0 \/ w1 = -1)%Z /\ (-8 <= beta <= 7)%Z
79
+ /\ a0 < 2 ^ al /\ a1 < 2 ^ al /\ ao < 2 ^ al
80
+ end.
81
+
82
+ Lemma wcode_enc : forall w, (w = 1 \/ w = 0 \/ w = -1)%Z ->
83
+ wcode (nth 0 (enc_w w) false) (nth 1 (enc_w w) false) = w.
84
+ Proof. intros w [->|[->| ->]]; reflexivity. Qed.
85
+
86
+ Lemma beta_code : forall beta, (-8 <= beta <= 7)%Z ->
87
+ (if Z.leb 8 (Z.of_nat (Z.to_nat (beta mod 16))) then Z.of_nat (Z.to_nat (beta mod 16)) - 16
88
+ else Z.of_nat (Z.to_nat (beta mod 16)))%Z = beta.
89
+ Proof.
90
+ intros beta Hb.
91
+ assert (E : (beta mod 16 = if Z.leb 0 beta then beta else beta + 16)%Z).
92
+ { destruct (Z.leb_spec 0 beta).
93
+ - apply Z.mod_small. lia.
94
+ - symmetry. apply (Z.mod_unique beta 16 (-1)); lia. }
95
+ rewrite E. destruct (Z.leb_spec 0 beta); rewrite Z2Nat.id by lia;
96
+ destruct (Z.leb_spec 8 beta); try destruct (Z.leb_spec 8 (beta + 16)); lia.
97
+ Qed.
98
+
99
+ Lemma decode_enc : forall al r, rec_ok al r -> decodeA al (enc_recA al r) = r.
100
+ Proof.
101
+ intros al [a0 w0 a1 w1 beta ao] (Hw0 & Hw1 & Hb & H0 & H1 & Ho).
102
+ unfold decodeA, enc_recA. cbv zeta.
103
+ set (e0 := enc_w w0). set (e1 := enc_w w1).
104
+ set (eb := nat2bits 4 (Z.to_nat (beta mod 16))).
105
+ set (x0 := nat2bits al a0). set (x1 := nat2bits al a1). set (xo := nat2bits al ao).
106
+ assert (L0 : length e0 = 2) by apply length_enc_w. assert (L1 : length e1 = 2) by apply length_enc_w.
107
+ assert (Lb : length eb = 4) by apply length_nat2bits.
108
+ assert (Lx0 : length x0 = al) by apply length_nat2bits. assert (Lx1 : length x1 = al) by apply length_nat2bits.
109
+ assert (Lxo : length xo = al) by apply length_nat2bits.
110
+ assert (G0 : forall i, i < 2 -> nth i (e0 ++ e1 ++ eb ++ x0 ++ x1 ++ xo) false = nth i e0 false)
111
+ by (intros i Hi; apply app_nth1; lia).
112
+ assert (G1 : forall i, i < 2 -> nth (2 + i) (e0 ++ e1 ++ eb ++ x0 ++ x1 ++ xo) false = nth i e1 false).
113
+ { intros i Hi. rewrite app_nth2 by lia. rewrite L0. replace (2 + i - 2) with i by lia. apply app_nth1. lia. }
114
+ assert (G2 : nth 2 (e0 ++ e1 ++ eb ++ x0 ++ x1 ++ xo) false = nth 0 e1 false) by exact (G1 0 ltac:(lia)).
115
+ assert (G3 : nth 3 (e0 ++ e1 ++ eb ++ x0 ++ x1 ++ xo) false = nth 1 e1 false) by exact (G1 1 ltac:(lia)).
116
+ assert (S4 : skipn 4 (e0 ++ e1 ++ eb ++ x0 ++ x1 ++ xo) = eb ++ x0 ++ x1 ++ xo).
117
+ { rewrite app_assoc, skipn_app, skipn_all2 by (rewrite length_app; lia).
118
+ rewrite length_app, L0, L1. reflexivity. }
119
+ assert (S8 : skipn 8 (e0 ++ e1 ++ eb ++ x0 ++ x1 ++ xo) = x0 ++ x1 ++ xo).
120
+ { replace 8 with (4 + 4) by reflexivity. rewrite <- skipn_skipn, S4.
121
+ rewrite skipn_app, skipn_all2 by lia. rewrite Lb. reflexivity. }
122
+ assert (S8a : skipn (8 + al) (e0 ++ e1 ++ eb ++ x0 ++ x1 ++ xo) = x1 ++ xo).
123
+ { rewrite Nat.add_comm, <- skipn_skipn, S8, skipn_app, skipn_all2 by lia. rewrite Lx0, Nat.sub_diag. reflexivity. }
124
+ assert (S8b : skipn (8 + 2 * al) (e0 ++ e1 ++ eb ++ x0 ++ x1 ++ xo) = xo).
125
+ { replace (8 + 2 * al) with (al + (8 + al)) by lia. rewrite <- skipn_skipn, S8a, skipn_app, skipn_all2 by lia.
126
+ rewrite Lx1, Nat.sub_diag. reflexivity. }
127
+ rewrite S4, S8, S8a, S8b.
128
+ rewrite (G0 0), (G0 1), G2, G3 by lia.
129
+ rewrite !firstn_app, Lb, Lx0, Lx1, !Nat.sub_diag, !firstn_O, !app_nil_r.
130
+ rewrite !firstn_all2 by lia.
131
+ unfold x0, x1, xo, eb, e0, e1.
132
+ rewrite (bits2nat_nat2bits al a0 H0), (bits2nat_nat2bits al a1 H1), (bits2nat_nat2bits al ao Ho).
133
+ rewrite (bits2nat_nat2bits 4 (Z.to_nat (beta mod 16)))
134
+ by (change (2 ^ 4) with 16; pose proof (Z.mod_pos_bound beta 16 ltac:(lia)); lia).
135
+ rewrite (wcode_enc w0 Hw0), (wcode_enc w1 Hw1), (beta_code beta Hb). reflexivity.
136
+ Qed.
137
+
138
+ (* ---- a bank holding records -------------------------------------------------------------------- *)
139
+ Definition encA (al : nat) (rs : list rec) : list bool := concat (map (enc_recA al) rs).
140
+
141
+ Lemma length_encA : forall al rs, length (encA al rs) = recw al * length rs.
142
+ Proof.
143
+ intros al rs. induction rs as [|r rs IH]; unfold encA in *; cbn [map concat length]; [lia|].
144
+ rewrite length_app, length_enc_recA, IH. lia.
145
+ Qed.
146
+
147
+ Lemma encA_app : forall al a b, encA al (a ++ b) = encA al a ++ encA al b.
148
+ Proof. intros al a b. unfold encA. rewrite map_app, concat_app. reflexivity. Qed.
149
+
150
+ Lemma slot_recA : forall al rs tail a r, nth_error rs a = Some r ->
151
+ firstn (recw al) (skipn (a * recw al) (encA al rs ++ tail)) = enc_recA al r.
152
+ Proof.
153
+ intros al rs tail a r H.
154
+ destruct (nth_error_split rs a H) as (l1 & l2 & -> & Hl).
155
+ rewrite encA_app. assert (E : encA al (r :: l2) = enc_recA al r ++ encA al l2) by reflexivity. rewrite E.
156
+ replace (a * recw al) with (length (encA al l1)) by (rewrite length_encA; lia).
157
+ rewrite <- !app_assoc, skipn_app, skipn_all, Nat.sub_diag, skipn_O, app_nil_l.
158
+ rewrite firstn_app, length_enc_recA, Nat.sub_diag, firstn_O, app_nil_r. apply firstn_all2.
159
+ rewrite length_enc_recA. lia.
160
+ Qed.
161
+
162
+ (* ---- the machine against the view ---------------------------------------------------------------- *)
163
+ (* the idle bank read as a tape: its bits, the arm on bit bs * b + bj *)
164
+ Definition lin (al : nat) (q : bank) : tape := mkT (bq q) (bs q * recw al + bj q).
165
+
166
+ Lemma advb_lin : forall al S0 q, bs q < S0 -> bj q < recw al ->
167
+ lin al (advb S0 (recw al) q) = mkT (bq q) (succ_mod (S0 * recw al) (bs q * recw al + bj q))
168
+ /\ bs (advb S0 (recw al) q) < S0 /\ bj (advb S0 (recw al) q) < recw al.
169
+ Proof.
170
+ intros al S0 [X s j] Hs Hj. cbn [bs bj] in *. unfold advb, lin, succ_mod. cbn [bq bs bj].
171
+ set (b := recw al) in *.
172
+ destruct (Nat.eqb_spec (S j) b) as [E|E]; cbn [bq bs bj].
173
+ - destruct (Nat.eqb_spec (S s) S0) as [E2|E2];
174
+ destruct (Nat.eqb_spec (S (s * b + j)) (S0 * b)) as [E3|E3]; repeat split; try f_equal; nia.
175
+ - destruct (Nat.eqb_spec (S (s * b + j)) (S0 * b)) as [E3|E3]; repeat split; try f_equal; nia.
176
+ Qed.
177
+
178
+ Section Seg.
179
+ Variables (al K S0 L : nat) (s0 : st).
180
+ Hypotheses (Hal : 4 <= al) (HK : 2 <= K) (HS : 1 <= S0) (HL : 1 <= L) (Hfit : fits al K S0 L s0).
181
+
182
+ Definition view0 : view :=
183
+ mkV (win s0) (nth (kap s0) (tapes s0) tape0) (lin al (nth (succ_mod K (kap s0)) (banks s0) bank0))
184
+ (nth (succ_mod K (kap s0)) (tapes s0) tape0) false.
185
+
186
+ (* s is the state n steps into a segment of the active bank of s0, seen as the view v *)
187
+ Definition mv (n : nat) (s : st) (v : view) : Prop :=
188
+ fits al K S0 L s /\ win s = vw v /\ kap s = (if vho v then succ_mod K (kap s0) else kap s0)
189
+ /\ nth (kap s0) (banks s) bank0
190
+ = mkB (bq (nth (kap s0) (banks s0) bank0)) ((bs (nth (kap s0) (banks s0) bank0) + n) mod S0)
191
+ (bj (nth (kap s0) (banks s0) bank0))
192
+ /\ lin al (nth (succ_mod K (kap s0)) (banks s) bank0) = va v
193
+ /\ nth (kap s0) (tapes s) tape0 = vr v /\ nth (succ_mod K (kap s0)) (tapes s) tape0 = vc v
194
+ /\ (forall x, x < K -> x <> kap s0 -> x <> succ_mod K (kap s0) ->
195
+ nth x (banks s) bank0 = nth x (banks s0) bank0 /\ nth x (tapes s) tape0 = nth x (tapes s0) tape0).
196
+
197
+ Lemma k0_lt' : kap s0 < K.
198
+ Proof. destruct Hfit as (_ & H & _). exact H. Qed.
199
+
200
+ Lemma i0_lt' : succ_mod K (kap s0) < K.
201
+ Proof. pose proof k0_lt'. unfold succ_mod. destruct (Nat.eqb_spec (S (kap s0)) K); lia. Qed.
202
+
203
+ Lemma i0_k0' : succ_mod K (kap s0) <> kap s0.
204
+ Proof. pose proof k0_lt'. unfold succ_mod. destruct (Nat.eqb_spec (S (kap s0)) K); lia. Qed.
205
+
206
+ Lemma mv_0 : mv 0 s0 view0.
207
+ Proof.
208
+ pose proof k0_lt' as Hk. pose proof Hfit as (_ & _ & _ & _ & HB & _).
209
+ destruct (HB (kap s0) Hk) as (_ & Hs & _).
210
+ refine (conj Hfit (conj eq_refl (conj eq_refl (conj _ (conj eq_refl (conj eq_refl (conj eq_refl _))))))).
211
+ - rewrite Nat.add_0_r, Nat.mod_small by exact Hs. symmetry. apply eta_bank.
212
+ - intros; split; reflexivity.
213
+ Qed.
214
+
215
+ Lemma mv_step : forall n s v r, mv n s v -> vho v = false ->
216
+ slot al (nth (kap s) (banks s) bank0) = enc_recA al r -> decodeA al (enc_recA al r) = r ->
217
+ mv (S n) (step al K S0 L s) (vexec (S0 * recw al) L r v).
218
+ Proof.
219
+ intros n s v r (Hf & Hw & Hk & HA & HI & HR & HC & Ho) Hho Hsl Hdr.
220
+ rewrite Hho in Hk. pose proof k0_lt' as Hk0. pose proof i0_lt' as Hi0. pose proof i0_k0' as Hik.
221
+ pose proof (step_fits al K S0 L s Hal HK HS HL Hf) as Hf'.
222
+ pose proof Hf as (_ & _ & _ & _ & HB & HT).
223
+ destruct (HB (succ_mod K (kap s0)) Hi0) as (Hqi & Hsi & Hji).
224
+ destruct (HT (kap s0) Hk0) as (Hd0 & Ht0). destruct (HT (succ_mod K (kap s0)) Hi0) as (Hdi & Hti).
225
+ refine (conj Hf' _).
226
+ unfold step in *. rewrite Hsl, Hdr. destruct r as [a0 w0 a1 w1 beta ao].
227
+ assert (Hc : forall a, cellof al K s a = vcell v a).
228
+ { intro a. unfold cellof, vcell. rewrite Hk.
229
+ destruct (Nat.eqb a SINK); [reflexivity|]. destruct (Nat.eqb a RD); [rewrite HR; reflexivity|].
230
+ destruct (Nat.eqb a ARM); [|destruct (Nat.eqb a CPY); [rewrite HC; reflexivity | rewrite Hw; reflexivity]].
231
+ rewrite <- HI. unfold bget, tget, lin, apos. reflexivity. }
232
+ rewrite !Hc. unfold vexec, rval, vput, stepres. cbn [ao_of]. rewrite Hk, <- Hw.
233
+ set (x := Z.leb 0 (w0 * b2z (vcell v a0) + w1 * b2z (vcell v a1) + beta)%Z).
234
+ set (wn := wnext (win s) ao x).
235
+ cbn [win kap banks tapes vw vho vr va vc].
236
+ refine (conj eq_refl (conj _ (conj _ (conj _ (conj _ (conj _ _)))))).
237
+ - rewrite Hho. cbn [orb]. destruct (wget wn HO); reflexivity.
238
+ - rewrite (nth_map_seq _ _ K (kap s0) bank0 Hk0), Nat.eqb_refl, HA. cbn [bq bs bj].
239
+ rewrite succ_mod_mod, Nat.add_succ_r by lia. reflexivity.
240
+ - rewrite (nth_map_seq _ _ K (succ_mod K (kap s0)) bank0 Hi0), (proj2 (Nat.eqb_neq _ _) Hik), Nat.eqb_refl.
241
+ rewrite <- HI. unfold lin at 2. set (I := nth (succ_mod K (kap s0)) (banks s) bank0) in *.
242
+ destruct (Nat.eqb ao ARM); cbn [bq bs bj td th];
243
+ (destruct (wget wn RA); [unfold lin; cbn [bq bs bj]; reflexivity|]);
244
+ (destruct (wget wn AA); [|unfold lin; cbn [bq bs bj]; reflexivity]).
245
+ + destruct (advb_lin al S0 (mkB (if wget wn CB then repeat false (S0 * recw al) else upd (bq I) (apos al I) x)
246
+ (bs I) (bj I)) Hsi Hji) as (E & _). rewrite E. reflexivity.
247
+ + destruct (advb_lin al S0 (mkB (if wget wn CB then repeat false (S0 * recw al) else bq I) (bs I) (bj I)) Hsi Hji)
248
+ as (E & _). rewrite E. reflexivity.
249
+ - rewrite (nth_map_seq _ _ K (kap s0) tape0 Hk0), Nat.eqb_refl, HR. reflexivity.
250
+ - rewrite (nth_map_seq _ _ K (succ_mod K (kap s0)) tape0 Hi0), (proj2 (Nat.eqb_neq _ _) Hik), Nat.eqb_refl, HC.
251
+ destruct (Nat.eqb ao CPY); reflexivity.
252
+ - intros y Hy E1 E2. rewrite (nth_map_seq _ _ K y bank0 Hy), (nth_map_seq _ _ K y tape0 Hy).
253
+ rewrite (proj2 (Nat.eqb_neq _ _) E1), (proj2 (Nat.eqb_neq _ _) E2). apply Ho; assumption.
254
+ Qed.
255
+
256
+ Lemma itern_S_r : forall n s, itern al K S0 L (S n) s = step al K S0 L (itern al K S0 L n s).
257
+ Proof. intros n s. replace (S n) with (n + 1) by lia. rewrite itern_add. reflexivity. Qed.
258
+
259
+ (* the records rs in the active bank from slot 0, none but the last handing over: running them is the
260
+ machine running the segment *)
261
+ Theorem seg_run : forall rs tail,
262
+ bq (nth (kap s0) (banks s0) bank0) = encA al rs ++ tail -> bs (nth (kap s0) (banks s0) bank0) = 0 ->
263
+ length rs <= S0 -> Forall (rec_ok al) rs ->
264
+ (forall j, 1 <= j < length rs -> vho (vrun (S0 * recw al) L (firstn j rs) view0) = false) ->
265
+ forall j, j <= length rs ->
266
+ mv j (itern al K S0 L j s0) (vrun (S0 * recw al) L (firstn j rs) view0).
267
+ Proof.
268
+ intros rs tail Hq Hb Hl Hok Hho j. induction j as [|j IH]; intro Hj; [exact mv_0|].
269
+ rewrite itern_S_r.
270
+ destruct (nth_error rs j) as [r|] eqn:Er; [|apply nth_error_None in Er; lia].
271
+ rewrite (firstn_S_nth rs j r Er), vrun_app. cbn [vrun].
272
+ pose proof (IH ltac:(lia)) as M.
273
+ apply mv_step; [exact M | | |].
274
+ - destruct j as [|j]; [reflexivity|]. apply Hho. lia.
275
+ - destruct M as (_ & _ & Hk & HA & _).
276
+ assert (Hk' : kap (itern al K S0 L j s0) = kap s0).
277
+ { rewrite Hk. destruct j as [|j]; [reflexivity|]. rewrite Hho by lia. reflexivity. }
278
+ rewrite Hk', HA. unfold slot. cbn [bq bs]. rewrite Hb, Nat.add_0_l, Nat.mod_small by lia.
279
+ rewrite Hq. apply slot_recA. exact Er.
280
+ - apply decode_enc. rewrite Forall_forall in Hok. apply Hok. eapply nth_error_In. exact Er.
281
+ Qed.
282
+
283
+ End Seg.
rocq/ViewOps.v ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* One record on a view: the value of a gate, and the effect of a record that writes a window cell, the
2
+ cell under the arm or under the copy head, or a request. *)
3
+ From Stdlib Require Import List Bool Arith ZArith Lia.
4
+ Import ListNotations.
5
+ From TH Require Import TwoHead Abstract Indep Run View Stored WinRun.
6
+
7
+ Definition lv (v : view) (l : nat * bool) : bool := if snd l then vcell v (fst l) else negb (vcell v (fst l)).
8
+
9
+ Lemma rval_and : forall v x y d, rval v (gAND x y d) = lv v x && lv v y.
10
+ Proof.
11
+ intros v [a p] [c q] d. unfold rval, gAND, lv, pm. cbn [fst snd].
12
+ destruct p, q, (vcell v a), (vcell v c); reflexivity.
13
+ Qed.
14
+
15
+ Lemma rval_or : forall v x y d, rval v (gOR x y d) = lv v x || lv v y.
16
+ Proof.
17
+ intros v [a p] [c q] d. unfold rval, gOR, lv, pm. cbn [fst snd].
18
+ destruct p, q, (vcell v a), (vcell v c); reflexivity.
19
+ Qed.
20
+
21
+ Lemma rval_copy : forall v x d, rval v (gCOPY x d) = lv v x.
22
+ Proof. intros v [a p] d. unfold rval, gCOPY, lv, pm. cbn [fst snd]. destruct p, (vcell v a); reflexivity. Qed.
23
+
24
+ Lemma rval_const : forall v b d, rval v (gCONST b d) = b.
25
+ Proof. intros v [|] d; reflexivity. Qed.
26
+
27
+ Lemma rval_empty : forall v, rval v EMPTY = true.
28
+ Proof. reflexivity. Qed.
29
+
30
+ Lemma vcell_win : forall v c, CPY < c -> vcell v c = wget (vw v) c.
31
+ Proof.
32
+ intros v c Hc. unfold vcell. unfold SINK, RD, ARM, CPY in *.
33
+ replace (Nat.eqb c 0) with false by (symmetry; apply Nat.eqb_neq; lia).
34
+ replace (Nat.eqb c 1) with false by (symmetry; apply Nat.eqb_neq; lia).
35
+ replace (Nat.eqb c 2) with false by (symmetry; apply Nat.eqb_neq; lia).
36
+ replace (Nat.eqb c 3) with false by (symmetry; apply Nat.eqb_neq; lia). reflexivity.
37
+ Qed.
38
+
39
+ Lemma lv_win : forall v c p, CPY < c -> lv v (c, p) = if p then wget (vw v) c else negb (wget (vw v) c).
40
+ Proof. intros v c p Hc. unfold lv. cbn [fst snd]. rewrite vcell_win by exact Hc. reflexivity. Qed.
41
+
42
+ (* ---- the request cells ------------------------------------------------------------------------------ *)
43
+ Lemma wget_upd_same_false : forall w i, wget (upd w i false) i = false.
44
+ Proof.
45
+ intros w i. unfold wget. destruct (Nat.lt_ge_cases i (length w)) as [H|H].
46
+ - apply nth_upd_same. exact H.
47
+ - rewrite nth_overflow; [reflexivity | rewrite upd_length; exact H].
48
+ Qed.
49
+
50
+ Lemma wget_upd_other : forall w i j v, i <> j -> wget (upd w i v) j = wget w j.
51
+ Proof. intros w i j v H. unfold wget. apply nth_upd_other. exact H. Qed.
52
+
53
+ Lemma wget_clearq_req : forall w i, AR <= i <= HO -> wget (clearq w) i = false.
54
+ Proof.
55
+ intros w i Hi. unfold clearq. unfold AR, AA, AC, RR, RA, RC, CB, CT, HO in *.
56
+ assert (Hc : i = 4 \/ i = 5 \/ i = 6 \/ i = 7 \/ i = 8 \/ i = 9 \/ i = 10 \/ i = 11 \/ i = 12) by lia.
57
+ destruct Hc as [->|[->|[->|[->|[->|[->|[->|[->| ->]]]]]]]];
58
+ repeat (rewrite wget_upd_other by lia); apply wget_upd_same_false.
59
+ Qed.
60
+
61
+ Lemma wget_clearq_cell : forall w i, ~ (AR <= i <= HO) -> wget (clearq w) i = wget w i.
62
+ Proof.
63
+ intros w i Hi. destruct (Nat.lt_ge_cases i AR); [apply wget_clearq_out; left; assumption|].
64
+ apply wget_clearq_out. right. unfold AR, HO in *. lia.
65
+ Qed.
66
+
67
+ Lemma clearq_upd_req : forall w c x, AR <= c <= HO -> reqclear w -> clearq (upd w c x) = w.
68
+ Proof.
69
+ intros w c x Hc Hq. apply (nth_ext _ _ false false); [rewrite length_clearq, upd_length; reflexivity|].
70
+ intros i _. change (wget (clearq (upd w c x)) i = wget w i).
71
+ destruct (Nat.le_gt_cases AR i) as [H1|H1]; [destruct (Nat.le_gt_cases i HO) as [H2|H2]|].
72
+ - rewrite wget_clearq_req by lia. symmetry. apply Hq. lia.
73
+ - rewrite wget_clearq_cell by lia. rewrite wget_upd. replace (Nat.eqb i c) with false by (symmetry; apply Nat.eqb_neq; lia).
74
+ reflexivity.
75
+ - rewrite wget_clearq_cell by lia. rewrite wget_upd. replace (Nat.eqb i c) with false by (symmetry; apply Nat.eqb_neq; lia).
76
+ reflexivity.
77
+ Qed.
78
+
79
+ Lemma reqclear_upd : forall w c x, HO < c -> reqclear w -> reqclear (upd w c x).
80
+ Proof.
81
+ intros w c x Hc Hq i Hi. rewrite wget_upd. replace (Nat.eqb i c) with false by (symmetry; apply Nat.eqb_neq; lia).
82
+ apply Hq. exact Hi.
83
+ Qed.
84
+
85
+ (* ---- a record writing a window cell, the arm, the copy head, a request, or the sink ----------------- *)
86
+ Section Ops.
87
+ Variables (Lb L : nat).
88
+
89
+ Lemma vexec_cell : forall r v, reqclear (vw v) -> HO < ao_of r ->
90
+ vexec Lb L r v = mkV (upd (vw v) (ao_of r) (rval v r)) (vr v) (va v) (vc v) (vho v).
91
+ Proof.
92
+ intros r v Hq Hc. unfold vexec, vput.
93
+ assert (Hw : wnext (vw v) (ao_of r) (rval v r) = upd (vw v) (ao_of r) (rval v r)).
94
+ { unfold wnext. destruct (Nat.leb_spec (ao_of r) CPY); [unfold CPY, HO in *; lia | reflexivity]. }
95
+ rewrite Hw. pose proof (reqclear_upd (vw v) (ao_of r) (rval v r) Hc Hq) as Hq'.
96
+ rewrite (Hq' RR), (Hq' AR), (Hq' CB), (Hq' RA), (Hq' AA), (Hq' CT), (Hq' RC), (Hq' AC), (Hq' HO)
97
+ by (unfold AR, AA, AC, RR, RA, RC, CB, CT, HO; lia).
98
+ rewrite (clearq_id _ Hq').
99
+ replace (Nat.eqb (ao_of r) ARM) with false by (symmetry; apply Nat.eqb_neq; unfold ARM, HO in *; lia).
100
+ replace (Nat.eqb (ao_of r) CPY) with false by (symmetry; apply Nat.eqb_neq; unfold CPY, HO in *; lia).
101
+ rewrite orb_false_r, !eta_tape. reflexivity.
102
+ Qed.
103
+
104
+ Lemma vexec_sink : forall r v, reqclear (vw v) -> ao_of r = SINK -> vexec Lb L r v = v.
105
+ Proof.
106
+ intros r v Hq Hs. unfold vexec, vput. rewrite Hs.
107
+ change (wnext (vw v) SINK (rval v r)) with (vw v).
108
+ rewrite (Hq RR), (Hq AR), (Hq CB), (Hq RA), (Hq AA), (Hq CT), (Hq RC), (Hq AC), (Hq HO)
109
+ by (unfold AR, AA, AC, RR, RA, RC, CB, CT, HO; lia).
110
+ rewrite (clearq_id _ Hq). cbn [Nat.eqb SINK ARM CPY]. rewrite orb_false_r, !eta_tape. destruct v; reflexivity.
111
+ Qed.
112
+
113
+ Lemma vexec_arm : forall r v, reqclear (vw v) -> ao_of r = ARM ->
114
+ vexec Lb L r v = mkV (vw v) (vr v) (mkT (upd (td (va v)) (th (va v)) (rval v r)) (th (va v))) (vc v) (vho v).
115
+ Proof.
116
+ intros r v Hq Ha. unfold vexec, vput. rewrite Ha.
117
+ change (wnext (vw v) ARM (rval v r)) with (vw v).
118
+ rewrite (Hq RR), (Hq AR), (Hq CB), (Hq RA), (Hq AA), (Hq CT), (Hq RC), (Hq AC), (Hq HO)
119
+ by (unfold AR, AA, AC, RR, RA, RC, CB, CT, HO; lia).
120
+ rewrite (clearq_id _ Hq). cbn [Nat.eqb ARM CPY td th]. rewrite orb_false_r, !eta_tape. reflexivity.
121
+ Qed.
122
+
123
+ Lemma vexec_cpy : forall r v, reqclear (vw v) -> ao_of r = CPY ->
124
+ vexec Lb L r v = mkV (vw v) (vr v) (va v) (mkT (upd (td (vc v)) (th (vc v)) (rval v r)) (th (vc v))) (vho v).
125
+ Proof.
126
+ intros r v Hq Ha. unfold vexec, vput. rewrite Ha.
127
+ change (wnext (vw v) CPY (rval v r)) with (vw v).
128
+ rewrite (Hq RR), (Hq AR), (Hq CB), (Hq RA), (Hq AA), (Hq CT), (Hq RC), (Hq AC), (Hq HO)
129
+ by (unfold AR, AA, AC, RR, RA, RC, CB, CT, HO; lia).
130
+ rewrite (clearq_id _ Hq). cbn [Nat.eqb ARM CPY td th]. rewrite orb_false_r, !eta_tape. reflexivity.
131
+ Qed.
132
+
133
+ (* what a request does when it holds 1 *)
134
+ Definition vact (c : nat) (v : view) : view :=
135
+ match c with
136
+ | 4 => mkV (vw v) (mkT (td (vr v)) (succ_mod L (th (vr v)))) (va v) (vc v) (vho v)
137
+ | 5 => mkV (vw v) (vr v) (mkT (td (va v)) (succ_mod Lb (th (va v)))) (vc v) (vho v)
138
+ | 6 => mkV (vw v) (vr v) (va v) (mkT (td (vc v)) (succ_mod L (th (vc v)))) (vho v)
139
+ | 7 => mkV (vw v) (mkT (td (vr v)) 0) (va v) (vc v) (vho v)
140
+ | 8 => mkV (vw v) (vr v) (mkT (td (va v)) 0) (vc v) (vho v)
141
+ | 9 => mkV (vw v) (vr v) (va v) (mkT (td (vc v)) 0) (vho v)
142
+ | 10 => mkV (vw v) (vr v) (mkT (repeat false Lb) (th (va v))) (vc v) (vho v)
143
+ | 11 => mkV (vw v) (vr v) (va v) (mkT (repeat false L) (th (vc v))) (vho v)
144
+ | 12 => mkV (vw v) (vr v) (va v) (vc v) true
145
+ | _ => v
146
+ end.
147
+
148
+ Lemma vexec_req : forall r v, reqclear (vw v) -> AR <= ao_of r <= HO -> ao_of r < length (vw v) ->
149
+ vexec Lb L r v = if rval v r then vact (ao_of r) v else v.
150
+ Proof.
151
+ intros r v Hq Hc Hl. unfold vexec, vput.
152
+ assert (Hw : wnext (vw v) (ao_of r) (rval v r) = upd (vw v) (ao_of r) (rval v r)).
153
+ { unfold wnext. destruct (Nat.leb_spec (ao_of r) CPY); [unfold AR, CPY in *; lia | reflexivity]. }
154
+ rewrite Hw, (clearq_upd_req _ _ _ Hc Hq).
155
+ assert (Hg : forall c', AR <= c' <= HO -> wget (upd (vw v) (ao_of r) (rval v r)) c'
156
+ = if Nat.eqb c' (ao_of r) then rval v r else false).
157
+ { intros c' Hc'. rewrite wget_upd, (proj2 (Nat.ltb_lt _ _) Hl), andb_true_r.
158
+ destruct (Nat.eqb c' (ao_of r)); [reflexivity | apply Hq; exact Hc']. }
159
+ rewrite (Hg RR), (Hg AR), (Hg CB), (Hg RA), (Hg AA), (Hg CT), (Hg RC), (Hg AC), (Hg HO)
160
+ by (unfold AR, AA, AC, RR, RA, RC, CB, CT, HO; lia).
161
+ replace (Nat.eqb (ao_of r) ARM) with false by (symmetry; apply Nat.eqb_neq; unfold AR, ARM in *; lia).
162
+ replace (Nat.eqb (ao_of r) CPY) with false by (symmetry; apply Nat.eqb_neq; unfold AR, CPY in *; lia).
163
+ destruct v as [w R I C h]. cbn [vw vr va vc vho] in *.
164
+ unfold AR, AA, AC, RR, RA, RC, CB, CT, HO in *.
165
+ assert (Hc9 : ao_of r = 4 \/ ao_of r = 5 \/ ao_of r = 6 \/ ao_of r = 7 \/ ao_of r = 8 \/ ao_of r = 9
166
+ \/ ao_of r = 10 \/ ao_of r = 11 \/ ao_of r = 12) by lia.
167
+ destruct Hc9 as [E|[E|[E|[E|[E|[E|[E|[E|E]]]]]]]]; rewrite E; cbn [Nat.eqb vact vw vr va vc vho];
168
+ destruct (rval (mkV w R I C h) r); cbn [orb]; rewrite ?orb_false_r, ?orb_true_r; destruct R, I, C; reflexivity.
169
+ Qed.
170
+
171
+ End Ops.
rocq/WinPar.v ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* Window records that read no cell another record of the list writes run as if at once; a multiplexer and
2
+ an exclusive or of three records through two scratch cells. *)
3
+ From Stdlib Require Import List Bool Arith ZArith Lia.
4
+ Import ListNotations.
5
+ From TH Require Import TwoHead Abstract Indep Run View Stored WinRun.
6
+
7
+ Definition reads_of (r : rec) : list nat :=
8
+ match r with Rec a0 w0 a1 w1 _ _ => (if Z.eqb w0 0 then [] else [a0]) ++ (if Z.eqb w1 0 then [] else [a1]) end.
9
+
10
+ Lemma wval_ext : forall r w1 w2, (forall c, In c (reads_of r) -> wcell w1 c = wcell w2 c) -> wval w1 r = wval w2 r.
11
+ Proof.
12
+ intros [a0 w0 a1 w1' beta ao] x y H. unfold wval. cbn [reads_of] in H.
13
+ assert (H0 : (w0 * b2z (wcell x a0) = w0 * b2z (wcell y a0))%Z).
14
+ { destruct (Z.eqb_spec w0 0) as [->|E]; [reflexivity|]. rewrite (H a0); [reflexivity|]. left. reflexivity. }
15
+ assert (H1 : (w1' * b2z (wcell x a1) = w1' * b2z (wcell y a1))%Z).
16
+ { destruct (Z.eqb_spec w1' 0) as [->|E]; [reflexivity|]. rewrite (H a1); [reflexivity|].
17
+ apply in_or_app. right. left. reflexivity. }
18
+ rewrite H0, H1. reflexivity.
19
+ Qed.
20
+
21
+ Lemma wcell_wnext_other : forall w ao x c, HO < ao -> ao < length w -> c <> ao -> wcell (wnext w ao x) c = wcell w c.
22
+ Proof.
23
+ intros w ao x c H1 H2 H3. unfold wcell. destruct (Nat.eqb c SINK); [reflexivity|].
24
+ rewrite wget_wnext by assumption. rewrite (proj2 (Nat.eqb_neq _ _) H3). reflexivity.
25
+ Qed.
26
+
27
+ (* records that read, among the cells the list writes, only their own *)
28
+ Lemma wrun_par : forall rs w, NoDup (map ao_of rs) -> (forall r, In r rs -> HO < ao_of r < length w) ->
29
+ (forall r r', In r rs -> In r' rs -> In (ao_of r') (reads_of r) -> ao_of r' = ao_of r) ->
30
+ (forall r, In r rs -> wget (wrun rs w) (ao_of r) = wval w r)
31
+ /\ (forall c, ~ In c (map ao_of rs) -> wget (wrun rs w) c = wget w c).
32
+ Proof.
33
+ induction rs as [|r rs IH]; intros w Hnd Hl Hrd; [split; [intros r [] | intros; reflexivity]|].
34
+ inversion Hnd as [|? ? Hni Hnd']; subst.
35
+ cbn [wrun]. unfold wexec.
36
+ destruct (Hl r (or_introl eq_refl)) as [Hr1 Hr2].
37
+ set (w1 := wnext w (ao_of r) (wval w r)).
38
+ assert (Hw1 : forall c, wget w1 c = if Nat.eqb c (ao_of r) then wval w r else wget w c)
39
+ by (intro c; unfold w1; apply wget_wnext; assumption).
40
+ assert (Hl1 : forall r', In r' rs -> HO < ao_of r' < length w1)
41
+ by (intros r' Hr'; unfold w1; rewrite length_wnext; apply Hl; right; exact Hr').
42
+ assert (Hrd' : forall r1 r2, In r1 rs -> In r2 rs -> In (ao_of r2) (reads_of r1) -> ao_of r2 = ao_of r1)
43
+ by (intros r1 r2 H1 H2 H3; apply Hrd; [right; exact H1 | right; exact H2 | exact H3]).
44
+ destruct (IH w1 Hnd' Hl1 Hrd') as [IH1 IH2].
45
+ assert (Hv : forall r', In r' rs -> wval w1 r' = wval w r').
46
+ { intros r' Hr'. apply wval_ext. intros c Hc. unfold w1. apply wcell_wnext_other; [exact Hr1 | exact Hr2|].
47
+ intro E. subst c. pose proof (Hrd r' r (or_intror Hr') (or_introl eq_refl) Hc) as E.
48
+ apply Hni. rewrite E. apply in_map. exact Hr'. }
49
+ split.
50
+ - intros r' [<-|Hr'].
51
+ + rewrite IH2 by exact Hni. rewrite Hw1, Nat.eqb_refl. reflexivity.
52
+ + rewrite (IH1 r' Hr'). apply Hv. exact Hr'.
53
+ - intros c Hc. rewrite IH2 by (intro H; apply Hc; right; exact H). rewrite Hw1.
54
+ replace (Nat.eqb c (ao_of r)) with false by (symmetry; apply Nat.eqb_neq; intro E; apply Hc; left; congruence).
55
+ reflexivity.
56
+ Qed.
57
+
58
+ (* ---- a multiplexer and an exclusive or through the cells m0 and m1 ----------------------------------- *)
59
+ Section Mux.
60
+ Variables (m0 m1 : nat).
61
+
62
+ Lemma wl_wnext : forall w ao x l, HO < ao -> ao < length w -> fst l <> ao -> wl (wnext w ao x) l = wl w l.
63
+ Proof. intros w ao x [c p] H1 H2 H3. unfold wl. cbn [fst snd] in *. rewrite wcell_wnext_other by assumption. reflexivity. Qed.
64
+
65
+ Lemma wl_cell : forall w c, HO < c -> wl w (c, true) = wget w c.
66
+ Proof.
67
+ intros w c H. unfold wl, wcell. cbn [fst snd].
68
+ replace (Nat.eqb c SINK) with false by (symmetry; apply Nat.eqb_neq; unfold SINK, HO in *; lia). reflexivity.
69
+ Qed.
70
+
71
+ Lemma wrun_mux : forall s a b d w,
72
+ HO < m0 -> HO < m1 -> m0 <> m1 -> m0 < length w -> m1 < length w -> HO < d -> d < length w ->
73
+ HO < s -> s <> m0 -> fst a <> m0 -> fst b <> m0 -> fst b <> m1 ->
74
+ let w' := wrun [gAND (s, true) a m0; gAND (s, false) b m1; gOR (m0, true) (m1, true) d] w in
75
+ length w' = length w
76
+ /\ wget w' d = (if wget w s then wl w a else wl w b)
77
+ /\ (forall c, c <> m0 -> c <> m1 -> c <> d -> wget w' c = wget w c).
78
+ Proof.
79
+ intros s a b d w H0 H1 H01 Hl0 Hl1 Hd Hld Hs Hs0 Ha0 Hb0 Hb1 w'. unfold w'. cbn [wrun]. unfold wexec.
80
+ cbn [ao_of gAND gOR]. rewrite !wval_and, wval_or.
81
+ set (w1 := wnext w m0 (wl w (s, true) && wl w a)).
82
+ assert (L1 : length w1 = length w) by apply length_wnext.
83
+ set (w2 := wnext w1 m1 (wl w1 (s, false) && wl w1 b)).
84
+ assert (L2 : length w2 = length w) by (unfold w2; rewrite length_wnext; exact L1).
85
+ assert (E1s : wl w1 (s, false) = negb (wget w s))
86
+ by (unfold w1; rewrite wl_wnext by (cbn [fst]; assumption); unfold wl, wcell; cbn [fst snd];
87
+ replace (Nat.eqb s SINK) with false by (symmetry; apply Nat.eqb_neq; unfold SINK, HO in *; lia); reflexivity).
88
+ assert (E1b : wl w1 b = wl w b) by (unfold w1; apply wl_wnext; assumption).
89
+ assert (E2m0 : wl w2 (m0, true) = wl w (s, true) && wl w a).
90
+ { rewrite wl_cell by exact H0. unfold w2. rewrite wget_wnext by (rewrite ?L1; assumption).
91
+ rewrite (proj2 (Nat.eqb_neq _ _) H01). unfold w1. rewrite wget_wnext by assumption. rewrite Nat.eqb_refl. reflexivity. }
92
+ assert (E2m1 : wl w2 (m1, true) = negb (wget w s) && wl w b).
93
+ { rewrite wl_cell by exact H1. unfold w2. rewrite wget_wnext by (rewrite ?L1; assumption). rewrite Nat.eqb_refl.
94
+ rewrite E1s, E1b. reflexivity. }
95
+ rewrite E2m0, E2m1. rewrite wl_cell by exact Hs.
96
+ split; [rewrite length_wnext; exact L2|]. split.
97
+ - rewrite wget_wnext by (rewrite ?L2; assumption). rewrite Nat.eqb_refl.
98
+ destruct (wget w s); cbn [andb orb negb]; [rewrite orb_false_r | ]; reflexivity.
99
+ - intros c C0 C1 Cd. rewrite wget_wnext by (rewrite ?L2; assumption). rewrite (proj2 (Nat.eqb_neq _ _) Cd).
100
+ unfold w2. rewrite wget_wnext by (rewrite ?L1; assumption). rewrite (proj2 (Nat.eqb_neq _ _) C1).
101
+ unfold w1. rewrite wget_wnext by assumption. rewrite (proj2 (Nat.eqb_neq _ _) C0). reflexivity.
102
+ Qed.
103
+
104
+ Lemma wrun_xor : forall x y d w,
105
+ HO < m0 -> HO < m1 -> m0 <> m1 -> m0 < length w -> m1 < length w -> HO < d -> d < length w ->
106
+ fst x <> m0 -> fst y <> m0 -> fst x <> m1 -> fst y <> m1 ->
107
+ let w' := wrun [gOR x y m0; gOR (fst x, negb (snd x)) (fst y, negb (snd y)) m1; gAND (m0, true) (m1, true) d] w in
108
+ length w' = length w
109
+ /\ wget w' d = xorb (wl w x) (wl w y)
110
+ /\ (forall c, c <> m0 -> c <> m1 -> c <> d -> wget w' c = wget w c).
111
+ Proof.
112
+ intros x y d w H0 H1 H01 Hl0 Hl1 Hd Hld Hx0 Hy0 Hx1 Hy1 w'. unfold w'. cbn [wrun]. unfold wexec.
113
+ cbn [ao_of gAND gOR]. rewrite !wval_or, wval_and.
114
+ set (w1 := wnext w m0 (wl w x || wl w y)).
115
+ assert (L1 : length w1 = length w) by apply length_wnext.
116
+ assert (Ex : forall l, fst l <> m0 -> wl w1 l = wl w l) by (intros l Hl; unfold w1; apply wl_wnext; assumption).
117
+ set (w2 := wnext w1 m1 (wl w1 (fst x, negb (snd x)) || wl w1 (fst y, negb (snd y)))).
118
+ assert (L2 : length w2 = length w) by (unfold w2; rewrite length_wnext; exact L1).
119
+ assert (Neg : forall l, wl w (fst l, negb (snd l)) = negb (wl w l)) by (intros [c p]; unfold wl; cbn [fst snd]; destruct p; [reflexivity | apply negb_involutive_reverse]).
120
+ assert (E2m0 : wl w2 (m0, true) = wl w x || wl w y).
121
+ { rewrite wl_cell by exact H0. unfold w2. rewrite wget_wnext by (rewrite ?L1; assumption).
122
+ rewrite (proj2 (Nat.eqb_neq _ _) H01). unfold w1. rewrite wget_wnext by assumption. rewrite Nat.eqb_refl. reflexivity. }
123
+ assert (E2m1 : wl w2 (m1, true) = negb (wl w x) || negb (wl w y)).
124
+ { rewrite wl_cell by exact H1. unfold w2. rewrite wget_wnext by (rewrite ?L1; assumption). rewrite Nat.eqb_refl.
125
+ rewrite (Ex (fst x, negb (snd x))) by (cbn [fst]; exact Hx0). rewrite (Ex (fst y, negb (snd y))) by (cbn [fst]; exact Hy0).
126
+ rewrite !Neg. reflexivity. }
127
+ rewrite E2m0, E2m1.
128
+ split; [rewrite length_wnext; exact L2|]. split.
129
+ - rewrite wget_wnext by (rewrite ?L2; assumption). rewrite Nat.eqb_refl.
130
+ destruct (wl w x), (wl w y); reflexivity.
131
+ - intros c C0 C1 Cd. rewrite wget_wnext by (rewrite ?L2; assumption). rewrite (proj2 (Nat.eqb_neq _ _) Cd).
132
+ unfold w2. rewrite wget_wnext by (rewrite ?L1; assumption). rewrite (proj2 (Nat.eqb_neq _ _) C1).
133
+ unfold w1. rewrite wget_wnext by assumption. rewrite (proj2 (Nat.eqb_neq _ _) C0). reflexivity.
134
+ Qed.
135
+
136
+ End Mux.
rocq/WinRun.v ADDED
@@ -0,0 +1,453 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* Records that read and write the window alone, and the gates, chains and threshold units of Stored.v
2
+ run on it: a chain leaves the conjunction or the disjunction of its literals in its cell, and the
3
+ compiled threshold unit leaves in its cell whether at least t of its literals are true. *)
4
+ From Stdlib Require Import List Bool Arith ZArith Lia.
5
+ Import ListNotations.
6
+ From TH Require Import TwoHead Abstract Indep Run View Stored.
7
+
8
+ (* ---- the window alone ------------------------------------------------------------------------------ *)
9
+ Definition wcell (w : list bool) (a : nat) : bool := if Nat.eqb a SINK then false else wget w a.
10
+
11
+ Definition wval (w : list bool) (r : rec) : bool :=
12
+ match r with Rec a0 w0 a1 w1 beta _ => Z.leb 0 (w0 * b2z (wcell w a0) + w1 * b2z (wcell w a1) + beta) end.
13
+
14
+ Definition wexec (r : rec) (w : list bool) : list bool := wnext w (ao_of r) (wval w r).
15
+
16
+ Fixpoint wrun (rs : list rec) (w : list bool) : list bool :=
17
+ match rs with [] => w | r :: t => wrun t (wexec r w) end.
18
+
19
+ Lemma wrun_app : forall a b w, wrun (a ++ b) w = wrun b (wrun a w).
20
+ Proof. induction a as [|r a IH]; intros b w; [reflexivity|]. cbn [app wrun]. apply IH. Qed.
21
+
22
+ (* a record that reads no head and writes the sink or a cell above the requests *)
23
+ Definition wrec (r : rec) : Prop :=
24
+ match r with
25
+ | Rec a0 w0 a1 w1 _ ao => (w0 = 0%Z \/ a0 = SINK \/ CPY < a0) /\ (w1 = 0%Z \/ a1 = SINK \/ CPY < a1)
26
+ /\ (ao = SINK \/ HO < ao)
27
+ end.
28
+
29
+ Lemma reqclear_wnext : forall w ao x, reqclear w -> (ao = SINK \/ HO < ao) -> reqclear (wnext w ao x).
30
+ Proof.
31
+ intros w ao x H Hao c Hc. unfold wnext. destruct (Nat.leb_spec ao CPY); [apply H; exact Hc|].
32
+ rewrite wget_upd. destruct Hao as [->|Hao]; [unfold SINK, CPY in *; lia|].
33
+ replace (Nat.eqb c ao) with false by (symmetry; apply Nat.eqb_neq; unfold HO in *; lia). apply H. exact Hc.
34
+ Qed.
35
+
36
+ Lemma vexec_wrec : forall Lb L r v, wrec r -> reqclear (vw v) ->
37
+ vexec Lb L r v = mkV (wexec r (vw v)) (vr v) (va v) (vc v) (vho v).
38
+ Proof.
39
+ intros Lb L [a0 w0 a1 w1 beta ao] v (H0 & H1 & Ho) Hq.
40
+ assert (Hc : forall a w', (w' = 0%Z \/ a = SINK \/ CPY < a) -> (w' * b2z (vcell v a) = w' * b2z (wcell (vw v) a))%Z).
41
+ { intros a w' [->|[->|Ha]]; [reflexivity | reflexivity|].
42
+ unfold vcell, wcell. unfold SINK, RD, ARM, CPY in *.
43
+ replace (Nat.eqb a 0) with false by (symmetry; apply Nat.eqb_neq; lia).
44
+ replace (Nat.eqb a 1) with false by (symmetry; apply Nat.eqb_neq; lia).
45
+ replace (Nat.eqb a 2) with false by (symmetry; apply Nat.eqb_neq; lia).
46
+ replace (Nat.eqb a 3) with false by (symmetry; apply Nat.eqb_neq; lia). reflexivity. }
47
+ unfold vexec, wexec, rval, wval, vput. cbn [ao_of]. rewrite (Hc a0 w0 H0), (Hc a1 w1 H1).
48
+ set (x := Z.leb 0 (w0 * b2z (wcell (vw v) a0) + w1 * b2z (wcell (vw v) a1) + beta)%Z).
49
+ pose proof (reqclear_wnext (vw v) ao x Hq Ho) as Hq'.
50
+ rewrite (Hq' RR), (Hq' AR), (Hq' CB), (Hq' RA), (Hq' AA), (Hq' CT), (Hq' RC), (Hq' AC), (Hq' HO)
51
+ by (unfold AR, AA, AC, RR, RA, RC, CB, CT, HO; lia).
52
+ rewrite (clearq_id _ Hq').
53
+ replace (Nat.eqb ao ARM) with false by (symmetry; apply Nat.eqb_neq; destruct Ho as [->|Ho]; unfold SINK, ARM, HO in *; lia).
54
+ replace (Nat.eqb ao CPY) with false by (symmetry; apply Nat.eqb_neq; destruct Ho as [->|Ho]; unfold SINK, CPY, HO in *; lia).
55
+ rewrite orb_false_r, !eta_tape. reflexivity.
56
+ Qed.
57
+
58
+ Lemma vrun_wrun : forall Lb L rs v, Forall wrec rs -> reqclear (vw v) ->
59
+ vrun Lb L rs v = mkV (wrun rs (vw v)) (vr v) (va v) (vc v) (vho v).
60
+ Proof.
61
+ intros Lb L rs. induction rs as [|r rs IH]; intros v Hf Hq; [destruct v; reflexivity|].
62
+ apply Forall_cons_iff in Hf as [Hr Hf]. cbn [vrun wrun]. rewrite (vexec_wrec Lb L r v Hr Hq).
63
+ rewrite IH; [reflexivity | exact Hf |]. cbn [vw]. unfold wexec.
64
+ apply reqclear_wnext; [exact Hq|]. destruct r as [a0 w0 a1 w1 beta ao]. apply Hr.
65
+ Qed.
66
+
67
+ Lemma wget_wnext : forall w ao x c, HO < ao -> ao < length w ->
68
+ wget (wnext w ao x) c = if Nat.eqb c ao then x else wget w c.
69
+ Proof.
70
+ intros w ao x c H1 H2. unfold wnext. destruct (Nat.leb_spec ao CPY) as [E|E]; [unfold CPY, HO in *; lia|].
71
+ rewrite wget_upd. destruct (Nat.eqb c ao); [|reflexivity]. rewrite (proj2 (Nat.ltb_lt _ _) H2). reflexivity.
72
+ Qed.
73
+
74
+ Lemma length_wnext' : forall w ao x, length (wnext w ao x) = length w.
75
+ Proof. apply length_wnext. Qed.
76
+
77
+ Lemma length_wrun : forall rs w, length (wrun rs w) = length w.
78
+ Proof. induction rs as [|r rs IH]; intro w; [reflexivity|]. cbn [wrun]. rewrite IH. apply length_wnext. Qed.
79
+
80
+ (* ---- gates ----------------------------------------------------------------------------------------- *)
81
+ Definition wl (w : list bool) (l : nat * bool) : bool := if snd l then wcell w (fst l) else negb (wcell w (fst l)).
82
+
83
+ Lemma wval_and : forall w x y d, wval w (gAND x y d) = wl w x && wl w y.
84
+ Proof.
85
+ intros w [a p] [c q] d. unfold wval, gAND, wl, pm. cbn [fst snd].
86
+ destruct p, q, (wcell w a), (wcell w c); reflexivity.
87
+ Qed.
88
+
89
+ Lemma wval_or : forall w x y d, wval w (gOR x y d) = wl w x || wl w y.
90
+ Proof.
91
+ intros w [a p] [c q] d. unfold wval, gOR, wl, pm. cbn [fst snd].
92
+ destruct p, q, (wcell w a), (wcell w c); reflexivity.
93
+ Qed.
94
+
95
+ Lemma wval_copy : forall w x d, wval w (gCOPY x d) = wl w x.
96
+ Proof. intros w [a p] d. unfold wval, gCOPY, wl, pm. cbn [fst snd]. destruct p, (wcell w a); reflexivity. Qed.
97
+
98
+ Lemma wval_const : forall w b d, wval w (gCONST b d) = b.
99
+ Proof. intros w [|] d; reflexivity. Qed.
100
+
101
+ Lemma ao_gates : forall x y d b,
102
+ ao_of (gAND x y d) = d /\ ao_of (gOR x y d) = d /\ ao_of (gCOPY x d) = d /\ ao_of (gCONST b d) = d.
103
+ Proof. intros x y d [|]; repeat split. Qed.
104
+
105
+ (* the cells a record reads, by weight *)
106
+ Definition rd_ok (c : nat) : Prop := c = SINK \/ CPY < c.
107
+
108
+ Lemma wrec_and : forall x y d, rd_ok (fst x) -> rd_ok (fst y) -> (d = SINK \/ HO < d) -> wrec (gAND x y d).
109
+ Proof. intros [a p] [c q] d Ha Hc Hd. cbn [fst] in *. unfold wrec, gAND, rd_ok in *. cbn [fst snd]. tauto. Qed.
110
+
111
+ Lemma wrec_or : forall x y d, rd_ok (fst x) -> rd_ok (fst y) -> (d = SINK \/ HO < d) -> wrec (gOR x y d).
112
+ Proof. intros [a p] [c q] d Ha Hc Hd. cbn [fst] in *. unfold wrec, gOR, rd_ok in *. cbn [fst snd]. tauto. Qed.
113
+
114
+ Lemma wrec_copy : forall x d, rd_ok (fst x) -> (d = SINK \/ HO < d) -> wrec (gCOPY x d).
115
+ Proof. intros [a p] d Ha Hd. cbn [fst] in *. unfold wrec, gCOPY, rd_ok in *. cbn [fst snd]. tauto. Qed.
116
+
117
+ Lemma wrec_const : forall b d, (d = SINK \/ HO < d) -> wrec (gCONST b d).
118
+ Proof. intros [|] d Hd; unfold wrec, gCONST, gOR, gAND; cbn [fst snd]; tauto. Qed.
119
+
120
+ (* ---- chains ---------------------------------------------------------------------------------------- *)
121
+ Section Chain.
122
+ Variable W : nat.
123
+
124
+ Definition ok_cell (c : nat) : Prop := HO < c /\ c < W.
125
+
126
+ Variables (g : nat * bool -> nat * bool -> nat -> rec) (f : bool -> bool -> bool).
127
+ Hypothesis Hg : forall x y d w, wval w (g x y d) = f (wl w x) (wl w y).
128
+ Hypothesis Hgo : forall x y d, ao_of (g x y d) = d.
129
+
130
+ Lemma chain_tail_run : forall acc d ls l w,
131
+ length w = W -> ok_cell d -> ok_cell acc -> (forall l', In l' (l :: ls) -> fst l' <> acc) ->
132
+ let w' := wrun (chain_tail g acc l ls d) w in
133
+ length w' = W
134
+ /\ wget w' d = fold_left (fun a l' => f a (wl w l')) (l :: ls) (wget w acc)
135
+ /\ (forall c, c <> d -> c <> acc -> wget w' c = wget w c).
136
+ Proof.
137
+ intros acc d. induction ls as [|l2 ls IH]; intros l w Hw Hd Ha Hl.
138
+ - cbn [chain_tail wrun fold_left]. unfold wexec. rewrite Hgo, Hg.
139
+ assert (Eacc : wl w (acc, true) = wget w acc) by (unfold wl, wcell; cbn [fst snd];
140
+ replace (Nat.eqb acc SINK) with false by (symmetry; apply Nat.eqb_neq; unfold ok_cell, SINK, HO in *; lia);
141
+ reflexivity).
142
+ rewrite Eacc. split; [rewrite length_wnext; exact Hw|].
143
+ split; [rewrite wget_wnext by (unfold ok_cell in Hd; lia); rewrite Nat.eqb_refl; reflexivity|].
144
+ intros c H1 H2. rewrite wget_wnext by (unfold ok_cell in Hd; lia). rewrite (proj2 (Nat.eqb_neq _ _) H1). reflexivity.
145
+ - cbn [chain_tail wrun].
146
+ assert (E1 : wexec (g (acc, true) l acc) w = wnext w acc (f (wl w (acc, true)) (wl w l)))
147
+ by (unfold wexec; rewrite Hgo, Hg; reflexivity).
148
+ rewrite E1. set (w1 := wnext w acc (f (wl w (acc, true)) (wl w l))).
149
+ assert (Hw1 : length w1 = W) by (unfold w1; rewrite length_wnext; exact Hw).
150
+ assert (Eacc : wl w (acc, true) = wget w acc) by (unfold wl, wcell; cbn [fst snd];
151
+ replace (Nat.eqb acc SINK) with false by (symmetry; apply Nat.eqb_neq; unfold ok_cell, SINK, HO in *; lia);
152
+ reflexivity).
153
+ assert (Hlv : forall l', In l' (l2 :: ls) -> wl w1 l' = wl w l').
154
+ { intros l' Hin. assert (Hne : fst l' <> acc) by (apply Hl; right; exact Hin).
155
+ unfold wl, wcell. destruct (Nat.eqb (fst l') SINK); [reflexivity|].
156
+ unfold w1. rewrite wget_wnext by (unfold ok_cell in Ha; lia). rewrite (proj2 (Nat.eqb_neq _ _) Hne). reflexivity. }
157
+ destruct (IH l2 w1 Hw1 Hd Ha ltac:(intros l' Hin; apply Hl; right; exact Hin)) as (L1 & V1 & U1).
158
+ split; [exact L1|]. split.
159
+ + rewrite V1. cbn [fold_left].
160
+ assert (Wacc : wget w1 acc = f (wget w acc) (wl w l)).
161
+ { unfold w1. rewrite wget_wnext by (unfold ok_cell in Ha; lia). rewrite Nat.eqb_refl, Eacc. reflexivity. }
162
+ rewrite Wacc, (Hlv l2 (or_introl eq_refl)).
163
+ assert (Fe : forall ys a, (forall y, In y ys -> wl w1 y = wl w y) ->
164
+ fold_left (fun a l' => f a (wl w1 l')) ys a = fold_left (fun a l' => f a (wl w l')) ys a).
165
+ { induction ys as [|y ys IHy]; intros a Hy; [reflexivity|]. cbn [fold_left].
166
+ rewrite (Hy y (or_introl eq_refl)). apply IHy. intros y' Hy'. apply Hy. right. exact Hy'. }
167
+ apply Fe. intros y Hy. apply Hlv. right. exact Hy.
168
+ + intros c H1 H2. rewrite (U1 c H1 H2). unfold w1. rewrite wget_wnext by (unfold ok_cell in Ha; lia).
169
+ rewrite (proj2 (Nat.eqb_neq _ _) H2). reflexivity.
170
+ Qed.
171
+
172
+ Lemma chain_run : forall ls d acc w,
173
+ ls <> [] -> length w = W -> ok_cell d -> ok_cell acc -> (forall l, In l ls -> fst l <> acc) ->
174
+ let w' := wrun (chain g ls d acc) w in
175
+ length w' = W
176
+ /\ wget w' d = fold_left (fun a l => f a (wl w l)) (tl ls) (wl w (hd (SINK, true) ls))
177
+ /\ (forall c, c <> d -> c <> acc -> wget w' c = wget w c).
178
+ Proof.
179
+ intros ls d acc w Hne Hw Hd Ha Hl.
180
+ destruct ls as [|l0 [|l1 [|l2 t]]]; [contradiction | | |].
181
+ - cbn [chain wrun hd tl fold_left]. unfold wexec. rewrite wval_copy. cbn [ao_of gCOPY].
182
+ split; [rewrite length_wnext; exact Hw|].
183
+ split; [rewrite wget_wnext by (unfold ok_cell in Hd; lia); rewrite Nat.eqb_refl; reflexivity|].
184
+ intros c H1 H2. rewrite wget_wnext by (unfold ok_cell in Hd; lia). rewrite (proj2 (Nat.eqb_neq _ _) H1). reflexivity.
185
+ - cbn [chain wrun hd tl fold_left]. unfold wexec. rewrite Hgo, Hg.
186
+ split; [rewrite length_wnext; exact Hw|].
187
+ split; [rewrite wget_wnext by (unfold ok_cell in Hd; lia); rewrite Nat.eqb_refl; reflexivity|].
188
+ intros c H1 H2. rewrite wget_wnext by (unfold ok_cell in Hd; lia). rewrite (proj2 (Nat.eqb_neq _ _) H1). reflexivity.
189
+ - cbn [chain wrun hd tl].
190
+ assert (E1 : wexec (g l0 l1 acc) w = wnext w acc (f (wl w l0) (wl w l1)))
191
+ by (unfold wexec; rewrite Hgo, Hg; reflexivity).
192
+ rewrite E1. set (w1 := wnext w acc (f (wl w l0) (wl w l1))).
193
+ assert (Hw1 : length w1 = W) by (unfold w1; rewrite length_wnext; exact Hw).
194
+ assert (Hlv : forall l', In l' (l2 :: t) -> wl w1 l' = wl w l').
195
+ { intros l' Hin. assert (Hne' : fst l' <> acc) by (apply Hl; right; right; exact Hin).
196
+ unfold wl, wcell. destruct (Nat.eqb (fst l') SINK); [reflexivity|].
197
+ unfold w1. rewrite wget_wnext by (unfold ok_cell in Ha; lia). rewrite (proj2 (Nat.eqb_neq _ _) Hne'). reflexivity. }
198
+ destruct (chain_tail_run acc d t l2 w1 Hw1 Hd Ha ltac:(intros l' Hin; apply Hl; right; right; exact Hin))
199
+ as (L1 & V1 & U1).
200
+ split; [exact L1|]. split.
201
+ + rewrite V1. cbn [fold_left].
202
+ assert (Wacc : wget w1 acc = f (wl w l0) (wl w l1)).
203
+ { unfold w1. rewrite wget_wnext by (unfold ok_cell in Ha; lia). rewrite Nat.eqb_refl. reflexivity. }
204
+ rewrite Wacc, (Hlv l2 (or_introl eq_refl)).
205
+ assert (Fe : forall ys a, (forall y, In y ys -> wl w1 y = wl w y) ->
206
+ fold_left (fun a l' => f a (wl w1 l')) ys a = fold_left (fun a l' => f a (wl w l')) ys a).
207
+ { induction ys as [|y ys IHy]; intros a Hy; [reflexivity|]. cbn [fold_left].
208
+ rewrite (Hy y (or_introl eq_refl)). apply IHy. intros y' Hy'. apply Hy. right. exact Hy'. }
209
+ apply Fe. intros y Hy. apply Hlv. right. exact Hy.
210
+ + intros c H1 H2. rewrite (U1 c H1 H2). unfold w1. rewrite wget_wnext by (unfold ok_cell in Ha; lia).
211
+ rewrite (proj2 (Nat.eqb_neq _ _) H2). reflexivity.
212
+ Qed.
213
+
214
+ End Chain.
215
+
216
+ Lemma chain_wrec : forall g ls d acc,
217
+ (forall x y d', rd_ok (fst x) -> rd_ok (fst y) -> (d' = SINK \/ HO < d') -> wrec (g x y d')) ->
218
+ (forall l, In l ls -> rd_ok (fst l)) -> HO < d -> HO < acc -> Forall wrec (chain g ls d acc).
219
+ Proof.
220
+ intros g ls d acc Hg Hl Hd Ha.
221
+ assert (Hacc : rd_ok acc) by (right; unfold CPY, HO in *; lia).
222
+ assert (T : forall l t, (forall l', In l' (l :: t) -> rd_ok (fst l')) -> Forall wrec (chain_tail g acc l t d)).
223
+ { intros l t. revert l. induction t as [|l' t IH]; intros l H; cbn [chain_tail].
224
+ - constructor; [apply Hg; [exact Hacc | apply H; left; reflexivity | right; exact Hd] | constructor].
225
+ - constructor; [apply Hg; [exact Hacc | apply H; left; reflexivity | right; exact Ha]|].
226
+ apply IH. intros l'' Hin. apply H. right. exact Hin. }
227
+ destruct ls as [|l0 [|l1 [|l2 t]]]; cbn [chain].
228
+ - constructor.
229
+ - constructor; [apply wrec_copy; [apply Hl; left; reflexivity | right; exact Hd] | constructor].
230
+ - constructor; [apply Hg; [apply Hl; left; reflexivity | apply Hl; right; left; reflexivity | right; exact Hd]
231
+ | constructor].
232
+ - constructor; [apply Hg; [apply Hl; left; reflexivity | apply Hl; right; left; reflexivity | right; exact Ha]|].
233
+ apply T. intros l' Hin. apply Hl. right. right. exact Hin.
234
+ Qed.
235
+
236
+ (* ---- chains as conjunctions and disjunctions ----------------------------------------------------------- *)
237
+ Lemma fold_and : forall (h : nat * bool -> bool) ys a, fold_left (fun a l => a && h l) ys a = a && forallb h ys.
238
+ Proof.
239
+ induction ys as [|y ys IH]; intro a; cbn [fold_left forallb]; [rewrite andb_true_r; reflexivity|].
240
+ rewrite IH, andb_assoc. reflexivity.
241
+ Qed.
242
+
243
+ Lemma fold_or : forall (h : nat * bool -> bool) ys a, fold_left (fun a l => a || h l) ys a = a || existsb h ys.
244
+ Proof.
245
+ induction ys as [|y ys IH]; intro a; cbn [fold_left existsb]; [rewrite orb_false_r; reflexivity|].
246
+ rewrite IH, orb_assoc. reflexivity.
247
+ Qed.
248
+
249
+ (* ---- the threshold units ----------------------------------------------------------------------------- *)
250
+ Definition ntrue (w : list bool) (ls : list (nat * bool)) : nat := length (filter (wl w) ls).
251
+
252
+ Lemma ntrue_le : forall w ls, ntrue w ls <= length ls.
253
+ Proof. intros w ls. unfold ntrue. apply filter_length_le. Qed.
254
+
255
+ Lemma forallb_ntrue : forall w ls, forallb (wl w) ls = Nat.eqb (ntrue w ls) (length ls).
256
+ Proof.
257
+ intros w ls. unfold ntrue. induction ls as [|l ls IH]; [reflexivity|].
258
+ cbn [forallb filter length]. destruct (wl w l); cbn [andb length].
259
+ - rewrite IH. reflexivity.
260
+ - assert (length (filter (wl w) ls) <= length ls) by apply filter_length_le.
261
+ symmetry. apply Nat.eqb_neq. lia.
262
+ Qed.
263
+
264
+ Lemma existsb_ntrue : forall w ls, existsb (wl w) ls = Nat.ltb 0 (ntrue w ls).
265
+ Proof.
266
+ intros w ls. unfold ntrue. induction ls as [|l ls IH]; [reflexivity|].
267
+ cbn [existsb filter]. destruct (wl w l); cbn [orb length]; [reflexivity | exact IH].
268
+ Qed.
269
+
270
+ Lemma ntrue_ext : forall w w' ls, (forall l, In l ls -> wl w' l = wl w l) -> ntrue w' ls = ntrue w ls.
271
+ Proof.
272
+ intros w w' ls H. unfold ntrue. f_equal. apply filter_ext_in. exact H.
273
+ Qed.
274
+
275
+ Section Ucomp.
276
+ Variables (W LV : nat) (xc : nat -> nat -> nat).
277
+ (* the three cells of each level lie above the requests, and in the window for the LV levels in use *)
278
+ Hypothesis Hxgt : forall j k, k < 3 -> HO < xc j k.
279
+ Hypothesis Hxlt : forall j k, j < LV -> k < 3 -> xc j k < W.
280
+ Hypothesis Hxinj : forall j k j' k', k < 3 -> k' < 3 -> xc j k = xc j' k' -> j = j' /\ k = k'.
281
+
282
+ (* the scratch cells of the levels from lev on, below LV *)
283
+ Definition scr (lev c : nat) : Prop := exists j k, lev <= j < LV /\ k < 3 /\ c = xc j k.
284
+
285
+ Lemma scr_S : forall lev c, scr (S lev) c -> scr lev c.
286
+ Proof. intros lev c (j & k & H1 & H2 & H3). exists j, k. split; [lia | split; assumption]. Qed.
287
+
288
+ Lemma scr_lev : forall lev k, k < 3 -> ~ scr (S lev) (xc lev k).
289
+ Proof. intros lev k Hk (j & k' & H1 & H2 & H3). destruct (Hxinj lev k j k' Hk H2 H3) as [E _]. lia. Qed.
290
+
291
+ Lemma ucomp_run : forall ls t d acc lev w,
292
+ length w = W -> ok_cell W d -> ok_cell W acc -> ~ scr lev d -> ~ scr lev acc ->
293
+ (forall l, In l ls -> fst l <> acc /\ ~ scr lev (fst l)) ->
294
+ ((1 < t < Z.of_nat (length ls))%Z -> lev + length ls <= LV + 2) ->
295
+ let w' := wrun (ucomp xc t ls d acc lev) w in
296
+ length w' = W /\ wget w' d = Z.leb t (Z.of_nat (ntrue w ls))
297
+ /\ (forall c, c <> d -> c <> acc -> ~ scr lev c -> wget w' c = wget w c).
298
+ Proof.
299
+ induction ls as [|l0 rest IH]; intros t d acc lev w Hw Hd Ha Hsd Hsa Hl Hlev.
300
+ - cbn [ucomp length]. unfold ntrue. cbn [filter length Z.of_nat].
301
+ destruct (Z.leb_spec t 0) as [Ht|Ht].
302
+ + cbn [wrun]. unfold wexec. rewrite wval_const. cbn [ao_of gCONST gOR gAND].
303
+ split; [rewrite length_wnext; exact Hw|].
304
+ split; [rewrite wget_wnext by (unfold ok_cell in Hd; lia); rewrite Nat.eqb_refl;
305
+ first [reflexivity | symmetry; apply Z.leb_le; lia | symmetry; apply Z.leb_gt; lia]|].
306
+ intros c H1 _ _. rewrite wget_wnext by (unfold ok_cell in Hd; lia). rewrite (proj2 (Nat.eqb_neq _ _) H1). reflexivity.
307
+ + rewrite (proj2 (Z.ltb_lt 0 t) Ht). cbn [wrun]. unfold wexec. rewrite wval_const. cbn [ao_of gCONST gOR gAND].
308
+ split; [rewrite length_wnext; exact Hw|].
309
+ split; [rewrite wget_wnext by (unfold ok_cell in Hd; lia); rewrite Nat.eqb_refl;
310
+ first [reflexivity | symmetry; apply Z.leb_le; lia | symmetry; apply Z.leb_gt; lia]|].
311
+ intros c H1 _ _. rewrite wget_wnext by (unfold ok_cell in Hd; lia). rewrite (proj2 (Nat.eqb_neq _ _) H1). reflexivity.
312
+ - set (k := length (l0 :: rest)).
313
+ assert (Hn : ntrue w (l0 :: rest) <= k) by apply ntrue_le.
314
+ assert (Hla : forall l, In l (l0 :: rest) -> fst l <> acc) by (intros l Hin; apply Hl; exact Hin).
315
+ cbn [ucomp]. fold k.
316
+ destruct (Z.leb_spec t 0) as [Ht0|Ht0].
317
+ { cbn [wrun]. unfold wexec. rewrite wval_const. cbn [ao_of gCONST gOR gAND].
318
+ split; [rewrite length_wnext; exact Hw|].
319
+ split; [rewrite wget_wnext by (unfold ok_cell in Hd; lia); rewrite Nat.eqb_refl;
320
+ first [reflexivity | symmetry; apply Z.leb_le; lia | symmetry; apply Z.leb_gt; lia]|].
321
+ intros c H1 _ _. rewrite wget_wnext by (unfold ok_cell in Hd; lia). rewrite (proj2 (Nat.eqb_neq _ _) H1). reflexivity. }
322
+ destruct (Z.ltb_spec (Z.of_nat k) t) as [Htk|Htk].
323
+ { cbn [wrun]. unfold wexec. rewrite wval_const. cbn [ao_of gCONST gOR gAND].
324
+ split; [rewrite length_wnext; exact Hw|].
325
+ split; [rewrite wget_wnext by (unfold ok_cell in Hd; lia); rewrite Nat.eqb_refl;
326
+ first [reflexivity | symmetry; apply Z.leb_le; lia | symmetry; apply Z.leb_gt; lia]|].
327
+ intros c H1 _ _. rewrite wget_wnext by (unfold ok_cell in Hd; lia). rewrite (proj2 (Nat.eqb_neq _ _) H1). reflexivity. }
328
+ destruct (Z.eqb_spec t 1) as [Ht1|Ht1].
329
+ { (* a disjunction *)
330
+ destruct (chain_run W gOR orb (fun x y d' w' => wval_or w' x y d') (fun x y d' => proj1 (proj2 (ao_gates x y d' true)))
331
+ (l0 :: rest) d acc w ltac:(discriminate) Hw Hd Ha Hla) as (L1 & V1 & U1).
332
+ split; [exact L1|]. split.
333
+ - rewrite V1. cbn [hd tl]. rewrite fold_or.
334
+ replace (wl w l0 || existsb (wl w) rest) with (existsb (wl w) (l0 :: rest)) by reflexivity.
335
+ rewrite existsb_ntrue, Ht1. destruct (Nat.ltb_spec 0 (ntrue w (l0 :: rest))); symmetry;
336
+ [apply Z.leb_le | apply Z.leb_gt]; lia.
337
+ - intros c H1 H2 _. exact (U1 c H1 H2). }
338
+ destruct (Z.eqb_spec t (Z.of_nat k)) as [Htk'|Htk'].
339
+ { (* a conjunction *)
340
+ destruct (chain_run W gAND andb (fun x y d' w' => wval_and w' x y d') (fun x y d' => proj1 (ao_gates x y d' true))
341
+ (l0 :: rest) d acc w ltac:(discriminate) Hw Hd Ha Hla) as (L1 & V1 & U1).
342
+ split; [exact L1|]. split.
343
+ - rewrite V1. cbn [hd tl]. rewrite fold_and.
344
+ replace (wl w l0 && forallb (wl w) rest) with (forallb (wl w) (l0 :: rest)) by reflexivity.
345
+ rewrite forallb_ntrue, Htk'. fold k.
346
+ destruct (Nat.eqb_spec (ntrue w (l0 :: rest)) k); symmetry; [apply Z.leb_le | apply Z.leb_gt]; lia.
347
+ - intros c H1 H2 _. exact (U1 c H1 H2). }
348
+ (* at least t of l0 :: rest, 1 < t < k *)
349
+ assert (Hlv : lev < LV) by (specialize (Hlev ltac:(fold k; lia)); fold k in Hlev; unfold k in *; cbn [length] in *; lia).
350
+ assert (Hx0 : ok_cell W (xc lev 0)) by (split; [apply Hxgt | apply Hxlt]; lia).
351
+ assert (Hx1 : ok_cell W (xc lev 1)) by (split; [apply Hxgt | apply Hxlt]; lia).
352
+ assert (Hx2 : ok_cell W (xc lev 2)) by (split; [apply Hxgt | apply Hxlt]; lia).
353
+ assert (Hlev' : forall t', (1 < t' < Z.of_nat (length rest))%Z -> S lev + length rest <= LV + 2).
354
+ { intros t' Ht'. specialize (Hlev ltac:(fold k; lia)). unfold k in Hlev. cbn [length] in Hlev. lia. }
355
+ assert (N01 : xc lev 0 <> xc lev 1) by (intro E; apply Hxinj in E; lia).
356
+ assert (N02 : xc lev 0 <> xc lev 2) by (intro E; apply Hxinj in E; lia).
357
+ assert (N12 : xc lev 1 <> xc lev 2) by (intro E; apply Hxinj in E; lia).
358
+ assert (Sx : forall kk, kk < 3 -> scr lev (xc lev kk)) by (intros kk Hkk; exists lev, kk; repeat split; lia).
359
+ assert (Hlr : forall l, In l rest -> fst l <> xc lev 0 /\ fst l <> xc lev 1 /\ fst l <> xc lev 2
360
+ /\ ~ scr (S lev) (fst l)).
361
+ { intros l Hin. destruct (Hl l (or_intror Hin)) as [_ Hs].
362
+ split; [intro E; apply Hs; rewrite E; apply Sx; lia|].
363
+ split; [intro E; apply Hs; rewrite E; apply Sx; lia|].
364
+ split; [intro E; apply Hs; rewrite E; apply Sx; lia|].
365
+ intro H. apply Hs. apply scr_S. exact H. }
366
+ destruct (IH t (xc lev 0) (xc lev 0) (S lev) w Hw Hx0 Hx0 (scr_lev lev 0 ltac:(lia)) (scr_lev lev 0 ltac:(lia))
367
+ ltac:(intros l Hin; destruct (Hlr l Hin) as (A0 & _ & _ & A3); split; assumption) (Hlev' t))
368
+ as (L1 & V1 & U1).
369
+ set (w1 := wrun (ucomp xc t rest (xc lev 0) (xc lev 0) (S lev)) w) in *.
370
+ destruct (IH (t - 1)%Z (xc lev 1) (xc lev 1) (S lev) w1 L1 Hx1 Hx1 (scr_lev lev 1 ltac:(lia)) (scr_lev lev 1 ltac:(lia))
371
+ ltac:(intros l Hin; destruct (Hlr l Hin) as (_ & A1 & _ & A3); split; assumption) (Hlev' (t - 1)%Z))
372
+ as (L2 & V2 & U2).
373
+ set (w2 := wrun (ucomp xc (t - 1) rest (xc lev 1) (xc lev 1) (S lev)) w1) in *.
374
+ (* the literals keep their values over the two sub-units *)
375
+ assert (Hcell : forall c, c <> xc lev 0 -> c <> xc lev 1 -> ~ scr (S lev) c -> wget w2 c = wget w c).
376
+ { intros c H0 H1 H2. rewrite (U2 c H1 H1 H2), (U1 c H0 H0 H2). reflexivity. }
377
+ assert (Hwl : forall l, In l (l0 :: rest) -> wl w2 l = wl w l /\ wl w1 l = wl w l).
378
+ { intros l Hin. destruct (Hl l Hin) as [_ Hs].
379
+ assert (E0 : fst l <> xc lev 0) by (intro E; apply Hs; rewrite E; apply Sx; lia).
380
+ assert (E1 : fst l <> xc lev 1) by (intro E; apply Hs; rewrite E; apply Sx; lia).
381
+ assert (E2 : ~ scr (S lev) (fst l)) by (intro H; apply Hs; apply scr_S; exact H).
382
+ unfold wl, wcell. destruct (Nat.eqb (fst l) SINK); [split; reflexivity|].
383
+ rewrite (Hcell (fst l) E0 E1 E2), (U1 (fst l) E0 E0 E2). split; reflexivity. }
384
+ assert (Nr : ntrue w1 rest = ntrue w rest)
385
+ by (apply ntrue_ext; intros l Hin; exact (proj2 (Hwl l (or_intror Hin)))).
386
+ rewrite Nr in V2.
387
+ assert (W0 : wget w2 (xc lev 0) = Z.leb t (Z.of_nat (ntrue w rest)))
388
+ by (rewrite (U2 (xc lev 0) N01 N01 (scr_lev lev 0 ltac:(lia))); exact V1).
389
+ rewrite !wrun_app. cbn [wrun]. fold w1 w2.
390
+ assert (E3 : wexec (gAND l0 (xc lev 1, true) (xc lev 2)) w2
391
+ = wnext w2 (xc lev 2) (wl w2 l0 && wl w2 (xc lev 1, true)))
392
+ by (unfold wexec; rewrite wval_and; reflexivity).
393
+ rewrite E3. set (w3 := wnext w2 (xc lev 2) (wl w2 l0 && wl w2 (xc lev 1, true))).
394
+ assert (Hw3 : length w3 = W) by (unfold w3; rewrite length_wnext; exact L2).
395
+ assert (Rx : forall c, ok_cell W c -> wl w2 (c, true) = wget w2 c).
396
+ { intros c Hc. unfold wl, wcell. cbn [fst snd].
397
+ replace (Nat.eqb c SINK) with false by (symmetry; apply Nat.eqb_neq; unfold ok_cell, SINK, HO in *; lia).
398
+ reflexivity. }
399
+ assert (E4 : wexec (gOR (xc lev 0, true) (xc lev 2, true) d) w3
400
+ = wnext w3 d (wl w3 (xc lev 0, true) || wl w3 (xc lev 2, true)))
401
+ by (unfold wexec; rewrite wval_or; reflexivity).
402
+ rewrite E4.
403
+ assert (Rx3 : forall c, ok_cell W c -> wl w3 (c, true) = wget w3 c).
404
+ { intros c Hc. unfold wl, wcell. cbn [fst snd].
405
+ replace (Nat.eqb c SINK) with false by (symmetry; apply Nat.eqb_neq; unfold ok_cell, SINK, HO in *; lia).
406
+ reflexivity. }
407
+ rewrite (Rx3 _ Hx0), (Rx3 _ Hx2).
408
+ assert (W30 : wget w3 (xc lev 0) = Z.leb t (Z.of_nat (ntrue w rest))).
409
+ { unfold w3. rewrite wget_wnext by (unfold ok_cell in Hx2; lia). rewrite (proj2 (Nat.eqb_neq _ _) N02). exact W0. }
410
+ assert (W32 : wget w3 (xc lev 2) = wl w l0 && Z.leb (t - 1) (Z.of_nat (ntrue w rest))).
411
+ { unfold w3. rewrite wget_wnext by (unfold ok_cell in Hx2; lia). rewrite Nat.eqb_refl, (Rx _ Hx1), V2.
412
+ rewrite (proj1 (Hwl l0 (or_introl eq_refl))). reflexivity. }
413
+ rewrite W30, W32.
414
+ split; [rewrite length_wnext; exact Hw3|]. split.
415
+ + rewrite wget_wnext by (unfold ok_cell in Hd; lia). rewrite Nat.eqb_refl.
416
+ unfold ntrue. cbn [filter]. destruct (wl w l0); cbn [length andb orb].
417
+ * rewrite Nat2Z.inj_succ. fold (ntrue w rest).
418
+ destruct (Z.leb_spec t (Z.of_nat (ntrue w rest))), (Z.leb_spec (t - 1) (Z.of_nat (ntrue w rest))),
419
+ (Z.leb_spec t (Z.succ (Z.of_nat (ntrue w rest)))); cbn [orb]; lia.
420
+ * fold (ntrue w rest). rewrite orb_false_r. reflexivity.
421
+ + intros c H1 H2 H3.
422
+ assert (C0 : c <> xc lev 0) by (intro E; apply H3; rewrite E; apply Sx; lia).
423
+ assert (C1 : c <> xc lev 1) by (intro E; apply H3; rewrite E; apply Sx; lia).
424
+ assert (C2 : c <> xc lev 2) by (intro E; apply H3; rewrite E; apply Sx; lia).
425
+ rewrite wget_wnext by (unfold ok_cell in Hd; lia). rewrite (proj2 (Nat.eqb_neq _ _) H1).
426
+ unfold w3. rewrite wget_wnext by (unfold ok_cell in Hx2; lia). rewrite (proj2 (Nat.eqb_neq _ _) C2).
427
+ apply Hcell; [exact C0 | exact C1 | intro H; apply H3; apply scr_S; exact H].
428
+ Qed.
429
+
430
+ Lemma ucomp_wrec : forall ls t d acc lev, HO < d -> HO < acc -> (forall l, In l ls -> rd_ok (fst l)) ->
431
+ Forall wrec (ucomp xc t ls d acc lev).
432
+ Proof.
433
+ induction ls as [|l0 rest IH]; intros t d acc lev Hd Ha Hl; cbn [ucomp].
434
+ - cbn [length]. destruct (Z.leb t 0); [constructor; [apply wrec_const; right; exact Hd | constructor]|].
435
+ destruct (Z.ltb (Z.of_nat 0) t); [constructor; [apply wrec_const; right; exact Hd | constructor]|].
436
+ destruct (Z.eqb t 1); [cbn [chain]; constructor|].
437
+ destruct (Z.eqb t (Z.of_nat 0)); cbn [chain]; constructor.
438
+ - assert (Hxo : forall kk, kk < 3 -> HO < xc lev kk) by (intros kk Hk; apply Hxgt; exact Hk).
439
+ destruct (Z.leb t 0); [constructor; [apply wrec_const; right; exact Hd | constructor]|].
440
+ destruct (Z.ltb (Z.of_nat (length (l0 :: rest))) t); [constructor; [apply wrec_const; right; exact Hd | constructor]|].
441
+ destruct (Z.eqb t 1); [apply chain_wrec; [exact wrec_or | exact Hl | exact Hd | exact Ha]|].
442
+ destruct (Z.eqb t (Z.of_nat (length (l0 :: rest)))); [apply chain_wrec; [exact wrec_and | exact Hl | exact Hd | exact Ha]|].
443
+ apply Forall_app. split; [apply IH; [apply Hxo; lia | apply Hxo; lia | intros l Hin; apply Hl; right; exact Hin]|].
444
+ apply Forall_app. split; [apply IH; [apply Hxo; lia | apply Hxo; lia | intros l Hin; apply Hl; right; exact Hin]|].
445
+ constructor; [apply wrec_and; [apply Hl; left; reflexivity
446
+ | right; cbn [fst]; pose proof (Hxo 1 ltac:(lia)); unfold CPY, HO in *; lia
447
+ | right; apply Hxo; lia]|].
448
+ constructor; [|constructor].
449
+ apply wrec_or; [right; cbn [fst]; pose proof (Hxo 0 ltac:(lia)); unfold CPY, HO in *; lia
450
+ | right; cbn [fst]; pose proof (Hxo 2 ltac:(lia)); unfold CPY, HO in *; lia | right; exact Hd].
451
+ Qed.
452
+
453
+ End Ucomp.
rocq/_CoqProject CHANGED
@@ -26,3 +26,20 @@ HostSem.v
26
  Device.v
27
  Pstar.v
28
  ExtractHost.v
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  Device.v
27
  Pstar.v
28
  ExtractHost.v
29
+ HostIP.v
30
+ View.v
31
+ Stored.v
32
+ WinRun.v
33
+ ViewOps.v
34
+ WinPar.v
35
+ StoredStep.v
36
+ StoredBoot.v
37
+ StoredDev.v
38
+ StoredPass.v
39
+ StoredOk.v
40
+ StoredRun.v
41
+ StoredWbr.v
42
+ StoredMain.v
43
+ StoredImage.v
44
+ StoredWidth.v
45
+ ExtractStored.v
rocq/extract/dumpstored.ml ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* writes the image of the stored host defined in Stored.v, extracted by ExtractStored.v, as bytes, most
2
+ significant bit first: dumpstored A W PATH *)
3
+ let () =
4
+ let a = int_of_string Sys.argv.(1) and w = int_of_string Sys.argv.(2) in
5
+ let bits = Storednet.stored_bits a w in
6
+ let oc = open_out_bin Sys.argv.(3) in
7
+ let rec go acc k = function
8
+ | [] -> if k > 0 then output_byte oc (acc lsl (8 - k))
9
+ | b :: t ->
10
+ let acc = 2 * acc + (if b then 1 else 0) in
11
+ if k = 7 then (output_byte oc acc; go 0 0 t) else go acc (k + 1) t in
12
+ go 0 0 bits;
13
+ close_out oc
src/paper.py CHANGED
@@ -1077,6 +1077,26 @@ def host_extraction(widths=(8, 9, 10)):
1077
  return dict(members=members, identical=all(m['identical'] for m in members))
1078
 
1079
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1080
  def pstar_images():
1081
  """The memory images m* and m_P written in rocq/Pstar.v, against those of src/host.py."""
1082
  from host import M_P, M_STAR
@@ -1138,16 +1158,18 @@ def main_rocq():
1138
  print(out.stdout)
1139
  return 1
1140
  host = host_extraction()
 
1141
  images = pstar_images()
1142
  ext = subprocess.run([sys.executable, os.path.join(REPO, 'src', 'twohead.py'), 'net', 'extract'],
1143
  capture_output=True, text=True)
1144
  identical = (ext.returncode == 0 and '"identical": true' in ext.stdout and host['identical']
1145
- and all(images.values()))
1146
  files = [l for l in open(os.path.join(ROCQ, '_CoqProject')).read().split() if l.endswith('.v')]
1147
  lines = sum(len(open(os.path.join(ROCQ, f)).read().splitlines()) for f in files)
1148
  res = dict(rocq=version.splitlines()[0], files=len(files), lines=lines,
1149
  build_seconds=round(build, 1), theorems={n: 'closed' for n in names},
1150
- host_extraction=host, pstar_images=images, extraction_identical=identical)
 
1151
  rec = json.load(open(RECORD)) if os.path.exists(RECORD) else {}
1152
  rec.update(res)
1153
  json.dump(rec, open(RECORD, 'w'), indent=1)
 
1077
  return dict(members=members, identical=all(m['identical'] for m in members))
1078
 
1079
 
1080
+ def stored_extraction(widths=(8, 9)):
1081
+ """The stored host of rocq/Stored.v, extracted to OCaml, against the image src/twohead.py builds."""
1082
+ import twohead
1083
+ ex = os.path.join(ROCQ, 'extract')
1084
+ subprocess.run(['ocamlfind', 'ocamlopt', '-package', 'stdlib', 'storednet.mli', 'storednet.ml',
1085
+ 'dumpstored.ml', '-o', 'dumpstored'], cwd=ex, check=True)
1086
+ out = os.path.join(ex, 'stored_rocq.bin')
1087
+ members = []
1088
+ for A in widths:
1089
+ S = twohead.build_stored(A)
1090
+ subprocess.run([os.path.join(ex, 'dumpstored'), str(A), str(S['w']), out], check=True)
1091
+ theirs = open(out, 'rb').read()
1092
+ members.append(dict(A=A, w=S['w'], records=len(S['recs']), bytes=len(S['image']),
1093
+ identical=theirs == S['image'], sha256=hashlib.sha256(theirs).hexdigest()))
1094
+ for f in os.listdir(ex):
1095
+ if not f.endswith(('.ml', '.mli')):
1096
+ os.remove(os.path.join(ex, f))
1097
+ return dict(members=members, identical=all(m['identical'] for m in members))
1098
+
1099
+
1100
  def pstar_images():
1101
  """The memory images m* and m_P written in rocq/Pstar.v, against those of src/host.py."""
1102
  from host import M_P, M_STAR
 
1158
  print(out.stdout)
1159
  return 1
1160
  host = host_extraction()
1161
+ stored = stored_extraction()
1162
  images = pstar_images()
1163
  ext = subprocess.run([sys.executable, os.path.join(REPO, 'src', 'twohead.py'), 'net', 'extract'],
1164
  capture_output=True, text=True)
1165
  identical = (ext.returncode == 0 and '"identical": true' in ext.stdout and host['identical']
1166
+ and stored['identical'] and all(images.values()))
1167
  files = [l for l in open(os.path.join(ROCQ, '_CoqProject')).read().split() if l.endswith('.v')]
1168
  lines = sum(len(open(os.path.join(ROCQ, f)).read().splitlines()) for f in files)
1169
  res = dict(rocq=version.splitlines()[0], files=len(files), lines=lines,
1170
  build_seconds=round(build, 1), theorems={n: 'closed' for n in names},
1171
+ host_extraction=host, stored_extraction=stored, pstar_images=images,
1172
+ extraction_identical=identical)
1173
  rec = json.load(open(RECORD)) if os.path.exists(RECORD) else {}
1174
  rec.update(res)
1175
  json.dump(rec, open(RECORD, 'w'), indent=1)
src/twohead.py CHANGED
@@ -1,7 +1,6 @@
1
  """The ring machine M^alpha_{K,S,L}: the organism, the netlist N^alpha_{K,S,L}, and the host stored in it."""
2
  import argparse
3
  import hashlib
4
- import heapq
5
  import json
6
  import math
7
  import os
@@ -891,12 +890,14 @@ def main_net():
891
  net_update_record('lockstep', res)
892
  print(json.dumps(res, indent=1))
893
  elif cmd == 'lev':
894
- # the rows of Lev(N^12_{3,S,L}), affine in S and L, and the noise a generation of the stored
895
- # host survives with probability 0.999 by Proposition 5.5 and Theorem 5.9(ii)
896
  t0 = time.time()
 
 
897
  pts = []
898
  for S, L in ((2, 3), (3, 3), (2, 5), (3, 5), (4, 9), (6, 4)):
899
- units, nxt, lay = build_net(3, S, L, 12)
900
  d, rows = lev_rows(units, nxt, lay.n)
901
  pts.append(dict(S=S, L=L, depth=d, rows=rows))
902
  print(pts[-1], flush=True)
@@ -904,7 +905,6 @@ def main_net():
904
  cS, cL = r0[(3, 3)] - r0[(2, 3)], (r0[(2, 5)] - r0[(2, 3)]) // 2
905
  c0 = r0[(2, 3)] - 2 * cS - 3 * cL
906
  affine = all(c0 + cS * p['S'] + cL * p['L'] == p['rows'] for p in pts)
907
- run = json.load(open(STORED_RECORD))['run']
908
  M = c0 + cS * run['S'] + cL * run['L']
909
  T = run['steps_expected']
910
 
@@ -917,7 +917,7 @@ def main_net():
917
  else:
918
  hi = mid
919
  return lo
920
- res = dict(K=3, alpha=12, members=pts, rows=dict(constant=c0, per_slot=cS, per_cell=cL),
921
  affine=affine, depth=pts[0]['depth'], stored_member=dict(S=run['S'], L=run['L'], rows=M,
922
  steps=T), s_max_0999={str(r): round(s_max(r), 4) for r in (1, 3, 5)},
923
  seconds=round(time.time() - t0, 1))
@@ -1011,15 +1011,13 @@ def pc_bit(t, A=8):
1011
  # records over named cells
1012
  # ---------------------------------------------------------------------------
1013
 
 
 
 
1014
  class Prog:
1015
  def __init__(self):
1016
  self.recs = [] # (a0, w0, a1, w1, beta, ao), cells by name
1017
  self.ends = {} # record -> the unit of the host whose value it writes
1018
- self.uid = 0
1019
-
1020
- def tmp(self):
1021
- self.uid += 1
1022
- return ('t', self.uid)
1023
 
1024
  def emit(self, a0, w0, a1, w1, beta, ao):
1025
  assert -8 <= beta <= 7
@@ -1043,145 +1041,76 @@ class Prog:
1043
  (self.OR if v else self.AND)((x, True), (x, False), dst)
1044
 
1045
  def XOR(self, x, y, dst):
1046
- t1, t2 = self.tmp(), self.tmp()
1047
  self.OR(x, y, t1)
1048
  self.OR((x[0], not x[1]), (y[0], not y[1]), t2)
1049
  self.AND((t1, True), (t2, True), dst)
1050
 
1051
  def MUX(self, s, a, b, dst):
1052
  """dst <- s ? a : b, s a cell, a and b literals."""
1053
- t1, t2 = self.tmp(), self.tmp()
1054
  self.AND((s, True), a, t1)
1055
  self.AND((s, False), b, t2)
1056
  self.OR((t1, True), (t2, True), dst)
1057
 
1058
- def chain(self, kind, lits, dst, before=None):
1059
- """Chain the literals by 'and' or 'or' into dst, written once, last."""
1060
- assert lits
1061
- if len(lits) == 1:
1062
- if before:
1063
- before(0)
1064
  self.COPY(lits[0], dst)
1065
  return
1066
- g = self.AND if kind == 'and' else self.OR
1067
- acc = self.tmp()
1068
- if before:
1069
- before(0); before(1)
1070
- if len(lits) == 2:
1071
  g(lits[0], lits[1], dst)
1072
  return
1073
  g(lits[0], lits[1], acc)
1074
- for i in range(2, len(lits)):
1075
- if before:
1076
- before(i)
1077
- g((acc, True), lits[i], dst if i == len(lits) - 1 else acc)
1078
 
1079
- def threshold(self, t, lits, dst):
1080
- """at least t of the literals, by T_t(x1..xk) = T_t(x2..xk) or (x1 and T_{t-1}(x2..xk))."""
 
1081
  k = len(lits)
1082
  if t <= 0:
1083
- self.CONST(1, dst); return
1084
- if t > k:
1085
- self.CONST(0, dst); return
1086
- if t == 1:
1087
- self.chain('or', lits, dst); return
1088
- if t == k:
1089
- self.chain('and', lits, dst); return
1090
- a, b = self.tmp(), self.tmp()
1091
- self.threshold(t, lits[1:], a)
1092
- self.threshold(t - 1, lits[1:], b)
1093
- c = self.tmp()
1094
- self.AND(lits[0], (b, True), c)
1095
- self.OR((a, True), (c, True), dst)
 
 
 
 
 
1096
 
1097
 
1098
  def compile_host(P, A=8):
1099
- """The records of one step of H_A; state bits are cells ('s', i)."""
 
1100
  n, units, nxt = host_units(A)
1101
- cons = {}
1102
- for u, (_, ins) in enumerate(units):
1103
- for s, _w in ins:
1104
- if s >= n:
1105
- cons.setdefault(s - n, []).append(u)
1106
  is_next = {nxt[i] - n: i for i in range(n)}
1107
  assert len(is_next) == n and all(v >= n for v in nxt)
1108
- fusable = {u for u, c in cons.items() if len(c) == 1}
1109
- done, cell = set(), {}
1110
-
1111
- def cell_of(s):
1112
- return ('s', s) if s < n else cell[s - n]
1113
-
1114
- def ensure_ancestors(u):
1115
- for s, _w in units[u][1]:
1116
- if s >= n:
1117
- v = s - n
1118
- if v in fusable:
1119
- ensure_ancestors(v)
1120
- else:
1121
- need(v)
1122
-
1123
- def need(u):
1124
- if u in done:
1125
- return
1126
- assert u not in is_next, 'a next value is read before the state is written'
1127
- ensure_ancestors(u)
1128
- cell[u] = P.tmp()
1129
- emit_unit(u, cell[u])
1130
- done.add(u)
1131
-
1132
- def fused(v):
1133
- if v not in done:
1134
- cell[v] = P.tmp()
1135
- emit_unit(v, cell[v])
1136
- done.add(v)
1137
-
1138
- def emit_unit(u, dst):
1139
- b, ins = units[u]
1140
- k = len(ins)
1141
- t = sum(1 for _, w in ins if w < 0) - b
1142
- lits = [None] * k
1143
-
1144
- def before(i):
1145
- s = ins[i][0]
1146
- if s >= n and (s - n) in fusable:
1147
- fused(s - n)
1148
- lits[i] = (cell_of(s), ins[i][1] > 0)
1149
- if t <= 0 or t > k:
1150
- P.CONST(1 if t <= 0 else 0, dst)
1151
- elif 1 < t < k:
1152
- for i in range(k):
1153
- before(i)
1154
- P.threshold(t, lits, dst)
1155
- else:
1156
- _chain_lazy(P, 'and' if t == k else 'or', lits, dst, before)
1157
  P.ends[len(P.recs) - 1] = u
1158
-
1159
- order_next = [nxt[pc_bit(t, A)] - n for t in range(A)] + [nxt[A] - n] + \
1160
- [nxt[mem_bit(j, t, A)] - n for j in range(1 << A) for t in range(A)]
1161
- for u in order_next: # stage A: everything the next values read
1162
- ensure_ancestors(u)
1163
- for u in order_next: # stage B: the next values, in place
1164
- emit_unit(u, ('s', is_next[u]))
1165
- done.add(u)
1166
  return n, units, nxt
1167
 
1168
 
1169
- def _chain_lazy(P, kind, lits, dst, before):
1170
- k = len(lits)
1171
- if k == 1:
1172
- before(0)
1173
- P.COPY(lits[0], dst)
1174
- return
1175
- g = P.AND if kind == 'and' else P.OR
1176
- before(0); before(1)
1177
- if k == 2:
1178
- g(lits[0], lits[1], dst)
1179
- return
1180
- acc = P.tmp()
1181
- g(lits[0], lits[1], acc)
1182
- for i in range(2, k):
1183
- before(i)
1184
- g((acc, True), lits[i], dst if i == k - 1 else acc)
1185
 
1186
 
1187
  # ---------------------------------------------------------------------------
@@ -1192,37 +1121,43 @@ def mem_cell(j, t, A=8):
1192
  return ('s', mem_bit(j, t, A))
1193
 
1194
 
1195
- def word_is_one(P, j, A=8):
1196
- """[memory word j == 1]"""
1197
- dst = P.tmp()
1198
  lits = [(mem_cell(j, 0, A), True)] + [(mem_cell(j, t, A), False) for t in range(1, A)]
1199
- P.chain('and', lits, dst)
1200
  return dst
1201
 
1202
 
 
 
 
 
 
 
1203
  def compile_device(P, A=8, w=CW):
1204
  io = SR.io_cells(A)
1205
  cnt = [('d', 'cnt', i) for i in range(w)]
1206
  lim = [('d', 'lim', i) for i in range(w)]
1207
  dest = ('d', 'dest')
1208
- wr = word_is_one(P, io['c_wr'], A)
1209
- rd = word_is_one(P, io['c_rd'], A)
1210
- rw = word_is_one(P, io['c_rw'], A)
 
1211
  # [cnt == lim]
1212
- eq = P.tmp()
1213
  xs = []
1214
  for i in range(w):
1215
- e = P.tmp()
1216
- a1, a0 = P.tmp(), P.tmp()
1217
  P.AND((cnt[i], True), (lim[i], True), a1)
1218
  P.AND((cnt[i], False), (lim[i], False), a0)
1219
  P.OR((a1, True), (a0, True), e)
1220
  xs.append((e, True))
1221
- P.chain('and', xs, eq)
1222
- eot = P.tmp() # the end of the recipe is known after the rewind
1223
  P.AND((eq, True), (dest, True), eot)
1224
  # (i) the low byte of R_out, most significant bit first, under the arm or under the copy head
1225
- ca, cc = P.tmp(), P.tmp()
1226
  P.AND((wr, True), (dest, False), ca)
1227
  P.AND((wr, True), (dest, True), cc)
1228
  out, inp, ceot = io['r_out'], io['r_in'], io['c_eot']
@@ -1233,7 +1168,7 @@ def compile_device(P, A=8, w=CW):
1233
  P.COPY((cc, True), ('c', AC))
1234
  for t in range(A):
1235
  P.AND((mem_cell(out, t, A), True), (wr, False), mem_cell(out, t, A))
1236
- g = P.tmp()
1237
  P.AND((rd, True), (eot, False), g)
1238
  # (ii) the byte under the read head into R_in, most significant bit first, each bit moving the head,
1239
  # and its sign bit into the bits above it
@@ -1249,7 +1184,7 @@ def compile_device(P, A=8, w=CW):
1249
  # the counter of bytes read: carries first, then the sum bits
1250
  car = [g]
1251
  for i in range(w - 1):
1252
- c = P.tmp()
1253
  P.AND((car[-1], True), (cnt[i], True), c)
1254
  car.append(c)
1255
  for i in range(w):
@@ -1306,49 +1241,28 @@ HANDOVER_RECORDS = 4
1306
  # allocation and encoding
1307
  # ---------------------------------------------------------------------------
1308
 
1309
- def allocate(recs):
1310
- """Window addresses for the special cells, the state, the registers and the temporaries."""
1311
- fixed = {}
1312
- nxt_addr = FREE
1313
- names = []
1314
- for r in recs:
1315
- for a in (r[0], r[2], r[5]):
1316
- if a is not None and a[0] in ('s', 'd') and a not in fixed:
1317
- names.append(a)
1318
- fixed[a] = None
1319
- for a in sorted(names, key=lambda x: (x[0], x[1:] if x[0] == 'd' else x[1])):
1320
- fixed[a] = nxt_addr
1321
- nxt_addr += 1
1322
- first_w, last_r = {}, {}
1323
- for i, (a0, w0, a1, w1, be, ao) in enumerate(recs):
1324
- for a, w in ((a0, w0), (a1, w1)):
1325
- if w and a[0] == 't':
1326
- assert a in first_w, ('read before written', a)
1327
- last_r[a] = i
1328
- if ao[0] == 't':
1329
- first_w.setdefault(ao, i)
1330
- base = nxt_addr
1331
- busy, free, top = [], [], base # (index after which it is free, cell); free cells
1332
- addr = dict(fixed)
1333
- for name in sorted(first_w, key=lambda x: first_w[x]):
1334
- start_, end = first_w[name], last_r.get(name, first_w[name])
1335
- while busy and busy[0][0] < start_:
1336
- heapq.heappush(free, heapq.heappop(busy)[1])
1337
- if free:
1338
- c = heapq.heappop(free)
1339
- else:
1340
- c, top = top, top + 1
1341
- addr[name] = c
1342
- heapq.heappush(busy, (end, c))
1343
-
1344
- def res(a):
1345
- if a is None:
1346
- return SINK
1347
- if a[0] == 'c':
1348
- return a[1]
1349
- return addr[a]
1350
- out = [(res(a0), w0, res(a1), w1, be, res(ao)) for (a0, w0, a1, w1, be, ao) in recs]
1351
- return out, addr, top
1352
 
1353
 
1354
  def bits_to_bytes(bits):
@@ -1361,7 +1275,8 @@ def bytes_to_bits(data):
1361
 
1362
 
1363
  def check_schedule(recs, lo, hi, n):
1364
- """Check the in-place order of the host block and the live intervals of the temporaries."""
 
1365
  written = {}
1366
  for i in range(lo, hi):
1367
  ao = recs[i][5]
@@ -1369,20 +1284,15 @@ def check_schedule(recs, lo, hi, n):
1369
  assert ao not in written, ('state bit written twice', ao)
1370
  written[ao] = i
1371
  assert len(written) == n, 'a state bit without its next value'
 
1372
  for i in range(lo, hi):
1373
- a0, w0, a1, w1, _, _ = recs[i]
1374
  for a, w in ((a0, w0), (a1, w1)):
1375
  if w and a[0] == 's':
1376
  assert i <= written[a], ('state bit read after it is written', a)
1377
- last_r, last_w = {}, {}
1378
- for i, (a0, w0, a1, w1, _, ao) in enumerate(recs):
1379
- for a, w in ((a0, w0), (a1, w1)):
1380
- if w and a[0] == 't':
1381
- last_r[a] = i
1382
- if ao[0] == 't':
1383
- last_w[ao] = i
1384
- assert all(last_w[t] < last_r.get(t, last_w[t] + 1) or t not in last_r for t in last_w), \
1385
- 'a temporary written after its last read'
1386
  return dict(state_bits_written=len(written))
1387
 
1388
 
@@ -1402,7 +1312,9 @@ def build_stored(A=8):
1402
  compile_device(P, A, w)
1403
  n_device = len(P.recs) - lo - n_host
1404
  compile_handover(P, A)
1405
- recs, addr, top = allocate(P.recs)
 
 
1406
  alpha = (top - 1).bit_length()
1407
  b = 8 + 3 * alpha
1408
  pad = 0
 
1
  """The ring machine M^alpha_{K,S,L}: the organism, the netlist N^alpha_{K,S,L}, and the host stored in it."""
2
  import argparse
3
  import hashlib
 
4
  import json
5
  import math
6
  import os
 
890
  net_update_record('lockstep', res)
891
  print(json.dumps(res, indent=1))
892
  elif cmd == 'lev':
893
+ # the rows of Lev(N^alpha_{3,S,L}) for the window of the stored host, affine in S and L, and the noise
894
+ # a generation of the stored host survives with probability 0.999 by Proposition 5.5 and Theorem 5.9(ii)
895
  t0 = time.time()
896
+ run = json.load(open(STORED_RECORD))['run']
897
+ alpha = (run['record_bits'] - 8) // 3
898
  pts = []
899
  for S, L in ((2, 3), (3, 3), (2, 5), (3, 5), (4, 9), (6, 4)):
900
+ units, nxt, lay = build_net(3, S, L, alpha)
901
  d, rows = lev_rows(units, nxt, lay.n)
902
  pts.append(dict(S=S, L=L, depth=d, rows=rows))
903
  print(pts[-1], flush=True)
 
905
  cS, cL = r0[(3, 3)] - r0[(2, 3)], (r0[(2, 5)] - r0[(2, 3)]) // 2
906
  c0 = r0[(2, 3)] - 2 * cS - 3 * cL
907
  affine = all(c0 + cS * p['S'] + cL * p['L'] == p['rows'] for p in pts)
 
908
  M = c0 + cS * run['S'] + cL * run['L']
909
  T = run['steps_expected']
910
 
 
917
  else:
918
  hi = mid
919
  return lo
920
+ res = dict(K=3, alpha=alpha, members=pts, rows=dict(constant=c0, per_slot=cS, per_cell=cL),
921
  affine=affine, depth=pts[0]['depth'], stored_member=dict(S=run['S'], L=run['L'], rows=M,
922
  steps=T), s_max_0999={str(r): round(s_max(r), 4) for r in (1, 3, 5)},
923
  seconds=round(time.time() - t0, 1))
 
1011
  # records over named cells
1012
  # ---------------------------------------------------------------------------
1013
 
1014
+ MX = (('v', 'm0'), ('v', 'm1')) # the two cells inside a multiplexer or an exclusive or
1015
+
1016
+
1017
  class Prog:
1018
  def __init__(self):
1019
  self.recs = [] # (a0, w0, a1, w1, beta, ao), cells by name
1020
  self.ends = {} # record -> the unit of the host whose value it writes
 
 
 
 
 
1021
 
1022
  def emit(self, a0, w0, a1, w1, beta, ao):
1023
  assert -8 <= beta <= 7
 
1041
  (self.OR if v else self.AND)((x, True), (x, False), dst)
1042
 
1043
  def XOR(self, x, y, dst):
1044
+ t1, t2 = MX
1045
  self.OR(x, y, t1)
1046
  self.OR((x[0], not x[1]), (y[0], not y[1]), t2)
1047
  self.AND((t1, True), (t2, True), dst)
1048
 
1049
  def MUX(self, s, a, b, dst):
1050
  """dst <- s ? a : b, s a cell, a and b literals."""
1051
+ t1, t2 = MX
1052
  self.AND((s, True), a, t1)
1053
  self.AND((s, False), b, t2)
1054
  self.OR((t1, True), (t2, True), dst)
1055
 
1056
+ def chain(self, kind, lits, dst, acc):
1057
+ """The literals joined by 'and' or 'or', accumulated in acc, the last record writing dst."""
1058
+ g = self.AND if kind == 'and' else self.OR
1059
+ k = len(lits)
1060
+ if k == 1:
 
1061
  self.COPY(lits[0], dst)
1062
  return
1063
+ if k == 2:
 
 
 
 
1064
  g(lits[0], lits[1], dst)
1065
  return
1066
  g(lits[0], lits[1], acc)
1067
+ for i in range(2, k - 1):
1068
+ g((acc, True), lits[i], acc)
1069
+ g((acc, True), lits[k - 1], dst)
 
1070
 
1071
+ def unit(self, t, lits, dst, acc, lev):
1072
+ """At least t of the literals, into dst, by T_t(x1..xk) = T_t(x2..xk) or (x1 and T_{t-1}(x2..xk)),
1073
+ the three cells of level lev holding T_t(x2..xk), T_{t-1}(x2..xk) and the conjunction."""
1074
  k = len(lits)
1075
  if t <= 0:
1076
+ self.CONST(1, dst)
1077
+ elif t > k:
1078
+ self.CONST(0, dst)
1079
+ elif t == 1:
1080
+ self.chain('or', lits, dst, acc)
1081
+ elif t == k:
1082
+ self.chain('and', lits, dst, acc)
1083
+ else:
1084
+ a, b, c = (('x', lev, i) for i in range(3))
1085
+ self.unit(t, lits[1:], a, a, lev + 1)
1086
+ self.unit(t - 1, lits[1:], b, b, lev + 1)
1087
+ self.AND(lits[0], (b, True), c)
1088
+ self.OR((a, True), (c, True), dst)
1089
+
1090
+
1091
+ def unit_threshold(bias, ins):
1092
+ """The least number of true literals at which the unit fires."""
1093
+ return sum(1 for _, w in ins if w < 0) - bias
1094
 
1095
 
1096
  def compile_host(P, A=8):
1097
+ """The records of one step of H_A: the units in the order of the netlist, unit u in cell ('u', u), and the
1098
+ unit of the next value of state bit i writing ('s', i) with its last record."""
1099
  n, units, nxt = host_units(A)
 
 
 
 
 
1100
  is_next = {nxt[i] - n: i for i in range(n)}
1101
  assert len(is_next) == n and all(v >= n for v in nxt)
1102
+ for u, (bias, ins) in enumerate(units):
1103
+ assert all(w in (1, -1) for _, w in ins)
1104
+ lits = [(('s', s) if s < n else ('u', s - n), w > 0) for s, w in ins]
1105
+ dst = ('s', is_next[u]) if u in is_next else ('u', u)
1106
+ P.unit(unit_threshold(bias, ins), lits, dst, ('u', u), 0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1107
  P.ends[len(P.recs) - 1] = u
 
 
 
 
 
 
 
 
1108
  return n, units, nxt
1109
 
1110
 
1111
+ def threshold_levels(units):
1112
+ """The levels of cells the units of threshold strictly between 1 and their fan-in use."""
1113
+ return max([len(ins) - 2 for b, ins in units if 1 < unit_threshold(b, ins) < len(ins)] or [0])
 
 
 
 
 
 
 
 
 
 
 
 
 
1114
 
1115
 
1116
  # ---------------------------------------------------------------------------
 
1121
  return ('s', mem_bit(j, t, A))
1122
 
1123
 
1124
+ def word_is_one(P, j, dst, A=8):
1125
+ """[memory word j == 1] into dst"""
 
1126
  lits = [(mem_cell(j, 0, A), True)] + [(mem_cell(j, t, A), False) for t in range(1, A)]
1127
+ P.chain('and', lits, dst, dst)
1128
  return dst
1129
 
1130
 
1131
+ def device_cells(w):
1132
+ """The cells of the device, in the order of their addresses."""
1133
+ return ['wr', 'rd', 'rw'] + [('e', i) for i in range(w)] + ['eq', 'eot', 'ca', 'cc', 'g'] + \
1134
+ [('car', i) for i in range(1, w)] + ['m0', 'm1']
1135
+
1136
+
1137
  def compile_device(P, A=8, w=CW):
1138
  io = SR.io_cells(A)
1139
  cnt = [('d', 'cnt', i) for i in range(w)]
1140
  lim = [('d', 'lim', i) for i in range(w)]
1141
  dest = ('d', 'dest')
1142
+ v = lambda name: ('v', name)
1143
+ wr = word_is_one(P, io['c_wr'], v('wr'), A)
1144
+ rd = word_is_one(P, io['c_rd'], v('rd'), A)
1145
+ rw = word_is_one(P, io['c_rw'], v('rw'), A)
1146
  # [cnt == lim]
1147
+ eq = v('eq')
1148
  xs = []
1149
  for i in range(w):
1150
+ e = v(('e', i))
1151
+ a1, a0 = MX
1152
  P.AND((cnt[i], True), (lim[i], True), a1)
1153
  P.AND((cnt[i], False), (lim[i], False), a0)
1154
  P.OR((a1, True), (a0, True), e)
1155
  xs.append((e, True))
1156
+ P.chain('and', xs, eq, eq)
1157
+ eot = v('eot') # the end of the recipe is known after the rewind
1158
  P.AND((eq, True), (dest, True), eot)
1159
  # (i) the low byte of R_out, most significant bit first, under the arm or under the copy head
1160
+ ca, cc = v('ca'), v('cc')
1161
  P.AND((wr, True), (dest, False), ca)
1162
  P.AND((wr, True), (dest, True), cc)
1163
  out, inp, ceot = io['r_out'], io['r_in'], io['c_eot']
 
1168
  P.COPY((cc, True), ('c', AC))
1169
  for t in range(A):
1170
  P.AND((mem_cell(out, t, A), True), (wr, False), mem_cell(out, t, A))
1171
+ g = v('g')
1172
  P.AND((rd, True), (eot, False), g)
1173
  # (ii) the byte under the read head into R_in, most significant bit first, each bit moving the head,
1174
  # and its sign bit into the bits above it
 
1184
  # the counter of bytes read: carries first, then the sum bits
1185
  car = [g]
1186
  for i in range(w - 1):
1187
+ c = v(('car', i + 1))
1188
  P.AND((car[-1], True), (cnt[i], True), c)
1189
  car.append(c)
1190
  for i in range(w):
 
1241
  # allocation and encoding
1242
  # ---------------------------------------------------------------------------
1243
 
1244
+ def layout(A, w, n, n_units, levels):
1245
+ """Window addresses: booted, the counter, dest and the limit, the state bits, one cell for each unit of
1246
+ H_A, three cells for each level of a threshold unit, and the cells of the device."""
1247
+ addr = {('d', 'booted'): FREE}
1248
+ for i in range(w):
1249
+ addr[('d', 'cnt', i)] = FREE + 1 + i
1250
+ addr[('d', 'lim', i)] = FREE + 2 + w + i
1251
+ addr[('d', 'dest')] = FREE + 1 + w
1252
+ base = FREE + 2 + 2 * w
1253
+ for i in range(n):
1254
+ addr[('s', i)] = base + i
1255
+ for u in range(n_units):
1256
+ addr[('u', u)] = base + n + u
1257
+ xbase = base + n + n_units
1258
+ for lev in range(levels):
1259
+ for k in range(3):
1260
+ addr[('x', lev, k)] = xbase + 3 * lev + k
1261
+ dbase = xbase + 3 * levels
1262
+ names = device_cells(w)
1263
+ for k, name in enumerate(names):
1264
+ addr[('v', name)] = dbase + k
1265
+ return addr, dbase + len(names)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1266
 
1267
 
1268
  def bits_to_bytes(bits):
 
1275
 
1276
 
1277
  def check_schedule(recs, lo, hi, n):
1278
+ """Check the in-place order of the host block: every state bit written once, after its last reader,
1279
+ and every other cell the block reads written earlier in it."""
1280
  written = {}
1281
  for i in range(lo, hi):
1282
  ao = recs[i][5]
 
1284
  assert ao not in written, ('state bit written twice', ao)
1285
  written[ao] = i
1286
  assert len(written) == n, 'a state bit without its next value'
1287
+ seen = set()
1288
  for i in range(lo, hi):
1289
+ a0, w0, a1, w1, _, ao = recs[i]
1290
  for a, w in ((a0, w0), (a1, w1)):
1291
  if w and a[0] == 's':
1292
  assert i <= written[a], ('state bit read after it is written', a)
1293
+ elif w and a[0] != 'c':
1294
+ assert a in seen, ('read before written', a)
1295
+ seen.add(ao)
 
 
 
 
 
 
1296
  return dict(state_bits_written=len(written))
1297
 
1298
 
 
1312
  compile_device(P, A, w)
1313
  n_device = len(P.recs) - lo - n_host
1314
  compile_handover(P, A)
1315
+ addr, top = layout(A, w, n, len(units), threshold_levels(units))
1316
+ res = lambda a: a[1] if a[0] == 'c' else addr[a]
1317
+ recs = [(res(a0), w0, res(a1), w1, be, res(ao)) for (a0, w0, a1, w1, be, ao) in P.recs]
1318
  alpha = (top - 1).bit_length()
1319
  b = 8 + 3 * alpha
1320
  pad = 0