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

Prove the paper's counts, levelization, depth bounds, recipe lengths and Section 6 in Rocq, and revise the paper

Browse files
.gitignore CHANGED
@@ -15,6 +15,7 @@ rocq/*.vos
15
  rocq/*.glob
16
  rocq/.*.aux
17
  rocq/.lia.cache
 
18
  rocq/extract/physnet.ml
19
  rocq/extract/physnet.mli
20
  rocq/extract/hostnet.ml
 
15
  rocq/*.glob
16
  rocq/.*.aux
17
  rocq/.lia.cache
18
+ rocq/.nra.cache
19
  rocq/extract/physnet.ml
20
  rocq/extract/physnet.mli
21
  rocq/extract/hostnet.ml
README.md CHANGED
@@ -597,9 +597,12 @@ and that a fixed ternary network, the ring machine of `src/twohead.py`, holds
597
  stored networks in its state, a ring of K banks of records and K tapes with
598
  heads at absolute positions, and evaluates one record per step, which `rocq/`
599
  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 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
@@ -607,8 +610,7 @@ 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
@@ -624,6 +626,9 @@ probability of second order that the paper bounds, and completes the
624
  self-reproducing run under read noise at levels where the host fails within its
625
  first bytes. Under von Neumann's model of independent output flips the same
626
  redundancy works only below a threshold inversely proportional to the fan-in.
 
 
 
627
 
628
  Every figure of the paper comes from `src/paper.py`, `src/host.py`, `src/twohead.py` and
629
  `src/noise.py`, with the C programs beside them, and their records are in `paper/runs/`;
@@ -1019,13 +1024,15 @@ src/ the library; `python src/<file>.py <command>
1019
  └── nsim.c the noise simulator of independent.py
1020
  paper/ the manuscript, and the record of every run it reports
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
 
597
  stored networks in its state, a ring of K banks of records and K tapes with
598
  heads at absolute positions, and evaluates one record per step, which `rocq/`
599
  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, with its
601
+ depth and its numbers of units and edges, that the levelization of every clocked
602
+ netlist computes its step, that a read and the branch need two ternary levels, that
603
+ the recipes and their encoder have the stated lengths, that the 21- and
604
+ 27-instruction programs do what the paper states at every word width from 8 on, and
605
+ that the H_8 it defines is the netlist of the published serialization.
606
  The host itself, compiled into 36,080 records of two inputs with records that
607
  load its memory, its tape device and a hand-over, and stored in the member with
608
  32,768 window cells, runs the 27-instruction program on a recipe for its own
 
610
  and hands control to the copy, so that it reproduces itself, weights included, by
611
  the dynamics alone, and the copies accumulate until every bank holds one;
612
  `src/ring_run.c` runs six generations of 95,762,842,100 steps each in a ring of
613
+ three banks. `rocq/` defines the stored host for every word width from 8 on, the
 
614
  records `src/twohead.py` writes among them, and proves its universal
615
  construction, its reproduction in every ring, the accumulation of the copies and
616
  the period of the state, in the machine and in the network. An organism of 143
 
626
  self-reproducing run under read noise at levels where the host fails within its
627
  first bytes. Under von Neumann's model of independent output flips the same
628
  redundancy works only below a threshold inversely proportional to the fan-in.
629
+ `rocq/` proves the margin, the noise bounds, the amplification, the threshold and
630
+ the restoration bound, on a probability space with Gaussian perturbations, and
631
+ evaluates the numbers the paper derives from them.
632
 
633
  Every figure of the paper comes from `src/paper.py`, `src/host.py`, `src/twohead.py` and
634
  `src/noise.py`, with the C programs beside them, and their records are in `paper/runs/`;
 
1024
  └── nsim.c the noise simulator of independent.py
1025
  paper/ the manuscript, and the record of every run it reports
1026
  rocq/ Rocq proofs: the host family H_A computes SUBLEQ for every word
1027
+ width, with its depth and sizes, levelization and the depth
1028
+ lower bounds, the recipe lengths, P and P* do what the paper
1029
+ states at every width from 8, the netlist of the ring machine
1030
+ computes its step for every window, ring, bank and tape, the
1031
+ host stored as records builds every image that fits a bank and
1032
+ reproduces in every ring at every width from 8, the organism
1033
+ builds every image that fits a bank from any description of it
1034
+ and reproduces in every ring, the state periodic once every
1035
+ bank holds a copy, and the margin and noise bounds of Section 6
1036
  tools/play.py the playground, and a demonstration on each machine
1037
  llm_integration/
1038
  ├── llm.py SmolLM2 with the frozen circuits: the circuit wrapper, the
paper/README.md CHANGED
@@ -12,7 +12,8 @@ runs/ the record written by each command
12
  ## What each command establishes
13
 
14
  Each command is `python src/<file>.py <command>` and writes its record to `runs/`;
15
- `paper.py rocq` needs Rocq 9.1 and ocamlfind on the PATH.
 
16
 
17
  | Command | Record | Establishes |
18
  |---|---|---|
@@ -42,7 +43,7 @@ Each command is `python src/<file>.py <command>` and writes its record to `runs/
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 |
43
  | `noise.py host` | `paper_noise_*.json` | the margin, the profile bound in sum and product form, read noise, the deviation curve, the exact Poisson intervals of the measured rates (`host intervals`), weight error with leakage, the active-input counts of the orbit certificate |
44
  | `noise.py amplified` | `paper_redundant_*.json` | the amplified host N_3: one step on replicated states, the margin 3/2, exact self-reproduction in C, the run under noise, the deviation curve and its bound by layer, the failure rate of the state read by majority and the restoration bound, computed by `src/restore_bound.c` |
45
- | `independent.py` | `independent_*.json` | code written from the paper's definitions alone: H_A rebuilt from Construction 3.8 for A = 3 to 12, Lev(N_host) from sigma and the measurements of Section 6.1 and Appendix A with the noise simulator `src/nsim.c` |
46
 
47
  Rebuild the typeset paper with any TeX installation:
48
 
 
12
  ## What each command establishes
13
 
14
  Each command is `python src/<file>.py <command>` and writes its record to `runs/`;
15
+ `paper.py rocq` needs Rocq 9.1 with the opam packages `coq-coquelicot` and
16
+ `coq-interval`, and ocamlfind, on the PATH.
17
 
18
  | Command | Record | Establishes |
19
  |---|---|---|
 
43
  | `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 |
44
  | `noise.py host` | `paper_noise_*.json` | the margin, the profile bound in sum and product form, read noise, the deviation curve, the exact Poisson intervals of the measured rates (`host intervals`), weight error with leakage, the active-input counts of the orbit certificate |
45
  | `noise.py amplified` | `paper_redundant_*.json` | the amplified host N_3: one step on replicated states, the margin 3/2, exact self-reproduction in C, the run under noise, the deviation curve and its bound by layer, the failure rate of the state read by majority and the restoration bound, computed by `src/restore_bound.c` |
46
+ | `independent.py` | `independent_*.json` | code written from the paper's definitions alone: H_A rebuilt from Construction 3.7 for A = 3 to 12, Lev(N_host) from sigma and the measurements of Section 6.1 and Appendix A with the noise simulator `src/nsim.c` |
47
 
48
  Rebuild the typeset paper with any TeX installation:
49
 
paper/runs/paper_rocq.json CHANGED
@@ -1,7 +1,7 @@
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",
@@ -39,10 +39,99 @@
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
  {
@@ -90,6 +179,14 @@
90
  "bytes": 563241,
91
  "identical": true,
92
  "sha256": "8fe4d6719955e5e4c776514f3910facf60d8d6357f677f9978682e4932b1fbf8"
 
 
 
 
 
 
 
 
93
  }
94
  ],
95
  "identical": true
 
1
  {
2
  "rocq": "The Rocq Prover, version 9.1.1",
3
+ "files": 63,
4
+ "build_seconds": 96.0,
5
  "theorems": {
6
  "PhysSem.netlist_step": "closed",
7
  "PhysMain.network_orbit": "closed",
 
39
  "StoredMain.network_reproduces": "closed",
40
  "StoredMain.network_periodic": "closed",
41
  "StoredWidth.width_exists": "closed",
42
+ "StoredWidth.recipe_of_image": "closed",
43
+ "StoredProp.stored_pass": "closed",
44
+ "Recipe.desc_spec": "closed",
45
+ "Recipe.describe_spec": "closed",
46
+ "Recipe.recipes_complete": "closed",
47
+ "Recipe.recipe_optimal": "closed",
48
+ "Recipe.describe_steps": "closed",
49
+ "Recipe.psteps_lower": "closed",
50
+ "Lev.lev_ok": "closed",
51
+ "Lev.lev_units": "closed",
52
+ "Lev.lev_widths": "closed",
53
+ "Lev.lev_size": "closed",
54
+ "HostLev.host_dmax": "closed",
55
+ "HostLev.host_lev_widths": "closed",
56
+ "HostLev.host_lev_rows": "closed",
57
+ "HostLev.host_lev_widths_8": "closed",
58
+ "HostLev.host_lev_rows_8": "closed",
59
+ "HostLev.host_lev_dense_8": "closed",
60
+ "HostLev.host_lev_widest_8": "closed",
61
+ "HostCount.host_units_count": "closed",
62
+ "HostCount.host_memory_count": "closed",
63
+ "HostCount.host_edges": "closed",
64
+ "HostCount.host_weights_biases": "closed",
65
+ "HostCount.host_lev_identity": "closed",
66
+ "HostCount.host_units_8": "closed",
67
+ "HostCount.host_edges_8": "closed",
68
+ "HostCount.host_memory_8": "closed",
69
+ "HostCount.host_lev_identity_8": "closed",
70
+ "HostCount.host_lev_nonzero_8": "closed",
71
+ "StoredCount.stored_records": "closed",
72
+ "StoredCount.alpha_bounds": "closed",
73
+ "StoredCount.width_least": "closed",
74
+ "StoredCount.generation_bounds": "closed",
75
+ "PhysLev.phys_dmax": "closed",
76
+ "PhysLev.phys_lev_depth": "closed",
77
+ "PhysLev.phys_lev_rows": "closed",
78
+ "PhysLev.phys_edges": "closed",
79
+ "PhysLev.phys_lev_rows_15": "closed",
80
+ "PhysLev.phys_lev_rows_S": "closed",
81
+ "Lower.read_needs_two_levels": "reals",
82
+ "Lower.onehot_needs_two_levels": "reals",
83
+ "Lower.branch_not_ternary": "closed",
84
+ "Margin.margin": "reals",
85
+ "Margin.margin_tight": "reals",
86
+ "Margin.mismatch_all": "reals",
87
+ "Margin.mismatch_run": "reals",
88
+ "Margin.amap_rep": "closed",
89
+ "Margin.amp_wrong": "reals",
90
+ "Margin.amp_margin": "reals",
91
+ "Margin.flip_ok": "closed",
92
+ "Erfc.gauss_square": "reals",
93
+ "Erfc.erfc_le_exp": "reals",
94
+ "Erfc.erfc_upper1": "reals",
95
+ "Erfc.erfc_upper3": "reals",
96
+ "Erfc.erfc_lower1": "reals",
97
+ "Choose.binom_bound": "reals",
98
+ "Noise.union_bound": "reals",
99
+ "Noise.union_gauss": "reals",
100
+ "Noise.profile_step": "reals",
101
+ "Noise.profile_le": "reals",
102
+ "Noise.copy_bound": "reals",
103
+ "Noise.union_profile": "reals",
104
+ "Noise.amp_union": "reals",
105
+ "Noise.amp_gauss": "reals",
106
+ "Noise.amp_profile": "reals",
107
+ "Noise.amp_choose": "reals",
108
+ "Noise.amp_choose_exp": "reals",
109
+ "Noise.synapse_bound": "reals",
110
+ "Noise.flip_bound": "reals",
111
+ "Noise.flip_choose": "reals",
112
+ "NoiseNum.p_005": "reals, primitive numbers",
113
+ "NoiseNum.TMp_005": "reals, primitive numbers",
114
+ "NoiseNum.TMp_010": "reals, primitive numbers",
115
+ "NoiseNum.flip_threshold": "reals, primitive numbers",
116
+ "NoiseNum.synapse_005": "reals, primitive numbers",
117
+ "NoiseNum.synapse_010": "reals, primitive numbers",
118
+ "NoiseNum.N3_first_order": "reals, primitive numbers",
119
+ "NoiseNum.generation_1": "reals, primitive numbers",
120
+ "NoiseNum.generation_3": "reals, primitive numbers",
121
+ "NoiseNum.generation_5": "reals, primitive numbers",
122
+ "Restore.tw_paper": "closed",
123
+ "Restore.far_core": "reals",
124
+ "Restore.wrong_far": "reals",
125
+ "Restore.claims": "reals",
126
+ "Restore.claim_stop": "reals",
127
+ "Restore.restoration": "reals",
128
+ "FlipLower.P_few": "reals",
129
+ "FlipLower.flip_fails": "reals",
130
+ "AmpHost.amp_run": "closed",
131
+ "AmpHost.amp_selfrep": "closed"
132
  },
133
  "extraction_identical": true,
134
+ "lines": 23368,
135
  "host_extraction": {
136
  "members": [
137
  {
 
179
  "bytes": 563241,
180
  "identical": true,
181
  "sha256": "8fe4d6719955e5e4c776514f3910facf60d8d6357f677f9978682e4932b1fbf8"
182
+ },
183
+ {
184
+ "A": 10,
185
+ "w": 22,
186
+ "records": 178112,
187
+ "bytes": 1313576,
188
+ "identical": true,
189
+ "sha256": "222e17b6fab50dfe3c4b97274826bc740b799e35a3cdd8a1825f2d915ad8d3a5"
190
  }
191
  ],
192
  "identical": true
paper/universal_construction_ternary.pdf CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:922ef023fe09cef59891dc62bd7eab1b68b15be41216f4425959ef241ec8b9ad
3
- size 355574
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:260303cc3b22bb2884fc465dccbd20e41a0e15203e3a19cf7cf069ae7d56a821
3
+ size 367476
paper/universal_construction_ternary.tex CHANGED
@@ -79,9 +79,9 @@ and its netlist is proved in Rocq to compute this machine for every number and s
79
  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. 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
@@ -94,7 +94,9 @@ Replicating every unit $r$ times multiplies every margin by $r$: under noise on
94
  pre-activations, which does not grow with fan-in, every noise level is survived
95
  with $r=O(s\sqrt{\log(TM/\delta)})$. Under von Neumann's independent output flips a
96
  threshold appears: the same redundancy is reliable for flip probabilities below
97
- $1/(2ek)$, $k$ the largest fan-in, and not, for the host, above $1/(2k)$.
 
 
98
  \end{abstract}
99
 
100
  \maketitle
@@ -144,21 +146,24 @@ perturbation of a pre-activation below one half.
144
 
145
  \subsection{Contributions}
146
 
 
 
147
  \begin{enumerate}[label=(\arabic*),leftmargin=2em]
148
  \item \emph{Host.} A ternary threshold network executing SUBLEQ, a computer with a
149
  single instruction~\cite{MavaddatParhami1988}, with memory-mapped tape and output
150
  devices. It is the member with eight-bit words of a family $H_A$ whose step has
151
  depth $13$ at every word width, $17{,}598$ units for $A=8$
152
  (Proposition~\ref{prop:host}); that the step of $H_A$ is the step of SUBLEQ from
153
- every state is proved in Rocq for every $A$. A read from memory and the branch
154
- predicate each need two levels of ternary units (Lemma~\ref{lem:muxdepth},
 
155
  Remark~\ref{rem:ternarydepth}); folding the address decoders into the reads
156
  gives depth $11$ (Remark~\ref{rem:fold}).
157
  \item \emph{Universal construction.} A program of $21$ instructions that emits
158
  the byte string its tape describes, in a number of steps given in closed form,
159
  proved in Rocq for every word width $A\ge8$. Every string $f$ has a description of
160
  length at most $|f|+\lceil|f|/127\rceil+1$, and none shorter when $f$ has no two
161
- equal adjacent bytes (Section~\ref{sec:univ}).
162
  \item \emph{Exact self-reproduction of the host.} A program of $27$
163
  instructions, separating construction from copying as von Neumann did, with which
164
  the host emits the serialization of itself, its memory and its tape, also proved in
@@ -186,6 +191,7 @@ 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
187
  of the orbit, lies within the $95\%$ interval of the measured failure rate of the
188
  host at every noise level at which failures were observed (Section~\ref{sec:robust}).
 
189
  \item \emph{Fault tolerance.} Replacing every row by $r$ rows that read all
190
  copies of its inputs, Pierce's interwoven redundancy~\cite{Pierce1965} with
191
  threshold units, multiplies every margin by $r$. Under Gaussian noise of deviation
@@ -197,38 +203,39 @@ $O(s_{\mathrm w}^2K^\ast\log(TM/\delta))$, $K^\ast$ the largest number of active
197
  inputs of a unit (Theorem~\ref{thm:amplify},
198
  Corollary~\ref{cor:synapse}). Under von Neumann's model, in which every unit's
199
  output flips with probability $\varepsilon$, the same redundancy is reliable for
200
- $\varepsilon<1/(2ek^\ast)$, $k^\ast$ the largest fan-in, and a threshold of this
201
- order cannot be avoided (Proposition~\ref{prop:flip}). A second-order bound
202
- certifies the complete run of
203
- the threefold host where the first-order bound exceeds one
204
- (Proposition~\ref{prop:restore}).
205
  \end{enumerate}
206
 
207
- Table~\ref{tab:claims} lists each claim with the evidence for it.
208
-
209
  \begin{table}[ht]
210
  \centering\small
211
  \begin{tabularx}{\textwidth}{@{}>{\raggedright\arraybackslash}p{0.36\textwidth}>{\raggedright\arraybackslash}p{0.2\textwidth}>{\raggedright\arraybackslash}X@{}}
212
  \toprule
213
  Claim & Where & Evidence\\
214
  \midrule
 
215
  The step of $H_A$ is the step of $\mathrm{SUBLEQ}_A$, every $A\ge3$ & Prop.~\ref{prop:host} & Rocq; the netlists extracted for $A=8,9,10$ equal the generator's\\
216
- Unit counts and depth $13$ of $H_A$ & Prop.~\ref{prop:host} & counting; rebuilt independently for $A=3$ to $12$\\
217
- A read and the branch need two ternary levels & Lem.~\ref{lem:muxdepth}, Rem.~\ref{rem:ternarydepth} & proof; exhaustive search on eight inputs\\
 
218
  $P$ builds every string, in the stated steps, every $A\ge8$ & Thm.~\ref{thm:univ} & Rocq; $29$ recipes run on the reference and four on the netlist\\
219
- Length of $\describe$ & Lem.~\ref{lem:describe}, Prop.~\ref{prop:optimal} & proof; checked on $971$ MB and on $68{,}061$ boundary strings\\
220
  $P^\ast$ reproduces the host, in the stated steps, every $A\ge8$ & Thm.~\ref{thm:selfrep}, Prop.~\ref{prop:steps} & Rocq; three generations on three evaluators\\
221
- Margin $1/2$ and the profile bound & Thm.~\ref{thm:margin}, Prop.~\ref{prop:profile} & proof; measured rates of Table~\ref{tab:curve}\\
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}
230
- \caption{The claims of the paper and the evidence for each: a proof checked in Rocq,
231
- a proof on paper, a computation recorded in the artifact.}
232
  \label{tab:claims}
233
  \end{table}
234
 
@@ -324,7 +331,9 @@ $\depth(v)-1$, since $\depth(u)\le\depth(v)-1<\lambda(u)$. Layer $d$ holds one r
324
  for each state coordinate, in order: the unit assigned to it if that unit has depth
325
  $d$, and otherwise the copy of the assigned signal. Since $\Hv(x-1)=x$ on $\B$,
326
  induction on $\ell$ shows that each row of layer $\ell$ outputs the value of its
327
- signal of $N$.
 
 
328
  \end{proof}
329
 
330
  \begin{remark}\label{rem:levsizes}
@@ -332,7 +341,9 @@ The host $\Nhost$ of Section~\ref{sec:host} has $17{,}598$ units of maximal dept
332
  $13$, all contributing to a next-state value, and distinct signals for distinct
333
  state bits; $\Lev(\Nhost)$ adds $24{,}369$ identity units, $M=41{,}967$ rows on
334
  $n=2057$ state bits, and as dense matrices has maximal layer width $8210$ and
335
- $124{,}165{,}940$ entries, $75{,}501$ of them nonzero.
 
 
336
  \end{remark}
337
 
338
  \subsection{Tape transducers}
@@ -395,8 +406,8 @@ Address & Symbol & Role & Effect \\
395
  \begin{definition}[Serialization]\label{def:sigma}
396
  Let $N$ be a clocked netlist on $n$ state bits. Number its signals with the state
397
  bits first, in the order fixed by the state layout, and the units after them in
398
- the order of $N$, which is the order in which the construction lists them; the
399
- serialization sorts nothing. The \emph{serialization} $\sigma(N)$ is the
400
  \texttt{safetensors} encoding of four integer vectors:
401
  \begin{enumerate}[label=(\roman*)]
402
  \item the bias of each unit, in the order of $N$;
@@ -469,8 +480,7 @@ second statement follows by induction on $k$.
469
  The maps $\inst$ and $\Lev$ together with the device of
470
  Definition~\ref{def:transducer} are the \emph{instantiation map}: the network
471
  emits a description, and $\inst$, $\sigma^{-1}$ and $\Lev$ turn it into the next
472
- running network; each is linear in the data it reads or places.
473
- Section~\ref{sec:storedhost} removes the map: the host, held as records in the state
474
  of a fixed network, carries out the same step by the dynamics.
475
 
476
  % =============================================================================
@@ -553,7 +563,7 @@ ternary unit computes it when $n\ge3$. If $\Hv(\langle w,r\rangle+b)$ with
553
  $w\in\Tern^n$ did, then $r=0$ would give $b\ge0$, each unit vector $e_i$ with
554
  $i<n-1$ would give $w_i=-1$ and then $b=0$, and the vector of ones, whose value is
555
  negative, would force $w_{n-1}\ge n-1\ge2$. So the cell of Lemma~\ref{lem:branch}
556
- has the least ternary depth.
557
  \end{remark}
558
 
559
  \begin{lemma}[Address decoder and memory]\label{lem:mem}
@@ -599,7 +609,7 @@ inequalities at the two points where it is $1$ would give
599
  $\langle w,(1,1,1)\rangle+2b\ge0$, and at the two points where it is $0$ the
600
  strict opposite, a contradiction. The one-hot case is the same argument on
601
  $(s_0,s_1,\mu_0,\mu_1)$ at $(1,0,1,0)$, $(0,1,0,1)$ against $(1,0,0,1)$,
602
- $(0,1,1,0)$.
603
  \end{proof}
604
 
605
  \begin{construction}[The host family]\label{con:host}
@@ -662,8 +672,9 @@ of the block's units.}
662
  \begin{proposition}[Constant-depth host]\label{prop:host}
663
  For every $A\ge3$ one step of the netlist $H_A$, from every state, is one step of
664
  $\mathrm{SUBLEQ}_A$ with the halt latch; its weights are ternary and its biases
665
- integers, it has depth $13$, $(8A+4)2^A+\tfrac12(A^2+39A+4)$ units and $O(A2^A)$
666
- edges, and for $A\ge8$, with the device of Definition~\ref{def:transducer} on its
 
667
  seven top words, it realizes the transducer of Definitions~\ref{def:transducer}
668
  and~\ref{def:subleq}. The host $\Nhost=H_8$ has $17{,}598$ units carrying $68{,}730$
669
  parameters, $51{,}132$ weights of $\pm1$ and one bias per unit in $[-8,1]$; its
@@ -688,10 +699,11 @@ That one step of $H_A$ is one step of $\mathrm{SUBLEQ}_A$ with the halt latch, f
688
  every state and for every $A\ge3$, is proved in Rocq. The proof defines $H_A$ block
689
  by block in the order of Table~\ref{tab:blocks} and gives every unit its value in
690
  terms of the state, the carries through the recurrence of Lemma~\ref{lem:sub};
691
- induction over the units shows that the netlist computes these values. Extracted
692
- for $A=8$ to $10$,
693
- the definition gives the netlist that $\sigma(\Nhost)$ denotes and those of the
694
- generator, unit for unit.
 
695
  \end{proof}
696
 
697
  \begin{remark}[Depth]\label{rem:fold}
@@ -703,7 +715,7 @@ so the step has depth $11$ for every $A$. For $A=8$ the folded netlist has
703
  $17{,}086$ units and $120{,}508$ edges, against $17{,}598$ and $51{,}132$, and for
704
  every $A$ from $3$ to $12$ one step of it agreed with $\mathrm{SUBLEQ}_A$ on
705
  $2^{16}$ uniformly random full states for $A\le10$ and on $2^{15}$ and $2^{14}$
706
- for $A=11$ and $12$. The least depth of a ternary SUBLEQ step is open.
707
  \end{remark}
708
 
709
  % =============================================================================
@@ -799,7 +811,9 @@ $R\ge1$, then
799
  \[
800
  L-2R\le F+(R+1)-2R\le F\le\frac{|f|-4}{127}<\frac{|f|}{127}\le\Bigl\lceil\frac{|f|}{127}\Bigr\rceil ,
801
  \]
802
- and the bound is strict.
 
 
803
  \end{proof}
804
 
805
  \begin{construction}[The constructor $P$]\label{con:P}
@@ -1048,7 +1062,10 @@ orbit under random perturbations, from the pre-activations the orbit visits. It
1048
  compares the bounds with measurements of the host under noise
1049
  (Section~\ref{sec:certified}), and it shows that replicating every unit multiplies
1050
  the margin, which gives reliable runs under three models of noise, below a
1051
- threshold in one of them (Section~\ref{sec:amplify}).
 
 
 
1052
 
1053
  Let $\Hv_{1/2}(z)=1$ if $z\ge -\tfrac12$ and $\Hv_{1/2}(z)=0$ otherwise; on integer
1054
  arguments $\Hv_{1/2}$ and $\Hv$ agree. A \emph{layered integer threshold map} is
@@ -1390,11 +1407,18 @@ below a threshold.
1390
  \begin{proposition}[Output flips]\label{prop:flip}
1391
  Suppose that every evaluation of every row of $F^{(r)}$ outputs the complement of
1392
  its value with probability $\varepsilon$, independently, and let $k^\ast$ be the
1393
- largest effective fan-in of a row of $F$ and $n$ its number of state bits. Started
1394
- from $\rho_r(x_0)$, the probability that the state of $F^{(r)}$ read by majority
1395
- differs from $F^t(x_0)$ after one of the first $T$ steps is at most
 
1396
  $T(M+n)(2ek^\ast\varepsilon)^{(r+1)/2}$. For $\varepsilon<1/(2ek^\ast)$ it is at
1397
  most $\delta$ when $r+1\ge2\ln(T(M+n)/\delta)/\ln\bigl(1/(2ek^\ast\varepsilon)\bigr)$.
 
 
 
 
 
 
1398
  \end{proposition}
1399
 
1400
  \begin{proof}
@@ -1409,16 +1433,30 @@ $\binom{k^\ast r}{(r+1)/2}\varepsilon^{(r+1)/2}\le(2ek^\ast\varepsilon)^{(r+1)/2
1409
  since $\binom mj\le(em/j)^j$. While no row is wrong, the majority of the $r$ copies
1410
  of a state bit is wrong only if at least $(r+1)/2$ of them flipped, with probability
1411
  at most $(2e\varepsilon)^{(r+1)/2}$. The union bound over the $M$ rows and the $n$
1412
- state bits of each of the $T$ steps gives the first statement, and taking
1413
- logarithms gives the second.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1414
  \end{proof}
1415
 
1416
- A threshold of this order is unavoidable for the construction. A disjunction of
1417
- fan-in $k^\ast$ whose inputs hold $0$ on the orbit, such as a disjunction of the
1418
- operand fetch of the host, reads on average $k^\ast r\varepsilon$ flipped copies,
1419
- more than $r/2$ when $\varepsilon>1/(2k^\ast)$, and then fails with a probability
1420
- that tends to one as $r$ grows. For $\Lev(\Nhost)$, $k^\ast=256$ and the threshold
1421
- of Proposition~\ref{prop:flip} is $\varepsilon<7.2\times10^{-4}$.
1422
 
1423
  Integer weights reach the same margin without copies: the layer with weights
1424
  $rW_\ell$ and biases $rb_\ell+\tfrac{r-1}{2}$ has pre-activation $rz+\tfrac{r-1}{2}$
@@ -1483,7 +1521,12 @@ copies, which is their common value, and writes every copy, so the run of $N_r$
1483
  from $\rho_r(x_0(m))$ visits the replications of the states $\Nhost$ visits from
1484
  $x_0(m)$ on the same tape and emits the same bytes. The proofs of
1485
  Theorems~\ref{thm:univ} and~\ref{thm:selfrep} use the transducer alone, so they
1486
- hold with $N_r$ in place of $\Nhost$.
 
 
 
 
 
1487
  \end{proof}
1488
 
1489
  One step of $N_3$ agreed with Definition~\ref{def:subleq} on $65{,}536$
@@ -1741,9 +1784,9 @@ Counting the units and edges of the blocks gives the sizes. The depth of a unit
1741
  depends only on its block, the requests being decided at depth $14$ and the slot
1742
  head lines at depth $19$. That the next state is the encoding of the next state of
1743
  $x$, for all $\alpha\ge4$, $K\ge2$, $S,L\ge1$ and $x$, is proved in Rocq together
1744
- with the number of units and the weights: every unit is given a value in terms of
1745
- $x$ and fires to it on the values of the units it reads, and induction over the
1746
- units shows that the netlist computes these values.
1747
  \end{proof}
1748
 
1749
  \begin{remark}[Corroboration]\label{rem:physcheck}
@@ -1961,12 +2004,12 @@ 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
@@ -2097,7 +2140,7 @@ of $\Theta(A^34^A)$ applications of $M^{\alpha_A}_{K,S,L}$.
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
@@ -2109,7 +2152,10 @@ term from the carry terms. The window holds the $A2^A+A+1$ state bits, a cell fo
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
@@ -2132,9 +2178,9 @@ $s\le0.247$.
2132
 
2133
  \begin{proof}
2134
  Proposition~\ref{prop:random} and Theorem~\ref{thm:amplify}(ii) over the $T$
2135
- applications. Each slot and each tape cell places a fixed number of units and
2136
- identity rows, so the number of rows is affine in $S$ and $L$; it was counted on six
2137
- members and the affine form fits all of them.
2138
  \end{proof}
2139
 
2140
  \begin{remark}[Corroboration]\label{rem:storedcheck}
@@ -2550,28 +2596,65 @@ measurements of Section~\ref{sec:certified} and Appendix~\ref{app:measure} in C
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,
2561
- and proves Theorems~\ref{thm:univ} and~\ref{thm:selfrep} and
2562
- Proposition~\ref{prop:steps} for every $A\ge8$ on the step of $\mathrm{SUBLEQ}_A$
2563
- and the device. It defines the ring machine for every address width, its netlist
2564
- block by block, the organism, the description code and the decoder, and proves
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$
@@ -2670,6 +2753,11 @@ V.~Beiu, J.~M.~Quintana, and M.~J.~Avedillo,
2670
  \emph{VLSI implementations of threshold logic---a comprehensive survey},
2671
  IEEE Trans. Neural Networks \textbf{14} (2003), no.~5, 1217--1243.
2672
 
 
 
 
 
 
2673
  \bibitem{Burks1970}
2674
  A.~W.~Burks (ed.),
2675
  \emph{Essays on Cellular Automata}, University of Illinois Press, Urbana, 1970.
@@ -2833,6 +2921,12 @@ W.~S.~McCulloch and W.~Pitts,
2833
  \emph{A logical calculus of the ideas immanent in nervous activity}, Bull. Math.
2834
  Biophys. \textbf{5} (1943), 115--133.
2835
 
 
 
 
 
 
 
2836
  \bibitem{Minsky1967}
2837
  M.~L.~Minsky,
2838
  \emph{Computation: Finite and Infinite Machines}, Prentice-Hall, Englewood Cliffs,
 
79
  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. For every
83
+ word width from $8$ on and every ring it is proved in Rocq that the stored computer
84
+ 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
 
94
  pre-activations, which does not grow with fan-in, every noise level is survived
95
  with $r=O(s\sqrt{\log(TM/\delta)})$. Under von Neumann's independent output flips a
96
  threshold appears: the same redundancy is reliable for flip probabilities below
97
+ $1/(2ek)$, $k$ the largest fan-in, and above $1/(2k)$ a disjunction of fan-in $k$
98
+ fails with a probability that tends to one as $r$ grows. The margin, the noise bounds
99
+ and the threshold are proved in Rocq.
100
  \end{abstract}
101
 
102
  \maketitle
 
146
 
147
  \subsection{Contributions}
148
 
149
+ The contributions are the following, each listed with its evidence in
150
+ Table~\ref{tab:claims}.
151
  \begin{enumerate}[label=(\arabic*),leftmargin=2em]
152
  \item \emph{Host.} A ternary threshold network executing SUBLEQ, a computer with a
153
  single instruction~\cite{MavaddatParhami1988}, with memory-mapped tape and output
154
  devices. It is the member with eight-bit words of a family $H_A$ whose step has
155
  depth $13$ at every word width, $17{,}598$ units for $A=8$
156
  (Proposition~\ref{prop:host}); that the step of $H_A$ is the step of SUBLEQ from
157
+ every state, its depth and its numbers of units and edges are proved in Rocq for
158
+ every $A$. A read from memory and the branch predicate each need two levels of
159
+ ternary units, also proved in Rocq (Lemma~\ref{lem:muxdepth},
160
  Remark~\ref{rem:ternarydepth}); folding the address decoders into the reads
161
  gives depth $11$ (Remark~\ref{rem:fold}).
162
  \item \emph{Universal construction.} A program of $21$ instructions that emits
163
  the byte string its tape describes, in a number of steps given in closed form,
164
  proved in Rocq for every word width $A\ge8$. Every string $f$ has a description of
165
  length at most $|f|+\lceil|f|/127\rceil+1$, and none shorter when $f$ has no two
166
+ equal adjacent bytes, both proved in Rocq (Section~\ref{sec:univ}).
167
  \item \emph{Exact self-reproduction of the host.} A program of $27$
168
  instructions, separating construction from copying as von Neumann did, with which
169
  the host emits the serialization of itself, its memory and its tape, also proved in
 
191
  probability that some unit fails in a step, computed from the pre-activation profile
192
  of the orbit, lies within the $95\%$ interval of the measured failure rate of the
193
  host at every noise level at which failures were observed (Section~\ref{sec:robust}).
194
+ The margin and the bound are proved in Rocq.
195
  \item \emph{Fault tolerance.} Replacing every row by $r$ rows that read all
196
  copies of its inputs, Pierce's interwoven redundancy~\cite{Pierce1965} with
197
  threshold units, multiplies every margin by $r$. Under Gaussian noise of deviation
 
203
  inputs of a unit (Theorem~\ref{thm:amplify},
204
  Corollary~\ref{cor:synapse}). Under von Neumann's model, in which every unit's
205
  output flips with probability $\varepsilon$, the same redundancy is reliable for
206
+ $\varepsilon<1/(2ek^\ast)$, $k^\ast$ the largest fan-in, and above $1/(2k^\ast)$ a
207
+ disjunction of fan-in $k^\ast$ fails with a probability that tends to one as $r$
208
+ grows (Proposition~\ref{prop:flip}). A second-order bound certifies the complete run
209
+ of the threefold host where the first-order bound exceeds one
210
+ (Proposition~\ref{prop:restore}). All of it is proved in Rocq.
211
  \end{enumerate}
212
 
 
 
213
  \begin{table}[ht]
214
  \centering\small
215
  \begin{tabularx}{\textwidth}{@{}>{\raggedright\arraybackslash}p{0.36\textwidth}>{\raggedright\arraybackslash}p{0.2\textwidth}>{\raggedright\arraybackslash}X@{}}
216
  \toprule
217
  Claim & Where & Evidence\\
218
  \midrule
219
+ Levelization; the sizes of $\Lev(\Nhost)$ & Lem.~\ref{lem:lev}, Rem.~\ref{rem:levsizes} & Rocq\\
220
  The step of $H_A$ is the step of $\mathrm{SUBLEQ}_A$, every $A\ge3$ & Prop.~\ref{prop:host} & Rocq; the netlists extracted for $A=8,9,10$ equal the generator's\\
221
+ Depth $13$, units, edges, weights and biases of $H_A$, every $A\ge3$ & Prop.~\ref{prop:host} & Rocq; rebuilt independently for $A=3$ to $12$\\
222
+ A read and the branch need two ternary levels & Lem.~\ref{lem:muxdepth}, Rem.~\ref{rem:ternarydepth} & Rocq; exhaustive search on eight inputs\\
223
+ Length and optimality of the recipes and of $\describe$ & Lems.~\ref{lem:complete}, \ref{lem:describe}, Prop.~\ref{prop:optimal} & Rocq; checked on $971$ MB and on $68{,}061$ boundary strings\\
224
  $P$ builds every string, in the stated steps, every $A\ge8$ & Thm.~\ref{thm:univ} & Rocq; $29$ recipes run on the reference and four on the netlist\\
 
225
  $P^\ast$ reproduces the host, in the stated steps, every $A\ge8$ & Thm.~\ref{thm:selfrep}, Prop.~\ref{prop:steps} & Rocq; three generations on three evaluators\\
226
+ Margin $1/2$, weight errors and the profile bound & Thm.~\ref{thm:margin}, Props.~\ref{prop:mismatch}--\ref{prop:profile} & Rocq; measured rates of Table~\ref{tab:curve}\\
227
+ Amplification under the three noise models, and the threshold & Thm.~\ref{thm:amplify}, Cor.~\ref{cor:synapse}, Prop.~\ref{prop:flip} & Rocq\\
228
+ Exact self-reproduction of the amplified host, every odd $r$ & Cor.~\ref{cor:amplifiedselfrep} & Rocq; $\Omega^\ast_3$ run on the evaluator in C\\
229
+ Restoration bound for $N_3$ & Prop.~\ref{prop:restore} & Rocq; its values computed along the run; measured rates of Table~\ref{tab:bound3}\\
230
+ The netlist computes the ring machine; its size, weights and depth & Thm.~\ref{thm:physnet} & Rocq; extraction equal to the generator's; random states\\
231
  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$\\
232
+ Construction and reproduction by the stored host: copies, period, network, counts, every $A\ge8$ & Thms.~\ref{thm:storedconstruct}--\ref{thm:widths} & Rocq; the extracted image equal to the generator's for $A=8,9$; six generations of $\mathcal S_8$ run\\
233
+ The stored host under noise & Cor.~\ref{cor:storednoise} & Rocq\\
234
  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\\
235
  \bottomrule
236
  \end{tabularx}
237
+ \caption{The claims of the paper and the evidence for each: the proof checked in Rocq,
238
+ and the computations and runs recorded in the artifact.}
239
  \label{tab:claims}
240
  \end{table}
241
 
 
331
  for each state coordinate, in order: the unit assigned to it if that unit has depth
332
  $d$, and otherwise the copy of the assigned signal. Since $\Hv(x-1)=x$ on $\B$,
333
  induction on $\ell$ shows that each row of layer $\ell$ outputs the value of its
334
+ signal of $N$. The lemma is proved in Rocq for every clocked netlist whose units
335
+ read earlier signals with weights $\pm1$, together with the number of rows each
336
+ unit occupies.
337
  \end{proof}
338
 
339
  \begin{remark}\label{rem:levsizes}
 
341
  $13$, all contributing to a next-state value, and distinct signals for distinct
342
  state bits; $\Lev(\Nhost)$ adds $24{,}369$ identity units, $M=41{,}967$ rows on
343
  $n=2057$ state bits, and as dense matrices has maximal layer width $8210$ and
344
+ $124{,}165{,}940$ entries, $75{,}501$ of them nonzero. These sizes are proved in
345
+ Rocq, the rows of every layer and the identity units in closed form for every
346
+ member of the family of Section~\ref{sec:host}.
347
  \end{remark}
348
 
349
  \subsection{Tape transducers}
 
406
  \begin{definition}[Serialization]\label{def:sigma}
407
  Let $N$ be a clocked netlist on $n$ state bits. Number its signals with the state
408
  bits first, in the order fixed by the state layout, and the units after them in
409
+ the order of $N$, which is the order in which the construction lists them. The
410
+ \emph{serialization} $\sigma(N)$ is the
411
  \texttt{safetensors} encoding of four integer vectors:
412
  \begin{enumerate}[label=(\roman*)]
413
  \item the bias of each unit, in the order of $N$;
 
480
  The maps $\inst$ and $\Lev$ together with the device of
481
  Definition~\ref{def:transducer} are the \emph{instantiation map}: the network
482
  emits a description, and $\inst$, $\sigma^{-1}$ and $\Lev$ turn it into the next
483
+ running network. Section~\ref{sec:storedhost} removes the map: the host, held as records in the state
 
484
  of a fixed network, carries out the same step by the dynamics.
485
 
486
  % =============================================================================
 
563
  $w\in\Tern^n$ did, then $r=0$ would give $b\ge0$, each unit vector $e_i$ with
564
  $i<n-1$ would give $w_i=-1$ and then $b=0$, and the vector of ones, whose value is
565
  negative, would force $w_{n-1}\ge n-1\ge2$. So the cell of Lemma~\ref{lem:branch}
566
+ has the least ternary depth. The argument is checked in Rocq for every $n\ge3$.
567
  \end{remark}
568
 
569
  \begin{lemma}[Address decoder and memory]\label{lem:mem}
 
609
  $\langle w,(1,1,1)\rangle+2b\ge0$, and at the two points where it is $0$ the
610
  strict opposite, a contradiction. The one-hot case is the same argument on
611
  $(s_0,s_1,\mu_0,\mu_1)$ at $(1,0,1,0)$, $(0,1,0,1)$ against $(1,0,0,1)$,
612
+ $(0,1,1,0)$. Both statements are proved in Rocq for real weights.
613
  \end{proof}
614
 
615
  \begin{construction}[The host family]\label{con:host}
 
672
  \begin{proposition}[Constant-depth host]\label{prop:host}
673
  For every $A\ge3$ one step of the netlist $H_A$, from every state, is one step of
674
  $\mathrm{SUBLEQ}_A$ with the halt latch; its weights are ternary and its biases
675
+ integers, it has depth $13$, $(8A+4)2^A+\tfrac12(A^2+39A+4)$ units and
676
+ $(49A+4)2^{A-1}+\tfrac16(A^3+9A^2+194A+24)$ edges, and for $A\ge8$, with the device
677
+ of Definition~\ref{def:transducer} on its
678
  seven top words, it realizes the transducer of Definitions~\ref{def:transducer}
679
  and~\ref{def:subleq}. The host $\Nhost=H_8$ has $17{,}598$ units carrying $68{,}730$
680
  parameters, $51{,}132$ weights of $\pm1$ and one bias per unit in $[-8,1]$; its
 
699
  every state and for every $A\ge3$, is proved in Rocq. The proof defines $H_A$ block
700
  by block in the order of Table~\ref{tab:blocks} and gives every unit its value in
701
  terms of the state, the carries through the recurrence of Lemma~\ref{lem:sub};
702
+ induction over the units shows that the netlist computes these values. The depth,
703
+ the numbers of units, of memory units and of edges, the weights and the range
704
+ $[-A,1]$ of the biases are proved in Rocq for every $A\ge3$ as well. Extracted for
705
+ $A=8$ to $10$, the definition gives the netlist that $\sigma(\Nhost)$ denotes and
706
+ those of the generator, unit for unit.
707
  \end{proof}
708
 
709
  \begin{remark}[Depth]\label{rem:fold}
 
715
  $17{,}086$ units and $120{,}508$ edges, against $17{,}598$ and $51{,}132$, and for
716
  every $A$ from $3$ to $12$ one step of it agreed with $\mathrm{SUBLEQ}_A$ on
717
  $2^{16}$ uniformly random full states for $A\le10$ and on $2^{15}$ and $2^{14}$
718
+ for $A=11$ and $12$.
719
  \end{remark}
720
 
721
  % =============================================================================
 
811
  \[
812
  L-2R\le F+(R+1)-2R\le F\le\frac{|f|-4}{127}<\frac{|f|}{127}\le\Bigl\lceil\frac{|f|}{127}\Bigr\rceil ,
813
  \]
814
+ and the bound is strict. Lemmas~\ref{lem:complete} and~\ref{lem:describe} and
815
+ Proposition~\ref{prop:optimal} are proved in Rocq, with a recipe given as its list
816
+ of tokens.
817
  \end{proof}
818
 
819
  \begin{construction}[The constructor $P$]\label{con:P}
 
1062
  compares the bounds with measurements of the host under noise
1063
  (Section~\ref{sec:certified}), and it shows that replicating every unit multiplies
1064
  the margin, which gives reliable runs under three models of noise, below a
1065
+ threshold in one of them (Section~\ref{sec:amplify}). The theorems, propositions
1066
+ and corollaries of the section are proved in Rocq, and the values of the union
1067
+ bounds, thresholds and redundancies stated with them are evaluated in Rocq from
1068
+ proved bounds on $\erfc$ (Appendix~\ref{sec:verification}).
1069
 
1070
  Let $\Hv_{1/2}(z)=1$ if $z\ge -\tfrac12$ and $\Hv_{1/2}(z)=0$ otherwise; on integer
1071
  arguments $\Hv_{1/2}$ and $\Hv$ agree. A \emph{layered integer threshold map} is
 
1407
  \begin{proposition}[Output flips]\label{prop:flip}
1408
  Suppose that every evaluation of every row of $F^{(r)}$ outputs the complement of
1409
  its value with probability $\varepsilon$, independently, and let $k^\ast$ be the
1410
+ largest effective fan-in of a row of $F$ and $n$ its number of state bits.
1411
+ \begin{enumerate}[label=(\roman*),leftmargin=2em]
1412
+ \item Started from $\rho_r(x_0)$, the probability that the state of $F^{(r)}$ read by
1413
+ majority differs from $F^t(x_0)$ after one of the first $T$ steps is at most
1414
  $T(M+n)(2ek^\ast\varepsilon)^{(r+1)/2}$. For $\varepsilon<1/(2ek^\ast)$ it is at
1415
  most $\delta$ when $r+1\ge2\ln(T(M+n)/\delta)/\ln\bigl(1/(2ek^\ast\varepsilon)\bigr)$.
1416
+ \item Let a row of $F$ be the disjunction of $k$ inputs that hold $0$ on the orbit,
1417
+ and let $2k\varepsilon>1$. There is $\theta<1$, depending on $k$ and $\varepsilon$
1418
+ only, such that a row of $F^{(r)}$ that copies it, reading $kr$ input copies each
1419
+ flipped with probability $\varepsilon$, independently, computes a wrong value with
1420
+ probability at least $1-\theta^{(r-1)/2}$.
1421
+ \end{enumerate}
1422
  \end{proposition}
1423
 
1424
  \begin{proof}
 
1433
  since $\binom mj\le(em/j)^j$. While no row is wrong, the majority of the $r$ copies
1434
  of a state bit is wrong only if at least $(r+1)/2$ of them flipped, with probability
1435
  at most $(2e\varepsilon)^{(r+1)/2}$. The union bound over the $M$ rows and the $n$
1436
+ state bits of each of the $T$ steps gives the bound of~(i), and taking logarithms
1437
+ gives the redundancy.
1438
+
1439
+ For~(ii), the copy has bias $-r+\tfrac{r-1}{2}=-\tfrac{r+1}{2}$ and reads its $kr$
1440
+ input copies with weight $1$, so its pre-activation is the number of flipped copies
1441
+ minus $\tfrac{r+1}{2}$, and it is wrong exactly when at least $\tfrac{r+1}{2}$ of
1442
+ them flipped. For $0<x\le1$ and $c=1-\varepsilon+\varepsilon x$, fewer than $t\ge1$
1443
+ of $m$ independent copies flip with probability at most $c^m/x^{t-1}$: by induction
1444
+ on $m$, either the first copy flips and fewer than $t-1$ of the others do, or it does
1445
+ not and fewer than $t$ do, which has probability at most
1446
+ $\varepsilon c^{m-1}/x^{t-2}+(1-\varepsilon)c^{m-1}/x^{t-1}=c^m/x^{t-1}$, the first
1447
+ term absent when $t=1$. For $r=2h+1$, $m=kr$ and $t=h+1$ this is
1448
+ $c^k(c^{2k}/x)^h\le\theta^h$ with $\theta=c^{2k}/x$. Take
1449
+ $u=(2k\varepsilon-1)/(4k\varepsilon)$, which lies in $(0,\tfrac12)$, and $x=1-u$, so
1450
+ that $c=1-\varepsilon u$. Then $c^{2k}(1+\varepsilon u)^{2k}\le1$,
1451
+ $(1+\varepsilon u)^{2k}\ge1+2k\varepsilon u$ and
1452
+ $(1+2k\varepsilon u)(1-u)=(2k\varepsilon+1)^2/(8k\varepsilon)>1$, so $\theta<1$.
1453
  \end{proof}
1454
 
1455
+ A threshold of this order is thus unavoidable for the construction. The operand
1456
+ fetch of the host has disjunctions of fan-in $k^\ast=256$, whose inputs all hold $0$
1457
+ when the fetched bit is $0$. For $\Lev(\Nhost)$ the amplification is therefore
1458
+ reliable for $\varepsilon<7.2\times10^{-4}$, and for $\varepsilon>1/512$ such a
1459
+ disjunction is wrong with a probability that tends to one as $r$ grows.
 
1460
 
1461
  Integer weights reach the same margin without copies: the layer with weights
1462
  $rW_\ell$ and biases $rb_\ell+\tfrac{r-1}{2}$ has pre-activation $rz+\tfrac{r-1}{2}$
 
1521
  from $\rho_r(x_0(m))$ visits the replications of the states $\Nhost$ visits from
1522
  $x_0(m)$ on the same tape and emits the same bytes. The proofs of
1523
  Theorems~\ref{thm:univ} and~\ref{thm:selfrep} use the transducer alone, so they
1524
+ hold with $N_r$ in place of $\Nhost$. For every odd $r$ and every $A\ge8$, with
1525
+ $\Lev(H_A)$ in place of $\Lev(\Nhost)$, it is proved in Rocq that the run of $N_r$
1526
+ from a replicated state visits the replicated states of the transducer's run with
1527
+ the same output, and that on $P^\ast$ and every recipe it reads its halt bit as $0$
1528
+ for the steps of Proposition~\ref{prop:steps} and as $1$ after them, with the output
1529
+ of Theorem~\ref{thm:selfrep}.
1530
  \end{proof}
1531
 
1532
  One step of $N_3$ agreed with Definition~\ref{def:subleq} on $65{,}536$
 
1784
  depends only on its block, the requests being decided at depth $14$ and the slot
1785
  head lines at depth $19$. That the next state is the encoding of the next state of
1786
  $x$, for all $\alpha\ge4$, $K\ge2$, $S,L\ge1$ and $x$, is proved in Rocq together
1787
+ with the numbers of units and edges, the weights and the depth: every unit is given
1788
+ a value in terms of $x$ and fires to it on the values of the units it reads, and
1789
+ induction over the units shows that the netlist computes these values.
1790
  \end{proof}
1791
 
1792
  \begin{remark}[Corroboration]\label{rem:physcheck}
 
2004
  \end{proof}
2005
 
2006
  The theorems below use what Proposition~\ref{prop:storedpass} states and one more
2007
+ property of the image: every cell read by a record after the startup records, other
2008
+ than the cells under the heads and the sink, is written earlier in the pass. The
2009
+ image $\mathcal S_{A,w}$ has this property for every $A\ge8$ and $w\ge1$, and
2010
  $B=bG/8$ bytes, with $b=8+3\alpha$; $\mathcal S$ has $\alpha=15$, $G=36{,}080$ and
2011
+ $B=239{,}030$. The proofs apply to every image with these two properties, so the step
2012
+ block may compile any netlist that computes the step of $H_A$.
2013
 
2014
  \begin{theorem}[Universal construction by the dynamics]\label{thm:storedconstruct}
2015
  Let $A\ge8$ and $w\ge1$, let $\mathcal S_{A,w}$ have $G$ records, and let $K\ge2$ and
 
2140
  \begin{proof}
2141
  The records of $\mathcal S_{A,w}$ grow linearly in $w$ and its window
2142
  logarithmically, so $B$ grows quadratically in $w$ while $2^w$ grows exponentially,
2143
+ and $w_A$ exists. The recipe of literal tokens of
2144
  Lemma~\ref{lem:complete} has $B+\lceil B/127\rceil+1\le2B+1$ bytes, and
2145
  $\describe$ gives no more by Lemma~\ref{lem:describe}. The startup and device
2146
  records are counted in Construction~\ref{con:stored} and the hand-over has
 
2152
  each of the $\Theta(A2^A)$ units of $H_A$ and $O(A+w_A)$ further cells, so
2153
  $\alpha_A=A+\Theta(\log A)$; then $b=8+3\alpha_A=\Theta(A)$,
2154
  $B=bG_A/8=\Theta(A^22^A)$, and Theorem~\ref{thm:storedrep} gives a generation of
2155
+ $\Theta(B)$ passes of $S=G_A$ steps. The record count, the bounds
2156
+ $A+\lfloor\log_2A\rfloor+3\le\alpha_A\le A+\lfloor\log_2A\rfloor+8$, the least $w_A$,
2157
+ which is at most $2A+10$, and the bounds $2^8A^34^A$ and $2^{13}A^34^A$ on the
2158
+ applications of a generation are proved in Rocq.
2159
  \end{proof}
2160
 
2161
  For $A=8$ to $12$, $\mathcal S_A$ has $36{,}080$, $80{,}463$, $178{,}112$, $391{,}220$ and
 
2178
 
2179
  \begin{proof}
2180
  Proposition~\ref{prop:random} and Theorem~\ref{thm:amplify}(ii) over the $T$
2181
+ applications, with the values evaluated in Rocq. $\Lev(N^\alpha_{K,S,L})$ has depth
2182
+ $19$ and $34\cdot2^\alpha+b+43K+24Kb+30KN+23KS+51KL-56$ rows, $N=Sb$, which is proved
2183
+ in Rocq for every $\alpha\ge4$, $K\ge2$ and $S,L\ge1$.
2184
  \end{proof}
2185
 
2186
  \begin{remark}[Corroboration]\label{rem:storedcheck}
 
2596
  on the accelerator; it gives the sizes, depths and exact runs stated here, and noisy
2597
  runs within sampling error.
2598
 
2599
+ The Rocq development, \texttt{rocq/} in the artifact, has $63$ files and
2600
+ $23{,}368$ lines and builds with Rocq 9.1.1 in about two minutes on the machine
2601
  below, most of it in the kernel's evaluation of the $15{,}872$ abstract passes of
2602
+ Proposition~\ref{prop:pass} and in the device records of the stored host. It proves
2603
+ Lemma~\ref{lem:lev} for every clocked netlist. It defines the host family $H_A$
2604
+ block by block and proves that its step is the step of $\mathrm{SUBLEQ}_A$ for every
2605
+ $A\ge3$, with its depth, its numbers of units, memory units and edges, its weights
2606
+ and biases and the sizes of $\Lev(H_A)$ (Proposition~\ref{prop:host},
2607
+ Remark~\ref{rem:levsizes}), and it proves Lemma~\ref{lem:muxdepth} and
2608
+ Remark~\ref{rem:ternarydepth}. It defines the recipes, $\describe$, the device of
2609
+ Definition~\ref{def:transducer} and the programs $P$ and $P^\ast$ in $2^A$ words, and
2610
+ proves Lemmas~\ref{lem:complete} and~\ref{lem:describe},
2611
+ Proposition~\ref{prop:optimal}, Theorems~\ref{thm:univ} and~\ref{thm:selfrep} and
2612
+ Proposition~\ref{prop:steps}, the last three for every $A\ge8$ on the step of
2613
+ $\mathrm{SUBLEQ}_A$ and the device, and Corollary~\ref{cor:amplifiedselfrep} for every
2614
+ odd $r$. It defines the ring machine for every address
2615
+ width, its netlist block by block, the organism, the description code and the
2616
+ decoder, and proves Theorem~\ref{thm:physnet} for every $\alpha\ge4$, $K\ge2$ and
2617
+ $S,L\ge1$, together with the numbers of units and edges, the weights and the depth;
2618
+ and it proves Lemma~\ref{lem:code}, Proposition~\ref{prop:pass},
2619
+ Theorem~\ref{thm:construct} and Theorem~\ref{thm:organism}, with the copies, the
2620
+ period and the network. It defines the stored host $\mathcal S_{A,w}$ of
2621
+ Construction~\ref{con:stored} for every $A\ge8$ and $w\ge1$ and proves its four
2622
+ blocks from every window (Proposition~\ref{prop:storedpass}), that every cell a pass
2623
+ reads after the startup is written earlier in the pass,
2624
+ Theorems~\ref{thm:storedconstruct} and~\ref{thm:storedrep} with the copies, the
2625
+ period and the network, the counts of Theorem~\ref{thm:widths} and
2626
+ Corollary~\ref{cor:storednoise}.
2627
+
2628
+ Section~\ref{sec:robust} is proved on a probability space given by its properties.
2629
+ A function $P$ on the events of the perturbations $(e_g)$ is monotone and
2630
+ subadditive, is $0$ on the empty event and $1$ on the sure one, multiplies on events
2631
+ that depend on disjoint sets of perturbations, and is additive and complementary on
2632
+ the events built from the threshold events $\{c\le e_g\}$; each perturbation has the
2633
+ tails $P(e_g\ge c)=Q(c/s)$ and $P(e_g\le c)=Q(-c/s)$, and in
2634
+ Proposition~\ref{prop:flip} each output flips with probability $\varepsilon$. The
2635
+ product of Gaussian measures with its outer measure is such a space.
2636
+ Corollary~\ref{cor:synapse} assumes in addition that a sum of $m$ independent
2637
+ centred Gaussians of deviation $s_{\mathrm w}$ is a centred Gaussian of deviation
2638
+ $s_{\mathrm w}\sqrt m$. In Proposition~\ref{prop:restore} the device writes every
2639
+ copy of its cells with the values of the run, as the device of $N_3$ does while the
2640
+ state read by majority is the run's. The identity
2641
+ $\bigl(\int_0^xe^{-t^2}dt\bigr)^2+\int_0^1e^{-x^2(1+t^2)}/(1+t^2)\,dt=\pi/4$ is proved
2642
+ from its derivative, which is $0$, with the integrals and derivatives of
2643
+ Coquelicot~\cite{BoldoLelayMelquiond2015}; with
2644
+ $\erfc(x)=1-\tfrac2{\sqrt\pi}\int_0^xe^{-t^2}dt$ it gives $\erfc(x)\le e^{-x^2}$ for
2645
+ $x\ge0$ and, for $x>0$,
2646
+ \[
2647
+ \frac{e^{-x^2}}{x\sqrt\pi}\Bigl(1-\frac1{2x^2}\Bigr)\le\erfc(x)
2648
+ \le\frac{e^{-x^2}}{x\sqrt\pi}\Bigl(1-\frac1{2x^2}+\frac3{4x^4}\Bigr),
2649
+ \]
2650
+ from which the union bounds, thresholds and redundancies stated in
2651
+ Sections~\ref{sec:robust} and~\ref{sec:storedhost} and in Appendix~\ref{app:measure}
2652
+ are evaluated with the interval tactic of the Interval
2653
+ library~\cite{Melquiond2008}. The
2654
+ results on real numbers rest on the classical axioms of Rocq's real numbers and on
2655
+ functional extensionality, and the evaluated values also on the specifications of
2656
+ its primitive integers and floating-point numbers; \texttt{src/paper.py rocq}
2657
+ rebuilds the development and prints the axioms of each main theorem.
2658
 
2659
  The file that defines the organism and its description is written by
2660
  \texttt{src/twohead.py}. The netlist definitions, extracted to OCaml, write for $H_8$
 
2753
  \emph{VLSI implementations of threshold logic---a comprehensive survey},
2754
  IEEE Trans. Neural Networks \textbf{14} (2003), no.~5, 1217--1243.
2755
 
2756
+ \bibitem{BoldoLelayMelquiond2015}
2757
+ S.~Boldo, C.~Lelay, and G.~Melquiond,
2758
+ \emph{Coquelicot: A user-friendly library of real analysis for Coq}, Math. Comput.
2759
+ Sci. \textbf{9} (2015), no.~1, 41--62.
2760
+
2761
  \bibitem{Burks1970}
2762
  A.~W.~Burks (ed.),
2763
  \emph{Essays on Cellular Automata}, University of Illinois Press, Urbana, 1970.
 
2921
  \emph{A logical calculus of the ideas immanent in nervous activity}, Bull. Math.
2922
  Biophys. \textbf{5} (1943), 115--133.
2923
 
2924
+ \bibitem{Melquiond2008}
2925
+ G.~Melquiond,
2926
+ \emph{Proving bounds on real-valued functions with computations}, Automated
2927
+ Reasoning (IJCAR 2008), Lecture Notes in Comput. Sci. \textbf{5195}, Springer, 2008,
2928
+ 2--17.
2929
+
2930
  \bibitem{Minsky1967}
2931
  M.~L.~Minsky,
2932
  \emph{Computation: Finite and Infinite Machines}, Prentice-Hall, Englewood Cliffs,
rocq/AmpHost.v ADDED
@@ -0,0 +1,320 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* Corollary 6.13: the r-fold amplification of Lev(H_A), with a device that reads the state as the majority of the
2
+ copies of each bit and writes every copy of the cells it writes, takes from a replicated state the steps of the host's
3
+ transducer, replicated; on P* and every recipe it halts after the steps of Proposition 5.3 with the output of the
4
+ host. *)
5
+ From Stdlib Require Import List Bool Arith Lia.
6
+ Import ListNotations.
7
+ Set Warnings "-ambiguous-paths".
8
+ From TH Require Import TwoHead Net Lev BlockLev Host HostWF HostIP HostSem HostLev Device Pstar Margin.
9
+ Set Warnings "ambiguous-paths".
10
+
11
+ (* ---- the rows of a levelized netlist read the layer before ------------------------------------------------------ *)
12
+ Lemma mkrow_reads : forall n us nx, wfn n us -> forall l c,
13
+ (forall s, c = Un s -> exists k, k < length us /\ s = n + k /\ need n us nx s = true /\ dep n us s = S l) ->
14
+ (forall s, c = Cp s -> at_layer n us nx l s) -> reads_lt (width n us nx l) (mkrow n us nx (S l) c).
15
+ Proof.
16
+ intros n us nx Hwf l c HU HC. destruct c as [s|s]; cbn [mkrow]; replace (S l - 1) with l by lia.
17
+ - specialize (HC s eq_refl). intros i z Hin. unfold idr in Hin. cbn [tin] in Hin. destruct Hin as [E|[]].
18
+ injection E as <- <-. apply pos_lt. exact HC.
19
+ - destruct (HU s eq_refl) as (k & Hk & -> & Hn & Hdk). replace (n + k - n) with k by lia.
20
+ intros i z Hin. unfold reidx in Hin. cbn [tin] in Hin. apply in_map_iff in Hin as ([p z'] & E & Hin).
21
+ cbn [fst snd] in E. injection E as <- <-. apply pos_lt. exact (pred_at n us nx Hwf l k p z' Hk Hn Hdk Hin).
22
+ Qed.
23
+
24
+ Lemma lev_lreads : forall n us nx, wfn n us -> Forall (fun s => s < NS n us) nx -> length nx = n -> 1 <= dmax n us ->
25
+ lreads n (lev n us nx).
26
+ Proof.
27
+ intros n us nx Hwf Hnx Hlen Hd.
28
+ assert (G : forall m, m <= dmax n us - 1 ->
29
+ lreads (width n us nx m) (map (fun p => map (mkrow n us nx (fst p)) (snd p))
30
+ (map (fun l => (l, srcs n us nx l)) (seq (S m) (dmax n us - 1 - m))
31
+ ++ [(dmax n us, srcd n us nx)]))).
32
+ { intros m Hm. remember (dmax n us - 1 - m) as c eqn:Ec. revert m Hm Ec. induction c as [|c IH]; intros m Hm Ec.
33
+ - cbn [seq map app lreads fst snd]. split; [|exact I].
34
+ apply Forall_forall. intros u Hu. apply in_map_iff in Hu as (c & <- & Hc).
35
+ destruct (srcd_spec n us nx Hnx Hlen Hd c Hc) as [HU HC].
36
+ replace (dmax n us) with (S m) by lia. apply mkrow_reads; [exact Hwf | |].
37
+ + intros s E. destruct (HU s E) as (k & Hk & Es & Hn & Hdk). exists k. repeat split; try assumption. lia.
38
+ + intros s E. destruct (HC s E) as (Hs & Hdl & Hlam). apply copy_at; [exact Hwf | exact Hs | lia | lia].
39
+ - cbn [seq map app lreads fst snd]. split.
40
+ + apply Forall_forall. intros u Hu. apply in_map_iff in Hu as (c' & <- & Hc).
41
+ destruct (srcs_spec n us nx (S m) c' Hc) as [HU HC]. apply mkrow_reads; [exact Hwf | exact HU |].
42
+ intros s E. destruct (HC s E) as (Hs & Hdl & Hlam). apply copy_at; [exact Hwf | exact Hs | lia | lia].
43
+ + rewrite length_map. unfold srcs. rewrite length_map.
44
+ replace (length (filter (live n us nx (S m)) (seq 0 (NS n us)))) with (width n us nx (S m)) by reflexivity.
45
+ apply IH; lia. }
46
+ specialize (G 0 ltac:(lia)). unfold lev, lsrc. replace (dmax n us - 1) with (dmax n us - 1 - 0) by lia. exact G.
47
+ Qed.
48
+
49
+ (* ---- a word of bits, most significant first ---------------------------------------------------------------------- *)
50
+ Definition bval (bs : list bool) : nat := fold_left (fun a b => 2 * a + Nat.b2n b) bs 0.
51
+
52
+ Lemma bval_app : forall l b, bval (l ++ [b]) = 2 * bval l + Nat.b2n b.
53
+ Proof. intros l b. unfold bval. rewrite fold_left_app. reflexivity. Qed.
54
+
55
+ Lemma bval_bits : forall k v, bval (map (fun t => Nat.testbit v (k - 1 - t)) (seq 0 k)) = v mod 2 ^ k.
56
+ Proof.
57
+ induction k as [|k IH]; intro v; [rewrite Nat.pow_0_r, Nat.mod_1_r; reflexivity|].
58
+ rewrite seq_S, map_app. cbn [map Nat.add]. rewrite bval_app. replace (S k - 1 - k) with 0 by lia.
59
+ rewrite (map_ext_in _ (fun t => Nat.testbit (Nat.div2 v) (k - 1 - t))).
60
+ - rewrite IH, Nat.bit0_odd. pose proof (Nat.div2_odd v) as Ev.
61
+ assert (Hp : 2 ^ k <> 0) by (apply Nat.pow_nonzero; lia).
62
+ pose proof (Nat.mod_upper_bound (Nat.div2 v) (2 ^ k) Hp) as Hm.
63
+ pose proof (Nat.div_mod (Nat.div2 v) (2 ^ k) Hp) as Ed.
64
+ apply (Nat.mod_unique v (2 ^ S k) (Nat.div2 v / 2 ^ k)); rewrite Nat.pow_succ_r'.
65
+ + destruct (Nat.odd v); cbn [Nat.b2n]; lia.
66
+ + nia.
67
+ - intros t Ht. apply in_seq in Ht. rewrite Nat.testbit_div2. f_equal. lia.
68
+ Qed.
69
+
70
+ Section AmpHost.
71
+ Variable A : nat.
72
+ Hypothesis HA : 8 <= A.
73
+ Variable r : nat.
74
+ Hypothesis Hr : Nat.odd r = true.
75
+
76
+ Lemma HA3 : 3 <= A.
77
+ Proof. lia. Qed.
78
+
79
+ Lemma SW_big : 256 <= SW A.
80
+ Proof. unfold SW. replace 256 with (2 ^ 8) by reflexivity. apply Nat.pow_le_mono_r; lia. Qed.
81
+
82
+ (* ---- decoding a state ------------------------------------------------------------------------------------------- *)
83
+ Definition bword (x : list bool) (o : nat) : nat := bval (map (fun t => nth (o + t) x false) (seq 0 A)).
84
+ Definition decodeH (x : list bool) : hst :=
85
+ mkH (bword x 0) (nth A x false) (map (fun j => bword x (A + 1 + j * A)) (seq 0 (SW A))).
86
+
87
+ Lemma bval_wbits : forall v, v < SW A -> bval (wbits A v) = v.
88
+ Proof. intros v Hv. unfold wbits, bitof. rewrite bval_bits. apply Nat.mod_small. exact Hv. Qed.
89
+
90
+ Lemma memv_lt : forall s j, hvalid A s -> j < SW A -> memv s j < SW A.
91
+ Proof.
92
+ intros s j (_ & Hl & Hf) Hj. unfold memv. rewrite Forall_forall in Hf. apply Hf. apply nth_In. lia.
93
+ Qed.
94
+
95
+ Lemma decode_encode : forall s, hvalid A s -> decodeH (encodeH A s) = s.
96
+ Proof.
97
+ intros s Hv. pose proof Hv as (Hp & Hl & Hf). destruct s as [p h m]. cbn [hpc hhalt hmem] in *. unfold decodeH. f_equal.
98
+ - unfold bword. rewrite (map_ext_in _ (bitof A p)).
99
+ + apply bval_wbits. exact Hp.
100
+ + intros t Ht. apply in_seq in Ht. cbn [Nat.add]. apply (nth_encodeH_pc A (mkH p h m) t). lia.
101
+ - apply (nth_encodeH_halt A (mkH p h m)).
102
+ - transitivity (map (fun j => nth j m 0) (seq 0 (SW A))).
103
+ + apply map_ext_in. intros j Hj. apply in_seq in Hj. unfold bword.
104
+ rewrite (map_ext_in _ (bitof A (memv (mkH p h m) j))).
105
+ * apply bval_wbits. exact (memv_lt (mkH p h m) j Hv ltac:(lia)).
106
+ * intros t Ht. apply in_seq in Ht. apply nth_encodeH_mem; [exact Hl | lia | lia].
107
+ + rewrite <- Hl. transitivity (map (fun b : nat => b) m); [|apply map_id].
108
+ symmetry. apply (map_seq_nth _ _ (fun b : nat => b) m 0).
109
+ Qed.
110
+
111
+ (* ---- the transducer keeps the state valid ---------------------------------------------------------------------- *)
112
+ Lemma hvalid_subleq : forall s, hvalid A s -> hvalid A (subleq A s).
113
+ Proof.
114
+ intros s Hv. pose proof SW_big. unfold subleq. destruct (hhalt s); [exact Hv|]. cbv zeta.
115
+ split; [|split].
116
+ - cbn [hpc]. destruct (_ || _); [apply memv_lt; [exact Hv | apply Nat.mod_upper_bound; lia] | apply Nat.mod_upper_bound; lia].
117
+ - cbn [hmem]. rewrite length_map, length_seq. reflexivity.
118
+ - cbn [hmem]. apply Forall_forall. intros v Hin. apply in_map_iff in Hin as (j & <- & Hj). apply in_seq in Hj.
119
+ destruct (Nat.eqb j _); [apply Nat.mod_upper_bound; lia | apply memv_lt; [exact Hv | lia]].
120
+ Qed.
121
+
122
+ Lemma memv_setm : forall s c v j, j < SW A -> memv (setm A s c v) j = if Nat.eqb j c then v else memv s j.
123
+ Proof. intros s c v j Hj. unfold setm, memv at 1. cbn [hmem]. rewrite nth_map_seq by exact Hj. reflexivity. Qed.
124
+
125
+ Lemma hvalid_setm : forall s c v, hvalid A s -> v < SW A -> hvalid A (setm A s c v).
126
+ Proof.
127
+ intros s c v Hv Hvl. pose proof Hv as (Hp & _ & _). unfold setm. split; [exact Hp|]. split.
128
+ - cbn [hmem]. rewrite length_map, length_seq. reflexivity.
129
+ - cbn [hmem]. apply Forall_forall. intros x Hin. apply in_map_iff in Hin as (j & <- & Hj). apply in_seq in Hj.
130
+ destruct (Nat.eqb j c); [exact Hvl | apply memv_lt; [exact Hv | lia]].
131
+ Qed.
132
+
133
+ Lemma nth_byte : forall l i, Forall (fun b => b < 256) l -> nth i l 0 < 256.
134
+ Proof.
135
+ intros l i H. destruct (Nat.lt_ge_cases i (length l)) as [Hi|Hi].
136
+ - rewrite Forall_forall in H. apply H. apply nth_In. exact Hi.
137
+ - rewrite nth_overflow by exact Hi. lia.
138
+ Qed.
139
+
140
+ Lemma hvalid_device : forall s d, hvalid A s -> Forall (fun b => b < 256) (dtape d) ->
141
+ hvalid A (fst (device A s d)) /\ dtape (snd (device A s d)) = dtape d.
142
+ Proof.
143
+ intros s d Hv Ht. pose proof SW_big. split; [|reflexivity]. unfold device. cbv zeta. cbn [fst].
144
+ assert (Hs : forall v, v < 256 -> sext A v < SW A) by (intros v Hb; unfold sext; destruct (v <? 128); lia).
145
+ pose proof (Hs _ (nth_byte (dtape d) (dhead d) Ht)) as Hb.
146
+ repeat apply hvalid_setm; try lia.
147
+ destruct (Nat.eqb (memv s (crd A)) 1); [destruct (dhead d <? length (dtape d))|];
148
+ destruct (Nat.eqb (memv s (cwr A)) 1); repeat apply hvalid_setm; (exact Hv || lia).
149
+ Qed.
150
+
151
+ (* the device writes the request cells, the end-of-tape status and the two registers, words SW - 7 to SW - 2 *)
152
+ Definition dword (j : nat) : bool := (SW A - 7 <=? j) && (j <? SW A - 1).
153
+
154
+ Lemma device_keeps : forall s d, hpc (fst (device A s d)) = hpc s /\ hhalt (fst (device A s d)) = hhalt s
155
+ /\ forall j, j < SW A -> dword j = false -> memv (fst (device A s d)) j = memv s j.
156
+ Proof.
157
+ intros s d. pose proof SW_big. unfold device. cbv zeta. cbn [fst].
158
+ destruct (Nat.eqb (memv s (crd A)) 1); [destruct (dhead d <? length (dtape d))|];
159
+ destruct (Nat.eqb (memv s (cwr A)) 1); (split; [reflexivity | split; [reflexivity|]]);
160
+ intros j Hj Hd; unfold dword in Hd; apply andb_false_iff in Hd;
161
+ repeat (rewrite memv_setm by exact Hj); unfold cwr, crd, crw, ceot, rin, rout;
162
+ repeat match goal with |- context [Nat.eqb j ?c] => destruct (Nat.eqb_spec j c) end;
163
+ try reflexivity; (exfalso; destruct Hd as [Hd|Hd]; [apply Nat.leb_gt in Hd | apply Nat.ltb_ge in Hd]; lia).
164
+ Qed.
165
+
166
+ (* ---- the amplified levelized host ------------------------------------------------------------------------------- *)
167
+ Definition LH : list (list tu) := lev (nH A) (host_units A) (host_next A).
168
+
169
+ Lemma host_lev_hyps : wfn (nH A) (host_units A) /\ Forall (fun s => s < NS (nH A) (host_units A)) (host_next A)
170
+ /\ length (host_next A) = nH A /\ 1 <= dmax (nH A) (host_units A).
171
+ Proof.
172
+ split; [exact (fwfn (hblocks A) (nH A) (host_wf' A HA3))|]. split; [|split; [apply host_next_len | rewrite (host_dmax A HA3); lia]].
173
+ apply Forall_forall. intros s Hs. unfold host_next in Hs. apply in_map_iff in Hs as (i & <- & Hi). apply in_seq in Hi.
174
+ unfold NS, host_units. rewrite (length_compile _ _ (hb_shaped A HA3)). apply idx_lt_total. apply hout_valid; [exact HA3 | lia].
175
+ Qed.
176
+
177
+ Lemma lmap_LH : forall x, length x = nH A -> lmap LH x = netstep (nH A) (host_units A) (host_next A) x.
178
+ Proof.
179
+ intros x Hx. destruct host_lev_hyps as (H1 & H2 & H3 & H4). exact (lev_correct _ _ _ H1 H2 H3 H4 x Hx).
180
+ Qed.
181
+
182
+ Lemma lreads_LH : lreads (nH A) LH.
183
+ Proof. destruct host_lev_hyps as (H1 & H2 & H3 & H4). exact (lev_lreads _ _ _ H1 H2 H3 H4). Qed.
184
+
185
+ (* bit k of the state lies in a word the device writes *)
186
+ Definition dbit (k : nat) : bool := (A + 1 <=? k) && dword ((k - (A + 1)) / A).
187
+
188
+ (* one step of N_r: the amplified layers, then the device on the state read by majority, which writes every copy of
189
+ the bits of the cells it writes and leaves the other bits as the layers left them *)
190
+ Definition stepr (c : list bool * dev) : list bool * dev :=
191
+ let y := lmap (amap r (nH A) LH) (fst c) in
192
+ let c' := device A (decodeH (maj r (nH A) y)) (snd c) in
193
+ (map (fun k => if dbit (k mod nH A) then nth (k mod nH A) (encodeH A (fst c')) false else nth k y false)
194
+ (seq 0 (length y)), snd c').
195
+
196
+ Fixpoint runr (t : nat) (c : list bool * dev) : list bool * dev :=
197
+ match t with O => c | S t' => stepr (runr t' c) end.
198
+
199
+ Lemma maj_rep : forall x, length x = nH A -> maj r (nH A) (rep r x) = x.
200
+ Proof.
201
+ intros x Hx. rewrite <- (xorv_false (rep r x)). apply maj_ok; [exact Hr | exact Hx|].
202
+ intros j Hj. assert (Z : forall k, ncnt k (fun _ => false) = 0) by (induction k as [|k IHk]; cbn [ncnt]; [reflexivity | rewrite IHk; reflexivity]).
203
+ cbv beta. rewrite Z. lia.
204
+ Qed.
205
+
206
+ (* off the cells the device writes, the state before and after the device have the same bits *)
207
+ Lemma enc_agree : forall s1 s2, hvalid A s1 -> hvalid A s2 -> hpc s2 = hpc s1 -> hhalt s2 = hhalt s1 ->
208
+ (forall j, j < SW A -> dword j = false -> memv s2 j = memv s1 j) ->
209
+ forall k, k < nH A -> dbit k = false -> nth k (encodeH A s2) false = nth k (encodeH A s1) false.
210
+ Proof.
211
+ intros s1 s2 (_ & L1 & _) (_ & L2 & _) Ep Eh Em k Hk Hd. unfold nH in Hk.
212
+ destruct (Nat.lt_ge_cases k A) as [Hk1|Hk1]; [rewrite !nth_encodeH_pc, Ep by exact Hk1; reflexivity|].
213
+ destruct (Nat.eq_dec k A) as [->|Hk2]; [rewrite !nth_encodeH_halt, Eh; reflexivity|].
214
+ set (j := (k - (A + 1)) / A). set (t := (k - (A + 1)) mod A).
215
+ assert (Ek : k = A + 1 + j * A + t) by (unfold j, t; pose proof (Nat.div_mod (k - (A + 1)) A ltac:(lia)); lia).
216
+ assert (Hj : j < SW A) by (unfold j; apply Nat.Div0.div_lt_upper_bound; nia).
217
+ assert (Ht : t < A) by (unfold t; apply Nat.mod_upper_bound; lia).
218
+ unfold dbit in Hd. fold j in Hd. replace (A + 1 <=? k) with true in Hd by (symmetry; apply Nat.leb_le; lia).
219
+ cbn [andb] in Hd. rewrite Ek, !nth_encodeH_mem by assumption. rewrite (Em j Hj Hd). reflexivity.
220
+ Qed.
221
+
222
+ (* from a replicated state, a step of N_r is the replicated step of the transducer *)
223
+ Lemma stepr_rep : forall s d, hvalid A s -> Forall (fun b => b < 256) (dtape d) ->
224
+ stepr (rep r (encodeH A s), d) = (rep r (encodeH A (fst (tstep A (s, d)))), snd (tstep A (s, d))).
225
+ Proof.
226
+ intros s d Hv Ht. pose proof (hvalid_subleq s Hv) as Hv'. pose proof Hv' as (_ & Hl' & _).
227
+ pose proof Hv as (_ & Hl & _).
228
+ assert (Y : lmap (amap r (nH A) LH) (rep r (encodeH A s)) = rep r (encodeH A (subleq A s))).
229
+ { rewrite <- (length_encodeH A s Hl) at 1.
230
+ rewrite amap_rep by (exact Hr || (rewrite length_encodeH by exact Hl; exact lreads_LH)).
231
+ rewrite lmap_LH by (apply length_encodeH; exact Hl). rewrite host_step by (exact HA3 || exact Hv). reflexivity. }
232
+ unfold stepr. cbn [fst snd]. rewrite Y, maj_rep by (apply length_encodeH; exact Hl'). rewrite decode_encode by exact Hv'.
233
+ change (device A (subleq A s) d) with (tstep A (s, d)).
234
+ destruct (hvalid_device (subleq A s) d Hv' Ht) as [Hvs _]. destruct (device_keeps (subleq A s) d) as (Ep & Eh & Em).
235
+ change (device A (subleq A s) d) with (tstep A (s, d)) in Hvs, Ep, Eh, Em.
236
+ set (s' := fst (tstep A (s, d))) in *. pose proof Hvs as (_ & Ls' & _).
237
+ f_equal. apply nth_ext with (d := false) (d' := false).
238
+ - rewrite length_map, length_seq, !length_rep, !length_encodeH by assumption. reflexivity.
239
+ - intros k Hk. rewrite length_map, length_seq, length_rep, length_encodeH in Hk by exact Hl'.
240
+ rewrite nth_map_seq by (rewrite length_rep, length_encodeH by exact Hl'; exact Hk).
241
+ rewrite (nth_rep_mod r (encodeH A s') k) by (rewrite length_encodeH by exact Ls'; exact Hk).
242
+ rewrite (nth_rep_mod r (encodeH A (subleq A s)) k) by (rewrite length_encodeH by exact Hl'; exact Hk).
243
+ rewrite !length_encodeH by assumption.
244
+ assert (Hkm : k mod nH A < nH A) by (apply Nat.mod_upper_bound; unfold nH; lia).
245
+ destruct (dbit (k mod nH A)) eqn:Db; [reflexivity|].
246
+ symmetry. apply (enc_agree (subleq A s) s' Hv' Hvs Ep Eh Em (k mod nH A) Hkm Db).
247
+ Qed.
248
+
249
+ Lemma trun_inv : forall t c, hvalid A (fst c) -> Forall (fun b => b < 256) (dtape (snd c)) ->
250
+ hvalid A (fst (trun A t c)) /\ dtape (snd (trun A t c)) = dtape (snd c).
251
+ Proof.
252
+ induction t as [|t IH]; intros c Hv Ht; [split; [exact Hv | reflexivity]|]. cbn [trun].
253
+ destruct (hvalid_device (subleq A (fst c)) (snd c) (hvalid_subleq (fst c) Hv) Ht) as [H1 H2].
254
+ destruct (IH (tstep A c) H1 ltac:(unfold tstep; rewrite H2; exact Ht)) as [IH1 IH2].
255
+ split; [exact IH1|]. rewrite IH2. exact H2.
256
+ Qed.
257
+
258
+ (* Corollary 6.13: from a replicated state, N_r visits the replicated states of the transducer's run and emits the
259
+ same bytes *)
260
+ Theorem amp_run : forall t s d, hvalid A s -> Forall (fun b => b < 256) (dtape d) ->
261
+ runr t (rep r (encodeH A s), d) = (rep r (encodeH A (fst (trun A t (s, d)))), snd (trun A t (s, d))).
262
+ Proof.
263
+ induction t as [|t IH]; intros s d Hv Ht; [reflexivity|]. cbn [runr]. rewrite IH by assumption.
264
+ destruct (trun_inv t (s, d) Hv Ht) as [Hvt Htt].
265
+ rewrite stepr_rep by (exact Hvt || (rewrite Htt; exact Ht)).
266
+ rewrite <- surjective_pairing. replace (S t) with (t + 1) by lia. rewrite trun_add. reflexivity.
267
+ Qed.
268
+
269
+ (* ---- on P* ------------------------------------------------------------------------------------------------------- *)
270
+ Lemma recipe_bytes : forall ks, Forall tok_ok ks -> Forall (fun b => b < 256) (recipe ks).
271
+ Proof.
272
+ intros ks Hks. unfold recipe. apply Forall_app. split; [|apply Forall_cons; [lia | apply Forall_nil]].
273
+ induction ks as [|k ks IH]; [constructor|]. inversion Hks as [|? ? Hk Hks']; subst. cbn [map concat].
274
+ apply Forall_app. split; [|exact (IH Hks')].
275
+ destruct k as [bs|t b]; cbn [enc tok_ok] in *.
276
+ - destruct Hk as [Hl Hb]. apply Forall_cons; [lia | exact Hb].
277
+ - destruct Hk as [Ht Hb]. apply Forall_cons; [lia|]. apply Forall_cons; [lia | apply Forall_nil].
278
+ Qed.
279
+
280
+ Lemma prog_bounds : Forall (fun '(a, b, c) => a < SW A /\ b < SW A /\ c < SW A) (progPstar A).
281
+ Proof.
282
+ pose proof SW_big. unfold progPstar, decode_loop, t2c, t1c, neg1c, crd, rin, zc, rout, cwr, onec, crw, ceot, eokc, haltc.
283
+ repeat (apply Forall_cons || apply Forall_nil || split); lia.
284
+ Qed.
285
+
286
+ Lemma hvalid_init : forall tau, hvalid A (fst (init A (progPstar A) tau)).
287
+ Proof.
288
+ intro tau. pose proof SW_big. cbn [init fst]. split; [cbn [hpc]; lia|]. split.
289
+ - cbn [hmem]. unfold image. rewrite length_map, length_seq. reflexivity.
290
+ - cbn [hmem]. unfold image. apply Forall_forall. intros v Hin. apply in_map_iff in Hin as (j & <- & Hj). apply in_seq in Hj.
291
+ unfold img0. destruct (j <? 3 * length (progPstar A)).
292
+ + unfold word. pose proof prog_bounds as F. rewrite Forall_forall in F.
293
+ destruct (nth_in_or_default (j / 3) (progPstar A) (0, 0, 0)) as [Hin|Hd].
294
+ * destruct (nth (j / 3) (progPstar A) (0, 0, 0)) as [[a b] c] eqn:E. destruct (F _ Hin) as (Ha & Hb & Hc).
295
+ destruct (j mod 3) as [|[|]]; assumption.
296
+ * rewrite Hd. destruct (j mod 3) as [|[|]]; lia.
297
+ + unfold onec, neg1c, eokc. destruct (Nat.eqb j _); [lia|]. destruct (Nat.eqb j _); [lia|]. destruct (Nat.eqb j _); lia.
298
+ Qed.
299
+
300
+ (* N_r running P* on a recipe reads its halt bit as 0 for the steps of Proposition 5.3 and as 1 after them, and has
301
+ emitted the decoded string followed by the recipe *)
302
+ Theorem amp_selfrep : forall ks, Forall tok_ok ks ->
303
+ let c0 := init A (progPstar A) (recipe ks) in
304
+ let N := (dsteps ks + 7 + 1 + (6 * length (recipe ks) + 2))%nat in
305
+ (forall t, t < N -> nth A (maj r (nH A) (fst (runr t (rep r (encodeH A (fst c0)), snd c0)))) false = false)
306
+ /\ nth A (maj r (nH A) (fst (runr N (rep r (encodeH A (fst c0)), snd c0)))) false = true
307
+ /\ dout (snd (runr N (rep r (encodeH A (fst c0)), snd c0))) = delta ks ++ recipe ks.
308
+ Proof.
309
+ intros ks Hks c0 N. destruct (selfrep_run A HA ks Hks) as [H1 (H2 & H3 & _)]. fold c0 N in H1, H2, H3.
310
+ assert (Hv : hvalid A (fst c0)) by apply hvalid_init.
311
+ assert (Ht : Forall (fun b => b < 256) (dtape (snd c0))) by (cbn [c0 init snd dtape]; apply recipe_bytes; exact Hks).
312
+ assert (R : forall t, runr t (rep r (encodeH A (fst c0)), snd c0) = (rep r (encodeH A (fst (trun A t c0))), snd (trun A t c0))).
313
+ { intro t. rewrite amp_run by assumption. rewrite <- surjective_pairing. reflexivity. }
314
+ assert (M : forall t, nth A (maj r (nH A) (fst (runr t (rep r (encodeH A (fst c0)), snd c0)))) false = hhalt (fst (trun A t c0))).
315
+ { intro t. rewrite R. cbn [fst]. destruct (trun_inv t c0 Hv Ht) as [(_ & Lt & _) _].
316
+ rewrite maj_rep by (apply length_encodeH; exact Lt). apply nth_encodeH_halt. }
317
+ split; [intros t Hlt; rewrite M; exact (H1 t Hlt)|]. split; [rewrite M; exact H2|]. rewrite R. exact H3.
318
+ Qed.
319
+
320
+ End AmpHost.
rocq/Assumptions.v CHANGED
@@ -1,6 +1,13 @@
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.
@@ -39,3 +46,92 @@ Print Assumptions StoredMain.network_reproduces.
39
  Print Assumptions StoredMain.network_periodic.
40
  Print Assumptions StoredWidth.width_exists.
41
  Print Assumptions StoredWidth.recipe_of_image.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* The assumptions of the main theorems, printed by src/paper.py rocq after the build. The theorems on the netlists,
2
+ the machines and the programs depend on no axiom; those on real numbers on the axioms of the standard library's
3
+ real numbers; the numbers evaluated by the interval tactic also on the specifications of the primitive integers and
4
+ floating-point numbers. *)
5
+ Set Warnings "-ambiguous-paths".
6
  From TH Require Import PhysSem PhysMain PhysFacts NetMain Complete Decoder Run PassLemma Main HostSem Pstar
7
+ StoredBoot StoredPass StoredDev StoredOk StoredRun StoredWbr StoredMain StoredWidth
8
+ Recipe Lower Lev HostLev HostCount StoredProp StoredCount PhysLev Margin Erfc Choose Noise NoiseNum Restore FlipLower
9
+ AmpHost.
10
+ Set Warnings "ambiguous-paths".
11
 
12
  Print Assumptions PhysSem.netlist_step.
13
  Print Assumptions PhysMain.network_orbit.
 
46
  Print Assumptions StoredMain.network_periodic.
47
  Print Assumptions StoredWidth.width_exists.
48
  Print Assumptions StoredWidth.recipe_of_image.
49
+ Print Assumptions StoredProp.stored_pass.
50
+ Print Assumptions Recipe.desc_spec.
51
+ Print Assumptions Recipe.describe_spec.
52
+ Print Assumptions Recipe.recipes_complete.
53
+ Print Assumptions Recipe.recipe_optimal.
54
+ Print Assumptions Recipe.describe_steps.
55
+ Print Assumptions Recipe.psteps_lower.
56
+ Print Assumptions Lev.lev_ok.
57
+ Print Assumptions Lev.lev_units.
58
+ Print Assumptions Lev.lev_widths.
59
+ Print Assumptions Lev.lev_size.
60
+ Print Assumptions HostLev.host_dmax.
61
+ Print Assumptions HostLev.host_lev_widths.
62
+ Print Assumptions HostLev.host_lev_rows.
63
+ Print Assumptions HostLev.host_lev_widths_8.
64
+ Print Assumptions HostLev.host_lev_rows_8.
65
+ Print Assumptions HostLev.host_lev_dense_8.
66
+ Print Assumptions HostLev.host_lev_widest_8.
67
+ Print Assumptions HostCount.host_units_count.
68
+ Print Assumptions HostCount.host_memory_count.
69
+ Print Assumptions HostCount.host_edges.
70
+ Print Assumptions HostCount.host_weights_biases.
71
+ Print Assumptions HostCount.host_lev_identity.
72
+ Print Assumptions HostCount.host_units_8.
73
+ Print Assumptions HostCount.host_edges_8.
74
+ Print Assumptions HostCount.host_memory_8.
75
+ Print Assumptions HostCount.host_lev_identity_8.
76
+ Print Assumptions HostCount.host_lev_nonzero_8.
77
+ Print Assumptions StoredCount.stored_records.
78
+ Print Assumptions StoredCount.alpha_bounds.
79
+ Print Assumptions StoredCount.width_least.
80
+ Print Assumptions StoredCount.generation_bounds.
81
+ Print Assumptions PhysLev.phys_dmax.
82
+ Print Assumptions PhysLev.phys_lev_depth.
83
+ Print Assumptions PhysLev.phys_lev_rows.
84
+ Print Assumptions PhysLev.phys_edges.
85
+ Print Assumptions PhysLev.phys_lev_rows_15.
86
+ Print Assumptions PhysLev.phys_lev_rows_S.
87
+ Print Assumptions Lower.read_needs_two_levels.
88
+ Print Assumptions Lower.onehot_needs_two_levels.
89
+ Print Assumptions Lower.branch_not_ternary.
90
+ Print Assumptions Margin.margin.
91
+ Print Assumptions Margin.margin_tight.
92
+ Print Assumptions Margin.mismatch_all.
93
+ Print Assumptions Margin.mismatch_run.
94
+ Print Assumptions Margin.amap_rep.
95
+ Print Assumptions Margin.amp_wrong.
96
+ Print Assumptions Margin.amp_margin.
97
+ Print Assumptions Margin.flip_ok.
98
+ Print Assumptions Erfc.gauss_square.
99
+ Print Assumptions Erfc.erfc_le_exp.
100
+ Print Assumptions Erfc.erfc_upper1.
101
+ Print Assumptions Erfc.erfc_upper3.
102
+ Print Assumptions Erfc.erfc_lower1.
103
+ Print Assumptions Choose.binom_bound.
104
+ Print Assumptions Noise.union_bound.
105
+ Print Assumptions Noise.union_gauss.
106
+ Print Assumptions Noise.profile_step.
107
+ Print Assumptions Noise.profile_le.
108
+ Print Assumptions Noise.copy_bound.
109
+ Print Assumptions Noise.union_profile.
110
+ Print Assumptions Noise.amp_union.
111
+ Print Assumptions Noise.amp_gauss.
112
+ Print Assumptions Noise.amp_profile.
113
+ Print Assumptions Noise.amp_choose.
114
+ Print Assumptions Noise.amp_choose_exp.
115
+ Print Assumptions Noise.synapse_bound.
116
+ Print Assumptions Noise.flip_bound.
117
+ Print Assumptions Noise.flip_choose.
118
+ Print Assumptions NoiseNum.p_005.
119
+ Print Assumptions NoiseNum.TMp_005.
120
+ Print Assumptions NoiseNum.TMp_010.
121
+ Print Assumptions NoiseNum.flip_threshold.
122
+ Print Assumptions NoiseNum.synapse_005.
123
+ Print Assumptions NoiseNum.synapse_010.
124
+ Print Assumptions NoiseNum.N3_first_order.
125
+ Print Assumptions NoiseNum.generation_1.
126
+ Print Assumptions NoiseNum.generation_3.
127
+ Print Assumptions NoiseNum.generation_5.
128
+ Print Assumptions Restore.tw_paper.
129
+ Print Assumptions Restore.far_core.
130
+ Print Assumptions Restore.wrong_far.
131
+ Print Assumptions Restore.claims.
132
+ Print Assumptions Restore.claim_stop.
133
+ Print Assumptions Restore.restoration.
134
+ Print Assumptions FlipLower.P_few.
135
+ Print Assumptions FlipLower.flip_fails.
136
+ Print Assumptions AmpHost.amp_run.
137
+ Print Assumptions AmpHost.amp_selfrep.
rocq/BlockLev.v ADDED
@@ -0,0 +1,564 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* The levelization of a netlist given in blocks (Lemma 2.6 applied): the depth of every signal, the last layer that
2
+ reads it and the width of every layer, from claims that are checked block by block. *)
3
+ From Stdlib Require Import List Bool Arith ZArith Lia.
4
+ Import ListNotations.
5
+ From TH Require Import TwoHead Net Lev.
6
+
7
+ (* ---- finite sums -------------------------------------------------------------------------------------------- *)
8
+ Fixpoint nsum (k : nat) (g : nat -> nat) : nat := match k with O => 0 | S k' => nsum k' g + g k' end.
9
+
10
+ Lemma nsum_ext : forall k g h, (forall i, i < k -> g i = h i) -> nsum k g = nsum k h.
11
+ Proof. induction k as [|k IH]; intros g h H; cbn [nsum]; [reflexivity|]. rewrite (IH g h), (H k); [reflexivity | lia |]. intros i Hi. apply H. lia. Qed.
12
+
13
+ Lemma nsum_const : forall k c, nsum k (fun _ => c) = k * c.
14
+ Proof. induction k as [|k IH]; intro c; cbn [nsum]; [reflexivity|]. rewrite IH. lia. Qed.
15
+
16
+ Lemma nsum_add : forall k g h, nsum k (fun i => g i + h i) = nsum k g + nsum k h.
17
+ Proof. induction k as [|k IH]; intros g h; cbn [nsum]; [reflexivity|]. rewrite IH. lia. Qed.
18
+
19
+ Lemma nsum_split : forall a b g, nsum (a + b) g = nsum a g + nsum b (fun i => g (a + i)).
20
+ Proof.
21
+ intros a b g. induction b as [|b IH]; [rewrite Nat.add_0_r; cbn [nsum]; lia|].
22
+ replace (a + S b) with (S (a + b)) by lia. cbn [nsum]. rewrite IH. lia.
23
+ Qed.
24
+
25
+ Lemma nsum_mul : forall c s g, nsum (c * s) g = nsum c (fun j => nsum s (fun r => g (s * j + r))).
26
+ Proof.
27
+ induction c as [|c IH]; intros s g; cbn [nsum]; [reflexivity|]. replace (S c * s) with (c * s + s) by lia.
28
+ rewrite nsum_split, IH. f_equal. apply nsum_ext. intros r Hr. f_equal. lia.
29
+ Qed.
30
+
31
+ Lemma nsum_le : forall k g h, (forall i, i < k -> g i <= h i) -> nsum k g <= nsum k h.
32
+ Proof. induction k as [|k IH]; intros g h H; cbn [nsum]; [lia|]. pose proof (IH g h (fun i Hi => H i ltac:(lia))). pose proof (H k ltac:(lia)). lia. Qed.
33
+
34
+ Lemma nsum_zero : forall k g, (forall i, i < k -> g i = 0) -> nsum k g = 0.
35
+ Proof. intros k g H. rewrite (nsum_ext k g (fun _ => 0)) by exact H. rewrite nsum_const. lia. Qed.
36
+
37
+ Lemma nsum_one : forall k g j, j < k -> (forall i, i < k -> i <> j -> g i = 0) -> nsum k g = g j.
38
+ Proof.
39
+ induction k as [|k IH]; intros g j Hj H; [lia|]. cbn [nsum]. destruct (Nat.eq_dec j k) as [->|E].
40
+ - rewrite nsum_zero; [lia|]. intros i Hi. apply H; lia.
41
+ - rewrite (IH g j) by (lia || (intros i Hi Hne; apply H; lia)). rewrite (H k) by lia. lia.
42
+ Qed.
43
+
44
+ Lemma nsum_swap : forall a b (f : nat -> nat -> nat), nsum a (fun i => nsum b (f i)) = nsum b (fun j => nsum a (fun i => f i j)).
45
+ Proof.
46
+ induction a as [|a IH]; intros b f; cbn [nsum].
47
+ - symmetry. apply nsum_zero. reflexivity.
48
+ - rewrite IH, <- nsum_add. reflexivity.
49
+ Qed.
50
+
51
+ Lemma nsum_eq_split : forall k a u v, a < k -> nsum k (fun j => if Nat.eqb j a then u else v) = (k - 1) * v + u.
52
+ Proof.
53
+ induction k as [|k IH]; intros a u v Ha; [lia|]. cbn [nsum]. destruct (Nat.eqb_spec k a) as [<-|E].
54
+ - rewrite (nsum_ext k _ (fun _ => v)) by (intros i Hi; destruct (Nat.eqb_spec i k); [lia | reflexivity]).
55
+ rewrite nsum_const. lia.
56
+ - rewrite IH by lia. destruct k; [lia|]. lia.
57
+ Qed.
58
+
59
+ Lemma nsum_lt_split : forall k a u v, a <= k -> nsum k (fun j => if j <? a then u else v) = a * u + (k - a) * v.
60
+ Proof.
61
+ intros k a u v Ha. replace k with (a + (k - a)) at 1 by lia. rewrite nsum_split.
62
+ rewrite (nsum_ext a _ (fun _ => u)) by (intros i Hi; destruct (Nat.ltb_spec i a); [reflexivity | lia]).
63
+ rewrite (nsum_ext (k - a) _ (fun _ => v)) by (intros i Hi; destruct (Nat.ltb_spec (a + i) a); [lia | reflexivity]).
64
+ rewrite !nsum_const. lia.
65
+ Qed.
66
+
67
+ Lemma nsum_succ : forall k g, nsum (S k) g = nsum k g + g k.
68
+ Proof. reflexivity. Qed.
69
+
70
+ Lemma nsum_mulc : forall k f c, nsum k (fun i => f i * c) = nsum k f * c.
71
+ Proof. induction k as [|k IH]; intros f c; cbn [nsum]; [reflexivity|]. rewrite IH. lia. Qed.
72
+
73
+ Lemma fold_nsum_seq : forall m (f : nat -> nat), fold_right Nat.add 0 (map f (seq 0 m)) = nsum m f.
74
+ Proof.
75
+ assert (G : forall l c, fold_right Nat.add c l = fold_right Nat.add 0 l + c)
76
+ by (induction l as [|y l IHl]; intro c; cbn [fold_right]; [reflexivity | rewrite IHl; lia]).
77
+ induction m as [|m IH]; intro f; [reflexivity|]. rewrite seq_S, map_app, fold_right_app. cbn [map fold_right nsum].
78
+ rewrite G, IH. cbn [Nat.add]. lia.
79
+ Qed.
80
+
81
+ Lemma length_filter_seq : forall (f : nat -> bool) a k, length (filter f (seq a k)) = nsum k (fun i => Nat.b2n (f (a + i))).
82
+ Proof.
83
+ intros f a k. revert a. induction k as [|k IH]; intro a; [reflexivity|].
84
+ rewrite seq_S, filter_app, length_app, IH. cbn [nsum filter]. destruct (f (a + k)); cbn [length Nat.b2n]; lia.
85
+ Qed.
86
+
87
+ Definition usu (bs : list block) (x : sref) : su := match x with SIn _ => su0 | SRef b j r => sunit bs b j r end.
88
+
89
+ (* ---- the rows of a layered map by their sources ------------------------------------------------------------ *)
90
+ Definition isUn (c : src) : bool := match c with Un _ => true | Cp _ => false end.
91
+ Definition rowlen (us : list tu) (n : nat) (c : src) : nat := match c with Cp _ => 1 | Un s => length (tin (nth (s - n) us tu0)) end.
92
+
93
+ Lemma count_Un : forall (L : list src) n m, (forall s, In (Un s) L -> n <= s < n + m) ->
94
+ length (filter isUn L) = nsum m (fun k => length (filter (isun (n + k)) L)).
95
+ Proof.
96
+ induction L as [|c t IH]; intros n m H; cbn [filter length].
97
+ - symmetry. apply nsum_zero. reflexivity.
98
+ - rewrite (nsum_ext m _ (fun k => (if isun (n + k) c then 1 else 0) + length (filter (isun (n + k)) t)))
99
+ by (intros k _; cbn [filter]; destruct (isun (n + k) c); reflexivity).
100
+ rewrite nsum_add, <- IH by (intros s Hs; apply H; right; exact Hs).
101
+ destruct c as [s|s]; cbn [isUn isun].
102
+ + rewrite nsum_zero by reflexivity. lia.
103
+ + specialize (H s (or_introl eq_refl)). rewrite (nsum_one m _ (s - n)); [| lia |].
104
+ * replace (n + (s - n)) with s by lia. rewrite Nat.eqb_refl. cbn [length]. lia.
105
+ * intros k Hk E. destruct (Nat.eqb_spec s (n + k)); [lia | reflexivity].
106
+ Qed.
107
+
108
+ Lemma sum_rowlen : forall (L : list src) us n m, (forall s, In (Un s) L -> n <= s < n + m) ->
109
+ fold_right Nat.add 0 (map (rowlen us n) L)
110
+ = length (filter (fun c => negb (isUn c)) L) + nsum m (fun k => length (filter (isun (n + k)) L) * length (tin (nth k us tu0))).
111
+ Proof.
112
+ induction L as [|c t IH]; intros us n m H; cbn [map fold_right filter length].
113
+ - rewrite nsum_zero by reflexivity. reflexivity.
114
+ - rewrite (nsum_ext m _ (fun k => (if isun (n + k) c then length (tin (nth k us tu0)) else 0)
115
+ + length (filter (isun (n + k)) t) * length (tin (nth k us tu0))))
116
+ by (intros k _; cbn [filter]; destruct (isun (n + k) c); cbn [length]; lia).
117
+ rewrite nsum_add, (IH us n m) by (intros s Hs; apply H; right; exact Hs).
118
+ destruct c as [s|s]; cbn [isUn isun negb rowlen].
119
+ + rewrite (nsum_zero m (fun _ => 0)) by reflexivity. cbn [length]. lia.
120
+ + specialize (H s (or_introl eq_refl)).
121
+ rewrite (nsum_one m (fun k => if Nat.eqb s (n + k) then length (tin (nth k us tu0)) else 0) (s - n)); [| lia |].
122
+ * replace (n + (s - n)) with s by lia. rewrite Nat.eqb_refl. lia.
123
+ * intros k Hk E. destruct (Nat.eqb_spec s (n + k)); [lia | reflexivity].
124
+ Qed.
125
+
126
+ Lemma fold_add : forall (l : list nat) c, fold_right Nat.add c l = fold_right Nat.add 0 l + c.
127
+ Proof. induction l as [|a t IH]; intro c; cbn [fold_right]; [reflexivity|]. rewrite IH. lia. Qed.
128
+
129
+ Lemma fold_add_app : forall (l1 l2 : list nat), fold_right Nat.add 0 (l1 ++ l2) = fold_right Nat.add 0 l1 + fold_right Nat.add 0 l2.
130
+ Proof. intros l1 l2. rewrite fold_right_app, fold_add. lia. Qed.
131
+
132
+ (* the rows of Lev(N) and their entries, by their sources *)
133
+ Lemma lev_rowcount : forall n us nx, length (concat (lev n us nx)) = length (concat (map snd (lsrc n us nx))).
134
+ Proof.
135
+ intros n us nx. unfold lev. induction (lsrc n us nx) as [|[l cs] P IH]; [reflexivity|].
136
+ cbn [map concat fst snd]. rewrite !length_app, length_map, IH. reflexivity.
137
+ Qed.
138
+
139
+ Lemma lev_rowlens : forall n us nx,
140
+ fold_right Nat.add 0 (map (fun row => length (tin row)) (concat (lev n us nx)))
141
+ = fold_right Nat.add 0 (map (rowlen us n) (concat (map snd (lsrc n us nx)))).
142
+ Proof.
143
+ intros n us nx. unfold lev. induction (lsrc n us nx) as [|[l cs] P IH]; [reflexivity|].
144
+ cbn [map concat fst snd]. rewrite !map_app, !fold_add_app, IH. f_equal. f_equal. rewrite map_map.
145
+ apply map_ext. intros [s|s]; cbn [mkrow rowlen idr reidx tin]; [reflexivity|]. apply length_map.
146
+ Qed.
147
+
148
+ Lemma boff_S_gen : forall bs b, b < length bs -> boff bs (S b) = boff bs b + bcount (nth b bs blk0) * bsize (nth b bs blk0).
149
+ Proof.
150
+ induction bs as [|blk t IH]; intros b Hb; cbn [length] in Hb; [lia|].
151
+ destruct b as [|b]; cbn [boff nth]; [assert (boff t 0 = 0) by (destruct t; reflexivity); lia|]. rewrite IH by lia. lia.
152
+ Qed.
153
+
154
+ Definition isref (x : sref) : bool := match x with SIn _ => false | SRef _ _ _ => true end.
155
+
156
+ Section BL.
157
+ Variable bs : list block.
158
+ Variable n : nat.
159
+ Variable out : nat -> sref.
160
+ Hypothesis Hwf : wf bs n.
161
+ Hypothesis Hout : forall i, i < n -> valid bs n (out i).
162
+
163
+ Definition fus : list tu := compile n bs.
164
+ Definition fnx : list nat := map (fun i => idx n bs (out i)) (seq 0 n).
165
+ Definition nun : nat := boff bs (length bs).
166
+
167
+ Definition cnt (b : nat) : nat := bcount (nth b bs blk0).
168
+ Definition sz (b : nat) : nat := bsize (nth b bs blk0).
169
+
170
+ (* the sum of g over the units, block by block *)
171
+ Definition bsum (g : sref -> nat) : nat := nsum (length bs) (fun b => nsum (cnt b) (fun j => nsum (sz b) (fun r => g (SRef b j r)))).
172
+
173
+ Lemma shaped_all : Forall shaped bs.
174
+ Proof. exact (proj1 Hwf). Qed.
175
+
176
+ Lemma fus_len : length fus = nun.
177
+ Proof. unfold fus, nun. apply length_compile. exact shaped_all. Qed.
178
+
179
+ Lemma fwfn : wfn n fus.
180
+ Proof. intros k Hk. exact (wf_reads_below bs n Hwf k Hk). Qed.
181
+
182
+ Lemma fnx_len : length fnx = n.
183
+ Proof. unfold fnx. rewrite length_map, length_seq. reflexivity. Qed.
184
+
185
+ Lemma boff_S : forall b, b < length bs -> boff bs (S b) = boff bs b + cnt b * sz b.
186
+ Proof. intros b Hb. unfold cnt, sz. apply boff_S_gen. exact Hb. Qed.
187
+
188
+ Lemma nsum_units : forall (g : nat -> nat), nsum nun g = bsum (fun x => match x with SRef b j r => g (boff bs b + sz b * j + r) | SIn _ => 0 end).
189
+ Proof.
190
+ intro g. unfold nun, bsum.
191
+ assert (G : forall k, k <= length bs -> nsum (boff bs k) g
192
+ = nsum k (fun b => nsum (cnt b) (fun j => nsum (sz b) (fun r => g (boff bs b + sz b * j + r))))).
193
+ { induction k as [|k IH]; intro Hk; [destruct bs; reflexivity|].
194
+ rewrite boff_S by lia. cbn [nsum]. rewrite nsum_split, IH by lia. f_equal.
195
+ rewrite (Nat.mul_comm (cnt k) (sz k)) at 1. rewrite Nat.mul_comm, nsum_mul. apply nsum_ext. intros j Hj.
196
+ apply nsum_ext. intros r Hr. f_equal. lia. }
197
+ apply G. lia.
198
+ Qed.
199
+
200
+ Lemma nsum_bsum_swap : forall m (g : nat -> sref -> nat), nsum m (fun l => bsum (g l)) = bsum (fun x => nsum m (fun l => g l x)).
201
+ Proof.
202
+ intros m g. unfold bsum. rewrite nsum_swap. apply nsum_ext. intros b _. rewrite nsum_swap. apply nsum_ext.
203
+ intros j _. apply nsum_swap.
204
+ Qed.
205
+
206
+ Lemma bsum_ext : forall g1 g2, (forall b j r, valid bs n (SRef b j r) -> g1 (SRef b j r) = g2 (SRef b j r)) ->
207
+ bsum g1 = bsum g2.
208
+ Proof.
209
+ intros g1 g2 H. unfold bsum. apply nsum_ext. intros b Hb. apply nsum_ext. intros j Hj. apply nsum_ext. intros r Hr.
210
+ apply H. split; [exact Hb | split; [exact Hj | exact Hr]].
211
+ Qed.
212
+
213
+ (* locating a unit *)
214
+ Lemma loc : forall k, k < nun -> exists b j r, valid bs n (SRef b j r) /\ k = boff bs b + sz b * j + r.
215
+ Proof.
216
+ unfold nun, sz, valid. pose proof shaped_all as Hsh. clear -Hsh. intros k Hk. revert k Hk.
217
+ induction Hsh as [|blk t Hs Ht IH]; intros k Hk; cbn [boff length] in Hk; [lia|].
218
+ destruct (Nat.lt_ge_cases k (bcount blk * bsize blk)) as [Hl|Hg].
219
+ - exists 0, (k / bsize blk), (k mod bsize blk).
220
+ assert (bsize blk <> 0) by (intro E; rewrite E in Hl; lia).
221
+ cbn [nth length boff]. split; [split; [lia|]; split; [apply Nat.Div0.div_lt_upper_bound; nia | apply Nat.mod_upper_bound; exact H]|].
222
+ rewrite (Nat.div_mod k (bsize blk)) at 1 by exact H. lia.
223
+ - destruct (IH (k - bcount blk * bsize blk) ltac:(lia)) as (b & j & r & (Hb & Hj & Hr) & Hk').
224
+ exists (S b), j, r. cbn [nth length boff]. split; [split; [lia|]; split; assumption|]. lia.
225
+ Qed.
226
+
227
+ Lemma idx_ref : forall b j r, idx n bs (SRef b j r) = n + (boff bs b + sz b * j + r).
228
+ Proof. intros b j r. cbn [idx]. unfold sz. lia. Qed.
229
+
230
+ Lemma fus_nth : forall b j r, valid bs n (SRef b j r) ->
231
+ nth (boff bs b + sz b * j + r) fus tu0 = flat_unit n bs (sunit bs b j r).
232
+ Proof. intros b j r (Hb & Hj & Hr). unfold fus, sz. apply compile_nth; [exact shaped_all | exact Hb | exact Hj | exact Hr]. Qed.
233
+
234
+ Lemma unit_lt : forall b j r, valid bs n (SRef b j r) -> boff bs b + sz b * j + r < nun.
235
+ Proof.
236
+ intros b j r Hv. pose proof (idx_lt_total bs n (SRef b j r) Hv) as H. rewrite idx_ref in H. unfold nun. lia.
237
+ Qed.
238
+
239
+ (* the units and the edges, block by block *)
240
+ Lemma units_bsum : length fus = bsum (fun _ => 1).
241
+ Proof.
242
+ rewrite fus_len. rewrite <- (Nat.mul_1_r nun) at 1. rewrite <- nsum_const, nsum_units.
243
+ apply bsum_ext. reflexivity.
244
+ Qed.
245
+
246
+ Lemma edges_bsum : nsum (length fus) (fun k => length (tin (nth k fus tu0))) = bsum (fun x => length (sin (usu bs x))).
247
+ Proof.
248
+ rewrite fus_len, nsum_units. apply bsum_ext. intros b j r Hv. cbn [usu].
249
+ rewrite fus_nth by exact Hv. unfold flat_unit. cbn [tin]. apply length_map.
250
+ Qed.
251
+
252
+ (* the predecessors of a unit are valid signals with smaller indices *)
253
+ Lemma pred_ok : forall b j r x z, valid bs n (SRef b j r) -> In (x, z) (sin (sunit bs b j r)) ->
254
+ valid bs n x /\ idx n bs x < idx n bs (SRef b j r).
255
+ Proof.
256
+ intros b j r x z Hv Hin. destruct Hv as (Hb & Hj & Hr). destruct Hwf as [Hsh Hrd].
257
+ pose proof (Hrd b j r x z Hb Hj Hr Hin) as Hbk. destruct x as [i|b' j' r']; cbn [reads_back valid] in *.
258
+ - split; [exact Hbk|]. cbn [idx]. lia.
259
+ - destruct Hbk as [(Hb' & Hj' & Hr')|(-> & -> & Hr')].
260
+ + split; [split; [lia|]; split; assumption|].
261
+ pose proof (boff_mono bs b b' Hb' ltac:(lia)) as Hm. cbn [idx]. nia.
262
+ + split; [split; [lia|]; split; lia|]. cbn [idx]. lia.
263
+ Qed.
264
+
265
+ Lemma idx_inj : forall x y, valid bs n x -> valid bs n y -> idx n bs x = idx n bs y -> x = y.
266
+ Proof.
267
+ assert (L : forall b j r b' j' r', valid bs n (SRef b j r) -> valid bs n (SRef b' j' r') -> b < b' ->
268
+ idx n bs (SRef b j r) < idx n bs (SRef b' j' r')).
269
+ { intros b j r b' j' r' (_ & Hj & Hr) (Hb' & _ & _) Hlt.
270
+ pose proof (boff_mono bs b' b Hlt ltac:(lia)) as Hm. cbn [idx]. nia. }
271
+ intros [i|b j r] [i'|b' j' r'] Hx Hy E; cbn [idx valid] in E, Hx, Hy.
272
+ - congruence.
273
+ - lia.
274
+ - lia.
275
+ - destruct (Nat.lt_trichotomy b b') as [Hlt|[<-|Hgt]].
276
+ + pose proof (L b j r b' j' r' Hx Hy Hlt). cbn [idx] in *. lia.
277
+ + assert (Hs : bsize (nth b bs blk0) * j + r = bsize (nth b bs blk0) * j' + r') by lia.
278
+ destruct Hx as (_ & _ & Hr), Hy as (_ & _ & Hr').
279
+ destruct (Nat.lt_trichotomy j j') as [Hj|[<-|Hj]]; [nia | | nia].
280
+ assert (r = r') by lia. subst. reflexivity.
281
+ + pose proof (L b' j' r' b j r Hy Hx Hgt). cbn [idx] in *. lia.
282
+ Qed.
283
+
284
+ (* ---- depths ----------------------------------------------------------------------------------------- *)
285
+ Lemma dep_su : forall b j r, valid bs n (SRef b j r) ->
286
+ dep n fus (idx n bs (SRef b j r)) = S (maxl (map (fun p => dep n fus (idx n bs (fst p))) (sin (sunit bs b j r)))).
287
+ Proof.
288
+ intros b j r Hv. rewrite idx_ref. rewrite dep_unit; [| exact fwfn | rewrite fus_len; exact (unit_lt b j r Hv)].
289
+ rewrite fus_nth by exact Hv. unfold flat_unit. cbn [tin]. rewrite map_map. reflexivity.
290
+ Qed.
291
+
292
+ (* the depth recursion from bounds on each unit: every predecessor lies below it, one of them just below *)
293
+ Lemma cd_rec : forall (cd : sref -> nat) (u : su) c,
294
+ (forall p z, In (p, z) (sin u) -> S (cd p) <= c) -> (exists p z, In (p, z) (sin u) /\ S (cd p) = c) ->
295
+ c = S (maxl (map (fun p => cd (fst p)) (sin u))).
296
+ Proof.
297
+ intros cd u c Hle (p0 & z0 & Hin0 & E0). apply Nat.le_antisymm.
298
+ - rewrite <- E0. apply le_n_S. apply maxl_ge. apply in_map_iff. exists (p0, z0). split; [reflexivity | exact Hin0].
299
+ - assert (maxl (map (fun p => cd (fst p)) (sin u)) <= c - 1); [|lia].
300
+ apply maxl_le. intros a Ha. apply in_map_iff in Ha as ([p z] & <- & Hin). specialize (Hle p z Hin). cbn [fst]. lia.
301
+ Qed.
302
+
303
+ Section Depth.
304
+ Variable cd : sref -> nat.
305
+ Hypothesis Hcd0 : forall i, cd (SIn i) = 0.
306
+ Hypothesis Hcd : forall b j r, valid bs n (SRef b j r) ->
307
+ cd (SRef b j r) = S (maxl (map (fun p => cd (fst p)) (sin (sunit bs b j r)))).
308
+
309
+ Theorem dep_cd : forall x, valid bs n x -> dep n fus (idx n bs x) = cd x.
310
+ Proof.
311
+ assert (G : forall k x, idx n bs x < k -> valid bs n x -> dep n fus (idx n bs x) = cd x).
312
+ { induction k as [|k IH]; intros x Hk Hv; [lia|]. destruct x as [i|b j r].
313
+ - cbn [idx]. rewrite Hcd0. apply dep_state. exact Hv.
314
+ - rewrite dep_su by exact Hv. rewrite Hcd by exact Hv. f_equal. f_equal. apply map_ext_in. intros [p z] Hin.
315
+ cbn [fst]. destruct (pred_ok b j r p z Hv Hin) as [Hvp Hlt]. apply IH; [lia | exact Hvp]. }
316
+ intros x Hv. exact (G (S (idx n bs x)) x (Nat.lt_succ_diag_r _) Hv).
317
+ Qed.
318
+
319
+ Theorem dmax_cd : forall D, (forall b j r, valid bs n (SRef b j r) -> cd (SRef b j r) <= D) ->
320
+ (exists b j r, valid bs n (SRef b j r) /\ cd (SRef b j r) = D) -> dmax n fus = D.
321
+ Proof.
322
+ intros D Hle (b0 & j0 & r0 & Hv0 & E0). apply Nat.le_antisymm.
323
+ - apply maxl_le. intros a Ha. apply in_map_iff in Ha as (k & <- & Hk). apply in_seq in Hk. rewrite fus_len in Hk.
324
+ destruct (loc k ltac:(lia)) as (b & j & r & Hv & ->). rewrite <- idx_ref, dep_cd by exact Hv. apply Hle. exact Hv.
325
+ - rewrite <- E0, <- (dep_cd _ Hv0), idx_ref. apply maxl_ge. apply in_map_iff. exists (boff bs b0 + sz b0 * j0 + r0).
326
+ split; [reflexivity|]. apply in_seq. rewrite fus_len. pose proof (unit_lt b0 j0 r0 Hv0). lia.
327
+ Qed.
328
+
329
+ End Depth.
330
+
331
+ (* ---- every unit contributes to a next value ---------------------------------------------------------- *)
332
+ Section Need.
333
+ Hypothesis Hrd : forall b j r, valid bs n (SRef b j r) -> (exists i, i < n /\ out i = SRef b j r) \/
334
+ (exists b' j' r' z, valid bs n (SRef b' j' r') /\ In (SRef b j r, z) (sin (sunit bs b' j' r'))).
335
+
336
+ Theorem need_all : forall b j r, valid bs n (SRef b j r) -> need n fus fnx (idx n bs (SRef b j r)) = true.
337
+ Proof.
338
+ assert (G : forall k b j r, n + nun - idx n bs (SRef b j r) < k -> valid bs n (SRef b j r) ->
339
+ need n fus fnx (idx n bs (SRef b j r)) = true).
340
+ { induction k as [|k IH]; intros b j r Hk Hv; [lia|].
341
+ destruct (Hrd b j r Hv) as [(i & Hi & Ei)|(b' & j' & r' & z & Hvr & Hin)].
342
+ - apply need_nx. unfold fnx. apply in_map_iff. exists i. split; [rewrite Ei; reflexivity | apply in_seq; lia].
343
+ - destruct (pred_ok b' j' r' (SRef b j r) z Hvr Hin) as [_ Hlt].
344
+ assert (Hn' : need n fus fnx (idx n bs (SRef b' j' r')) = true).
345
+ { apply IH; [| exact Hvr]. pose proof (idx_lt_total bs n _ Hvr). unfold nun in *. lia. }
346
+ rewrite idx_ref in Hn'. apply (need_pred n fus fnx fwfn (boff bs b' + sz b' * j' + r') (idx n bs (SRef b j r)) z).
347
+ + rewrite fus_len. exact (unit_lt b' j' r' Hvr).
348
+ + exact Hn'.
349
+ + rewrite fus_nth by exact Hvr. unfold flat_unit. cbn [tin]. apply in_map_iff. exists (SRef b j r, z).
350
+ split; [reflexivity | exact Hin]. }
351
+ intros b j r Hv. apply (G (S (n + nun)) b j r); [lia | exact Hv].
352
+ Qed.
353
+
354
+ End Need.
355
+
356
+ (* ---- the last layer that reads each signal ------------------------------------------------------------- *)
357
+ Lemma reads_su : forall b j r x, valid bs n (SRef b j r) -> valid bs n x ->
358
+ reads fus (boff bs b + sz b * j + r) (idx n bs x) = true <-> exists z, In (x, z) (sin (sunit bs b j r)).
359
+ Proof.
360
+ intros b j r x Hv Hx. rewrite reads_in. rewrite fus_nth by exact Hv. unfold flat_unit. cbn [tin]. split.
361
+ - intros (z & Hin). apply in_map_iff in Hin as ([p z'] & E & Hin). cbn [fst snd] in E. injection E as Ep <-.
362
+ exists z'. destruct (pred_ok b j r p z' Hv Hin) as [Hvp _]. rewrite (idx_inj p x Hvp Hx Ep) in Hin. exact Hin.
363
+ - intros (z & Hin). exists z. apply in_map_iff. exists (x, z). split; [reflexivity | exact Hin].
364
+ Qed.
365
+
366
+ Section Lam.
367
+ Variable cd : sref -> nat.
368
+ Hypothesis Hdep : forall x, valid bs n x -> dep n fus (idx n bs x) = cd x.
369
+ Hypothesis Hneed : forall b j r, valid bs n (SRef b j r) -> need n fus fnx (idx n bs (SRef b j r)) = true.
370
+ Variable D : nat.
371
+ Hypothesis HD : dmax n fus = D.
372
+ Variable cl : sref -> nat.
373
+ Hypothesis Hup : forall b j r p z, valid bs n (SRef b j r) -> In (p, z) (sin (sunit bs b j r)) -> cd (SRef b j r) <= cl p.
374
+ Hypothesis Hcl_out : forall i, i < n -> cl (out i) = S D.
375
+ Hypothesis Hlow : forall x, valid bs n x -> (forall i, i < n -> out i <> x) ->
376
+ cl x = 0 \/ exists b j r z, valid bs n (SRef b j r) /\ In (x, z) (sin (sunit bs b j r)) /\ cd (SRef b j r) = cl x.
377
+
378
+ Lemma unit_dep_le : forall k, k < nun -> dep n fus (n + k) <= D.
379
+ Proof. intros k Hk. rewrite <- HD. apply dep_le_dmax. rewrite fus_len. exact Hk. Qed.
380
+
381
+ Theorem lam_cl : forall x, valid bs n x -> lam n fus fnx (idx n bs x) = cl x.
382
+ Proof.
383
+ intros x Hx. unfold lam.
384
+ (* the readers *)
385
+ assert (Hr : maxl (map (fun k => if need n fus fnx (n + k) && reads fus k (idx n bs x) then dep n fus (n + k) else 0)
386
+ (seq 0 (length fus))) <= cl x).
387
+ { apply maxl_le. intros a Ha. apply in_map_iff in Ha as (k & <- & Hk). apply in_seq in Hk. rewrite fus_len in Hk.
388
+ destruct (loc k ltac:(lia)) as (b & j & r & Hv & ->).
389
+ destruct (need n fus fnx _ && reads fus _ (idx n bs x)) eqn:E; [|lia].
390
+ apply andb_true_iff in E as [_ E]. apply (reads_su b j r x Hv Hx) in E as (z & Hin).
391
+ rewrite <- idx_ref, Hdep by exact Hv. exact (Hup b j r x z Hv Hin). }
392
+ destruct (existsb (Nat.eqb (idx n bs x)) fnx) eqn:Eo.
393
+ - apply existsb_exists in Eo as (s & Hs & E). apply Nat.eqb_eq in E. unfold fnx in Hs.
394
+ apply in_map_iff in Hs as (i & Ei & Hi). apply in_seq in Hi. rewrite <- Ei in E.
395
+ apply (idx_inj x (out i) Hx (Hout i ltac:(lia))) in E. subst x. rewrite Hcl_out by lia. rewrite HD.
396
+ apply Nat.max_l. eapply Nat.le_trans; [|apply Nat.le_succ_diag_r]. apply maxl_le. intros a Ha.
397
+ apply in_map_iff in Ha as (k & <- & Hk). apply in_seq in Hk. rewrite fus_len in Hk.
398
+ destruct (_ && _); [apply unit_dep_le; lia | lia].
399
+ - cbn [Nat.max]. apply Nat.le_antisymm; [exact Hr|].
400
+ assert (Hno : forall i, i < n -> out i <> x).
401
+ { intros i Hi E. subst x. assert (existsb (Nat.eqb (idx n bs (out i))) fnx = true) as C.
402
+ { apply existsb_exists. exists (idx n bs (out i)). split; [|apply Nat.eqb_refl].
403
+ unfold fnx. apply in_map_iff. exists i. split; [reflexivity | apply in_seq; lia]. }
404
+ rewrite C in Eo. discriminate. }
405
+ destruct (Hlow x Hx Hno) as [Z|(b & j & r & z & Hv & Hin & E)]; [rewrite Z; lia|].
406
+ rewrite <- E. apply maxl_ge. apply in_map_iff. exists (boff bs b + sz b * j + r).
407
+ split; [|apply in_seq; rewrite fus_len; pose proof (unit_lt b j r Hv); lia].
408
+ rewrite <- idx_ref, Hneed by exact Hv.
409
+ replace (reads fus (boff bs b + sz b * j + r) (idx n bs x)) with true
410
+ by (symmetry; apply (reads_su b j r x Hv Hx); exists z; exact Hin).
411
+ cbn [andb]. apply Hdep. exact Hv.
412
+ Qed.
413
+
414
+ (* the rows of layer l: the units of depth l and the copies of the signals of smaller depth read after l *)
415
+ Theorem live_cl : forall l x, valid bs n x ->
416
+ live n fus fnx l (idx n bs x) = isref x && Nat.eqb (cd x) l || Nat.ltb (cd x) l && Nat.ltb l (cl x).
417
+ Proof.
418
+ intros l x Hx. unfold live, isunit. rewrite Hdep, lam_cl by exact Hx. destruct x as [i|b j r].
419
+ - cbn [idx isref valid] in *. destruct (Nat.leb_spec n i); [lia|]. reflexivity.
420
+ - rewrite Hneed by exact Hx. rewrite idx_ref. destruct (Nat.leb_spec n (n + (boff bs b + sz b * j + r))); [|lia].
421
+ cbn [isref andb]. rewrite andb_true_r. reflexivity.
422
+ Qed.
423
+
424
+ Theorem width_bsum : forall l, 1 <= l ->
425
+ width n fus fnx l = nsum n (fun i => Nat.b2n (Nat.ltb (cd (SIn i)) l && Nat.ltb l (cl (SIn i))))
426
+ + bsum (fun x => Nat.b2n (Nat.eqb (cd x) l || Nat.ltb (cd x) l && Nat.ltb l (cl x))).
427
+ Proof.
428
+ intros [|l] Hl; [lia|]. cbn [width]. unfold NS. rewrite fus_len, seq_app, filter_app, length_app.
429
+ rewrite !length_filter_seq. f_equal.
430
+ - apply nsum_ext. intros i Hi. cbn [Nat.add]. replace i with (idx n bs (SIn i)) at 1 by reflexivity.
431
+ rewrite live_cl by (cbn [valid]; exact Hi). reflexivity.
432
+ - rewrite nsum_units. unfold bsum. apply nsum_ext. intros b Hb. apply nsum_ext. intros j Hj. apply nsum_ext.
433
+ intros r Hr. assert (Hv : valid bs n (SRef b j r)) by (split; [exact Hb | split; [exact Hj | exact Hr]]).
434
+ replace (0 + n + (boff bs b + sz b * j + r)) with (idx n bs (SRef b j r)) by (rewrite idx_ref; lia).
435
+ rewrite live_cl by exact Hv. reflexivity.
436
+ Qed.
437
+
438
+ End Lam.
439
+
440
+ (* ---- netlists with units that contribute to nothing ------------------------------------------------------ *)
441
+ Section Need2.
442
+ Variable nd : sref -> bool.
443
+ Hypothesis Hnd_up : forall b j r, valid bs n (SRef b j r) -> nd (SRef b j r) = true ->
444
+ (exists i, i < n /\ out i = SRef b j r) \/
445
+ (exists b' j' r' z, valid bs n (SRef b' j' r') /\ nd (SRef b' j' r') = true /\ In (SRef b j r, z) (sin (sunit bs b' j' r'))).
446
+ Hypothesis Hnd_down : forall b j r, valid bs n (SRef b j r) -> nd (SRef b j r) = false ->
447
+ (forall i, i < n -> out i <> SRef b j r) /\
448
+ forall b' j' r' z, valid bs n (SRef b' j' r') -> In (SRef b j r, z) (sin (sunit bs b' j' r')) -> nd (SRef b' j' r') = false.
449
+
450
+ Theorem need_eq : forall b j r, valid bs n (SRef b j r) -> need n fus fnx (idx n bs (SRef b j r)) = nd (SRef b j r).
451
+ Proof.
452
+ assert (G : forall m b j r, n + nun - idx n bs (SRef b j r) < m -> valid bs n (SRef b j r) ->
453
+ need n fus fnx (idx n bs (SRef b j r)) = nd (SRef b j r)).
454
+ { induction m as [|m IH]; intros b j r Hm Hv; [lia|]. pose proof (idx_lt_total bs n _ Hv) as Hlt.
455
+ destruct (nd (SRef b j r)) eqn:Hnd.
456
+ - destruct (Hnd_up b j r Hv Hnd) as [(i & Hi & Ei)|(b' & j' & r' & z & Hv' & Hn' & Hin)].
457
+ + apply need_nx. unfold fnx. apply in_map_iff. exists i. split; [rewrite Ei; reflexivity | apply in_seq; lia].
458
+ + destruct (pred_ok b' j' r' (SRef b j r) z Hv' Hin) as [_ Hl].
459
+ pose proof (idx_lt_total bs n _ Hv').
460
+ assert (Hn'' : need n fus fnx (idx n bs (SRef b' j' r')) = true)
461
+ by (rewrite (IH b' j' r'); [exact Hn' | unfold nun in *; lia | exact Hv']).
462
+ rewrite idx_ref in Hn''. apply (need_pred n fus fnx fwfn (boff bs b' + sz b' * j' + r') _ z).
463
+ * rewrite fus_len. exact (unit_lt b' j' r' Hv').
464
+ * exact Hn''.
465
+ * rewrite fus_nth by exact Hv'. unfold flat_unit. cbn [tin]. apply in_map_iff. exists (SRef b j r, z).
466
+ split; [reflexivity | exact Hin].
467
+ - destruct (need n fus fnx (idx n bs (SRef b j r))) eqn:E; [|reflexivity]. exfalso.
468
+ destruct (Hnd_down b j r Hv Hnd) as [Hno Hrd].
469
+ destruct (needf_step fus n _ _ E) as [H0|(k & z & Hk & Hk2 & Hin)].
470
+ + apply existsb_exists in H0 as (s & Hs & Es). apply Nat.eqb_eq in Es. unfold fnx in Hs.
471
+ apply in_map_iff in Hs as (i & Ei & Hi). apply in_seq in Hi. rewrite <- Ei in Es.
472
+ apply (Hno i ltac:(lia)). symmetry. exact (idx_inj _ _ Hv (Hout i ltac:(lia)) Es).
473
+ + rewrite fus_len in Hk. destruct (loc k Hk) as (b' & j' & r' & Hv' & ->).
474
+ rewrite fus_nth in Hin by exact Hv'. unfold flat_unit in Hin. cbn [tin] in Hin.
475
+ apply in_map_iff in Hin as ([p z'] & Ep & Hin). cbn [fst snd] in Ep. injection Ep as Ep _.
476
+ destruct (pred_ok b' j' r' p z' Hv' Hin) as [Hvp Hl].
477
+ rewrite (idx_inj _ _ Hvp Hv Ep) in Hin, Hl.
478
+ pose proof (Hrd b' j' r' z' Hv' Hin) as Hf. pose proof (idx_lt_total bs n _ Hv').
479
+ change (need n fus fnx (n + (boff bs b' + sz b' * j' + r')) = true) in Hk2.
480
+ rewrite <- idx_ref, (IH b' j' r') in Hk2; [rewrite Hf in Hk2; discriminate | unfold nun in *; lia | exact Hv']. }
481
+ intros b j r Hv. apply (G (S (n + nun)) b j r); [lia | exact Hv].
482
+ Qed.
483
+
484
+ End Need2.
485
+
486
+ Section Lam2.
487
+ Variable cd : sref -> nat.
488
+ Hypothesis Hdep : forall x, valid bs n x -> dep n fus (idx n bs x) = cd x.
489
+ Variable nd : sref -> bool.
490
+ Hypothesis Hneed : forall b j r, valid bs n (SRef b j r) -> need n fus fnx (idx n bs (SRef b j r)) = nd (SRef b j r).
491
+ Variable D : nat.
492
+ Hypothesis HD : dmax n fus = D.
493
+ Variable cl : sref -> nat.
494
+ Hypothesis Hup : forall b j r p z, valid bs n (SRef b j r) -> nd (SRef b j r) = true ->
495
+ In (p, z) (sin (sunit bs b j r)) -> cd (SRef b j r) <= cl p.
496
+ Hypothesis Hcl_out : forall i, i < n -> cl (out i) = S D.
497
+ Hypothesis Hlow : forall x, valid bs n x -> (forall i, i < n -> out i <> x) ->
498
+ cl x = 0 \/ exists b j r z, valid bs n (SRef b j r) /\ nd (SRef b j r) = true /\ In (x, z) (sin (sunit bs b j r))
499
+ /\ cd (SRef b j r) = cl x.
500
+
501
+ Theorem lam_cl2 : forall x, valid bs n x -> lam n fus fnx (idx n bs x) = cl x.
502
+ Proof.
503
+ intros x Hx. unfold lam.
504
+ assert (Hr : maxl (map (fun k => if need n fus fnx (n + k) && reads fus k (idx n bs x) then dep n fus (n + k) else 0)
505
+ (seq 0 (length fus))) <= cl x).
506
+ { apply maxl_le. intros a Ha. apply in_map_iff in Ha as (k & <- & Hk). apply in_seq in Hk. rewrite fus_len in Hk.
507
+ destruct (loc k ltac:(lia)) as (b & j & r & Hv & ->).
508
+ destruct (need n fus fnx _ && reads fus _ (idx n bs x)) eqn:E; [|lia].
509
+ apply andb_true_iff in E as [E1 E]. apply (reads_su b j r x Hv Hx) in E as (z & Hin).
510
+ rewrite <- idx_ref, Hneed in E1 by exact Hv.
511
+ rewrite <- idx_ref, Hdep by exact Hv. exact (Hup b j r x z Hv E1 Hin). }
512
+ destruct (existsb (Nat.eqb (idx n bs x)) fnx) eqn:Eo.
513
+ - apply existsb_exists in Eo as (s & Hs & E). apply Nat.eqb_eq in E. unfold fnx in Hs.
514
+ apply in_map_iff in Hs as (i & Ei & Hi). apply in_seq in Hi. rewrite <- Ei in E.
515
+ apply (idx_inj x (out i) Hx (Hout i ltac:(lia))) in E. subst x. rewrite Hcl_out by lia. rewrite HD.
516
+ apply Nat.max_l. eapply Nat.le_trans; [|apply Nat.le_succ_diag_r]. apply maxl_le. intros a Ha.
517
+ apply in_map_iff in Ha as (k & <- & Hk). apply in_seq in Hk. rewrite fus_len in Hk.
518
+ destruct (_ && _); [rewrite <- HD; apply dep_le_dmax; rewrite fus_len; lia | lia].
519
+ - cbn [Nat.max]. apply Nat.le_antisymm; [exact Hr|].
520
+ assert (Hno : forall i, i < n -> out i <> x).
521
+ { intros i Hi E. subst x. assert (existsb (Nat.eqb (idx n bs (out i))) fnx = true) as C.
522
+ { apply existsb_exists. exists (idx n bs (out i)). split; [|apply Nat.eqb_refl].
523
+ unfold fnx. apply in_map_iff. exists i. split; [reflexivity | apply in_seq; lia]. }
524
+ rewrite C in Eo. discriminate. }
525
+ destruct (Hlow x Hx Hno) as [Z|(b & j & r & z & Hv & Hn & Hin & E)]; [rewrite Z; lia|].
526
+ rewrite <- E. apply maxl_ge. apply in_map_iff. exists (boff bs b + sz b * j + r).
527
+ split; [|apply in_seq; rewrite fus_len; pose proof (unit_lt b j r Hv); lia].
528
+ rewrite <- idx_ref, Hneed, Hn by exact Hv.
529
+ replace (reads fus (boff bs b + sz b * j + r) (idx n bs x)) with true
530
+ by (symmetry; apply (reads_su b j r x Hv Hx); exists z; exact Hin).
531
+ cbn [andb]. apply Hdep. exact Hv.
532
+ Qed.
533
+
534
+ Theorem live_cl2 : forall l x, valid bs n x ->
535
+ live n fus fnx l (idx n bs x) = isref x && nd x && Nat.eqb (cd x) l || Nat.ltb (cd x) l && Nat.ltb l (cl x).
536
+ Proof.
537
+ intros l x Hx. unfold live, isunit. rewrite Hdep, lam_cl2 by exact Hx. destruct x as [i|b j r].
538
+ - cbn [idx isref valid] in *. destruct (Nat.leb_spec n i); [lia|]. reflexivity.
539
+ - rewrite Hneed by exact Hx. rewrite idx_ref. destruct (Nat.leb_spec n (n + (boff bs b + sz b * j + r))); [|lia].
540
+ cbn [isref andb]. destruct (nd (SRef b j r)), (Nat.eqb (cd (SRef b j r)) l); reflexivity.
541
+ Qed.
542
+
543
+ (* the rows of the layers 1 .. d - 1, signal by signal *)
544
+ Theorem rows_bsum : forall m, fold_right Nat.add 0 (map (width n fus fnx) (seq 1 m))
545
+ = nsum n (fun i => nsum m (fun l => Nat.b2n (Nat.ltb (cd (SIn i)) (S l) && Nat.ltb (S l) (cl (SIn i)))))
546
+ + bsum (fun x => nsum m (fun l => Nat.b2n (nd x && Nat.eqb (cd x) (S l) || Nat.ltb (cd x) (S l) && Nat.ltb (S l) (cl x)))).
547
+ Proof.
548
+ intro m. rewrite <- (seq_shift m 0), map_map.
549
+ rewrite (fold_nsum_seq _ (fun l => width n fus fnx (S l))).
550
+ rewrite (nsum_ext m _ (fun l => nsum n (fun i => Nat.b2n (Nat.ltb (cd (SIn i)) (S l) && Nat.ltb (S l) (cl (SIn i))))
551
+ + bsum (fun x => Nat.b2n (nd x && Nat.eqb (cd x) (S l) || Nat.ltb (cd x) (S l) && Nat.ltb (S l) (cl x))))).
552
+ - rewrite nsum_add, nsum_swap, nsum_bsum_swap. reflexivity.
553
+ - intros l _. cbn [width]. unfold NS. rewrite fus_len, seq_app, filter_app, length_app, !length_filter_seq. f_equal.
554
+ + apply nsum_ext. intros i Hi. cbn [Nat.add]. replace i with (idx n bs (SIn i)) at 1 by reflexivity.
555
+ rewrite live_cl2 by (cbn [valid]; exact Hi). reflexivity.
556
+ + rewrite nsum_units. unfold bsum. apply nsum_ext. intros b Hb. apply nsum_ext. intros j Hj. apply nsum_ext.
557
+ intros r Hr. assert (Hv : valid bs n (SRef b j r)) by (split; [exact Hb | split; [exact Hj | exact Hr]]).
558
+ replace (0 + n + (boff bs b + sz b * j + r)) with (idx n bs (SRef b j r)) by (rewrite idx_ref; lia).
559
+ rewrite live_cl2 by exact Hv. cbn [isref andb]. reflexivity.
560
+ Qed.
561
+
562
+ End Lam2.
563
+
564
+ End BL.
rocq/Choose.v ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* Subsets of a given size and the bound C(m, j) <= (e m / j)^j, for the union bound of Proposition 6.10. *)
2
+ From Stdlib Require Import List Bool Arith Reals Lia Lra.
3
+ Import ListNotations.
4
+
5
+ Local Open Scope R_scope.
6
+
7
+ (* ---- the j-element sublists of a list ----------------------------------------------------------------------------- *)
8
+ Fixpoint choose {A : Type} (j : nat) (l : list A) : list (list A) :=
9
+ match j, l with
10
+ | O, _ => [[]]
11
+ | S _, [] => []
12
+ | S j', a :: t => map (cons a) (choose j' t) ++ choose (S j') t
13
+ end.
14
+
15
+ Fixpoint binom (n k : nat) : nat :=
16
+ match n, k with
17
+ | _, O => 1
18
+ | O, S _ => 0
19
+ | S n', S k' => binom n' k' + binom n' (S k')
20
+ end.
21
+
22
+ Lemma length_choose : forall (A : Type) (l : list A) j, length (choose j l) = binom (length l) j.
23
+ Proof.
24
+ intros A l. induction l as [|a t IH]; intro j; destruct j as [|j]; try reflexivity.
25
+ cbn [choose length binom]. rewrite length_app, length_map, !IH. reflexivity.
26
+ Qed.
27
+
28
+ Lemma choose_incl : forall (A : Type) (l : list A) j c, In c (choose j l) -> incl c l.
29
+ Proof.
30
+ intros A l. induction l as [|a t IH]; intros j c H; destruct j as [|j]; cbn [choose] in H.
31
+ - destruct H as [<-|[]]. intros x [].
32
+ - destruct H.
33
+ - destruct H as [<-|[]]. intros x [].
34
+ - apply in_app_or in H as [H|H].
35
+ + apply in_map_iff in H as (c' & <- & H). intros x [<-|Hx]; [left; reflexivity | right; exact (IH j c' H x Hx)].
36
+ + intros x Hx. right. exact (IH (S j) c H x Hx).
37
+ Qed.
38
+
39
+ Lemma choose_length : forall (A : Type) (l : list A) j c, In c (choose j l) -> length c = j.
40
+ Proof.
41
+ intros A l. induction l as [|a t IH]; intros j c H; destruct j as [|j]; cbn [choose] in H.
42
+ - destruct H as [<-|[]]. reflexivity.
43
+ - destruct H.
44
+ - destruct H as [<-|[]]. reflexivity.
45
+ - apply in_app_or in H as [H|H].
46
+ + apply in_map_iff in H as (c' & <- & H). cbn [length]. rewrite (IH j c' H). reflexivity.
47
+ + exact (IH (S j) c H).
48
+ Qed.
49
+
50
+ Lemma choose_nodup : forall (A : Type) (l : list A) j c, NoDup l -> In c (choose j l) -> NoDup c.
51
+ Proof.
52
+ intros A l. induction l as [|a t IH]; intros j c Hn H; destruct j as [|j]; cbn [choose] in H.
53
+ - destruct H as [<-|[]]. constructor.
54
+ - destruct H.
55
+ - destruct H as [<-|[]]. constructor.
56
+ - inversion Hn as [|? ? Ha Ht]; subst. apply in_app_or in H as [H|H].
57
+ + apply in_map_iff in H as (c' & <- & H). constructor; [|exact (IH j c' Ht H)].
58
+ intro Hin. apply Ha. exact (choose_incl _ t j c' H a Hin).
59
+ + exact (IH (S j) c Ht H).
60
+ Qed.
61
+
62
+ (* if at least j elements satisfy f, a j-element sublist consists of such elements *)
63
+ Lemma choose_spec : forall (A : Type) (f : A -> bool) (l : list A) j, (j <= length (filter f l))%nat ->
64
+ exists c, In c (choose j l) /\ forall x, In x c -> f x = true.
65
+ Proof.
66
+ intros A f l. induction l as [|a t IH]; intros j Hj.
67
+ - cbn [filter length] in Hj. assert (j = 0%nat) by lia. subst. exists []. split; [left; reflexivity | intros x []].
68
+ - destruct j as [|j]; [exists []; split; [left; reflexivity | intros x []]|].
69
+ cbn [choose filter] in *. destruct (f a) eqn:Fa.
70
+ + cbn [length] in Hj. destruct (IH j ltac:(lia)) as (c & Hc & Hf). exists (a :: c). split.
71
+ * apply in_or_app. left. apply in_map. exact Hc.
72
+ * intros x [<-|Hx]; [exact Fa | exact (Hf x Hx)].
73
+ + destruct (IH (S j) Hj) as (c & Hc & Hf). exists c. split; [apply in_or_app; right; exact Hc | exact Hf].
74
+ Qed.
75
+
76
+ (* ---- C(m, j) j! <= m^j and j^j <= j! e^(j-1) ------------------------------------------------------------------------ *)
77
+ Lemma pow_step : forall m j, ((j + 1) * m ^ j + m ^ (j + 1) <= (m + 1) ^ (j + 1))%nat.
78
+ Proof.
79
+ intros m j. induction j as [|j IH]; [cbn; lia|].
80
+ replace (S j + 1)%nat with (S (j + 1)) by lia. rewrite !Nat.pow_succ_r'. replace (j + 1)%nat with (S j) in * by lia.
81
+ rewrite !Nat.pow_succ_r' in *. nia.
82
+ Qed.
83
+
84
+ Lemma binom_fact : forall m j, (binom m j * fact j <= m ^ j)%nat.
85
+ Proof.
86
+ induction m as [|m IH]; intro j; destruct j as [|j]; cbn [binom fact]; try (cbn; lia).
87
+ pose proof (IH j) as H1. pose proof (IH (S j)) as H2. cbn [fact] in H2. pose proof (pow_step m j) as P.
88
+ replace (S j) with (j + 1)%nat in * by lia. replace (S m) with (m + 1)%nat by lia. nia.
89
+ Qed.
90
+
91
+ Lemma exp_pow_nat : forall x n, exp x ^ n = exp (INR n * x).
92
+ Proof.
93
+ intros x n. induction n as [|n IH]; [cbn [pow INR]; rewrite Rmult_0_l, exp_0; reflexivity|].
94
+ cbn [pow]. rewrite IH, <- exp_plus, S_INR. f_equal. ring.
95
+ Qed.
96
+
97
+ Lemma one_plus_pow : forall j, (1 <= j)%nat -> (1 + / INR j) ^ j <= exp 1.
98
+ Proof.
99
+ intros j Hj. assert (HJ : 0 < INR j) by (apply lt_0_INR; lia).
100
+ replace (exp 1) with (exp (/ INR j) ^ j) by (rewrite exp_pow_nat; f_equal; field; lra).
101
+ apply pow_incr. split; [pose proof (Rinv_0_lt_compat _ HJ); lra | apply exp_ineq1_le].
102
+ Qed.
103
+
104
+ (* j^j / j! <= e^(j-1) for j >= 1 *)
105
+ Lemma pow_fact : forall j, (1 <= j)%nat -> INR j ^ j <= INR (fact j) * exp 1 ^ (j - 1).
106
+ Proof.
107
+ intros j Hj. induction j as [|j IH]; [lia|]. destruct (Nat.eq_dec j 0) as [->|Hj0]; [cbn; lra|].
108
+ specialize (IH ltac:(lia)). assert (HJ : 0 < INR j) by (apply lt_0_INR; lia).
109
+ (* (j+1)^(j+1) / (j+1)! = (j+1)^j / j! = j^j / j! (1 + 1/j)^j *)
110
+ assert (E : INR (S j) ^ S j = INR (S j) * (INR j ^ j * (1 + / INR j) ^ j)).
111
+ { rewrite <- Rpow_mult_distr. replace (INR j * (1 + / INR j)) with (INR (S j)) by (rewrite S_INR; field; lra).
112
+ cbn [pow]. reflexivity. }
113
+ rewrite E. replace (S j - 1)%nat with (S (j - 1)) by lia. cbn [fact pow]. rewrite mult_INR.
114
+ pose proof (one_plus_pow j ltac:(lia)) as O. pose proof (pos_INR (S j)).
115
+ assert (0 <= INR j ^ j) by (apply pow_le; lra). assert (0 <= (1 + / INR j) ^ j) by (apply pow_le; pose proof (Rinv_0_lt_compat _ HJ); lra).
116
+ assert (0 <= exp 1 ^ (j - 1)) by (apply pow_le; pose proof (exp_pos 1); lra).
117
+ assert (INR j ^ j * (1 + / INR j) ^ j <= INR (fact j) * exp 1 ^ (j - 1) * exp 1).
118
+ { apply Rmult_le_compat; assumption. }
119
+ apply Rmult_le_compat_l with (r := INR (S j)) in H2; [|lra]. nra.
120
+ Qed.
121
+
122
+ (* C(m, j) eps^j <= (e m eps / j)^j for j >= 1 and eps >= 0 *)
123
+ Theorem binom_bound : forall m j eps, (1 <= j)%nat -> 0 <= eps ->
124
+ INR (binom m j) * eps ^ j <= (exp 1 * INR m * eps / INR j) ^ j.
125
+ Proof.
126
+ intros m j eps Hj He. assert (HJ : 0 < INR j) by (apply lt_0_INR; lia).
127
+ pose proof (INR_fact_lt_0 j) as Hf. pose proof (exp_pos 1) as Hx.
128
+ assert (B : INR (binom m j) <= INR m ^ j / INR (fact j)).
129
+ { apply (Rmult_le_reg_r (INR (fact j))); [exact Hf|]. unfold Rdiv. rewrite Rmult_assoc, Rinv_l, Rmult_1_r by lra.
130
+ rewrite <- mult_INR, <- pow_INR. apply le_INR. apply binom_fact. }
131
+ assert (F : / INR (fact j) <= (exp 1 / INR j) ^ j).
132
+ { pose proof (pow_fact j Hj) as P.
133
+ assert (INR j ^ j <= INR (fact j) * exp 1 ^ j).
134
+ { eapply Rle_trans; [exact P|]. apply Rmult_le_compat_l; [lra|].
135
+ replace j with (S (j - 1)) at 2 by lia. cbn [pow]. assert (1 <= exp 1) by (pose proof (exp_ineq1_le 1); lra).
136
+ assert (0 <= exp 1 ^ (j - 1)) by (apply pow_le; lra). nra. }
137
+ assert (Hjj : 0 < INR j ^ j) by (apply pow_lt; lra).
138
+ unfold Rdiv. rewrite Rpow_mult_distr, pow_inv.
139
+ apply (Rmult_le_reg_r (INR (fact j) * INR j ^ j)); [apply Rmult_lt_0_compat; lra|].
140
+ replace (/ INR (fact j) * (INR (fact j) * INR j ^ j)) with (INR j ^ j) by (field; apply INR_fact_neq_0).
141
+ replace (exp 1 ^ j * / INR j ^ j * (INR (fact j) * INR j ^ j)) with (INR (fact j) * exp 1 ^ j)
142
+ by (field; apply pow_nonzero; apply Rgt_not_eq; exact HJ).
143
+ exact H. }
144
+ assert (Hm : 0 <= INR m ^ j) by (apply pow_le; apply pos_INR).
145
+ assert (He' : 0 <= eps ^ j) by (apply pow_le; exact He).
146
+ replace ((exp 1 * INR m * eps / INR j) ^ j) with (INR m ^ j * eps ^ j * (exp 1 / INR j) ^ j)
147
+ by (rewrite <- !Rpow_mult_distr; f_equal; field; lra).
148
+ apply Rle_trans with (INR m ^ j * eps ^ j * / INR (fact j)).
149
+ - replace (INR m ^ j * eps ^ j * / INR (fact j)) with (INR m ^ j / INR (fact j) * eps ^ j) by (field; lra).
150
+ apply Rmult_le_compat_r; [exact He' | exact B].
151
+ - apply Rmult_le_compat_l; [apply Rmult_le_pos; assumption | exact F].
152
+ Qed.
rocq/Erfc.v ADDED
@@ -0,0 +1,432 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* The Gaussian tail (Section 6): erf and erfc from the integral of exp(-t^2), the Gaussian integral, and the bounds
2
+ erfc x <= exp(-x^2) and erfc x <= exp(-x^2)/(x sqrt pi) (1 - 1/(2x^2) + 3/(4x^4)). *)
3
+ From Stdlib Require Import Reals Lra Lia.
4
+ Set Warnings "-ambiguous-paths".
5
+ From Coquelicot Require Import Coquelicot.
6
+ Set Warnings "ambiguous-paths".
7
+
8
+ Local Open Scope R_scope.
9
+
10
+ (* ---- Coquelicot's lemmas, for functions from R to R --------------------------------------------------------------- *)
11
+ Lemma dcont : forall (f : R -> R) x, ex_derive f x -> continuous f x.
12
+ Proof. intros f x. apply (ex_derive_continuous (K := R_AbsRing) (V := R_NormedModule)). Qed.
13
+
14
+ Lemma rint_cont : forall (f : R -> R) a b, (forall z, Rmin a b <= z <= Rmax a b -> continuous f z) -> ex_RInt f a b.
15
+ Proof. intros f a b. apply (ex_RInt_continuous (V := R_CompleteNormedModule)). Qed.
16
+
17
+ Lemma rint_correct : forall (f : R -> R) a b, ex_RInt f a b -> is_RInt f a b (RInt f a b).
18
+ Proof. intros f a b. apply (RInt_correct (V := R_CompleteNormedModule)). Qed.
19
+
20
+ Lemma rint_ext : forall (f g : R -> R) a b, (forall x, Rmin a b < x < Rmax a b -> f x = g x) -> RInt f a b = RInt g a b.
21
+ Proof. intros f g a b. apply (RInt_ext (V := R_CompleteNormedModule)). Qed.
22
+
23
+ Lemma rint_scal : forall (f : R -> R) a b l, ex_RInt f a b -> RInt (fun x => l * f x) a b = l * RInt f a b.
24
+ Proof. intros f a b l H. apply (RInt_scal (V := R_CompleteNormedModule)). exact H. Qed.
25
+
26
+ Lemma rint_const : forall a b c, RInt (fun _ => c) a b = (b - a) * c.
27
+ Proof. intros a b c. apply (RInt_const (V := R_CompleteNormedModule)). Qed.
28
+
29
+ Lemma rint_point : forall (f : R -> R) a, RInt f a a = 0.
30
+ Proof. intros f a. apply (RInt_point (V := R_CompleteNormedModule)). Qed.
31
+
32
+ Lemma rint_comp_lin : forall (f : R -> R) u v a b, ex_RInt f (u * a + v) (u * b + v) ->
33
+ RInt (fun y => u * f (u * y + v)) a b = RInt f (u * a + v) (u * b + v).
34
+ Proof. intros f u v a b. apply (RInt_comp_lin (V := R_CompleteNormedModule)). Qed.
35
+
36
+ Lemma rint_derive : forall (f df : R -> R) a b, (forall x, Rmin a b <= x <= Rmax a b -> is_derive f x (df x)) ->
37
+ (forall x, Rmin a b <= x <= Rmax a b -> continuous df x) -> RInt df a b = f b - f a.
38
+ Proof.
39
+ intros f df a b H1 H2. apply (is_RInt_unique (V := R_CompleteNormedModule)).
40
+ apply (is_RInt_derive (V := R_CompleteNormedModule)); assumption.
41
+ Qed.
42
+
43
+ Lemma rint_ex_const : forall a b (c : R), ex_RInt (fun _ => c) a b.
44
+ Proof. intros a b c. apply (ex_RInt_const (V := R_CompleteNormedModule)). Qed.
45
+
46
+ (* an integral of a nonnegative function over [a, b] is nonnegative *)
47
+ Lemma rint_nonneg : forall (f : R -> R) a b, a <= b -> ex_RInt f a b -> (forall x, a < x < b -> 0 <= f x) -> 0 <= RInt f a b.
48
+ Proof.
49
+ intros f a b Hab Hf H. assert (Z : RInt (fun _ => 0) a b = 0) by (rewrite rint_const; apply Rmult_0_r).
50
+ rewrite <- Z. apply RInt_le; [exact Hab | apply rint_ex_const | exact Hf | exact H].
51
+ Qed.
52
+
53
+ Lemma exp_le : forall x y, x <= y -> exp x <= exp y.
54
+ Proof.
55
+ intros x y H. destruct (Rle_lt_or_eq_dec x y H) as [H'|H']; [apply Rlt_le, exp_increasing; exact H' | rewrite H'; lra].
56
+ Qed.
57
+
58
+ (* ---- the integrand ------------------------------------------------------------------------------------------------ *)
59
+ Definition gs (t : R) : R := exp (- (t * t)).
60
+
61
+ Lemma gs_pos : forall t, 0 < gs t.
62
+ Proof. intro t. apply exp_pos. Qed.
63
+
64
+ Lemma gs_cont : forall t, continuous gs t.
65
+ Proof. intro t. apply dcont. unfold gs. auto_derive. exact I. Qed.
66
+
67
+ Lemma ex_RInt_gs : forall a b, ex_RInt gs a b.
68
+ Proof. intros a b. apply rint_cont. intros z _. apply gs_cont. Qed.
69
+
70
+ Definition G (x : R) : R := RInt gs 0 x.
71
+
72
+ Lemma G_derive : forall x, is_derive G x (gs x).
73
+ Proof.
74
+ intro x. apply (is_derive_RInt (V := R_NormedModule) gs G 0 x).
75
+ - apply filter_forall. intro b. apply rint_correct. apply ex_RInt_gs.
76
+ - apply gs_cont.
77
+ Qed.
78
+
79
+ Lemma G_nonneg : forall x, 0 <= x -> 0 <= G x.
80
+ Proof. intros x Hx. apply rint_nonneg; [exact Hx | apply ex_RInt_gs | intros t _; pose proof (gs_pos t); lra]. Qed.
81
+
82
+ Lemma G0 : G 0 = 0.
83
+ Proof. unfold G. apply rint_point. Qed.
84
+
85
+ (* ---- the auxiliary integral H x = int_0^1 exp(-x^2 (1 + t^2)) / (1 + t^2) dt ---------------------------------------- *)
86
+ Definition hh (x t : R) : R := exp (- (x * x) * (1 + t * t)) / (1 + t * t).
87
+ Definition H (x : R) : R := RInt (hh x) 0 1.
88
+
89
+ Lemma one_t2 : forall t, 0 < 1 + t * t.
90
+ Proof. intro t. pose proof (Rle_0_sqr t). unfold Rsqr in *. lra. Qed.
91
+
92
+ Lemma hh_cont_t : forall x t, continuous (hh x) t.
93
+ Proof. intros x t. apply dcont. unfold hh. auto_derive. pose proof (one_t2 t). lra. Qed.
94
+
95
+ Lemma ex_RInt_hh : forall x a b, ex_RInt (hh x) a b.
96
+ Proof. intros x a b. apply rint_cont. intros z _. apply hh_cont_t. Qed.
97
+
98
+ Definition dhh (x t : R) : R := - (2 * x) * exp (- (x * x) * (1 + t * t)).
99
+
100
+ Lemma hh_derive : forall x t, is_derive (fun u => hh u t) x (dhh x t).
101
+ Proof.
102
+ intros x t. unfold hh, dhh. auto_derive; [pose proof (one_t2 t); lra|]. pose proof (one_t2 t). field. lra.
103
+ Qed.
104
+
105
+ Lemma dhh_cont : forall x t, continuity_2d_pt (fun u v => Derive (fun z => hh z v) u) x t.
106
+ Proof.
107
+ intros x t. apply (continuity_2d_pt_ext (fun u v => dhh u v)).
108
+ - intros u v. symmetry. apply is_derive_unique. apply hh_derive.
109
+ - unfold dhh. apply continuity_2d_pt_mult.
110
+ + apply continuity_2d_pt_opp. apply continuity_2d_pt_mult; [apply continuity_2d_pt_const | apply continuity_2d_pt_id1].
111
+ + apply (continuity_1d_2d_pt_comp exp (fun u v => - (u * u) * (1 + v * v))).
112
+ * apply derivable_continuous_pt. apply derivable_pt_exp.
113
+ * apply continuity_2d_pt_mult.
114
+ -- apply continuity_2d_pt_opp. apply continuity_2d_pt_mult; apply continuity_2d_pt_id1.
115
+ -- apply continuity_2d_pt_plus; [apply continuity_2d_pt_const|].
116
+ apply continuity_2d_pt_mult; apply continuity_2d_pt_id2.
117
+ Qed.
118
+
119
+ Lemma H_derive_raw : forall x, is_derive H x (RInt (fun t => dhh x t) 0 1).
120
+ Proof.
121
+ intro x. unfold H.
122
+ assert (E : RInt (fun t => dhh x t) 0 1 = RInt (fun t => Derive (fun u => hh u t) x) 0 1).
123
+ { apply rint_ext. intros t _. symmetry. apply is_derive_unique. apply hh_derive. }
124
+ rewrite E. apply (is_derive_RInt_param hh 0 1 x).
125
+ - apply filter_forall. intros y t _. exists (dhh y t). apply hh_derive.
126
+ - intros t _. apply dhh_cont.
127
+ - apply filter_forall. intro y. apply ex_RInt_hh.
128
+ Qed.
129
+
130
+ (* substituting u = x t *)
131
+ Lemma subst_lin : forall x, RInt (fun t => x * gs (x * t)) 0 1 = G x.
132
+ Proof.
133
+ intro x. unfold G. pose proof (rint_comp_lin gs x 0 0 1 (ex_RInt_gs _ _)) as E.
134
+ rewrite !Rmult_0_r, Rmult_1_r, !Rplus_0_r in E. rewrite <- E. apply rint_ext. intros t _. rewrite Rplus_0_r. reflexivity.
135
+ Qed.
136
+
137
+ Lemma H_derive : forall x, is_derive H x (- 2 * gs x * G x).
138
+ Proof.
139
+ intro x. assert (E : @eq R (RInt (fun t => dhh x t) 0 1) (- 2 * gs x * G x)).
140
+ { rewrite <- subst_lin. rewrite (rint_ext (fun t => dhh x t) (fun t => (- 2 * gs x) * (x * gs (x * t)))).
141
+ - rewrite rint_scal; [reflexivity|]. apply rint_cont. intros z _. apply dcont. unfold gs. auto_derive. exact I.
142
+ - intros t _. unfold dhh, gs. replace (- (x * x) * (1 + t * t)) with (- (x * x) + - (x * t * (x * t))) by ring.
143
+ rewrite exp_plus. ring. }
144
+ rewrite <- E. apply H_derive_raw.
145
+ Qed.
146
+
147
+ Lemma H_zero : H 0 = PI / 4.
148
+ Proof.
149
+ unfold H. rewrite (rint_ext (hh 0) (fun t => / (1 + t²))).
150
+ - rewrite (rint_derive atan (fun t => / (1 + t²)) 0 1).
151
+ + rewrite atan_1, atan_0. lra.
152
+ + intros t _. apply is_derive_atan.
153
+ + intros t _. apply dcont. auto_derive. unfold Rsqr. pose proof (one_t2 t). lra.
154
+ - intros t _. unfold hh, Rsqr. rewrite Rmult_0_l, Ropp_0, Rmult_0_l, exp_0. field. pose proof (one_t2 t). lra.
155
+ Qed.
156
+
157
+ Lemma H_nonneg : forall x, 0 <= H x.
158
+ Proof.
159
+ intro x. apply rint_nonneg; [lra | apply ex_RInt_hh |]. intros t _. unfold hh.
160
+ pose proof (one_t2 t). pose proof (exp_pos (- (x * x) * (1 + t * t))). apply Rlt_le. apply Rdiv_lt_0_compat; lra.
161
+ Qed.
162
+
163
+ Lemma H_le : forall x, H x <= gs x * (PI / 4).
164
+ Proof.
165
+ intro x. rewrite <- H_zero. unfold H. rewrite <- rint_scal by apply ex_RInt_hh.
166
+ apply RInt_le; [lra | apply ex_RInt_hh | apply rint_cont; intros z _; apply dcont; unfold hh; auto_derive;
167
+ pose proof (one_t2 z); lra |].
168
+ intros t _. unfold hh, gs. rewrite Rmult_0_l, Ropp_0, Rmult_0_l, exp_0.
169
+ replace (- (x * x) * (1 + t * t)) with (- (x * x) + - (x * x * (t * t))) by ring. rewrite exp_plus.
170
+ pose proof (one_t2 t). pose proof (exp_pos (- (x * x))).
171
+ assert (Hle : exp (- (x * x * (t * t))) <= 1).
172
+ { rewrite <- exp_0. apply exp_le. pose proof (Rle_0_sqr x) as Sx. pose proof (Rle_0_sqr t) as St. unfold Rsqr in *.
173
+ pose proof (Rmult_le_pos _ _ Sx St). lra. }
174
+ unfold Rdiv. rewrite Rmult_assoc. apply Rmult_le_compat_l; [lra|]. rewrite Rmult_1_l.
175
+ rewrite <- (Rmult_1_l (/ (1 + t * t))) at 2. apply Rmult_le_compat_r; [apply Rlt_le, Rinv_0_lt_compat; lra | exact Hle].
176
+ Qed.
177
+
178
+ (* ---- the Gaussian integral: G x ^ 2 + H x = pi / 4 ------------------------------------------------------------------ *)
179
+ Definition FF (x : R) : R := G x * G x + H x.
180
+
181
+ Lemma FF_derive : forall x, is_derive FF x 0.
182
+ Proof.
183
+ intro x. unfold FF. replace 0 with (gs x * G x + G x * gs x + - 2 * gs x * G x) by ring.
184
+ apply (is_derive_plus (fun y => G y * G y) H).
185
+ - apply (is_derive_mult G G x (gs x) (gs x)); [apply G_derive | apply G_derive | intros; apply Rmult_comm].
186
+ - apply H_derive.
187
+ Qed.
188
+
189
+ Lemma FF_cont : forall x, continuity_pt FF x.
190
+ Proof. intro x. apply continuity_pt_filterlim. apply dcont. exists 0. apply FF_derive. Qed.
191
+
192
+ Theorem gauss_square : forall x, G x * G x + H x = PI / 4.
193
+ Proof.
194
+ intro x. change (FF x = PI / 4). rewrite <- H_zero. replace (H 0) with (FF 0) by (unfold FF; rewrite G0; ring).
195
+ destruct (MVT_gen FF 0 x (fun _ => 0)) as (c & _ & E).
196
+ - intros y _. apply FF_derive.
197
+ - intros y _. apply FF_cont.
198
+ - lra.
199
+ Qed.
200
+
201
+ (* ---- erf and erfc -------------------------------------------------------------------------------------------------- *)
202
+ Definition erf (x : R) : R := 2 / sqrt PI * G x.
203
+ Definition erfc (x : R) : R := 1 - erf x.
204
+
205
+ Lemma sqrtPI_pos : 0 < sqrt PI.
206
+ Proof. apply sqrt_lt_R0. apply PI_RGT_0. Qed.
207
+
208
+ Lemma erf_sq : forall x, erf x * erf x = 1 - 4 / PI * H x.
209
+ Proof.
210
+ intro x. unfold erf. pose proof (gauss_square x) as E. pose proof sqrtPI_pos. pose proof PI_RGT_0.
211
+ replace (2 / sqrt PI * G x * (2 / sqrt PI * G x)) with (4 / (sqrt PI * sqrt PI) * (G x * G x)) by (field; lra).
212
+ rewrite sqrt_sqrt by lra. replace (G x * G x) with (PI / 4 - H x) by lra. field. lra.
213
+ Qed.
214
+
215
+ (* the Gaussian integral gives 0 <= erfc x <= 4 H(x) / pi <= exp(-x^2) for x >= 0 *)
216
+ Theorem erfc_le_exp : forall x, 0 <= x -> 0 <= erfc x <= exp (- (x * x)).
217
+ Proof.
218
+ intros x Hx. pose proof PI_RGT_0. pose proof sqrtPI_pos. set (z := 4 / PI * H x).
219
+ assert (Hz : 0 <= z <= exp (- (x * x))).
220
+ { unfold z. pose proof (H_nonneg x) as Hn. pose proof (H_le x) as Hl. unfold gs in *. split.
221
+ - apply Rmult_le_pos; [apply Rlt_le, Rdiv_lt_0_compat; lra | exact Hn].
222
+ - replace (exp (- (x * x))) with (4 / PI * (exp (- (x * x)) * (PI / 4))) by (field; lra).
223
+ apply Rmult_le_compat_l; [apply Rlt_le, Rdiv_lt_0_compat; lra | exact Hl]. }
224
+ assert (He : 0 <= erf x) by (unfold erf; apply Rmult_le_pos; [apply Rlt_le, Rdiv_lt_0_compat; lra | apply G_nonneg; exact Hx]).
225
+ pose proof (erf_sq x) as Sq. fold z in Sq.
226
+ assert (Hexp : exp (- (x * x)) <= 1) by (rewrite <- exp_0; apply exp_le; pose proof (Rle_0_sqr x); unfold Rsqr in *; lra).
227
+ unfold erfc. split; nra.
228
+ Qed.
229
+
230
+ Lemma erfc_derive : forall x, is_derive erfc x (- (2 / sqrt PI * gs x)).
231
+ Proof.
232
+ intro x. unfold erfc, erf. replace (- (2 / sqrt PI * gs x)) with (minus 0 (2 / sqrt PI * gs x))
233
+ by (unfold minus, plus, opp; cbn; ring).
234
+ apply (is_derive_minus (fun _ => 1) (fun y => 2 / sqrt PI * G y)).
235
+ - apply (is_derive_const (K := R_AbsRing) (V := R_NormedModule)).
236
+ - apply is_derive_scal. apply G_derive.
237
+ Qed.
238
+
239
+ Lemma erfc_cont : forall x, continuity_pt erfc x.
240
+ Proof. intro x. apply continuity_pt_filterlim. apply dcont. eexists. apply erfc_derive. Qed.
241
+
242
+ (* ---- comparison by derivatives -------------------------------------------------------------------------------------- *)
243
+ (* on (a, +inf) a function with nonpositive derivative that is nearly nonnegative arbitrarily far out is nonnegative *)
244
+ Lemma decr_nonneg : forall (g dg : R -> R) a, (forall x, a < x -> is_derive g x (dg x)) -> (forall x, a < x -> dg x <= 0) ->
245
+ (forall x eps, a < x -> 0 < eps -> exists y, x <= y /\ - eps <= g y) -> forall x, a < x -> 0 <= g x.
246
+ Proof.
247
+ intros g dg a Hd Hneg Hfar x Hx. destruct (Rle_lt_dec 0 (g x)) as [Hg|Hg]; [exact Hg|]. exfalso.
248
+ destruct (Hfar x (- g x / 2) Hx ltac:(lra)) as (y & Hy & Hgy).
249
+ destruct (Rle_lt_or_eq_dec x y Hy) as [Hxy|Hxy]; [|subst y; lra].
250
+ destruct (MVT_gen g x y dg) as (c & Hc & E).
251
+ - intros z Hz. rewrite Rmin_left, Rmax_right in Hz by lra. apply Hd. lra.
252
+ - intros z Hz. rewrite Rmin_left, Rmax_right in Hz by lra. apply continuity_pt_filterlim, dcont.
253
+ exists (dg z). apply Hd. lra.
254
+ - rewrite Rmin_left, Rmax_right in Hc by lra. pose proof (Hneg c ltac:(lra)). nra.
255
+ Qed.
256
+
257
+ (* exp(-y^2) falls below every eps > 0 *)
258
+ Lemma gs_small : forall x eps, 0 < eps -> exists y, x <= y /\ 1 <= y /\ gs y <= eps.
259
+ Proof.
260
+ intros x eps He. set (y := Rmax x (Rmax 1 (/ eps))). exists y.
261
+ assert (Hy1 : 1 <= y) by (unfold y; pose proof (Rmax_r x (Rmax 1 (/ eps))); pose proof (Rmax_l 1 (/ eps)); lra).
262
+ assert (Hye : / eps <= y) by (unfold y; pose proof (Rmax_r x (Rmax 1 (/ eps))); pose proof (Rmax_r 1 (/ eps)); lra).
263
+ split; [apply Rmax_l|]. split; [exact Hy1|]. unfold gs. rewrite exp_Ropp.
264
+ pose proof (exp_ineq1_le (y * y)) as E1. pose proof (exp_pos (y * y)) as E2.
265
+ apply (Rmult_le_reg_l (exp (y * y))); [exact E2|]. rewrite Rinv_r by lra.
266
+ assert (1 <= eps * y) by (apply (Rmult_le_compat_l eps) in Hye; [rewrite Rinv_r in Hye by lra; exact Hye | lra]).
267
+ nra.
268
+ Qed.
269
+
270
+ Definition phi (x : R) : R := exp (- (x * x)) / sqrt PI.
271
+
272
+ Lemma phi_pos : forall x, 0 < phi x.
273
+ Proof. intro x. unfold phi. apply Rdiv_lt_0_compat; [apply exp_pos | apply sqrtPI_pos]. Qed.
274
+
275
+ Lemma is_derive_sub : forall (f g : R -> R) x df dg, is_derive f x df -> is_derive g x dg ->
276
+ is_derive (fun y => f y - g y) x (df - dg).
277
+ Proof. intros f g x df dg Hf Hg. exact (is_derive_minus f g x df dg Hf Hg). Qed.
278
+
279
+ Lemma is_derive_eq : forall (f : R -> R) (x l1 l2 : R), is_derive f x l1 -> l1 = l2 -> is_derive f x l2.
280
+ Proof. intros f x l1 l2 H E. rewrite <- E. exact H. Qed.
281
+
282
+ Lemma nz : forall x, 0 < x -> x <> 0.
283
+ Proof. intros x H. apply Rgt_not_eq. exact H. Qed.
284
+
285
+ (* ---- erfc x <= exp(-x^2) / (x sqrt pi) and the sharper bounds, for x > 0 ---------------------------------------------- *)
286
+ Definition up1 (x : R) : R := exp (- (x * x)) / (x * sqrt PI).
287
+ Definition up3 (x : R) : R := exp (- (x * x)) / (x * sqrt PI) * (1 - 1 / (2 * (x * x)) + 3 / (4 * (x * x * (x * x)))).
288
+ Definition lo1 (x : R) : R := exp (- (x * x)) / (x * sqrt PI) * (1 - 1 / (2 * (x * x))).
289
+
290
+ Lemma up1_derive : forall x, 0 < x -> is_derive up1 x (- (2 / sqrt PI * gs x) - phi x / (x * x)).
291
+ Proof.
292
+ intros x Hx. pose proof sqrtPI_pos as Hs. unfold up1. auto_derive.
293
+ - apply Rmult_integral_contrapositive_currified; apply nz; assumption.
294
+ - unfold phi, gs. field. split; apply nz; assumption.
295
+ Qed.
296
+
297
+ Lemma up3_derive : forall x, 0 < x ->
298
+ is_derive up3 x (- (2 / sqrt PI * gs x) - 15 * phi x / (4 * (x * x * (x * x) * (x * x)))).
299
+ Proof.
300
+ intros x Hx. pose proof sqrtPI_pos as Hs. unfold up3. auto_derive.
301
+ - repeat split; try (apply Rmult_integral_contrapositive_currified); try (apply Rmult_integral_contrapositive_currified);
302
+ try apply nz; try lra; nra.
303
+ - unfold phi, gs. field. split; apply nz; assumption.
304
+ Qed.
305
+
306
+ Lemma lo1_derive : forall x, 0 < x -> is_derive lo1 x (- (2 / sqrt PI * gs x) + 3 * phi x / (2 * (x * x * (x * x)))).
307
+ Proof.
308
+ intros x Hx. pose proof sqrtPI_pos as Hs. unfold lo1. auto_derive.
309
+ - repeat split; try (apply Rmult_integral_contrapositive_currified); try apply nz; try lra; nra.
310
+ - unfold phi, gs. field. split; apply nz; assumption.
311
+ Qed.
312
+
313
+ Lemma up3_pos : forall x, 0 < x -> 0 < up3 x.
314
+ Proof.
315
+ intros x Hx. pose proof sqrtPI_pos. unfold up3. apply Rmult_lt_0_compat.
316
+ - apply Rdiv_lt_0_compat; [apply exp_pos | nra].
317
+ - assert (0 < x * x) by nra. assert (0 < x * x * (x * x)) by nra.
318
+ replace (1 - 1 / (2 * (x * x)) + 3 / (4 * (x * x * (x * x))))
319
+ with (((2 * (x * x) - 1/2) * (2 * (x * x) - 1/2) + 11 / 4) / (4 * (x * x * (x * x)))) by (field; lra).
320
+ apply Rdiv_lt_0_compat; nra.
321
+ Qed.
322
+
323
+ Theorem erfc_upper1 : forall x, 0 < x -> erfc x <= up1 x.
324
+ Proof.
325
+ intros x Hx. pose proof sqrtPI_pos as Hs. cut (0 <= up1 x - erfc x); [lra|].
326
+ apply (decr_nonneg (fun y => up1 y - erfc y) (fun y => - (phi y / (y * y))) 0); [| | | exact Hx].
327
+ - intros y Hy. eapply is_derive_eq; [apply is_derive_sub; [apply up1_derive; exact Hy | apply erfc_derive]|]. ring.
328
+ - intros y Hy. pose proof (phi_pos y) as P1. assert (P2 : 0 < y * y) by nra. pose proof (Rdiv_lt_0_compat _ _ P1 P2). lra.
329
+ - intros y eps Hy He. destruct (gs_small y eps He) as (z & Hz & Hz1 & Hg). exists z. split; [exact Hz|].
330
+ destruct (erfc_le_exp z ltac:(lra)) as [_ E].
331
+ assert (0 <= up1 z) by (unfold up1; apply Rlt_le, Rdiv_lt_0_compat; [apply exp_pos | nra]). unfold gs in Hg. lra.
332
+ Qed.
333
+
334
+ Theorem erfc_upper3 : forall x, 0 < x -> erfc x <= up3 x.
335
+ Proof.
336
+ intros x Hx. pose proof sqrtPI_pos as Hs. cut (0 <= up3 x - erfc x); [lra|].
337
+ apply (decr_nonneg (fun y => up3 y - erfc y) (fun y => - (15 * phi y / (4 * (y * y * (y * y) * (y * y))))) 0);
338
+ [| | | exact Hx].
339
+ - intros y Hy. eapply is_derive_eq; [apply is_derive_sub; [apply up3_derive; exact Hy | apply erfc_derive]|]. ring.
340
+ - intros y Hy. pose proof (phi_pos y). assert (Y2 : 0 < y * y) by nra.
341
+ assert (Y4 : 0 < y * y * (y * y)) by (apply Rmult_lt_0_compat; exact Y2).
342
+ assert (Y6 : 0 < y * y * (y * y) * (y * y)) by (apply Rmult_lt_0_compat; [exact Y4 | exact Y2]).
343
+ assert (0 < 15 * phi y / (4 * (y * y * (y * y) * (y * y)))) by (apply Rdiv_lt_0_compat; nra). lra.
344
+ - intros y eps Hy He. destruct (gs_small y eps He) as (z & Hz & Hz1 & Hg). exists z. split; [exact Hz|].
345
+ destruct (erfc_le_exp z ltac:(lra)) as [_ E]. pose proof (up3_pos z ltac:(lra)). unfold gs in Hg. lra.
346
+ Qed.
347
+
348
+ Theorem erfc_lower1 : forall x, 0 < x -> lo1 x <= erfc x.
349
+ Proof.
350
+ intros x Hx. pose proof sqrtPI_pos as Hs. cut (0 <= erfc x - lo1 x); [lra|].
351
+ apply (decr_nonneg (fun y => erfc y - lo1 y) (fun y => - (3 * phi y / (2 * (y * y * (y * y))))) 0); [| | | exact Hx].
352
+ - intros y Hy. eapply is_derive_eq; [apply is_derive_sub; [apply erfc_derive | apply lo1_derive; exact Hy]|]. ring.
353
+ - intros y Hy. pose proof (phi_pos y). assert (Y2 : 0 < y * y) by nra.
354
+ assert (Y4 : 0 < y * y * (y * y)) by (apply Rmult_lt_0_compat; exact Y2).
355
+ assert (0 < 3 * phi y / (2 * (y * y * (y * y)))) by (apply Rdiv_lt_0_compat; nra). lra.
356
+ - intros y eps Hy He. destruct (gs_small y (eps * sqrt PI) ltac:(nra)) as (z & Hz & Hz1 & Hg). exists z.
357
+ split; [exact Hz|]. destruct (erfc_le_exp z ltac:(lra)) as [E _].
358
+ assert (lo1 z <= eps).
359
+ { unfold lo1. unfold gs in Hg. pose proof (exp_pos (- (z * z))).
360
+ assert (0 <= 1 / (2 * (z * z))) by (apply Rlt_le, Rdiv_lt_0_compat; nra).
361
+ assert (exp (- (z * z)) / (z * sqrt PI) <= eps).
362
+ { apply (Rmult_le_reg_r (z * sqrt PI)); [nra|]. unfold Rdiv. rewrite Rmult_assoc, Rinv_l, Rmult_1_r by (apply nz; nra).
363
+ nra. }
364
+ assert (0 <= exp (- (z * z)) / (z * sqrt PI)) by (apply Rlt_le, Rdiv_lt_0_compat; nra). nra. }
365
+ lra.
366
+ Qed.
367
+
368
+ (* ---- monotonicity and symmetry -------------------------------------------------------------------------------------- *)
369
+ Lemma erfc_decr : forall x y, x <= y -> erfc y <= erfc x.
370
+ Proof.
371
+ intros x y Hxy. destruct (Rle_lt_or_eq_dec x y Hxy) as [H|H]; [|rewrite H; lra].
372
+ destruct (MVT_gen erfc x y (fun z => - (2 / sqrt PI * gs z))) as (c & _ & E).
373
+ - intros z _. apply erfc_derive.
374
+ - intros z _. apply erfc_cont.
375
+ - pose proof sqrtPI_pos. pose proof (gs_pos c). assert (0 < 2 / sqrt PI * gs c) by (apply Rmult_lt_0_compat; [apply Rdiv_lt_0_compat|]; lra).
376
+ nra.
377
+ Qed.
378
+
379
+ Lemma gs_even : forall t, gs (- t) = gs t.
380
+ Proof. intro t. unfold gs. f_equal. ring. Qed.
381
+
382
+ Lemma G_odd : forall x, G (- x) = - G x.
383
+ Proof.
384
+ intro x. unfold G. pose proof (rint_comp_lin gs (-1) 0 0 x (ex_RInt_gs _ _)) as E.
385
+ replace (-1 * 0 + 0) with 0 in E by ring. replace (-1 * x + 0) with (- x) in E by ring. rewrite <- E.
386
+ rewrite (rint_ext (fun y => -1 * gs (-1 * y + 0)) (fun y => -1 * gs y)).
387
+ - rewrite rint_scal by apply ex_RInt_gs. ring.
388
+ - intros t _. replace (-1 * t + 0) with (- t) by ring. rewrite gs_even. reflexivity.
389
+ Qed.
390
+
391
+ Lemma erfc_sym : forall x, erfc (- x) = 2 - erfc x.
392
+ Proof. intro x. unfold erfc, erf. rewrite G_odd. ring. Qed.
393
+
394
+ Lemma erfc_range : forall x, 0 <= erfc x <= 2.
395
+ Proof.
396
+ intro x. destruct (Rle_lt_dec 0 x) as [H|H].
397
+ - destruct (erfc_le_exp x H) as [E1 E2]. assert (exp (- (x * x)) <= 1) by (rewrite <- exp_0; apply exp_le; nra). lra.
398
+ - replace x with (- (- x)) by ring. rewrite erfc_sym. destruct (erfc_le_exp (- x) ltac:(lra)) as [E1 E2].
399
+ assert (exp (- (- x * - x)) <= 1) by (rewrite <- exp_0; apply exp_le; nra). lra.
400
+ Qed.
401
+
402
+ (* ---- the tail of the standard normal law: Q u = P(N(0,1) >= u) = erfc(u / sqrt 2) / 2 ------------------------------- *)
403
+ Definition Q (u : R) : R := erfc (u / sqrt 2) / 2.
404
+
405
+ Lemma sqrt2_pos : 0 < sqrt 2.
406
+ Proof. apply sqrt_lt_R0. lra. Qed.
407
+
408
+ Lemma Q_decr : forall u v, u <= v -> Q v <= Q u.
409
+ Proof.
410
+ intros u v H. unfold Q. pose proof sqrt2_pos. apply Rmult_le_compat_r; [lra|]. apply erfc_decr.
411
+ unfold Rdiv. apply Rmult_le_compat_r; [apply Rlt_le, Rinv_0_lt_compat; lra | exact H].
412
+ Qed.
413
+
414
+ Lemma Q_sym : forall u, Q (- u) = 1 - Q u.
415
+ Proof. intro u. unfold Q. replace (- u / sqrt 2) with (- (u / sqrt 2)) by (field; pose proof sqrt2_pos; lra). rewrite erfc_sym. field. Qed.
416
+
417
+ Lemma Q_range : forall u, 0 <= Q u <= 1.
418
+ Proof. intro u. unfold Q. pose proof (erfc_range (u / sqrt 2)). lra. Qed.
419
+
420
+ (* Q u <= exp(-u^2/2) / 2 for u >= 0 *)
421
+ Lemma Q_exp : forall u, 0 <= u -> Q u <= exp (- (u * u) / 2) / 2.
422
+ Proof.
423
+ intros u Hu. unfold Q. pose proof sqrt2_pos. assert (Hx : 0 <= u / sqrt 2) by (apply Rmult_le_pos; [lra | apply Rlt_le, Rinv_0_lt_compat; lra]).
424
+ destruct (erfc_le_exp (u / sqrt 2) Hx) as [_ E].
425
+ assert (Eq : - (u / sqrt 2 * (u / sqrt 2)) = - (u * u) / 2).
426
+ { replace (u / sqrt 2 * (u / sqrt 2)) with (u * u / (sqrt 2 * sqrt 2)) by (field; lra). rewrite sqrt_sqrt by lra. field. }
427
+ rewrite Eq in E. lra.
428
+ Qed.
429
+
430
+ (* erfc in terms of Q: P(|N(0, s^2)| >= u) = 2 Q(u/s) = erfc(u / (sqrt 2 s)) *)
431
+ Lemma erfc_Q : forall u s, 0 < s -> erfc (u / (sqrt 2 * s)) = 2 * Q (u / s).
432
+ Proof. intros u s Hs. unfold Q. pose proof sqrt2_pos. replace (u / s / sqrt 2) with (u / (sqrt 2 * s)) by (field; lra). field. Qed.
rocq/ExtrNat.v ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* Machine arithmetic for the functions of PeanoNat.Nat, as ExtrOcamlNatInt gives it to those of Init.Nat;
2
+ the values extracted stay far below 2^62. *)
3
+ From Stdlib Require Import Arith Extraction ExtrOcamlBasic ExtrOcamlNatInt.
4
+
5
+ Extract Inlined Constant PeanoNat.Nat.add => "(+)".
6
+ Extract Inlined Constant PeanoNat.Nat.mul => "( * )".
7
+ Extract Inlined Constant PeanoNat.Nat.sub => "(fun n m -> if n > m then n - m else 0)".
8
+ Extract Inlined Constant PeanoNat.Nat.pred => "(fun n -> if n > 0 then n - 1 else 0)".
9
+ Extract Inlined Constant PeanoNat.Nat.div => "(fun x y -> if y = 0 then 0 else x / y)".
10
+ Extract Inlined Constant PeanoNat.Nat.modulo => "(fun x y -> if y = 0 then x else x mod y)".
11
+ Extract Inlined Constant PeanoNat.Nat.div2 => "(fun n -> n / 2)".
12
+ Extract Inlined Constant PeanoNat.Nat.even => "(fun n -> n land 1 = 0)".
13
+ Extract Inlined Constant PeanoNat.Nat.odd => "(fun n -> n land 1 = 1)".
14
+ Extract Inlined Constant PeanoNat.Nat.testbit => "(fun a n -> n < 62 && (a lsr n) land 1 = 1)".
15
+ Extract Inlined Constant PeanoNat.Nat.max => "(fun n m -> if n < m then m else n)".
16
+ Extract Inlined Constant PeanoNat.Nat.min => "(fun n m -> if n < m then n else m)".
17
+ Extract Inlined Constant PeanoNat.Nat.eqb => "(=)".
18
+ Extract Inlined Constant PeanoNat.Nat.leb => "(<=)".
19
+ Extract Inlined Constant PeanoNat.Nat.ltb => "(<)".
20
+ Extract Constant PeanoNat.Nat.pow => "(fun n m -> let rec p k = if k = 0 then 1 else n * p (k - 1) in p m)".
21
+ Extract Constant PeanoNat.Nat.log2 =>
22
+ "(fun n -> let rec g k x = if x <= 1 then k else g (k + 1) (x lsr 1) in if n <= 0 then 0 else g 0 n)".
23
+ Extract Constant PeanoNat.Nat.log2_up =>
24
+ "(fun a -> let rec g k x = if x = 0 then k else g (k + 1) (x lsr 1) in if a <= 1 then 0 else g 0 (a - 1))".
rocq/Extract.v CHANGED
@@ -1,5 +1,5 @@
1
  From Stdlib Require Import Extraction ExtrOcamlBasic ExtrOcamlNatInt ExtrOcamlZInt.
2
- From TH Require Import Net Phys.
3
  Extraction Language OCaml.
4
  Set Extraction Output Directory "extract".
5
  Extraction "physnet.ml" phys_units phys_next nst.
 
1
  From Stdlib Require Import Extraction ExtrOcamlBasic ExtrOcamlNatInt ExtrOcamlZInt.
2
+ From TH Require Import ExtrNat Net Phys.
3
  Extraction Language OCaml.
4
  Set Extraction Output Directory "extract".
5
  Extraction "physnet.ml" phys_units phys_next nst.
rocq/ExtractHost.v CHANGED
@@ -1,5 +1,5 @@
1
  From Stdlib Require Import Extraction ExtrOcamlBasic ExtrOcamlNatInt ExtrOcamlZInt.
2
- From TH Require Import Net Host.
3
  Extraction Language OCaml.
4
  Set Extraction Output Directory "extract".
5
  Extraction "hostnet.ml" host_units host_next nH.
 
1
  From Stdlib Require Import Extraction ExtrOcamlBasic ExtrOcamlNatInt ExtrOcamlZInt.
2
+ From TH Require Import ExtrNat Net Host.
3
  Extraction Language OCaml.
4
  Set Extraction Output Directory "extract".
5
  Extraction "hostnet.ml" host_units host_next nH.
rocq/ExtractStored.v CHANGED
@@ -1,5 +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.
 
1
  From Stdlib Require Import Extraction ExtrOcamlBasic ExtrOcamlNatInt ExtrOcamlZInt.
2
+ From TH Require Import ExtrNat StoredFast.
3
  Extraction Language OCaml.
4
  Set Extraction Output Directory "extract".
5
+ Extraction "storednet.ml" stored_bits_lin.
rocq/FlipLower.v ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* Above the threshold of Proposition 6.10 the amplification fails. A disjunction of k inputs that hold 0, amplified
2
+ r = 2h + 1 times, reads k r copies of its inputs; when each copy is flipped with probability eps, independently, and
3
+ 2 k eps > 1, it computes a wrong value with probability at least 1 - rho^h for some rho < 1 that depends on k and
4
+ eps only. *)
5
+ From Stdlib Require Import List Bool Arith ZArith Reals Lia Lra.
6
+ Import ListNotations.
7
+ Set Warnings "-ambiguous-paths".
8
+ From TH Require Import TwoHead Net Lev Margin Noise Restore.
9
+ Set Warnings "ambiguous-paths".
10
+
11
+ Local Open Scope R_scope.
12
+
13
+ (* ---- Bernoulli's inequality and the choice of rho ------------------------------------------------------------------ *)
14
+ Lemma pow_le_one : forall x n, 0 <= x <= 1 -> x ^ n <= 1.
15
+ Proof. intros x n [H0 H1]. induction n as [|n IH]; cbn [pow]; [lra|]. pose proof (pow_le x n H0). nra. Qed.
16
+
17
+ Lemma bernoulli : forall a n, 0 <= a -> 1 + INR n * a <= (1 + a) ^ n.
18
+ Proof.
19
+ intros a n Ha. induction n as [|n IH]; [cbn; lra|]. rewrite S_INR. cbn [pow].
20
+ assert (0 <= INR n * a * a) by (apply Rmult_le_pos; [apply Rmult_le_pos; [apply pos_INR | exact Ha] | exact Ha]). nra.
21
+ Qed.
22
+
23
+ (* with u = (2 k eps - 1)/(4 k eps), x = 1 - u and c = 1 - eps u: c^(2k) / x < 1 *)
24
+ Lemma rho_lt : forall k eps, (1 <= k)%nat -> 0 < eps <= 1 -> 1 < 2 * INR k * eps ->
25
+ let u := (2 * INR k * eps - 1) / (4 * INR k * eps) in
26
+ 0 < u < 1/2 /\ (1 - eps * u) ^ (2 * k) / (1 - u) < 1.
27
+ Proof.
28
+ intros k eps Hk [He0 He1] H u. assert (Hk' : 1 <= INR k) by (apply (le_INR 1); exact Hk).
29
+ assert (Hp : 1/2 < INR k * eps) by lra.
30
+ assert (Eu : u * (4 * (INR k * eps)) = 2 * (INR k * eps) - 1) by (unfold u; field; lra).
31
+ assert (Hu : 0 < u < 1/2).
32
+ { split.
33
+ - unfold u. apply Rdiv_lt_0_compat; lra.
34
+ - apply (Rmult_lt_reg_r (4 * (INR k * eps))); [lra|]. rewrite Eu. lra. }
35
+ split; [exact Hu|].
36
+ set (a := eps * u). assert (Ha : 0 < a < 1) by (unfold a; split; [apply Rmult_lt_0_compat; lra | nra]).
37
+ (* (1 - a)^(2k) (1 + a)^(2k) <= 1 and (1 + a)^(2k) >= 1 + 2 k a *)
38
+ assert (AB : (1 - a) ^ (2 * k) * (1 + a) ^ (2 * k) <= 1).
39
+ { rewrite <- Rpow_mult_distr. apply pow_le_one. split; nra. }
40
+ pose proof (bernoulli a (2 * k) ltac:(lra)) as Bb. rewrite mult_INR in Bb. cbn [INR] in Bb.
41
+ assert (HA : 0 <= (1 - a) ^ (2 * k)) by (apply pow_le; lra).
42
+ assert (C1 : (1 - a) ^ (2 * k) * (1 + 2 * INR k * a) <= 1) by nra.
43
+ assert (Hd : 1 < (1 + 2 * INR k * a) * (1 - u)).
44
+ { assert (E2 : 2 * INR k * a = (2 * (INR k * eps) - 1) / 2) by (unfold a; rewrite <- Eu; field).
45
+ rewrite E2. assert (E3 : 1 - u = (2 * (INR k * eps) + 1) / (4 * (INR k * eps))) by (unfold u; field; lra).
46
+ rewrite E3. apply (Rmult_lt_reg_r (8 * (INR k * eps))); [lra|].
47
+ replace ((1 + (2 * (INR k * eps) - 1) / 2) * ((2 * (INR k * eps) + 1) / (4 * (INR k * eps))) * (8 * (INR k * eps)))
48
+ with ((2 * (INR k * eps) + 1) * (2 * (INR k * eps) + 1)) by (field; lra).
49
+ nra. }
50
+ apply (Rmult_lt_reg_r (1 - u)); [lra|]. unfold Rdiv. rewrite Rmult_assoc, Rinv_l, Rmult_1_r by lra. nra.
51
+ Qed.
52
+
53
+ Section Fail.
54
+ Variable Omega : Type.
55
+ Variable P : (Omega -> Prop) -> R.
56
+ Hypothesis P_mono : forall A B : Omega -> Prop, (forall w, A w -> B w) -> P A <= P B.
57
+ Hypothesis P_or : forall A B : Omega -> Prop, P (fun w => A w \/ B w) <= P A + P B.
58
+ Hypothesis P_empty : P (fun _ => False) = 0.
59
+ Hypothesis P_true : P (fun _ => True) = 1.
60
+ Variable X : nat -> Omega -> R.
61
+ Hypothesis P_indep : forall (I J : nat -> Prop) (A B : Omega -> Prop), (forall g, I g -> J g -> False) ->
62
+ dep Omega X I A -> dep Omega X J B -> P (fun w => A w /\ B w) = P A * P B.
63
+ Hypothesis P_compl : forall A, meas Omega X A -> P (fun w => ~ A w) = 1 - P A.
64
+ (* the output of evaluation g flips when its variable is at least 1, with probability eps *)
65
+ Variable eps : R.
66
+ Hypothesis Hflip : forall g, P (fun w => 1 <= X g w) = eps.
67
+
68
+ Lemma eps_range : 0 <= eps <= 1.
69
+ Proof.
70
+ rewrite <- (Hflip 0%nat). split; [exact (P_nonneg Omega P P_mono P_empty _) | exact (P_le1 Omega P P_mono P_true _)].
71
+ Qed.
72
+
73
+ Lemma Pnone : forall A : Omega -> Prop, (forall w, ~ A w) -> P A = 0.
74
+ Proof.
75
+ intros A H. apply Rle_antisym; [rewrite <- P_empty; apply P_mono; intros w Hw; exact (H w Hw)|].
76
+ exact (P_nonneg Omega P P_mono P_empty A).
77
+ Qed.
78
+
79
+ (* the flips among the variables gs *)
80
+ Definition cnt (gs : list nat) (w : Omega) : nat := length (filter (fb Omega X w) gs).
81
+
82
+ Lemma dep_cnt : forall gs t, dep Omega X (fun g => In g gs) (fun w => (cnt gs w < t)%nat).
83
+ Proof.
84
+ intros gs t w w' H. unfold cnt. replace (filter (fb Omega X w') gs) with (filter (fb Omega X w) gs); [reflexivity|].
85
+ apply filter_ext_in. intros g Hg. unfold fb. rewrite (H g Hg). reflexivity.
86
+ Qed.
87
+
88
+ (* fewer than t of the |gs| variables flip with probability at most (1 - eps + eps x)^|gs| / x^(t - 1), 0 < x <= 1 *)
89
+ Lemma P_few : forall gs t x, NoDup gs -> 0 < x <= 1 -> (1 <= t)%nat ->
90
+ P (fun w => (cnt gs w < t)%nat) <= (1 - eps + eps * x) ^ length gs / x ^ (t - 1).
91
+ Proof.
92
+ pose proof eps_range as He. intros gs. induction gs as [|g gs IH]; intros t x Hnd Hx Ht.
93
+ - cbn [length pow]. eapply Rle_trans; [apply (P_le1 Omega P P_mono P_true)|].
94
+ assert (0 < x ^ (t - 1) <= 1) by (split; [apply pow_lt; lra | apply pow_le_one; lra]).
95
+ unfold Rdiv. rewrite Rmult_1_l. rewrite <- Rinv_1 at 1. apply Rinv_le_contravar; lra.
96
+ - inversion Hnd as [|? ? Hg Hgs]; subst. set (c := 1 - eps + eps * x).
97
+ assert (Hc : 1 - eps <= c <= 1) by (unfold c; split; nra).
98
+ (* the first variable flips and fewer than t - 1 others do, or it does not and fewer than t others do *)
99
+ eapply Rle_trans; [apply (P_mono _ (fun w => (1 <= X g w /\ (cnt gs w < t - 1)%nat) \/ (~ 1 <= X g w /\ (cnt gs w < t)%nat)))|].
100
+ { intros w Hw. unfold cnt in Hw. cbn [filter] in Hw. destruct (fb Omega X w g) eqn:E.
101
+ - left. split; [apply fb_iff; exact E|]. cbn [length] in Hw. unfold cnt. lia.
102
+ - right. split; [intro C; apply fb_iff in C; congruence | exact Hw]. }
103
+ eapply Rle_trans; [apply P_or|].
104
+ rewrite (P_indep (fun g' => g' = g) (fun g' => In g' gs) (fun w => 1 <= X g w) (fun w => (cnt gs w < t - 1)%nat)).
105
+ 2: { intros g' -> Hin. exact (Hg Hin). }
106
+ 2: { intros w w' H. rewrite (H g eq_refl). reflexivity. }
107
+ 2: { apply dep_cnt. }
108
+ rewrite (P_indep (fun g' => g' = g) (fun g' => In g' gs) (fun w => ~ 1 <= X g w) (fun w => (cnt gs w < t)%nat)).
109
+ 2: { intros g' -> Hin. exact (Hg Hin). }
110
+ 2: { intros w w' H. rewrite (H g eq_refl). reflexivity. }
111
+ 2: { apply dep_cnt. }
112
+ rewrite Hflip, P_compl, Hflip by apply meas_ge.
113
+ pose proof (IH t x Hgs Hx Ht) as B1. fold c in B1. cbn [length pow]. fold c.
114
+ pose proof (pow_le c (length gs) ltac:(lra)) as Hcm.
115
+ destruct (Nat.eq_dec t 1) as [->|Ht1].
116
+ + rewrite (Pnone (fun w => (cnt gs w < 1 - 1)%nat)) by (intros w Hw; lia).
117
+ cbn [Nat.sub pow] in B1 |- *. unfold Rdiv in *. rewrite Rinv_1, !Rmult_1_r in *. nra.
118
+ + pose proof (IH (t - 1)%nat x Hgs Hx ltac:(lia)) as B0. fold c in B0.
119
+ assert (Ex : x ^ (t - 1) = x * x ^ (t - 1 - 1)) by (replace (t - 1)%nat with (S (t - 1 - 1)) at 1 by lia; reflexivity).
120
+ rewrite Ex in B1 |- *. set (xp := x ^ (t - 1 - 1)) in *.
121
+ assert (Hxp : 0 < xp) by (apply pow_lt; lra).
122
+ assert (E : c * c ^ length gs / (x * xp) = eps * (c ^ length gs / xp) + (1 - eps) * (c ^ length gs / (x * xp)))
123
+ by (unfold c; field; lra).
124
+ rewrite E. apply Rplus_le_compat; apply Rmult_le_compat_l; lra.
125
+ Qed.
126
+
127
+ (* ---- a disjunction of inputs that hold 0 ---------------------------------------------------------------------------- *)
128
+ Definition disj (js : list nat) : tu := TU (-1) (map (fun j => (j, 1%Z)) js).
129
+
130
+ Lemma wsum_ones : forall ins E, (forall j z, In (j, z) ins -> z = 1%Z) ->
131
+ wsum ins E = Z.of_nat (length (filter (fun p => E (fst p)) ins)).
132
+ Proof.
133
+ induction ins as [|[j z] t IH]; intros E H; [reflexivity|]. cbn [wsum filter fst].
134
+ rewrite (H j z (or_introl eq_refl)). rewrite IH by (intros j' z' Hin; exact (H j' z' (or_intror Hin))).
135
+ destruct (E j); cbn [length b2z]; lia.
136
+ Qed.
137
+
138
+ (* on the replicated input with the copies psi flipped, the r-fold disjunction has pre-activation the number of flipped
139
+ copies it reads minus (r + 1)/2 *)
140
+ Lemma pre_disj : forall h js y psi, (forall j, In j js -> (j < length y)%nat /\ nth j y false = false) ->
141
+ pre (arow (2 * h + 1) (length y) (disj js)) (xorv (rep (2 * h + 1) y) psi)
142
+ = (Z.of_nat (length (filter (fun p => psi (fst p)) (tin (arow (2 * h + 1) (length y) (disj js))))) - Z.of_nat (h + 1))%Z.
143
+ Proof.
144
+ intros h js y psi Hy. unfold pre.
145
+ rewrite wsum_ones.
146
+ 2: { intros q z Hin. destruct (in_arow _ _ _ q z Hin) as (c & j & _ & Hj & _). cbn [tin disj] in Hj.
147
+ apply in_map_iff in Hj as (j' & E & _). injection E as _ <-. reflexivity. }
148
+ rewrite (filter_ext_in _ (fun p => psi (fst p))).
149
+ - unfold arow at 1. cbn [tb disj]. replace ((2 * h + 1 - 1) / 2)%nat with h.
150
+ + rewrite Nat2Z.inj_add, Nat2Z.inj_add, Nat2Z.inj_mul. cbn [Z.of_nat]. lia.
151
+ + replace (2 * h + 1 - 1)%nat with (h * 2)%nat by lia. rewrite Nat.div_mul by lia. reflexivity.
152
+ - intros [q z] Hin. cbn [fst]. destruct (in_arow _ _ _ q z Hin) as (c & j & Hc & Hj & ->). cbn [tin disj] in Hj.
153
+ apply in_map_iff in Hj as (j' & E & Hj'). injection E as -> _. destruct (Hy j Hj') as [Hjl Hj0].
154
+ rewrite nth_xorv by (rewrite length_rep; nia). rewrite nth_rep by assumption. rewrite Hj0. reflexivity.
155
+ Qed.
156
+
157
+ (* Above the threshold: a disjunction of k inputs that hold 0, amplified r = 2h + 1 times, whose kr input copies flip
158
+ independently with probability eps, outputs 1 with probability at least 1 - rho^h, rho < 1, when 2 k eps > 1 *)
159
+ Theorem flip_fails : forall k, (1 <= k)%nat -> 1 < 2 * INR k * eps ->
160
+ exists rho, 0 <= rho < 1 /\
161
+ forall h js y (src : nat -> nat), length js = k -> NoDup js ->
162
+ (forall j, In j js -> (j < length y)%nat /\ nth j y false = false) -> (forall q q', src q = src q' -> q = q') ->
163
+ 1 - rho ^ h <= P (fun w => Z.leb 0 (pre (arow (2 * h + 1) (length y) (disj js))
164
+ (xorv (rep (2 * h + 1) y) (fun q => fb Omega X w (src q)))) = true).
165
+ Proof.
166
+ intros k Hk H. pose proof eps_range as He. assert (Hk' : 1 <= INR k) by (apply (le_INR 1); exact Hk).
167
+ assert (He0 : 0 < eps) by (destruct (Rle_lt_dec eps 0); [nra | assumption]).
168
+ destruct (rho_lt k eps Hk (conj He0 (proj2 He)) H) as [Hu Hrho].
169
+ set (u := (2 * INR k * eps - 1) / (4 * INR k * eps)) in *. set (x := 1 - u). set (c := 1 - eps + eps * x).
170
+ assert (Ec : c = 1 - eps * u) by (unfold c, x; ring). rewrite <- Ec in Hrho. fold x in Hrho.
171
+ assert (Hc : 0 <= c <= 1) by (rewrite Ec; split; nra).
172
+ assert (Hx : 0 < x <= 1) by (unfold x; lra).
173
+ exists (c ^ (2 * k) / x). split; [split; [apply Rmult_le_pos; [apply pow_le; lra | apply Rlt_le, Rinv_0_lt_compat; lra] | exact Hrho]|].
174
+ intros h js y src Hlen Hnd Hy Hsrc.
175
+ set (r := (2 * h + 1)%nat).
176
+ assert (Hrow : rowok (length y) (disj js)).
177
+ { split.
178
+ - cbn [tin disj]. rewrite map_map. cbn [fst]. rewrite map_id. exact Hnd.
179
+ - intros j z Hin. cbn [tin disj] in Hin. apply in_map_iff in Hin as (j' & E & Hj'). injection E as <- <-.
180
+ split; [exact (proj1 (Hy j' Hj')) | left; reflexivity]. }
181
+ destruct (arow_ok r _ _ Hrow) as [Hnd' _].
182
+ set (gs := map (fun p => src (fst p)) (tin (arow r (length y) (disj js)))).
183
+ assert (Hgs : NoDup gs).
184
+ { unfold gs. rewrite <- (map_map fst src). apply nodup_map_inj; [intros q q' _ _ E; exact (Hsrc q q' E) | exact Hnd']. }
185
+ assert (Hlg : length gs = (k * r)%nat).
186
+ { unfold gs. rewrite length_map, length_tin_arow. cbn [tin disj]. rewrite length_map, Hlen. lia. }
187
+ (* the disjunction is wrong exactly when at least h + 1 of the copies it reads flip *)
188
+ eapply Rle_trans; [|apply (P_mono (fun w => ~ (cnt gs w < h + 1)%nat))].
189
+ 2: { intros w Hw. unfold r. rewrite pre_disj by exact Hy. unfold cnt, gs, r in Hw. rewrite length_filter_map in Hw.
190
+ cbv beta in Hw |- *. apply Z.leb_le. lia. }
191
+ assert (Hcomp : 1 <= P (fun w => ~ (cnt gs w < h + 1)%nat) + P (fun w => (cnt gs w < h + 1)%nat)).
192
+ { rewrite <- P_true. eapply Rle_trans; [|apply P_or]. apply P_mono. intros w _.
193
+ destruct (Nat.lt_ge_cases (cnt gs w) (h + 1)); [right | left]; lia. }
194
+ pose proof (P_few gs (h + 1) x Hgs Hx ltac:(lia)) as B. fold c in B. rewrite Hlg in B.
195
+ replace (h + 1 - 1)%nat with h in B by lia.
196
+ assert (Eb : c ^ (k * r) / x ^ h = c ^ k * (c ^ (2 * k) / x) ^ h).
197
+ { unfold r. replace (k * (2 * h + 1))%nat with (2 * k * h + k)%nat by lia. rewrite pow_add, pow_mult.
198
+ unfold Rdiv. rewrite Rpow_mult_distr, pow_inv. ring. }
199
+ rewrite Eb in B.
200
+ assert (Hck : c ^ k <= 1) by (apply pow_le_one; lra).
201
+ assert (Hr0 : 0 <= (c ^ (2 * k) / x) ^ h)
202
+ by (apply pow_le; apply Rmult_le_pos; [apply pow_le; lra | apply Rlt_le, Rinv_0_lt_compat; lra]).
203
+ assert (0 <= c ^ k) by (apply pow_le; lra). nra.
204
+ Qed.
205
+
206
+ End Fail.
rocq/Host.v CHANGED
@@ -1,5 +1,5 @@
1
  (* The SUBLEQ host H_A as a netlist of ternary threshold units, block by block in the order of
2
- the generator, for words of A bits (Construction 3.8), and the machine it computes. *)
3
  From Stdlib Require Import List Bool Arith ZArith Lia.
4
  Import ListNotations.
5
  From TH Require Import TwoHead Net Gates.
 
1
  (* The SUBLEQ host H_A as a netlist of ternary threshold units, block by block in the order of
2
+ the generator, for words of A bits (Construction 3.7), and the machine it computes. *)
3
  From Stdlib Require Import List Bool Arith ZArith Lia.
4
  Import ListNotations.
5
  From TH Require Import TwoHead Net Gates.
rocq/HostCount.v ADDED
@@ -0,0 +1,403 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* Proposition 3.8: the units, edges and biases of H_A for every A >= 3, and the identity units and nonzero entries of
2
+ Lev(H_A). *)
3
+ From Stdlib Require Import List Bool Arith ZArith Lia NArith Morphisms Setoid.
4
+ Import ListNotations.
5
+ From TH Require Import TwoHead Net Gates Host HostWF Lev BlockLev HostLev.
6
+
7
+ #[local] Instance nsum_proper : Proper (eq ==> pointwise_relation nat eq ==> eq) nsum.
8
+ Proof. intros k k' -> f g H. apply nsum_ext. intros i _. apply H. Qed.
9
+
10
+ (* ---- counting bits ---------------------------------------------------------------------------------------- *)
11
+ (* half of the values below 2^k have bit b set *)
12
+ Lemma count_bit : forall k b, b < k -> 2 * nsum (2 ^ k) (fun v => Nat.b2n (Nat.testbit v b)) = 2 ^ k.
13
+ Proof.
14
+ induction k as [|k IH]; intros b Hb; [lia|].
15
+ rewrite Nat.pow_succ_r', (Nat.mul_comm 2 (2 ^ k)), nsum_mul.
16
+ destruct b as [|b].
17
+ - rewrite (nsum_ext (2 ^ k) _ (fun _ => 1)); [rewrite nsum_const; lia|].
18
+ intros q _. cbn [nsum]. rewrite Nat.add_0_r, Nat.testbit_even_0, Nat.testbit_odd_0. reflexivity.
19
+ - rewrite (nsum_ext (2 ^ k) _ (fun q => Nat.b2n (Nat.testbit q b) + Nat.b2n (Nat.testbit q b))).
20
+ + rewrite nsum_add. specialize (IH b ltac:(lia)). lia.
21
+ + intros q _. cbn [nsum]. rewrite Nat.add_0_r, Nat.testbit_even_succ', Nat.testbit_odd_succ'. lia.
22
+ Qed.
23
+
24
+ (* a cyclic shift of the indices leaves a sum unchanged *)
25
+ Lemma nsum_shift : forall M c f, c <= M -> nsum M (fun j => f ((j + c) mod M)) = nsum M f.
26
+ Proof.
27
+ intros M c f Hc. destruct (Nat.eq_dec M 0) as [->|HM]; [reflexivity|].
28
+ replace M with ((M - c) + c) at 1 by lia. rewrite nsum_split.
29
+ rewrite (nsum_ext (M - c) _ (fun j => f (c + j))) by (intros j Hj; rewrite Nat.mod_small by lia; f_equal; lia).
30
+ rewrite (nsum_ext c _ f).
31
+ - transitivity (nsum (c + (M - c)) f); [rewrite nsum_split; lia | f_equal; lia].
32
+ - intros i Hi. f_equal. replace (M - c + i + c) with (i + 1 * M) by lia.
33
+ rewrite Nat.Div0.mod_add. apply Nat.mod_small. lia.
34
+ Qed.
35
+
36
+ Section HC.
37
+ Variable A : nat.
38
+ Hypothesis HA : 3 <= A.
39
+
40
+ Lemma SW_half : SW A = 2 * 2 ^ (A - 1).
41
+ Proof. unfold SW. replace A with (S (A - 1)) at 1 by lia. rewrite Nat.pow_succ_r'. reflexivity. Qed.
42
+
43
+ (* the decode lines of p + 3: half of the lines feed each bit *)
44
+ Lemma Q_count : forall i, i < A ->
45
+ length (filter (fun j => bitof A ((j + 3) mod SW A) i) (seq 0 (SW A))) = 2 ^ (A - 1).
46
+ Proof.
47
+ intros i Hi. pose proof (SW_ge A HA). rewrite length_filter_seq.
48
+ transitivity (nsum (SW A) (fun v => Nat.b2n (Nat.testbit v (A - 1 - i)))).
49
+ - rewrite <- (nsum_shift (SW A) 3 (fun v => Nat.b2n (Nat.testbit v (A - 1 - i)))) by lia.
50
+ apply nsum_ext. intros j _. reflexivity.
51
+ - pose proof (count_bit A (A - 1 - i) ltac:(lia)) as Hc. pose proof SW_half as E. unfold SW in *. lia.
52
+ Qed.
53
+
54
+ Lemma nsum_SS : nsum (A - 1) (fun i => S (S i)) = tri A + (A - 1).
55
+ Proof.
56
+ unfold tri. generalize (A - 1) as k. induction k as [|k IH]; cbn [nsum]; lia.
57
+ Qed.
58
+
59
+ (* ---- the units ------------------------------------------------------------------------------------------- *)
60
+ (* (8A + 4) 2^A + (A^2 + 39A + 4)/2 units *)
61
+ Theorem host_units_count : 2 * length (host_units A) = (16 * A + 8) * SW A + A * A + 39 * A + 4.
62
+ Proof.
63
+ change (host_units A) with (fus (hblocks A) (nH A)).
64
+ rewrite (units_bsum (hblocks A) (nH A) (hout A) (host_wf' A HA) (hout_valid A HA)), (bsum_host A HA).
65
+ rewrite (nsum_ext (A - 1) _ (fun i => S (S i))) by (intros i _; rewrite nsum_const; lia).
66
+ rewrite nsum_SS. pose proof (tri_eq A HA).
67
+ cbn [nsum nth hpre hpost bcount bsize blk_P blk_HP blk_FA blk_Q blk_F blk_PA blk_PB blk_AC blk_W blk_RX blk_RY blk_KP
68
+ blk_X blk_Y blk_PR blk_C blk_AX blk_NX blk_XN blk_EQ blk_R0 blk_H blk_R blk_LEQ blk_TA blk_TB blk_NP blk_HAB
69
+ blk_WR blk_NM].
70
+ rewrite !nsum_const. nia.
71
+ Qed.
72
+
73
+ (* the datapath and the memory: the blocks whose number of units grows with 2^A, with the operand fetch and the read
74
+ multiplexer, hold (8A + 4) 2^A + 5A of them *)
75
+ Definition memblocks : list nat := [0; 2; 3; 4; 6; 7; 8; 10; 11; 12; 13; 14; 15; tb A + 13; tb A + 14].
76
+
77
+ Theorem host_memory_count :
78
+ fold_right Nat.add 0 (map (fun b => bcount (nth b (hblocks A) blk0) * bsize (nth b (hblocks A) blk0)) memblocks)
79
+ = (8 * A + 4) * SW A + 5 * A.
80
+ Proof.
81
+ unfold memblocks. cbn [map fold_right]. rewrite !nth_hb_pre by lia. rewrite !nth_hb_post by lia.
82
+ cbn [nth hpre hpost bcount bsize blk_P blk_FA blk_F blk_PA blk_PB blk_W blk_RX blk_RY blk_KP blk_X blk_Y blk_WR blk_NM].
83
+ nia.
84
+ Qed.
85
+
86
+ (* ---- the edges --------------------------------------------------------------------------------------------- *)
87
+ Definition pe (b : nat) : nat :=
88
+ nsum (bcount (nth b (hpre A) blk0)) (fun j => nsum (bsize (nth b (hpre A) blk0))
89
+ (fun r => length (sin (nth r (bshape (nth b (hpre A) blk0) j) su0)))).
90
+ Definition qe (i : nat) : nat :=
91
+ nsum (bcount (nth i (hpost A) blk0)) (fun j => nsum (bsize (nth i (hpost A) blk0))
92
+ (fun r => length (sin (nth r (bshape (nth i (hpost A) blk0) j) su0)))).
93
+ Definition te (i : nat) : nat := nsum (S (S i)) (fun r => length (sin (nth r (bshape (blk_T A (S i)) 0) su0))).
94
+
95
+ Ltac ecnt := unfold pe, qe;
96
+ cbn [nth hpre hpost bcount bsize bshape blk_P blk_HP blk_FA blk_Q blk_F blk_PA blk_PB blk_AC blk_W blk_RX blk_RY blk_KP
97
+ blk_X blk_Y blk_PR blk_C blk_AX blk_NX blk_XN blk_EQ blk_R0 blk_H blk_R blk_LEQ blk_TA blk_TB blk_NP blk_HAB
98
+ blk_WR blk_NM nsum sin sAND sOR lits map length app];
99
+ repeat setoid_rewrite length_map; repeat setoid_rewrite length_seq; rewrite ?nsum_const; try lia.
100
+
101
+ Lemma pe_vals : pe 0 = SW A * A /\ pe 1 = A * 2 /\ pe 2 = A * SW A * 2 /\ pe 3 = A * SW A * 2 /\ pe 4 = A * SW A * 2
102
+ /\ pe 6 = 3 * A * SW A /\ pe 7 = SW A * A /\ pe 8 = SW A * A /\ pe 9 = A /\ pe 10 = SW A * 2 /\ pe 11 = A * SW A * 2
103
+ /\ pe 12 = A * SW A * 2 /\ pe 13 = SW A * A * 2 /\ pe 14 = A * SW A /\ pe 15 = A * SW A /\ pe 16 = (A - 1) * 2.
104
+ Proof. repeat split; ecnt. Qed.
105
+
106
+ Lemma pe5 : pe 5 = A * 2 ^ (A - 1).
107
+ Proof.
108
+ unfold pe. cbn [nth hpre bcount bsize bshape blk_Q nsum sin sOR].
109
+ rewrite (nsum_ext A _ (fun _ => 2 ^ (A - 1))); [rewrite nsum_const; lia|].
110
+ intros i Hi. cbn [nth Nat.add]. rewrite !length_map. apply Q_count. lia.
111
+ Qed.
112
+
113
+ Lemma qe_vals : qe 1 = A * 2 /\ qe 2 = A * 2 /\ qe 3 = A * 2 /\ qe 4 = A /\ qe 5 = 6 /\ qe 6 = (A - 1) * 9
114
+ /\ qe 7 = (A - 1) * 3 /\ qe 8 = 4 /\ qe 9 = A * 3 /\ qe 10 = A * 3 /\ qe 11 = A * 3 /\ qe 12 = 9
115
+ /\ qe 13 = SW A * A * 2 /\ qe 14 = SW A * A * 2.
116
+ Proof. repeat split; ecnt. Qed.
117
+
118
+ Lemma qe0 : qe 0 = tri A + (A - 1).
119
+ Proof.
120
+ unfold qe. cbn [nth hpost bcount bsize bshape blk_C nsum sin sOR]. rewrite <- nsum_SS.
121
+ apply nsum_ext. intros m _. cbn [nth map length]. rewrite !length_map, length_seq. lia.
122
+ Qed.
123
+
124
+ Lemma sum_rev : forall k, 2 * nsum k (fun j => k + 1 - j) = k * k + 3 * k.
125
+ Proof.
126
+ intro k. assert (H1 : nsum k (fun j => k + 1 - j) + nsum k (fun j => j) = k * (k + 1)).
127
+ { rewrite <- nsum_add, <- nsum_const. apply nsum_ext. intros j Hj. lia. }
128
+ assert (H2 : 2 * nsum k (fun j => j) = k * (k - 1)) by (clear; induction k as [|k IH]; cbn [nsum]; nia).
129
+ nia.
130
+ Qed.
131
+
132
+ Lemma te_val : forall i, 2 * te i = S i * S i + 5 * S i.
133
+ Proof.
134
+ intro i. unfold te. replace (S (S i)) with (1 + S i) by lia. rewrite nsum_split.
135
+ assert (H0 : nsum 1 (fun r => length (sin (nth r (bshape (blk_T A (S i)) 0) su0))) = S i)
136
+ by (cbn [nsum nth bshape blk_T sin sAND]; rewrite !length_map, length_seq; reflexivity).
137
+ rewrite H0. rewrite (nsum_ext (S i) _ (fun j => S i + 1 - j)).
138
+ - pose proof (sum_rev (S i)). lia.
139
+ - intros j Hj. cbn [Nat.add nth bshape blk_T]. rewrite nth_map_d with (d' := 0) by (rewrite length_seq; lia).
140
+ rewrite seq_nth by lia. cbn [sin sAND]. rewrite length_map, length_app, length_map, length_seq. cbn [length]. lia.
141
+ Qed.
142
+
143
+ Lemma sum_te : forall K, 6 * nsum K (fun i => S i * S i + 5 * S i) = K * (K + 1) * (2 * K + 1) + 15 * (K * (K + 1)).
144
+ Proof. induction K as [|K IH]; cbn [nsum]; nia. Qed.
145
+
146
+ (* (49A + 4) 2^(A-1) + (A^3 + 3A^2 + 2A)/6 + A^2 + 32A + 4 edges *)
147
+ Theorem host_edges : 6 * nsum (length (host_units A)) (fun k => length (tin (nth k (host_units A) tu0)))
148
+ = 3 * (49 * A + 4) * SW A + A * A * A + 9 * (A * A) + 194 * A + 24.
149
+ Proof.
150
+ change (host_units A) with (fus (hblocks A) (nH A)).
151
+ rewrite (edges_bsum (hblocks A) (nH A) (hout A) (host_wf' A HA) (hout_valid A HA)), (bsum_host A HA).
152
+ rewrite (nsum_ext 17 _ pe)
153
+ by (intros b Hb; unfold pe; apply nsum_ext; intros j _; apply nsum_ext; intros r _; cbn [usu]; unfold sunit;
154
+ rewrite nth_hb_pre by exact Hb; reflexivity).
155
+ rewrite (nsum_ext (A - 1) _ te)
156
+ by (intros i Hi; unfold te; apply nsum_ext; intros r _; cbn [usu]; unfold sunit;
157
+ replace (17 + i) with (16 + S i) by lia; rewrite nth_hb_T by lia; reflexivity).
158
+ rewrite (nsum_ext 15 _ qe)
159
+ by (intros i Hi; unfold qe; apply nsum_ext; intros j _; apply nsum_ext; intros r _; cbn [usu]; unfold sunit;
160
+ rewrite nth_hb_post by lia; reflexivity).
161
+ cbn [nsum]. rewrite pe5, qe0.
162
+ destruct pe_vals as (P0 & P1 & P2 & P3 & P4 & P6 & P7 & P8 & P9 & P10 & P11 & P12 & P13 & P14 & P15 & P16).
163
+ destruct qe_vals as (Q1 & Q2 & Q3 & Q4 & Q5 & Q6 & Q7 & Q8 & Q9 & Q10 & Q11 & Q12 & Q13 & Q14).
164
+ rewrite P0, P1, P2, P3, P4, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16.
165
+ rewrite Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13, Q14.
166
+ assert (HT : 2 * nsum (A - 1) te = nsum (A - 1) (fun i => S i * S i + 5 * S i)).
167
+ { generalize (A - 1) as K. induction K as [|K IH]; cbn [nsum]; [reflexivity|]. rewrite <- IH, <- te_val. lia. }
168
+ pose proof (sum_te (A - 1)) as HS6. pose proof (tri_eq A HA) as Htri. pose proof SW_half as Hh.
169
+ assert (Ea : exists a, A = S (S (S a))) by (exists (A - 3); lia). destruct Ea as [a Ea].
170
+ rewrite Ea in *. cbn [Nat.sub] in *. rewrite ?Nat.sub_0_r in *. nia.
171
+ Qed.
172
+
173
+ (* ---- the biases ---------------------------------------------------------------------------------------- *)
174
+ Lemma sb_and : forall ls, (- Z.of_nat (length ls) <= sb (sAND ls) <= 0)%Z.
175
+ Proof.
176
+ intro ls. cbn [sb sAND]. pose proof (npos_nneg ls). unfold npos in *. pose proof (filter_length_le _ snd ls). lia.
177
+ Qed.
178
+
179
+ Lemma sb_or : forall ls, sb (sOR ls) = (Z.of_nat (nneg ls) - 1)%Z.
180
+ Proof. reflexivity. Qed.
181
+
182
+ Lemma nneg_pos : forall (X : Type) (f : X -> sref) (l : list X), nneg (map (fun x => (f x, true)) l) = 0.
183
+ Proof. intros X f l. unfold nneg. induction l as [|x t IH]; [reflexivity|]. cbn [map filter snd negb]. exact IH. Qed.
184
+
185
+ Lemma lw_pm : forall (ls : list lit) p z, In (p, z) (map lw ls) -> z = 1%Z \/ z = (-1)%Z.
186
+ Proof.
187
+ intros ls p z H. apply in_map_iff in H as ([x pol] & E & _). unfold lw in E. cbn [fst snd] in E.
188
+ injection E as _ <-. destruct pol; [left | right]; reflexivity.
189
+ Qed.
190
+
191
+ (* every unit is a threshold unit with weights -1 or 1 and a bias in [-A, 1] *)
192
+ Definition gate_ok (u : su) : Prop :=
193
+ (forall p z, In (p, z) (sin u) -> z = 1%Z \/ z = (-1)%Z) /\ (- Z.of_nat A <= sb u <= 1)%Z.
194
+
195
+ Lemma and_ok : forall ls, length ls <= A -> gate_ok (sAND ls).
196
+ Proof.
197
+ intros ls H. split; [intros p z Hin; exact (lw_pm ls p z Hin)|]. pose proof (sb_and ls). lia.
198
+ Qed.
199
+
200
+ Lemma or_ok : forall ls, nneg ls <= 2 -> gate_ok (sOR ls).
201
+ Proof. intros ls H. split; [intros p z Hin; exact (lw_pm ls p z Hin)|]. rewrite sb_or. lia. Qed.
202
+
203
+ Theorem host_gate_ok : forall b j r, valid (hblocks A) (nH A) (SRef b j r) -> gate_ok (sunit (hblocks A) b j r).
204
+ Proof.
205
+ intros b j r (Hb & Hj & Hr). rewrite length_hblocks in Hb by lia. unfold sunit.
206
+ destruct (Nat.lt_ge_cases b 17) as [Hp|Hp].
207
+ { rewrite nth_hb_pre in Hj, Hr |- * by exact Hp.
208
+ assert (Hc : b = 0 \/ b = 1 \/ b = 2 \/ b = 3 \/ b = 4 \/ b = 5 \/ b = 6 \/ b = 7 \/ b = 8 \/ b = 9
209
+ \/ b = 10 \/ b = 11 \/ b = 12 \/ b = 13 \/ b = 14 \/ b = 15 \/ b = 16) by lia.
210
+ destruct Hc as [->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->| ->]]]]]]]]]]]]]]]];
211
+ cbn [nth hpre bcount bsize bshape blk_P blk_HP blk_FA blk_Q blk_F blk_PA blk_PB blk_AC blk_W
212
+ blk_RX blk_RY blk_KP blk_X blk_Y blk_PR] in Hj, Hr |- *;
213
+ (destruct r as [|r]; [|lia]); cbn [nth];
214
+ first [ apply and_ok; unfold lits; rewrite ?length_map, ?length_seq; cbn [length]; lia
215
+ | apply or_ok; rewrite ?nneg_pos; unfold nneg; cbn [filter snd negb length]; lia ]. }
216
+ destruct (Nat.lt_ge_cases b (tb A)) as [HT|HT].
217
+ { unfold tb in HT. replace b with (16 + (b - 16)) in Hj, Hr |- * by lia.
218
+ rewrite nth_hb_T in Hj, Hr |- * by lia. cbn [bcount bsize bshape blk_T] in Hj, Hr |- *.
219
+ destruct r as [|r]; cbn [nth].
220
+ - apply and_ok. rewrite length_map, length_seq. lia.
221
+ - rewrite nth_map_d with (d' := 0) by (rewrite length_seq; lia). rewrite seq_nth by lia.
222
+ apply and_ok. rewrite length_app, length_map, length_seq. cbn [length]. lia. }
223
+ replace b with (tb A + (b - tb A)) in Hj, Hr |- * by lia.
224
+ rewrite nth_hb_post in Hj, Hr |- * by lia.
225
+ assert (Hi : b - tb A < 15) by (unfold tb in *; lia).
226
+ remember (b - tb A) as i eqn:Ei. clear Ei Hb Hp HT.
227
+ assert (Hc : i = 0 \/ i = 1 \/ i = 2 \/ i = 3 \/ i = 4 \/ i = 5 \/ i = 6 \/ i = 7 \/ i = 8 \/ i = 9
228
+ \/ i = 10 \/ i = 11 \/ i = 12 \/ i = 13 \/ i = 14) by lia.
229
+ destruct Hc as [->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->| ->]]]]]]]]]]]]]];
230
+ cbn [nth hpost bcount bsize bshape blk_C blk_AX blk_NX blk_XN blk_EQ blk_R0 blk_H blk_R blk_LEQ
231
+ blk_TA blk_TB blk_NP blk_HAB blk_WR blk_NM] in Hj, Hr |- *.
232
+ - destruct r as [|r]; [|lia]. cbn [nth]. apply or_ok.
233
+ assert (E : forall x (l : list lit), nneg ((x, true) :: l) = nneg l) by reflexivity.
234
+ rewrite E, nneg_pos. lia.
235
+ - destruct r as [|r]; [|lia]. cbn [nth]. apply and_ok. cbn [length]. lia.
236
+ - destruct r as [|r]; [|lia]. cbn [nth]. apply and_ok. cbn [length]. lia.
237
+ - destruct r as [|r]; [|lia]. cbn [nth]. apply or_ok. unfold nneg. cbn [filter snd negb length]. lia.
238
+ - destruct r as [|r]; [|lia]. cbn [nth]. apply and_ok. rewrite length_map, length_seq. lia.
239
+ - assert (Hr3 : r = 0 \/ r = 1 \/ r = 2) by lia. destruct Hr3 as [->|[->| ->]]; cbn [nth];
240
+ first [apply and_ok; cbn [length]; lia | apply or_ok; unfold nneg; cbn [filter snd negb length]; lia].
241
+ - assert (Hr3 : r = 0 \/ r = 1 \/ r = 2) by lia.
242
+ destruct Hr3 as [->|[->| ->]]; cbn [nth map]; split; cbn [sin sb];
243
+ try (intros p z Hin; repeat (destruct Hin as [Hin|Hin]; [injection Hin as _ <-; auto|]); destruct Hin); lia.
244
+ - destruct r as [|r]; [|lia]. cbn [nth]. split; cbn [sin sb]; [|lia].
245
+ intros p z Hin. repeat (destruct Hin as [Hin|Hin]; [injection Hin as _ <-; auto|]). destruct Hin.
246
+ - destruct r as [|r]; [|lia]. cbn [nth]. split; cbn [sin sb]; [|lia].
247
+ intros p z Hin. repeat (destruct Hin as [Hin|Hin]; [injection Hin as _ <-; auto|]). destruct Hin.
248
+ - destruct r as [|r]; [|lia]. cbn [nth]. apply and_ok. cbn [length]. lia.
249
+ - destruct r as [|r]; [|lia]. cbn [nth]. apply and_ok. cbn [length]. lia.
250
+ - destruct r as [|r]; [|lia]. cbn [nth]. apply or_ok. unfold nneg. cbn [filter snd negb length]. lia.
251
+ - assert (Hr3 : r = 0 \/ r = 1 \/ r = 2) by lia. destruct Hr3 as [->|[->| ->]]; cbn [nth];
252
+ first [apply and_ok; cbn [length]; lia | apply or_ok; unfold nneg; cbn [filter snd negb length]; lia].
253
+ - destruct r as [|r]; [|lia]. cbn [nth]. apply and_ok. cbn [length]. lia.
254
+ - destruct r as [|r]; [|lia]. cbn [nth]. apply or_ok. unfold nneg. cbn [filter snd negb length]. lia.
255
+ Qed.
256
+
257
+ (* the units of the flat netlist, with their weights and biases *)
258
+ Theorem host_weights_biases : forall k, k < length (host_units A) ->
259
+ (forall i z, In (i, z) (tin (nth k (host_units A) tu0)) -> z = 1%Z \/ z = (-1)%Z)
260
+ /\ (- Z.of_nat A <= Net.tb (nth k (host_units A) tu0) <= 1)%Z.
261
+ Proof.
262
+ intros k Hk. change (host_units A) with (fus (hblocks A) (nH A)) in *.
263
+ rewrite (fus_len (hblocks A) (nH A) (host_wf' A HA)) in Hk.
264
+ destruct (loc (hblocks A) (nH A) (host_wf' A HA) k Hk) as (b & j & r & Hv & ->).
265
+ rewrite (fus_nth (hblocks A) (nH A) (host_wf' A HA) b j r Hv). unfold flat_unit. cbn [tin Net.tb].
266
+ destruct (host_gate_ok b j r Hv) as [Hw Hs]. split; [|exact Hs].
267
+ intros i z Hin. apply in_map_iff in Hin as ([p z'] & E & Hin). cbn [fst snd] in E. injection E as _ <-.
268
+ exact (Hw p z' Hin).
269
+ Qed.
270
+
271
+ (* ---- each unit occurs once in Lev(H_A) ---------------------------------------------------------------------- *)
272
+ Lemma hout_inj : forall i i', i < nH A -> i' < nH A -> hout A i = hout A i' -> i = i'.
273
+ Proof.
274
+ intros i i' Hi Hi' E. destruct (Nat.eq_dec i i') as [|Hne]; [assumption|]. exfalso. unfold hout in E.
275
+ 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);
276
+ try lia; injection E; intros; lia.
277
+ Qed.
278
+
279
+ Lemma depth13_out : forall x, valid (hblocks A) (nH A) x -> cdh A x = 13 -> exists i, i < nH A /\ hout A i = x.
280
+ Proof.
281
+ intros x Hx H13. destruct (out_dec A HA x) as [Ho|Hno]; [exact Ho|]. exfalso.
282
+ destruct (host_reader A HA x Hx Hno) as (b & j & r & z & Hv & Hin & _).
283
+ destruct (host_unit_ok A HA b j r Hv) as [Hall _]. pose proof (proj1 (Hall x z Hin)).
284
+ pose proof (cdh_le13 A HA (SRef b j r)). lia.
285
+ Qed.
286
+
287
+ Definition hsrc : list src := concat (map snd (lsrc (nH A) (host_units A) (host_next A))).
288
+
289
+ Lemma hsrc_range : forall s, In (Un s) hsrc -> nH A <= s < nH A + length (host_units A).
290
+ Proof.
291
+ intros s Hs. unfold hsrc, lsrc in Hs. rewrite map_app, concat_app in Hs. apply in_app_or in Hs as [Hs|Hs].
292
+ - rewrite map_map in Hs. apply in_concat in Hs as (cs & Hcs & Hin). apply in_map_iff in Hcs as (l & <- & _).
293
+ cbn [snd] in Hin. destruct (srcs_spec _ _ _ l (Un s) Hin) as [HU _]. destruct (HU s eq_refl) as (k & Hk & -> & _).
294
+ lia.
295
+ - cbn [map concat snd] in Hs. rewrite app_nil_r in Hs.
296
+ destruct (srcd_spec (nH A) (host_units A) (host_next A)) with (c := Un s) as [HU _]; try exact Hs.
297
+ + apply Forall_forall. intros a Ha. unfold host_next in Ha. apply in_map_iff in Ha as (i & <- & Hi).
298
+ apply in_seq in Hi. unfold NS. pose proof (idx_lt_total _ _ _ (hout_valid A HA i ltac:(lia))) as H.
299
+ change (host_units A) with (fus (hblocks A) (nH A)). rewrite (fus_len _ _ (host_wf' A HA)). exact H.
300
+ + exact (host_next_len A).
301
+ + rewrite (host_dmax A HA). lia.
302
+ + destruct (HU s eq_refl) as (k & Hk & -> & _). lia.
303
+ Qed.
304
+
305
+ Lemma host_once : forall k, k < length (host_units A) -> length (filter (isun (nH A + k)) hsrc) = 1.
306
+ Proof.
307
+ intros k Hk. unfold hsrc.
308
+ assert (Hwfn : wfn (nH A) (host_units A)) by exact (fwfn (hblocks A) (nH A) (host_wf' A HA)).
309
+ rewrite (lev_units (nH A) (host_units A) (host_next A) Hwfn (host_next_len A)) by (unfold NS; lia).
310
+ change (host_units A) with (fus (hblocks A) (nH A)) in Hk. rewrite (fus_len _ _ (host_wf' A HA)) in Hk.
311
+ destruct (loc (hblocks A) (nH A) (host_wf' A HA) k Hk) as (b & j & r & Hv & Ek).
312
+ replace (nH A + k) with (idx (nH A) (hblocks A) (SRef b j r)) by (rewrite idx_ref, Ek; reflexivity).
313
+ rewrite (host_need A HA b j r Hv), (host_dep A HA _ Hv), (host_dmax A HA).
314
+ destruct (Nat.ltb_spec (cdh A (SRef b j r)) 13) as [Hl|Hg]; [reflexivity|].
315
+ pose proof (cdh_le13 A HA (SRef b j r)).
316
+ destruct (depth13_out (SRef b j r) Hv ltac:(lia)) as (i0 & Hi0 & E0).
317
+ unfold host_next. rewrite length_filter_map, <- E0.
318
+ rewrite (filter_ext_in _ (fun i => true && Nat.eqb i i0)).
319
+ - rewrite filter_eqb_seq by exact Hi0. reflexivity.
320
+ - intros i Hi. apply in_seq in Hi. cbn [andb]. destruct (Nat.eqb_spec i i0) as [->|E]; [apply Nat.eqb_refl|].
321
+ apply Nat.eqb_neq. intro Ex. apply E. apply hout_inj; [lia | exact Hi0|].
322
+ exact (idx_inj (hblocks A) (nH A) _ _ (hout_valid A HA i ltac:(lia)) (hout_valid A HA i0 Hi0) Ex).
323
+ Qed.
324
+
325
+ (* the rows of Lev(H_A) that are not units of H_A are identity units, and the entries are the edges of H_A and one for
326
+ each identity unit *)
327
+ Theorem host_lev_rows_split :
328
+ length (concat (lev (nH A) (host_units A) (host_next A)))
329
+ = length (host_units A) + length (filter (fun c => negb (isUn c)) hsrc)
330
+ /\ fold_right Nat.add 0 (map (fun row => length (tin row)) (concat (lev (nH A) (host_units A) (host_next A))))
331
+ = nsum (length (host_units A)) (fun k => length (tin (nth k (host_units A) tu0)))
332
+ + length (filter (fun c => negb (isUn c)) hsrc).
333
+ Proof.
334
+ split.
335
+ - rewrite lev_rowcount. fold hsrc.
336
+ assert (Hs : forall L : list src, length L = length (filter isUn L) + length (filter (fun c => negb (isUn c)) L))
337
+ by (induction L as [|c t IH]; [reflexivity|]; cbn [filter length]; destruct (isUn c); cbn [negb length]; lia).
338
+ rewrite Hs, (count_Un hsrc (nH A) (length (host_units A)) hsrc_range).
339
+ rewrite (nsum_ext _ _ (fun _ => 1)) by (intros k Hk; apply host_once; exact Hk). rewrite nsum_const. lia.
340
+ - rewrite lev_rowlens. fold hsrc. rewrite (sum_rowlen hsrc (host_units A) (nH A) (length (host_units A)) hsrc_range).
341
+ rewrite (nsum_ext _ (fun k => length (filter (isun (nH A + k)) hsrc) * length (tin (nth k (host_units A) tu0)))
342
+ (fun k => length (tin (nth k (host_units A) tu0))))
343
+ by (intros k Hk; rewrite host_once by exact Hk; lia).
344
+ lia.
345
+ Qed.
346
+
347
+ (* Lev(H_A) adds (11A + 6) 2^A + 35A + 25 identity units to the units of H_A *)
348
+ Theorem host_lev_identity : length (filter (fun c => negb (isUn c)) hsrc) = (11 * A + 6) * SW A + 35 * A + 25.
349
+ Proof.
350
+ destruct host_lev_rows_split as [H _]. rewrite length_concat in H. unfold list_sum in H.
351
+ pose proof (host_lev_rows A HA) as R. pose proof host_units_count as U. lia.
352
+ Qed.
353
+
354
+ End HC.
355
+
356
+ (* the least and the greatest bias are attained, by the conjunction [c = 2^A - 1] and by the disjunction of the
357
+ negated low bits of the operands *)
358
+ Lemma host_bias_attained : forall A, 3 <= A ->
359
+ (exists k, k < length (host_units A) /\ Net.tb (nth k (host_units A) tu0) = (- Z.of_nat A)%Z)
360
+ /\ (exists k, k < length (host_units A) /\ Net.tb (nth k (host_units A) tu0) = 1%Z).
361
+ Proof.
362
+ intros A HA. pose proof (SW_ge A HA). change (host_units A) with (fus (hblocks A) (nH A)).
363
+ assert (Hv1 : valid (hblocks A) (nH A) (SRef 9 0 0)).
364
+ { split; [rewrite length_hblocks by lia; unfold tb; lia|]. rewrite nth_hb_pre by lia. cbn. lia. }
365
+ assert (Hv2 : valid (hblocks A) (nH A) (SRef (tb A + 5) 0 1)).
366
+ { split; [rewrite length_hblocks by lia; lia|]. rewrite nth_hb_post by lia. cbn. lia. }
367
+ split.
368
+ - exists (boff (hblocks A) 9 + sz (hblocks A) 9 * 0 + 0). split.
369
+ + rewrite (fus_len _ _ (host_wf' A HA)). exact (unit_lt _ _ 9 0 0 Hv1).
370
+ + rewrite (fus_nth _ _ (host_wf' A HA) 9 0 0 Hv1). unfold flat_unit, sunit. cbn [Net.tb].
371
+ rewrite nth_hb_pre by lia. cbn [nth hpre bshape blk_AC sb sAND]. unfold npos.
372
+ assert (G : forall l : list nat, length (filter snd (map (fun t => (opb A 2 t, true)) l)) = length l)
373
+ by (induction l as [|a t IH]; [reflexivity|]; cbn [map filter snd length]; rewrite IH; reflexivity).
374
+ rewrite G, length_seq. reflexivity.
375
+ - exists (boff (hblocks A) (tb A + 5) + sz (hblocks A) (tb A + 5) * 0 + 1). split.
376
+ + rewrite (fus_len _ _ (host_wf' A HA)). exact (unit_lt _ _ _ 0 1 Hv2).
377
+ + rewrite (fus_nth _ _ (host_wf' A HA) _ 0 1 Hv2). unfold flat_unit, sunit. cbn [Net.tb].
378
+ rewrite nth_hb_post by lia. reflexivity.
379
+ Qed.
380
+
381
+ (* ---- the host with eight-bit words, in binary numbers ------------------------------------------------------ *)
382
+ Lemma host_units_8 : N.of_nat (length (host_units 8)) = 17598%N.
383
+ Proof. pose proof (host_units_count 8 ltac:(lia)) as H. assert (SW 8 = 256) by reflexivity. lia. Qed.
384
+
385
+ Lemma host_edges_8 : N.of_nat (nsum (length (host_units 8)) (fun k => length (tin (nth k (host_units 8) tu0)))) = 51132%N.
386
+ Proof. pose proof (host_edges 8 ltac:(lia)) as H. assert (SW 8 = 256) by reflexivity. lia. Qed.
387
+
388
+ Lemma host_memory_8 : N.of_nat (fold_right Nat.add 0 (map (fun b => bcount (nth b (hblocks 8) blk0)
389
+ * bsize (nth b (hblocks 8) blk0)) (memblocks 8)))
390
+ = 17448%N.
391
+ Proof. pose proof (host_memory_count 8 ltac:(lia)) as H. assert (SW 8 = 256) by reflexivity. lia. Qed.
392
+
393
+ (* Lev(H_8): 24,369 identity units and 75,501 nonzero entries *)
394
+ Lemma host_lev_identity_8 : N.of_nat (length (filter (fun c => negb (isUn c)) (hsrc 8))) = 24369%N.
395
+ Proof. pose proof (host_lev_identity 8 ltac:(lia)) as H. assert (SW 8 = 256) by reflexivity. lia. Qed.
396
+
397
+ Lemma host_lev_nonzero_8 :
398
+ N.of_nat (fold_right Nat.add 0 (map (fun row => length (tin row)) (concat (lev (nH 8) (host_units 8) (host_next 8)))))
399
+ = 75501%N.
400
+ Proof.
401
+ destruct (host_lev_rows_split 8 ltac:(lia)) as [_ H]. rewrite H.
402
+ pose proof host_edges_8. pose proof host_lev_identity_8. lia.
403
+ Qed.
rocq/HostLev.v ADDED
@@ -0,0 +1,922 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* The host levelized (Proposition 3.8 and Remark 2.7): for every A >= 3 every unit of H_A contributes to a next
2
+ value, the step has depth 13, and the layers of Lev(H_A) have the widths given below; the units, edges and biases
3
+ of H_A. *)
4
+ From Stdlib Require Import List Bool Arith ZArith Lia.
5
+ Import ListNotations.
6
+ From TH Require Import TwoHead Net Gates Host HostWF Lev BlockLev.
7
+
8
+ Section HL.
9
+ Variable A : nat.
10
+ Hypothesis HA : 3 <= A.
11
+
12
+ (* ---- the depth and the last reading layer of each signal ------------------------------------------------- *)
13
+ Definition cd_pre (b : nat) : nat :=
14
+ match b with 0 | 1 => 1 | 2 | 3 | 4 | 5 => 2 | 6 => 3 | 7 | 8 | 9 => 4 | 10 | 11 | 12 => 5 | 13 | 14 | 15 => 6 | _ => 7 end.
15
+ Definition cd_T (k r : nat) : nat := if Nat.eqb r 0 then 8 else if Nat.eqb r k then 7 else 8.
16
+ Definition cd_post (i j r : nat) : nat :=
17
+ match i with
18
+ | 0 => 9 | 1 | 2 => 7 | 3 => 8 | 4 => 9 | 5 => if r <? 2 then 7 else 8 | 6 => 10 | 7 | 8 => 11
19
+ | 9 | 10 => 12 | 11 => 13 | 12 => if r <? 2 then 12 else 13
20
+ | 13 => if Nat.eqb (j mod A) (A - 1) then 9 else 12
21
+ | _ => if Nat.eqb (j mod A) (A - 1) then 10 else 13
22
+ end.
23
+ Definition cdh (x : sref) : nat :=
24
+ match x with
25
+ | SIn _ => 0
26
+ | SRef b j r => if b <? 17 then cd_pre b else if b <? tb A then cd_T (b - 16) r else cd_post (b - tb A) j r
27
+ end.
28
+
29
+ Definition cl_pre (b j : nat) : nat :=
30
+ match b with
31
+ | 0 => if Nat.eqb j (SW A - 4) then 12 else 2
32
+ | 1 => 13 | 2 | 3 | 4 => 3 | 5 => 12 | 6 => if j <? 2 * A then 4 else 12 | 7 | 8 => 5 | 9 | 10 => 12
33
+ | 11 | 12 => 6 | 13 => if Nat.eqb (j mod A) (A - 1) then 10 else 13
34
+ | 14 | 15 => if Nat.eqb j (A - 1) then 8 else 10
35
+ | _ => 8
36
+ end.
37
+ Definition cl_post (i j r : nat) : nat :=
38
+ match i with
39
+ | 0 => 10 | 1 | 2 => 8 | 3 => 9 | 4 => 11 | 5 => if r <? 2 then 8 else 9 | 6 => 11 | 7 | 8 => 12
40
+ | 9 | 10 => 13 | 11 => 14 | 12 => if r <? 2 then 13 else 14
41
+ | 13 => if Nat.eqb (j mod A) (A - 1) then 10 else 13
42
+ | _ => 14
43
+ end.
44
+ Definition clh (x : sref) : nat :=
45
+ match x with
46
+ | SIn i => if i <? A then 1 else if Nat.eqb i A then 13 else 6
47
+ | SRef b j r => if b <? 17 then cl_pre b j else if b <? tb A then 9 else cl_post (b - tb A) j r
48
+ end.
49
+
50
+ Lemma cdh_pre : forall b j r, b < 17 -> cdh (SRef b j r) = cd_pre b.
51
+ Proof. intros b j r H. cbn [cdh]. destruct (Nat.ltb_spec b 17); [reflexivity | lia]. Qed.
52
+
53
+ Lemma cdh_T : forall k r, 1 <= k -> k < A -> cdh (SRef (16 + k) 0 r) = cd_T k r.
54
+ Proof.
55
+ intros k r H1 H2. cbn [cdh]. destruct (Nat.ltb_spec (16 + k) 17); [lia|].
56
+ destruct (Nat.ltb_spec (16 + k) (tb A)); [|unfold tb in *; lia]. f_equal. lia.
57
+ Qed.
58
+
59
+ Lemma cdh_post : forall i j r, cdh (SRef (tb A + i) j r) = cd_post i j r.
60
+ Proof.
61
+ intros i j r. cbn [cdh]. destruct (Nat.ltb_spec (tb A + i) 17); [unfold tb in *; lia|].
62
+ destruct (Nat.ltb_spec (tb A + i) (tb A)); [lia|]. f_equal. lia.
63
+ Qed.
64
+
65
+ Lemma cdh_post_at : forall b i j r, b = tb A + i -> cdh (SRef b j r) = cd_post i j r.
66
+ Proof. intros b i j r ->. apply cdh_post. Qed.
67
+
68
+ Lemma clh_pre : forall b j r, b < 17 -> clh (SRef b j r) = cl_pre b j.
69
+ Proof. intros b j r H. cbn [clh]. destruct (Nat.ltb_spec b 17); [reflexivity | lia]. Qed.
70
+
71
+ Lemma clh_T : forall k r, 1 <= k -> k < A -> clh (SRef (16 + k) 0 r) = 9.
72
+ Proof.
73
+ intros k r H1 H2. cbn [clh]. destruct (Nat.ltb_spec (16 + k) 17); [lia|].
74
+ destruct (Nat.ltb_spec (16 + k) (tb A)); [reflexivity | unfold tb in *; lia].
75
+ Qed.
76
+
77
+ Lemma clh_post : forall i j r, clh (SRef (tb A + i) j r) = cl_post i j r.
78
+ Proof.
79
+ intros i j r. cbn [clh]. destruct (Nat.ltb_spec (tb A + i) 17); [unfold tb in *; lia|].
80
+ destruct (Nat.ltb_spec (tb A + i) (tb A)); [lia|]. f_equal. lia.
81
+ Qed.
82
+
83
+ Lemma clh_post_at : forall b i j r, b = tb A + i -> clh (SRef b j r) = cl_post i j r.
84
+ Proof. intros b i j r ->. apply clh_post. Qed.
85
+
86
+ Lemma SW_ge8 : 8 <= SW A.
87
+ Proof. apply SW_ge. exact HA. Qed.
88
+
89
+ (* the named signals *)
90
+ Lemma cl_pcb : forall i, i < A -> clh (pcb i) = 1.
91
+ Proof. intros i H. cbn [clh pcb]. destruct (Nat.ltb_spec i A); [reflexivity | lia]. Qed.
92
+
93
+ Lemma cl_halt : clh (haltb A) = 13.
94
+ Proof. cbn [clh haltb]. rewrite Nat.ltb_irrefl, Nat.eqb_refl. reflexivity. Qed.
95
+
96
+ Lemma cl_mu : forall j t, clh (mu A j t) = 6.
97
+ Proof.
98
+ intros j t. cbn [clh mu]. destruct (Nat.ltb_spec (A + 1 + j * A + t) A); [lia|].
99
+ destruct (Nat.eqb_spec (A + 1 + j * A + t) A); [lia | reflexivity].
100
+ Qed.
101
+
102
+ Lemma cd_opb : forall o t, cdh (opb A o t) = 3.
103
+ Proof. intros o t. unfold opb. rewrite cdh_pre by lia. reflexivity. Qed.
104
+
105
+ Lemma cl_opb : forall o t, t < A -> clh (opb A o t) = if o <? 2 then 4 else 12.
106
+ Proof.
107
+ intros o t Ht. unfold opb. rewrite clh_pre by lia. cbn [cl_pre].
108
+ destruct (Nat.ltb_spec (o * A + t) (2 * A)), (Nat.ltb_spec o 2); try reflexivity; nia.
109
+ Qed.
110
+
111
+ Lemma cd_xv : forall i, cdh (xv A i) = 6.
112
+ Proof. intro i. unfold xv. rewrite cdh_pre by lia. reflexivity. Qed.
113
+
114
+ Lemma cd_yv : forall i, cdh (yv A i) = 6.
115
+ Proof. intro i. unfold yv. rewrite cdh_pre by lia. reflexivity. Qed.
116
+
117
+ Lemma cl_xv : forall i, i < A -> clh (xv A i) = if Nat.eqb i 0 then 8 else 10.
118
+ Proof.
119
+ intros i Hi. unfold xv. rewrite clh_pre by lia. cbn [cl_pre].
120
+ destruct (Nat.eqb_spec (A - 1 - i) (A - 1)), (Nat.eqb_spec i 0); try reflexivity; lia.
121
+ Qed.
122
+
123
+ Lemma cl_yv : forall i, i < A -> clh (yv A i) = if Nat.eqb i 0 then 8 else 10.
124
+ Proof.
125
+ intros i Hi. unfold yv. rewrite clh_pre by lia. cbn [cl_pre].
126
+ destruct (Nat.eqb_spec (A - 1 - i) (A - 1)), (Nat.eqb_spec i 0); try reflexivity; lia.
127
+ Qed.
128
+
129
+ Lemma cd_prr : forall i, cdh (prr i) = 7.
130
+ Proof. intro i. unfold prr. rewrite cdh_pre by lia. reflexivity. Qed.
131
+
132
+ Lemma cl_prr : forall i, clh (prr i) = 8.
133
+ Proof. intro i. unfold prr. rewrite clh_pre by lia. reflexivity. Qed.
134
+
135
+ Lemma cd_rbit : forall k, cdh (rbit A k) = if Nat.eqb k 0 then 8 else 11.
136
+ Proof. intro k. unfold rbit. destruct (Nat.eqb k 0); rewrite cdh_post; reflexivity. Qed.
137
+
138
+ Lemma cl_rbit : forall k, clh (rbit A k) = if Nat.eqb k 0 then 9 else 12.
139
+ Proof. intro k. unfold rbit. destruct (Nat.eqb k 0); rewrite clh_post; reflexivity. Qed.
140
+
141
+ (* membership in the predecessors of a gate *)
142
+ Lemma in_and : forall (ls : list lit) (x : sref) (pol : bool), In (x, pol) ls ->
143
+ In (x, if pol then 1%Z else (-1)%Z) (sin (sAND ls)).
144
+ Proof. intros ls x pol H. cbn [sin sAND]. exact (in_map lw ls (x, pol) H). Qed.
145
+
146
+ Lemma in_or : forall (ls : list lit) (x : sref) (pol : bool), In (x, pol) ls ->
147
+ In (x, if pol then 1%Z else (-1)%Z) (sin (sOR ls)).
148
+ Proof. intros ls x pol H. cbn [sin sOR]. exact (in_map lw ls (x, pol) H). Qed.
149
+
150
+ Ltac ing pol := first [apply (in_and _ _ pol) | apply (in_or _ _ pol)].
151
+
152
+ Lemma sin_SU : forall b l, sin (SU b l) = l.
153
+ Proof. reflexivity. Qed.
154
+
155
+ Lemma gate_in : forall (ls : list lit) (x : sref) (z : Z),
156
+ In (x, z) (sin (sAND ls)) \/ In (x, z) (sin (sOR ls)) -> In x (map fst ls).
157
+ Proof. exact in_sin_lits. Qed.
158
+
159
+ Lemma Q_ne : forall i, i < A -> In (SW A - 4) (filter (fun j => bitof A ((j + 3) mod SW A) i) (seq 0 (SW A))).
160
+ Proof.
161
+ intros i Hi. pose proof SW_ge8. apply filter_In. split; [apply in_seq; lia|].
162
+ replace (SW A - 4 + 3) with (SW A - 1) by lia. rewrite Nat.mod_small by lia.
163
+ unfold bitof, SW. replace (2 ^ A - 1) with (Nat.ones A) by (unfold Nat.ones; rewrite Nat.shiftl_1_l; lia).
164
+ apply Nat.ones_spec_low. lia.
165
+ Qed.
166
+
167
+ Lemma cl_P_ge : forall j, 2 <= cl_pre 0 j.
168
+ Proof. intro j. cbn [cl_pre]. destruct (Nat.eqb j (SW A - 4)); lia. Qed.
169
+
170
+ Lemma mod_A : forall m, m mod A < A.
171
+ Proof. intro m. apply Nat.mod_upper_bound. lia. Qed.
172
+
173
+ (* every unit lies one layer above its deepest predecessor and no later than the last reader of each *)
174
+ Definition unit_ok (b j r : nat) : Prop :=
175
+ (forall p z, In (p, z) (sin (sunit (hblocks A) b j r)) -> S (cdh p) <= cdh (SRef b j r) <= clh p)
176
+ /\ exists p z, In (p, z) (sin (sunit (hblocks A) b j r)) /\ S (cdh p) = cdh (SRef b j r).
177
+
178
+ Theorem host_unit_ok : forall b j r, valid (hblocks A) (nH A) (SRef b j r) -> unit_ok b j r.
179
+ Proof.
180
+ intros b j r (Hb & Hj & Hr). pose proof SW_ge8 as HS. rewrite length_hblocks in Hb by lia. unfold unit_ok, sunit.
181
+ destruct (Nat.lt_ge_cases b 17) as [Hp|Hp].
182
+ { rewrite nth_hb_pre in Hj, Hr |- * by exact Hp. rewrite cdh_pre by exact Hp.
183
+ assert (Hc : b = 0 \/ b = 1 \/ b = 2 \/ b = 3 \/ b = 4 \/ b = 5 \/ b = 6 \/ b = 7 \/ b = 8 \/ b = 9
184
+ \/ b = 10 \/ b = 11 \/ b = 12 \/ b = 13 \/ b = 14 \/ b = 15 \/ b = 16) by lia.
185
+ destruct Hc as [->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->| ->]]]]]]]]]]]]]]]];
186
+ cbn [nth hpre bcount bsize bshape blk_P blk_HP blk_FA blk_Q blk_F blk_PA blk_PB blk_AC blk_W
187
+ blk_RX blk_RY blk_KP blk_X blk_Y blk_PR cd_pre] in Hj, Hr |- *;
188
+ (destruct r as [|r]; [|lia]); cbn [nth].
189
+ - (* P *) split.
190
+ + intros p z Hin. lits_in Hin. apply in_map_iff in H as (t & <- & Ht). apply in_seq in Ht.
191
+ cbn [cdh pcb]. rewrite cl_pcb by lia. lia.
192
+ + exists (pcb 0), (if bitof A j 0 then 1%Z else (-1)%Z). split; [|reflexivity].
193
+ ing (bitof A j 0). unfold lits. apply (in_map (fun t => (pcb t, bitof A j t))). apply in_seq. lia.
194
+ - (* HP *) split.
195
+ + intros p z Hin. lits_in Hin. destruct H as [<-|[<-|[]]]; [cbn [cdh pcb]; rewrite cl_pcb by lia | cbn [cdh haltb]; rewrite cl_halt]; lia.
196
+ + exists (pcb j), 1%Z. split; [ing true; left; reflexivity | reflexivity].
197
+ - (* FA 0 *) split.
198
+ + intros p z Hin. lits_in Hin. destruct H as [<-|[<-|[]]]; [cbn [cdh mu]; rewrite cl_mu; lia|].
199
+ rewrite cdh_pre, clh_pre by lia. pose proof (cl_P_ge (j mod SW A)). cbn [cd_pre]. lia.
200
+ + exists (SRef 0 (j mod SW A) 0), 1%Z. split; [ing true; right; left; reflexivity | rewrite cdh_pre by lia; reflexivity].
201
+ - (* FA 1 *) split.
202
+ + intros p z Hin. lits_in Hin. destruct H as [<-|[<-|[]]]; [cbn [cdh mu]; rewrite cl_mu; lia|].
203
+ rewrite cdh_pre, clh_pre by lia. pose proof (cl_P_ge (j mod SW A)). cbn [cd_pre]. lia.
204
+ + exists (SRef 0 (j mod SW A) 0), 1%Z. split; [ing true; right; left; reflexivity | rewrite cdh_pre by lia; reflexivity].
205
+ - (* FA 2 *) split.
206
+ + intros p z Hin. lits_in Hin. destruct H as [<-|[<-|[]]]; [cbn [cdh mu]; rewrite cl_mu; lia|].
207
+ rewrite cdh_pre, clh_pre by lia. pose proof (cl_P_ge (j mod SW A)). cbn [cd_pre]. lia.
208
+ + exists (SRef 0 (j mod SW A) 0), 1%Z. split; [ing true; right; left; reflexivity | rewrite cdh_pre by lia; reflexivity].
209
+ - (* Q *) split.
210
+ + intros p z Hin. lits_in Hin. rewrite ?map_map in H. apply in_map_iff in H as (j' & <- & _).
211
+ rewrite cdh_pre, clh_pre by lia. pose proof (cl_P_ge j'). cbn [cd_pre]. lia.
212
+ + exists (SRef 0 (SW A - 4) 0), 1%Z. split; [|rewrite cdh_pre by lia; reflexivity].
213
+ ing true. apply (in_map (fun j' => (SRef 0 j' 0, true))). apply Q_ne. lia.
214
+ - (* F *) assert (Ho : j / A = 0 \/ j / A = 1 \/ j / A = 2) by (pose proof (div_lt j 3 A ltac:(lia) ltac:(lia)); lia).
215
+ split.
216
+ + intros p z Hin. lits_in Hin. rewrite ?map_map in H. apply in_map_iff in H as (j' & <- & _).
217
+ rewrite cdh_pre, clh_pre by lia. destruct Ho as [-> | [-> | ->]]; cbn [cd_pre cl_pre Nat.add]; lia.
218
+ + exists (SRef (2 + j / A) ((j mod A) * SW A + 0) 0), 1%Z. split.
219
+ * ing true. apply (in_map (fun j' => (SRef (2 + j / A) ((j mod A) * SW A + j') 0, true))). apply in_seq. lia.
220
+ * rewrite cdh_pre by lia. destruct Ho as [-> | [-> | ->]]; reflexivity.
221
+ - (* PA *) split.
222
+ + intros p z Hin. lits_in Hin. apply in_map_iff in H as (t & <- & Ht). apply in_seq in Ht.
223
+ rewrite cd_opb, cl_opb by lia. cbn. lia.
224
+ + exists (opb A 0 0), (if bitof A j 0 then 1%Z else (-1)%Z). split; [|rewrite cd_opb; reflexivity].
225
+ ing (bitof A j 0). unfold lits. apply (in_map (fun t => (opb A 0 t, bitof A j t))). apply in_seq. lia.
226
+ - (* PB *) split.
227
+ + intros p z Hin. lits_in Hin. apply in_map_iff in H as (t & <- & Ht). apply in_seq in Ht.
228
+ rewrite cd_opb, cl_opb by lia. cbn. lia.
229
+ + exists (opb A 1 0), (if bitof A j 0 then 1%Z else (-1)%Z). split; [|rewrite cd_opb; reflexivity].
230
+ ing (bitof A j 0). unfold lits. apply (in_map (fun t => (opb A 1 t, bitof A j t))). apply in_seq. lia.
231
+ - (* AC *) split.
232
+ + intros p z Hin. lits_in Hin. rewrite ?map_map in H. apply in_map_iff in H as (t & <- & Ht). apply in_seq in Ht.
233
+ rewrite cd_opb, cl_opb by lia. cbn. lia.
234
+ + exists (opb A 2 0), 1%Z. split; [|rewrite cd_opb; reflexivity].
235
+ ing true. apply (in_map (fun t => (opb A 2 t, true))). apply in_seq. lia.
236
+ - (* W *) split.
237
+ + intros p z Hin. lits_in Hin. destruct H as [<-|[<-|[]]]; [cbn [cdh haltb]; rewrite cl_halt; lia|].
238
+ rewrite cdh_pre, clh_pre by lia. cbn. lia.
239
+ + exists (SRef 8 j 0), 1%Z. split; [ing true; right; left; reflexivity | rewrite cdh_pre by lia; reflexivity].
240
+ - (* RX *) split.
241
+ + intros p z Hin. lits_in Hin. destruct H as [<-|[<-|[]]]; [cbn [cdh mu]; rewrite cl_mu; lia|].
242
+ rewrite cdh_pre, clh_pre by lia. cbn. lia.
243
+ + exists (SRef 7 (j mod SW A) 0), 1%Z. split; [ing true; right; left; reflexivity | rewrite cdh_pre by lia; reflexivity].
244
+ - (* RY *) split.
245
+ + intros p z Hin. lits_in Hin. destruct H as [<-|[<-|[]]]; [cbn [cdh mu]; rewrite cl_mu; lia|].
246
+ rewrite cdh_pre, clh_pre by lia. cbn. lia.
247
+ + exists (SRef 8 (j mod SW A) 0), 1%Z. split; [ing true; right; left; reflexivity | rewrite cdh_pre by lia; reflexivity].
248
+ - (* KP *) split.
249
+ + intros p z Hin. lits_in Hin. destruct H as [<-|[<-|[]]]; [cbn [cdh mu]; rewrite cl_mu; lia|].
250
+ rewrite cdh_pre, clh_pre by lia. cbn. lia.
251
+ + exists (SRef 10 (j / A) 0), (-1)%Z. split; [|rewrite cdh_pre by lia; reflexivity].
252
+ ing false. right. left. reflexivity.
253
+ - (* X *) split.
254
+ + intros p z Hin. lits_in Hin. rewrite ?map_map in H. apply in_map_iff in H as (j' & <- & _).
255
+ rewrite cdh_pre, clh_pre by lia. cbn. lia.
256
+ + exists (SRef 11 (j * SW A + 0) 0), 1%Z. split; [|rewrite cdh_pre by lia; reflexivity].
257
+ ing true. apply (in_map (fun j' => (SRef 11 (j * SW A + j') 0, true))). apply in_seq. lia.
258
+ - (* Y *) split.
259
+ + intros p z Hin. lits_in Hin. rewrite ?map_map in H. apply in_map_iff in H as (j' & <- & _).
260
+ rewrite cdh_pre, clh_pre by lia. cbn. lia.
261
+ + exists (SRef 12 (j * SW A + 0) 0), 1%Z. split; [|rewrite cdh_pre by lia; reflexivity].
262
+ ing true. apply (in_map (fun j' => (SRef 12 (j * SW A + j') 0, true))). apply in_seq. lia.
263
+ - (* PR *) split.
264
+ + intros p z Hin. lits_in Hin. destruct H as [<-|[<-|[]]];
265
+ [rewrite cd_xv, cl_xv by lia | rewrite cd_yv, cl_yv by lia]; destruct (Nat.eqb j 0); lia.
266
+ + exists (xv A j), (-1)%Z. split; [ing false; left; reflexivity | rewrite cd_xv; reflexivity]. }
267
+ destruct (Nat.lt_ge_cases b (tb A)) as [HT|HT].
268
+ { (* the carry terms into bit k = b - 16 *)
269
+ unfold tb in HT. replace b with (16 + (b - 16)) in Hj, Hr |- * by lia.
270
+ rewrite nth_hb_T in Hj, Hr |- * by lia. cbn [bcount bsize bshape blk_T] in Hj, Hr |- *.
271
+ assert (Hj0 : j = 0) by lia. subst j. rewrite cdh_T by lia.
272
+ remember (b - 16) as k eqn:Ek. assert (Hk : 1 <= k < A) by lia. destruct k as [|k]; [lia|].
273
+ destruct r as [|r]; cbn [nth cd_T Nat.eqb].
274
+ - split.
275
+ + intros p z Hin. lits_in Hin. rewrite ?map_map in H. apply in_map_iff in H as (i & <- & Hi). apply in_seq in Hi.
276
+ rewrite cd_prr, cl_prr. lia.
277
+ + exists (prr 0), 1%Z. split; [|rewrite cd_prr; reflexivity].
278
+ ing true. apply (in_map (fun i => (prr i, true))). apply in_seq. lia.
279
+ - rewrite nth_map_d with (d' := 0) by (rewrite length_seq; lia). rewrite seq_nth by lia. cbn [Nat.add].
280
+ assert (Hrk : r <= k) by lia.
281
+ split.
282
+ + intros p z Hin. lits_in Hin. rewrite ?map_app, ?map_map in H. cbn [map fst app] in H.
283
+ destruct H as [<-|[<-|H]].
284
+ * rewrite cd_yv, cl_yv by lia. destruct (Nat.eqb_spec r k), (Nat.eqb r 0); lia.
285
+ * rewrite cd_xv, cl_xv by lia. destruct (Nat.eqb_spec r k), (Nat.eqb r 0); lia.
286
+ * apply in_map_iff in H as (i & <- & Hi). apply in_seq in Hi. rewrite cd_prr, cl_prr.
287
+ destruct (Nat.eqb_spec r k); lia.
288
+ + destruct (Nat.eqb_spec r k) as [E|E].
289
+ * exists (yv A r), 1%Z. split; [ing true; left; reflexivity | rewrite cd_yv; reflexivity].
290
+ * exists (prr (S r)), 1%Z. split; [|rewrite cd_prr; reflexivity].
291
+ ing true. apply in_or_app. right. apply (in_map (fun i => (prr i, true))). apply in_seq. lia. }
292
+ replace b with (tb A + (b - tb A)) in Hj, Hr |- * by lia.
293
+ rewrite nth_hb_post in Hj, Hr |- * by lia. rewrite cdh_post.
294
+ assert (Hi : b - tb A < 15) by (unfold tb in *; lia).
295
+ remember (b - tb A) as i eqn:Ei. clear Ei Hb Hp HT.
296
+ assert (Hc : i = 0 \/ i = 1 \/ i = 2 \/ i = 3 \/ i = 4 \/ i = 5 \/ i = 6 \/ i = 7 \/ i = 8 \/ i = 9
297
+ \/ i = 10 \/ i = 11 \/ i = 12 \/ i = 13 \/ i = 14) by lia.
298
+ destruct Hc as [->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->| ->]]]]]]]]]]]]]];
299
+ cbn [nth hpost bcount bsize bshape blk_C blk_AX blk_NX blk_XN blk_EQ blk_R0 blk_H blk_R blk_LEQ
300
+ blk_TA blk_TB blk_NP blk_HAB blk_WR blk_NM cd_post] in Hj, Hr |- *.
301
+ - (* C *) destruct r as [|r]; [|lia]. cbn [nth]. split.
302
+ + intros p z Hin. lits_in Hin. destruct H as [<-|H].
303
+ * rewrite (cdh_T (S j)), (clh_T (S j)) by lia. cbn [cd_T Nat.eqb]. lia.
304
+ * rewrite ?map_map in H. apply in_map_iff in H as (j' & <- & Hj'). apply in_seq in Hj'. cbn [fst].
305
+ rewrite (cdh_T (S j)), (clh_T (S j)) by lia. unfold cd_T. destruct (Nat.eqb (S j') 0), (Nat.eqb (S j') (S j)); lia.
306
+ + exists (SRef (16 + S j) 0 0), 1%Z. split; [ing true; left; reflexivity|].
307
+ rewrite (cdh_T (S j)) by lia. reflexivity.
308
+ - (* AX *) destruct r as [|r]; [|lia]. cbn [nth]. split.
309
+ + intros p z Hin. lits_in Hin. destruct H as [<-|[<-|[]]];
310
+ [rewrite cd_xv, cl_xv by lia | rewrite cd_yv, cl_yv by lia]; destruct (Nat.eqb j 0); lia.
311
+ + exists (xv A j), 1%Z. split; [ing true; left; reflexivity | rewrite cd_xv; reflexivity].
312
+ - (* NX *) destruct r as [|r]; [|lia]. cbn [nth]. split.
313
+ + intros p z Hin. lits_in Hin. destruct H as [<-|[<-|[]]];
314
+ [rewrite cd_xv, cl_xv by lia | rewrite cd_yv, cl_yv by lia]; destruct (Nat.eqb j 0); lia.
315
+ + exists (xv A j), (-1)%Z. split; [ing false; left; reflexivity | rewrite cd_xv; reflexivity].
316
+ - (* XN *) destruct r as [|r]; [|lia]. cbn [nth]. split.
317
+ + intros p z Hin. lits_in Hin. destruct H as [<-|[<-|[]]]; rewrite cdh_post, clh_post; cbn; lia.
318
+ + exists (SRef (tb A + 1) j 0), 1%Z. split; [ing true; left; reflexivity | rewrite cdh_post; reflexivity].
319
+ - (* EQ *) destruct r as [|r]; [|lia]. cbn [nth]. split.
320
+ + intros p z Hin. lits_in Hin. rewrite ?map_map in H. apply in_map_iff in H as (i' & <- & _).
321
+ rewrite cdh_post, clh_post. cbn. lia.
322
+ + exists (SRef (tb A + 3) 0 0), 1%Z. split; [|rewrite cdh_post; reflexivity].
323
+ ing true. apply (in_map (fun i' => (SRef (tb A + 3) i' 0, true))). apply in_seq. lia.
324
+ - (* R0 *) assert (Hj0 : j = 0) by lia. subst j. assert (Hr3 : r = 0 \/ r = 1 \/ r = 2) by lia.
325
+ destruct Hr3 as [->|[->| ->]]; cbn [nth Nat.ltb Nat.leb]; split.
326
+ + intros p z Hin. lits_in Hin. destruct H as [<-|[<-|[]]];
327
+ [rewrite cd_yv, cl_yv by lia | rewrite cd_xv, cl_xv by lia]; cbn; lia.
328
+ + exists (yv A 0), 1%Z. split; [ing true; left; reflexivity | rewrite cd_yv; reflexivity].
329
+ + intros p z Hin. lits_in Hin. destruct H as [<-|[<-|[]]];
330
+ [rewrite cd_yv, cl_yv by lia | rewrite cd_xv, cl_xv by lia]; cbn; lia.
331
+ + exists (yv A 0), (-1)%Z. split; [ing false; left; reflexivity | rewrite cd_yv; reflexivity].
332
+ + intros p z Hin. lits_in Hin. destruct H as [<-|[<-|[]]]; rewrite cdh_post, clh_post; cbn; lia.
333
+ + exists (SRef (tb A + 5) 0 0), 1%Z. split; [ing true; left; reflexivity | rewrite cdh_post; reflexivity].
334
+ - (* H *) assert (Hr3 : r = 0 \/ r = 1 \/ r = 2) by lia.
335
+ assert (Hpre : forall bias,
336
+ (forall p z, In (p, z) (sin (SU bias [(yv A (S j), 1%Z); (xv A (S j), (-1)%Z); (SRef (tb A) j 0, 1%Z)])) ->
337
+ S (cdh p) <= 10 <= clh p)
338
+ /\ exists p z, In (p, z) (sin (SU bias [(yv A (S j), 1%Z); (xv A (S j), (-1)%Z); (SRef (tb A) j 0, 1%Z)]))
339
+ /\ S (cdh p) = 10).
340
+ { intro bias. split.
341
+ - intros p z Hin. cbn [sin] in Hin. destruct Hin as [E|[E|[E|[]]]]; injection E as <- <-.
342
+ + rewrite cd_yv, cl_yv by lia. cbn. lia.
343
+ + rewrite cd_xv, cl_xv by lia. cbn. lia.
344
+ + rewrite <- (Nat.add_0_r (tb A)), cdh_post, clh_post. cbn. lia.
345
+ - exists (SRef (tb A) j 0), 1%Z. split; [cbn [sin]; right; right; left; reflexivity|].
346
+ rewrite <- (Nat.add_0_r (tb A)), cdh_post. reflexivity. }
347
+ destruct Hr3 as [->|[->| ->]]; cbn [nth map]; apply Hpre.
348
+ - (* R *) destruct r as [|r]; [|lia]. cbn [nth]. split.
349
+ + intros p z Hin. rewrite sin_SU in Hin. repeat (destruct Hin as [Hin|Hin]; [injection Hin as <- <-|]); try destruct Hin;
350
+ rewrite (cdh_post_at _ 6), (clh_post_at _ 6) by (unfold tb; lia); cbn; lia.
351
+ + exists (SRef (tb A + 6) j 0), 1%Z. split; [cbn [sin]; left; reflexivity | rewrite cdh_post; reflexivity].
352
+ - (* LEQ *) destruct r as [|r]; [|lia]. cbn [nth]. split.
353
+ + intros p z Hin. rewrite sin_SU in Hin. repeat (destruct Hin as [Hin|Hin]; [injection Hin as <- <-|]); try destruct Hin;
354
+ first [rewrite (cdh_post_at _ 6), (clh_post_at _ 6) by (unfold tb; lia)
355
+ | rewrite (cdh_post_at _ 4), (clh_post_at _ 4) by (unfold tb; lia)]; cbn; lia.
356
+ + exists (SRef (tb A + 6) (A - 2) 0), 1%Z. split; [cbn [sin]; left; reflexivity | rewrite cdh_post; reflexivity].
357
+ - (* TA *) destruct r as [|r]; [|lia]. cbn [nth]. split.
358
+ + intros p z Hin. lits_in Hin. destruct H as [<-|[<-|[<-|[]]]].
359
+ * cbn [cdh haltb]. rewrite cl_halt. lia.
360
+ * rewrite cdh_post, clh_post. cbn. lia.
361
+ * rewrite cd_opb, cl_opb by lia. cbn. lia.
362
+ + exists (SRef (tb A + 8) 0 0), 1%Z. split; [ing true; right; left; reflexivity | rewrite cdh_post; reflexivity].
363
+ - (* TB *) destruct r as [|r]; [|lia]. cbn [nth]. split.
364
+ + intros p z Hin. lits_in Hin. destruct H as [<-|[<-|[<-|[]]]].
365
+ * cbn [cdh haltb]. rewrite cl_halt. lia.
366
+ * rewrite cdh_post, clh_post. cbn. lia.
367
+ * rewrite cdh_pre, clh_pre by lia. cbn. lia.
368
+ + exists (SRef (tb A + 8) 0 0), (-1)%Z. split; [ing false; right; left; reflexivity | rewrite cdh_post; reflexivity].
369
+ - (* NP *) destruct r as [|r]; [|lia]. cbn [nth]. split.
370
+ + intros p z Hin. lits_in Hin. destruct H as [<-|[<-|[<-|[]]]].
371
+ * rewrite cdh_pre, clh_pre by lia. cbn. lia.
372
+ * rewrite cdh_post, clh_post. cbn. lia.
373
+ * rewrite cdh_post, clh_post. cbn. lia.
374
+ + exists (SRef (tb A + 9) j 0), 1%Z. split; [ing true; right; left; reflexivity | rewrite cdh_post; reflexivity].
375
+ - (* HA, HB, NH *) assert (Hj0 : j = 0) by lia. subst j. assert (Hr3 : r = 0 \/ r = 1 \/ r = 2) by lia.
376
+ destruct Hr3 as [->|[->| ->]]; cbn [nth Nat.ltb Nat.leb]; split.
377
+ + intros p z Hin. lits_in Hin. destruct H as [<-|[<-|[<-|[]]]].
378
+ * cbn [cdh haltb]. rewrite cl_halt. lia.
379
+ * rewrite cdh_post, clh_post. cbn. lia.
380
+ * rewrite cdh_pre, clh_pre by lia. cbn. lia.
381
+ + exists (SRef (tb A + 8) 0 0), 1%Z. split; [ing true; right; left; reflexivity | rewrite cdh_post; reflexivity].
382
+ + intros p z Hin. lits_in Hin. destruct H as [<-|[<-|[<-|[]]]].
383
+ * cbn [cdh haltb]. rewrite cl_halt. lia.
384
+ * rewrite cdh_post, clh_post. cbn. lia.
385
+ * rewrite cdh_pre, clh_pre by lia. cbn [cd_pre cl_pre]. rewrite Nat.eqb_refl. lia.
386
+ + exists (SRef (tb A + 8) 0 0), (-1)%Z. split; [ing false; right; left; reflexivity | rewrite cdh_post; reflexivity].
387
+ + intros p z Hin. lits_in Hin. destruct H as [<-|[<-|[<-|[]]]].
388
+ * cbn [cdh haltb]. rewrite cl_halt. lia.
389
+ * rewrite cdh_post, clh_post. cbn. lia.
390
+ * rewrite cdh_post, clh_post. cbn. lia.
391
+ + exists (SRef (tb A + 12) 0 0), 1%Z. split; [ing true; right; left; reflexivity | rewrite cdh_post; reflexivity].
392
+ - (* WR *) destruct r as [|r]; [|lia]. cbn [nth]. pose proof (mod_A j) as Hm. split.
393
+ + intros p z Hin. lits_in Hin. destruct H as [<-|[<-|[]]].
394
+ * rewrite cd_rbit, cl_rbit. destruct (Nat.eqb_spec (j mod A) (A - 1)), (Nat.eqb_spec (A - 1 - j mod A) 0); lia.
395
+ * rewrite cdh_pre, clh_pre by lia. cbn [cd_pre cl_pre]. destruct (Nat.eqb (j mod A) (A - 1)); lia.
396
+ + exists (rbit A (A - 1 - j mod A)), 1%Z. split; [ing true; left; reflexivity|].
397
+ rewrite cd_rbit. destruct (Nat.eqb_spec (j mod A) (A - 1)), (Nat.eqb_spec (A - 1 - j mod A) 0); lia.
398
+ - (* NM *) destruct r as [|r]; [|lia]. cbn [nth]. split.
399
+ + intros p z Hin. lits_in Hin. destruct H as [<-|[<-|[]]].
400
+ * rewrite cdh_pre, clh_pre by lia. cbn [cd_pre cl_pre]. destruct (Nat.eqb (j mod A) (A - 1)); lia.
401
+ * rewrite cdh_post, clh_post. cbn [cd_post cl_post]. destruct (Nat.eqb (j mod A) (A - 1)); lia.
402
+ + exists (SRef (tb A + 13) j 0), 1%Z. split; [ing true; right; left; reflexivity|].
403
+ rewrite cdh_post. cbn [cd_post]. destruct (Nat.eqb (j mod A) (A - 1)); reflexivity.
404
+ Qed.
405
+
406
+ (* ---- every signal but a next value has a reader in its last reading layer ---------------------------------- *)
407
+ Ltac vpre := split; [rewrite length_hblocks by lia; unfold tb; lia|]; rewrite nth_hb_pre by lia;
408
+ cbn [nth hpre bcount bsize blk_P blk_HP blk_FA blk_Q blk_F blk_PA blk_PB blk_AC blk_W blk_RX blk_RY blk_KP blk_X
409
+ blk_Y blk_PR]; split; try nia.
410
+ Ltac vpost := split; [rewrite length_hblocks by lia; unfold tb; lia|]; rewrite nth_hb_post by lia;
411
+ cbn [nth hpost bcount bsize blk_C blk_AX blk_NX blk_XN blk_EQ blk_R0 blk_H blk_R blk_LEQ blk_TA blk_TB blk_NP
412
+ blk_HAB blk_WR blk_NM]; split; try nia.
413
+ Ltac upre := unfold sunit; rewrite nth_hb_pre by lia;
414
+ cbn [nth hpre bshape blk_P blk_HP blk_FA blk_Q blk_F blk_PA blk_PB blk_AC blk_W blk_RX blk_RY blk_KP blk_X blk_Y blk_PR].
415
+ Ltac upost := unfold sunit; rewrite nth_hb_post by lia;
416
+ cbn [nth hpost bshape blk_C blk_AX blk_NX blk_XN blk_EQ blk_R0 blk_H blk_R blk_LEQ blk_TA blk_TB blk_NP blk_HAB
417
+ blk_WR blk_NM].
418
+
419
+ Theorem host_reader : forall x, valid (hblocks A) (nH A) x -> (forall i, i < nH A -> hout A i <> x) ->
420
+ exists b j r z, valid (hblocks A) (nH A) (SRef b j r) /\ In (x, z) (sin (sunit (hblocks A) b j r))
421
+ /\ cdh (SRef b j r) = clh x.
422
+ Proof.
423
+ intros x Hx Hno. pose proof SW_ge8 as HS. destruct x as [i|b j r].
424
+ - (* the state bits *) cbn [valid] in Hx. unfold nH in Hx.
425
+ destruct (Nat.lt_trichotomy i A) as [Hi|[Hi|Hi]].
426
+ + exists 0, 0, 0, (if bitof A 0 i then 1%Z else (-1)%Z). split; [vpre|]. split.
427
+ * upre. ing (bitof A 0 i). unfold lits. apply (in_map (fun t => (pcb t, bitof A 0 t))). apply in_seq. lia.
428
+ * cbn [clh]. destruct (Nat.ltb_spec i A); [|lia]. rewrite cdh_pre by lia. reflexivity.
429
+ + subst i. exists (tb A + 12), 0, 2, 1%Z. split; [vpost|]. split.
430
+ * upost. ing true. left. reflexivity.
431
+ * rewrite cdh_post. cbn [clh]. rewrite Nat.ltb_irrefl, Nat.eqb_refl. reflexivity.
432
+ + exists 13, (i - A - 1), 0, 1%Z. split; [vpre|]. split.
433
+ * upre. ing true. left. unfold mu. f_equal. f_equal.
434
+ pose proof (Nat.div_mod (i - A - 1) A ltac:(lia)). nia.
435
+ * rewrite cdh_pre by lia. cbn [clh]. destruct (Nat.ltb_spec i A); [lia|]. destruct (Nat.eqb_spec i A); [lia|].
436
+ reflexivity.
437
+ - destruct Hx as (Hb & Hj & Hr). rewrite length_hblocks in Hb by lia.
438
+ destruct (Nat.lt_ge_cases b 17) as [Hp|Hp].
439
+ { rewrite nth_hb_pre in Hj, Hr by exact Hp. rewrite clh_pre by exact Hp.
440
+ assert (Hc : b = 0 \/ b = 1 \/ b = 2 \/ b = 3 \/ b = 4 \/ b = 5 \/ b = 6 \/ b = 7 \/ b = 8 \/ b = 9
441
+ \/ b = 10 \/ b = 11 \/ b = 12 \/ b = 13 \/ b = 14 \/ b = 15 \/ b = 16) by lia.
442
+ destruct Hc as [->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->| ->]]]]]]]]]]]]]]]];
443
+ cbn [nth hpre bcount bsize bshape blk_P blk_HP blk_FA blk_Q blk_F blk_PA blk_PB blk_AC blk_W
444
+ blk_RX blk_RY blk_KP blk_X blk_Y blk_PR cl_pre] in Hj, Hr |- *;
445
+ (destruct r as [|r]; [|lia]).
446
+ - (* P *) destruct (Nat.eqb_spec j (SW A - 4)) as [->|E].
447
+ + exists (tb A + 12), 0, 1, 1%Z. split; [vpost|]. split; [upost; ing true; right; right; left; reflexivity|].
448
+ rewrite cdh_post. reflexivity.
449
+ + exists 2, j, 0, 1%Z. split; [vpre|]. split; [|rewrite cdh_pre by lia; reflexivity].
450
+ upre. rewrite Nat.add_0_r, Nat.Div0.mod_mod, Nat.mod_small by lia. ing true. right. left. reflexivity.
451
+ - (* HP *) exists (tb A + 11), j, 0, 1%Z. split; [vpost|]. split; [upost; ing true; left; reflexivity|].
452
+ rewrite cdh_post. reflexivity.
453
+ - (* FA 0 *) assert (Hd : j / SW A < A) by (apply Nat.Div0.div_lt_upper_bound; nia).
454
+ exists 6, (0 * A + j / SW A), 0, 1%Z. split; [vpre|].
455
+ split; [|rewrite cdh_pre by lia; reflexivity].
456
+ upre. ing true. replace ((0 * A + j / SW A) / A) with 0 by (symmetry; apply Nat.div_small; lia).
457
+ replace ((0 * A + j / SW A) mod A) with (j / SW A) by (symmetry; apply Nat.mod_small; lia).
458
+ apply in_map_iff. exists (j mod SW A). split.
459
+ + f_equal. f_equal. pose proof (Nat.div_mod j (SW A) ltac:(lia)). lia.
460
+ + apply in_seq. pose proof (Nat.mod_upper_bound j (SW A) ltac:(lia)). lia.
461
+ - (* FA 1 *) assert (Hd : j / SW A < A) by (apply Nat.Div0.div_lt_upper_bound; nia).
462
+ exists 6, (1 * A + j / SW A), 0, 1%Z. split; [vpre|].
463
+ split; [|rewrite cdh_pre by lia; reflexivity].
464
+ upre. ing true.
465
+ replace ((1 * A + j / SW A) / A) with 1 by (apply (Nat.div_unique _ _ _ (j / SW A)); lia).
466
+ replace ((1 * A + j / SW A) mod A) with (j / SW A) by (apply (Nat.mod_unique _ _ 1); lia).
467
+ apply in_map_iff. exists (j mod SW A). split.
468
+ + f_equal. f_equal. pose proof (Nat.div_mod j (SW A) ltac:(lia)). lia.
469
+ + apply in_seq. pose proof (Nat.mod_upper_bound j (SW A) ltac:(lia)). lia.
470
+ - (* FA 2 *) assert (Hd : j / SW A < A) by (apply Nat.Div0.div_lt_upper_bound; nia).
471
+ exists 6, (2 * A + j / SW A), 0, 1%Z. split; [vpre|].
472
+ split; [|rewrite cdh_pre by lia; reflexivity].
473
+ upre. ing true.
474
+ replace ((2 * A + j / SW A) / A) with 2 by (apply (Nat.div_unique _ _ _ (j / SW A)); lia).
475
+ replace ((2 * A + j / SW A) mod A) with (j / SW A) by (apply (Nat.mod_unique _ _ 2); lia).
476
+ apply in_map_iff. exists (j mod SW A). split.
477
+ + f_equal. f_equal. pose proof (Nat.div_mod j (SW A) ltac:(lia)). lia.
478
+ + apply in_seq. pose proof (Nat.mod_upper_bound j (SW A) ltac:(lia)). lia.
479
+ - (* Q *) exists (tb A + 10), j, 0, 1%Z. split; [vpost|]. split; [upost; ing true; right; right; left; reflexivity|].
480
+ rewrite cdh_post. reflexivity.
481
+ - (* F *) destruct (Nat.ltb_spec j (2 * A)) as [Hl|Hg].
482
+ + destruct (Nat.lt_ge_cases j A) as [H0|H1].
483
+ * exists 7, 0, 0, (if bitof A 0 j then 1%Z else (-1)%Z). split; [vpre|].
484
+ split; [|rewrite cdh_pre by lia; reflexivity].
485
+ upre. ing (bitof A 0 j). unfold lits, opb. apply in_map_iff. exists j.
486
+ split; [f_equal; f_equal; lia | apply in_seq; lia].
487
+ * exists 8, 0, 0, (if bitof A 0 (j - A) then 1%Z else (-1)%Z). split; [vpre|].
488
+ split; [|rewrite cdh_pre by lia; reflexivity].
489
+ upre. ing (bitof A 0 (j - A)). unfold lits, opb. apply in_map_iff. exists (j - A).
490
+ split; [f_equal; f_equal; lia | apply in_seq; lia].
491
+ + exists (tb A + 9), (j - 2 * A), 0, 1%Z. split; [vpost; pose proof (div_lt j 3 A); lia|].
492
+ split; [|rewrite cdh_post; reflexivity].
493
+ upost. ing true. right. right. left. unfold opb. f_equal. f_equal. lia.
494
+ - (* PA *) exists 11, j, 0, 1%Z. split; [vpre|]. split; [|rewrite cdh_pre by lia; reflexivity].
495
+ upre. rewrite Nat.mod_small by lia. ing true. right. left. reflexivity.
496
+ - (* PB *) exists 10, j, 0, 1%Z. split; [vpre|]. split; [|rewrite cdh_pre by lia; reflexivity].
497
+ upre. ing true. right. left. reflexivity.
498
+ - (* AC *) assert (Hj0 : j = 0) by lia. subst j.
499
+ exists (tb A + 12), 0, 0, 1%Z. split; [vpost|]. split; [upost; ing true; right; right; left; reflexivity|].
500
+ rewrite cdh_post. reflexivity.
501
+ - (* W *) exists (tb A + 13), (j * A), 0, 1%Z. split; [vpost|]. split.
502
+ + upost. ing true. right. left. rewrite Nat.div_mul by lia. reflexivity.
503
+ + rewrite cdh_post. cbn [cd_post]. rewrite Nat.Div0.mod_mul. destruct (Nat.eqb_spec 0 (A - 1)); [lia | reflexivity].
504
+ - (* RX *) assert (Hd : j / SW A < A) by (apply Nat.Div0.div_lt_upper_bound; nia).
505
+ exists 14, (j / SW A), 0, 1%Z. split; [vpre|].
506
+ split; [|rewrite cdh_pre by lia; reflexivity].
507
+ upre. ing true. apply in_map_iff. exists (j mod SW A). split.
508
+ + f_equal. f_equal. pose proof (Nat.div_mod j (SW A) ltac:(lia)). lia.
509
+ + apply in_seq. pose proof (Nat.mod_upper_bound j (SW A) ltac:(lia)). lia.
510
+ - (* RY *) assert (Hd : j / SW A < A) by (apply Nat.Div0.div_lt_upper_bound; nia).
511
+ exists 15, (j / SW A), 0, 1%Z. split; [vpre|].
512
+ split; [|rewrite cdh_pre by lia; reflexivity].
513
+ upre. ing true. apply in_map_iff. exists (j mod SW A). split.
514
+ + f_equal. f_equal. pose proof (Nat.div_mod j (SW A) ltac:(lia)). lia.
515
+ + apply in_seq. pose proof (Nat.mod_upper_bound j (SW A) ltac:(lia)). lia.
516
+ - (* KP *) exists (tb A + 14), j, 0, 1%Z. split; [vpost|]. split; [upost; ing true; left; reflexivity|].
517
+ rewrite cdh_post. reflexivity.
518
+ - (* X *) destruct (Nat.eqb_spec j (A - 1)) as [->|E].
519
+ + exists (16 + 2), 0, 1, (-1)%Z. split.
520
+ * split; [rewrite length_hblocks by lia; unfold tb; lia|]. rewrite nth_hb_T by lia. cbn [bcount bsize blk_T]. lia.
521
+ * split; [|rewrite cdh_T by lia; reflexivity].
522
+ unfold sunit. rewrite nth_hb_T by lia. cbn [bshape blk_T nth seq map Nat.sub]. ing false. right. left.
523
+ unfold xv. f_equal. f_equal. lia.
524
+ + exists (tb A + 6), (A - 2 - j), 0, (-1)%Z. split; [vpost|]. split; [|rewrite cdh_post; reflexivity].
525
+ upost. right. left. unfold xv. f_equal. f_equal. lia.
526
+ - (* Y *) destruct (Nat.eqb_spec j (A - 1)) as [->|E].
527
+ + exists (16 + 2), 0, 1, 1%Z. split.
528
+ * split; [rewrite length_hblocks by lia; unfold tb; lia|]. rewrite nth_hb_T by lia. cbn [bcount bsize blk_T]. lia.
529
+ * split; [|rewrite cdh_T by lia; reflexivity].
530
+ unfold sunit. rewrite nth_hb_T by lia. cbn [bshape blk_T nth seq map Nat.sub]. ing true. left.
531
+ unfold yv. f_equal. f_equal. lia.
532
+ + exists (tb A + 6), (A - 2 - j), 0, 1%Z. split; [vpost|]. split; [|rewrite cdh_post; reflexivity].
533
+ upost. left. unfold yv. f_equal. f_equal. lia.
534
+ - (* PR *) exists (16 + (A - 1)), 0, 0, 1%Z. split.
535
+ + split; [rewrite length_hblocks by lia; unfold tb; lia|]. rewrite nth_hb_T by lia. cbn [bcount bsize blk_T]. lia.
536
+ + split; [|rewrite cdh_T by lia; reflexivity].
537
+ unfold sunit. rewrite nth_hb_T by lia. cbn [bshape blk_T nth]. ing true.
538
+ apply (in_map (fun i' => (prr i', true))). apply in_seq. lia. }
539
+ destruct (Nat.lt_ge_cases b (tb A)) as [HT|HT].
540
+ { (* the carry terms *)
541
+ unfold tb in HT. replace b with (16 + (b - 16)) in Hj, Hr |- * by lia.
542
+ rewrite nth_hb_T in Hj, Hr by lia. cbn [bcount bsize blk_T] in Hj, Hr. assert (Hj0 : j = 0) by lia. subst j.
543
+ rewrite clh_T by lia.
544
+ exists (tb A + 0), (b - 16 - 1), 0, 1%Z. split; [vpost|]. split; [|rewrite cdh_post; reflexivity].
545
+ upost. ing true.
546
+ replace (16 + S (b - 16 - 1)) with (16 + (b - 16)) by lia.
547
+ destruct r as [|r]; [left; reflexivity|]. right.
548
+ apply (in_map (fun j' => (SRef (16 + (b - 16)) 0 (S j'), true))). apply in_seq. lia. }
549
+ replace b with (tb A + (b - tb A)) in Hj, Hr, Hno |- * by lia.
550
+ rewrite nth_hb_post in Hj, Hr by lia. rewrite clh_post.
551
+ assert (Hi : b - tb A < 15) by (unfold tb in *; lia).
552
+ remember (b - tb A) as i eqn:Ei. clear Ei Hb Hp HT.
553
+ assert (Hc : i = 0 \/ i = 1 \/ i = 2 \/ i = 3 \/ i = 4 \/ i = 5 \/ i = 6 \/ i = 7 \/ i = 8 \/ i = 9
554
+ \/ i = 10 \/ i = 11 \/ i = 12 \/ i = 13 \/ i = 14) by lia.
555
+ destruct Hc as [->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->| ->]]]]]]]]]]]]]];
556
+ cbn [nth hpost bcount bsize blk_C blk_AX blk_NX blk_XN blk_EQ blk_R0 blk_H blk_R blk_LEQ
557
+ blk_TA blk_TB blk_NP blk_HAB blk_WR blk_NM cl_post] in Hj, Hr |- *;
558
+ try (assert (Hr0 : r = 0) by lia; subst r); try (assert (Hj0 : j = 0) by lia; subst j).
559
+ + (* C *) exists (tb A + 6), j, 0, 1%Z. split; [vpost|]. split; [|rewrite cdh_post; reflexivity].
560
+ upost. right. right. left. rewrite Nat.add_0_r. reflexivity.
561
+ + (* AX *) exists (tb A + 3), j, 0, 1%Z. split; [vpost|]. split; [upost; ing true; left; reflexivity|].
562
+ rewrite cdh_post. reflexivity.
563
+ + (* NX *) exists (tb A + 3), j, 0, 1%Z. split; [vpost|]. split; [upost; ing true; right; left; reflexivity|].
564
+ rewrite cdh_post. reflexivity.
565
+ + (* XN *) exists (tb A + 4), 0, 0, 1%Z. split; [vpost|]. split; [|rewrite cdh_post; reflexivity].
566
+ upost. ing true. apply (in_map (fun i' => (SRef (tb A + 3) i' 0, true))). apply in_seq. lia.
567
+ + (* EQ *) exists (tb A + 8), 0, 0, 1%Z. split; [vpost|]. split; [upost; right; right; right; left; reflexivity|].
568
+ rewrite cdh_post. reflexivity.
569
+ + (* R0 *) destruct (Nat.ltb_spec r 2) as [Hr2|Hr2].
570
+ * exists (tb A + 5), 0, 2, 1%Z. split; [vpost|]. split; [|rewrite cdh_post; reflexivity].
571
+ upost. ing true. destruct r as [|[|r]]; [left; reflexivity | right; left; reflexivity | lia].
572
+ * exists (tb A + 13), (A - 1), 0, 1%Z. split; [vpost|]. split.
573
+ -- upost. ing true. left. rewrite Nat.mod_small by lia. replace (A - 1 - (A - 1)) with 0 by lia.
574
+ unfold rbit. cbn [Nat.eqb]. f_equal. f_equal. lia.
575
+ -- rewrite cdh_post. cbn [cd_post]. rewrite Nat.mod_small by lia. rewrite Nat.eqb_refl. reflexivity.
576
+ + (* H *) assert (Hr3 : r = 0 \/ r = 1 \/ r = 2) by lia. destruct Hr3 as [->|[->| ->]].
577
+ * exists (tb A + 7), j, 0, 1%Z. split; [vpost|].
578
+ split; [upost; left; reflexivity | rewrite cdh_post; reflexivity].
579
+ * exists (tb A + 7), j, 0, (-1)%Z. split; [vpost|].
580
+ split; [upost; right; left; reflexivity | rewrite cdh_post; reflexivity].
581
+ * exists (tb A + 7), j, 0, 1%Z. split; [vpost|].
582
+ split; [upost; right; right; left; reflexivity | rewrite cdh_post; reflexivity].
583
+ + (* R *) exists (tb A + 13), (A - 2 - j), 0, 1%Z. split; [vpost|]. split.
584
+ * upost. ing true. left. rewrite Nat.mod_small by lia. replace (A - 1 - (A - 2 - j)) with (S j) by lia.
585
+ unfold rbit. cbn [Nat.eqb]. f_equal. f_equal. lia.
586
+ * rewrite cdh_post. cbn [cd_post]. rewrite Nat.mod_small by lia. destruct (Nat.eqb_spec (A - 2 - j) (A - 1)); [lia|].
587
+ reflexivity.
588
+ + (* LEQ *) exists (tb A + 9), 0, 0, 1%Z. split; [vpost|]. split; [upost; ing true; right; left; reflexivity|].
589
+ rewrite cdh_post. reflexivity.
590
+ + (* TA *) exists (tb A + 11), j, 0, 1%Z. split; [vpost|]. split; [upost; ing true; right; left; reflexivity|].
591
+ rewrite cdh_post. reflexivity.
592
+ + (* TB *) exists (tb A + 11), j, 0, 1%Z. split; [vpost|]. split; [upost; ing true; right; right; left; reflexivity|].
593
+ rewrite cdh_post. reflexivity.
594
+ + (* NP: a next value *) exfalso. apply (Hno j); [unfold nH; lia|]. unfold hout.
595
+ destruct (Nat.ltb_spec j A); [|lia]. f_equal; lia.
596
+ + (* HAB *) destruct (Nat.ltb_spec r 2) as [Hr2|Hr2].
597
+ * exists (tb A + 12), 0, 2, 1%Z. split; [vpost|]. split; [|rewrite cdh_post; reflexivity].
598
+ upost. ing true. destruct r as [|[|r]]; [right; left; reflexivity | right; right; left; reflexivity | lia].
599
+ * exfalso. apply (Hno A); [unfold nH; lia|]. unfold hout. rewrite Nat.ltb_irrefl, Nat.eqb_refl.
600
+ f_equal; lia.
601
+ + (* WR *) exists (tb A + 14), j, 0, 1%Z. split; [vpost|]. split; [upost; ing true; right; left; reflexivity|].
602
+ rewrite cdh_post. reflexivity.
603
+ + (* NM: a next value *) exfalso. apply (Hno (A + 1 + j)); [unfold nH; nia|]. unfold hout.
604
+ destruct (Nat.ltb_spec (A + 1 + j) A); [lia|]. destruct (Nat.eqb_spec (A + 1 + j) A); [lia|].
605
+ f_equal; lia.
606
+ Qed.
607
+
608
+ (* ---- depth, contribution and last readers of the levelized host --------------------------------------------- *)
609
+ Lemma host_wf' : wf (hblocks A) (nH A).
610
+ Proof. apply host_wf. exact HA. Qed.
611
+
612
+ Lemma hout_valid : forall i, i < nH A -> valid (hblocks A) (nH A) (hout A i).
613
+ Proof.
614
+ intros i Hi. pose proof SW_ge8. unfold hout. destruct (Nat.ltb_spec i A); [|destruct (Nat.eqb_spec i A)].
615
+ - vpost.
616
+ - vpost.
617
+ - unfold nH in Hi. vpost.
618
+ Qed.
619
+
620
+ Lemma sref_eq_dec : forall x y : sref, {x = y} + {x <> y}.
621
+ Proof. decide equality; apply Nat.eq_dec. Qed.
622
+
623
+ Lemma out_dec : forall x, {exists i, i < nH A /\ hout A i = x} + {forall i, i < nH A -> hout A i <> x}.
624
+ Proof.
625
+ intro x. destruct (in_dec sref_eq_dec x (map (hout A) (seq 0 (nH A)))) as [H|H].
626
+ - left. apply in_map_iff in H as (i & E & Hi). apply in_seq in Hi. exists i. split; [lia | exact E].
627
+ - right. intros i Hi E. apply H. apply in_map_iff. exists i. split; [exact E | apply in_seq; lia].
628
+ Qed.
629
+
630
+ Lemma host_cd_rec : forall b j r, valid (hblocks A) (nH A) (SRef b j r) ->
631
+ cdh (SRef b j r) = S (maxl (map (fun p => cdh (fst p)) (sin (sunit (hblocks A) b j r)))).
632
+ Proof.
633
+ intros b j r Hv. destruct (host_unit_ok b j r Hv) as [Hall Hex].
634
+ apply cd_rec; [intros p z Hin; exact (proj1 (Hall p z Hin)) | exact Hex].
635
+ Qed.
636
+
637
+ Lemma cdh0 : forall i, cdh (SIn i) = 0.
638
+ Proof. reflexivity. Qed.
639
+
640
+ Theorem host_dep : forall x, valid (hblocks A) (nH A) x -> dep (nH A) (host_units A) (idx (nH A) (hblocks A) x) = cdh x.
641
+ Proof. exact (dep_cd (hblocks A) (nH A) host_wf' cdh cdh0 host_cd_rec). Qed.
642
+
643
+ Lemma cd_pre_le : forall b, cd_pre b <= 7.
644
+ Proof. intro b. unfold cd_pre. repeat (destruct b as [|b]; [lia|]). lia. Qed.
645
+
646
+ Lemma cd_post_le : forall i j r, cd_post i j r <= 13.
647
+ Proof.
648
+ intros i j r. unfold cd_post.
649
+ repeat (destruct i as [|i]; [repeat (destruct (_ <? _)); repeat (destruct (Nat.eqb _ _)); lia|]).
650
+ destruct (Nat.eqb _ _); lia.
651
+ Qed.
652
+
653
+ Lemma cdh_le13 : forall x, cdh x <= 13.
654
+ Proof.
655
+ intros [i|b j r]; cbn [cdh]; [lia|]. pose proof (cd_pre_le b). pose proof (cd_post_le (b - tb A) j r).
656
+ destruct (b <? 17); [lia|]. destruct (b <? tb A); [unfold cd_T; destruct (Nat.eqb r 0), (Nat.eqb r (b - 16)); lia | lia].
657
+ Qed.
658
+
659
+ (* the step of H_A has depth 13 *)
660
+ Theorem host_dmax : dmax (nH A) (host_units A) = 13.
661
+ Proof.
662
+ apply (dmax_cd (hblocks A) (nH A) host_wf' cdh cdh0 host_cd_rec 13).
663
+ - intros b j r _. apply cdh_le13.
664
+ - exists (tb A + 11), 0, 0. split; [pose proof SW_ge8; vpost | rewrite cdh_post; reflexivity].
665
+ Qed.
666
+
667
+ (* every unit of H_A contributes to a next value *)
668
+ Theorem host_need : forall b j r, valid (hblocks A) (nH A) (SRef b j r) ->
669
+ need (nH A) (host_units A) (host_next A) (idx (nH A) (hblocks A) (SRef b j r)) = true.
670
+ Proof.
671
+ apply (need_all (hblocks A) (nH A) (hout A) host_wf'). intros b j r Hv.
672
+ destruct (out_dec (SRef b j r)) as [(i & Hi & E)|Hno]; [left; exists i; split; assumption|].
673
+ right. destruct (host_reader (SRef b j r) Hv Hno) as (b' & j' & r' & z & Hv' & Hin & _).
674
+ exists b', j', r', z. split; assumption.
675
+ Qed.
676
+
677
+ Lemma clh_out : forall i, i < nH A -> clh (hout A i) = 14.
678
+ Proof.
679
+ intros i Hi. unfold hout. destruct (Nat.ltb_spec i A); [|destruct (Nat.eqb_spec i A)]; rewrite clh_post; reflexivity.
680
+ Qed.
681
+
682
+ (* the last layer that reads each signal *)
683
+ Theorem host_lam : forall x, valid (hblocks A) (nH A) x ->
684
+ lam (nH A) (host_units A) (host_next A) (idx (nH A) (hblocks A) x) = clh x.
685
+ Proof.
686
+ apply (lam_cl (hblocks A) (nH A) (hout A) host_wf' hout_valid cdh host_dep host_need 13 host_dmax clh).
687
+ - intros b j r p z Hv Hin. exact (proj2 (proj1 (host_unit_ok b j r Hv) p z Hin)).
688
+ - exact clh_out.
689
+ - intros x Hx Hno. right. exact (host_reader x Hx Hno).
690
+ Qed.
691
+
692
+ (* ---- the widths of the layers ------------------------------------------------------------------------- *)
693
+ (* a unit of depth c read last at layer c' has a row in layer l if l = c or c < l < c'; a state bit if 0 < l < c' *)
694
+ Definition occ (c c' l : nat) : nat := Nat.b2n (Nat.eqb c l || Nat.ltb c l && Nat.ltb l c').
695
+ Definition occs (c' l : nat) : nat := Nat.b2n (Nat.ltb 0 l && Nat.ltb l c').
696
+ Definition tri : nat := nsum (A - 1) (fun i => S i).
697
+
698
+ Definition wform (l : nat) : nat :=
699
+ A * occs 1 l + occs 13 l + SW A * A * occs 6 l
700
+ + ((SW A - 1) * occ 1 2 l + occ 1 12 l) + A * occ 1 13 l + 3 * (A * SW A * occ 2 3 l) + A * occ 2 12 l
701
+ + (2 * A * occ 3 4 l + A * occ 3 12 l) + 2 * (SW A * occ 4 5 l) + occ 4 12 l + SW A * occ 5 12 l
702
+ + 2 * (A * SW A * occ 5 6 l) + (SW A * occ 6 10 l + SW A * (A - 1) * occ 6 13 l)
703
+ + 2 * (occ 6 8 l + (A - 1) * occ 6 10 l) + (A - 1) * occ 7 8 l
704
+ + (tri * occ 8 9 l + (A - 1) * occ 7 9 l)
705
+ + ((A - 1) * occ 9 10 l + 2 * (A * occ 7 8 l) + A * occ 8 9 l + occ 9 11 l + (2 * occ 7 8 l + occ 8 9 l)
706
+ + (A - 1) * (3 * occ 10 11 l) + (A - 1) * occ 11 12 l + occ 11 12 l + 2 * (A * occ 12 13 l)
707
+ + A * occ 13 14 l + (2 * occ 12 13 l + occ 13 14 l) + (SW A * occ 9 10 l + SW A * (A - 1) * occ 12 13 l)
708
+ + (SW A * occ 10 14 l + SW A * (A - 1) * occ 13 14 l)).
709
+
710
+ Lemma nsum_mod_split : forall c u v, nsum (c * A) (fun j => if Nat.eqb (j mod A) (A - 1) then u else v) = c * u + c * (A - 1) * v.
711
+ Proof.
712
+ intros c u v. rewrite nsum_mul.
713
+ rewrite (nsum_ext c _ (fun _ => (A - 1) * v + u)); [rewrite nsum_const; lia|].
714
+ intros q Hq. rewrite (nsum_ext A _ (fun r => if Nat.eqb r (A - 1) then u else v)).
715
+ - apply nsum_eq_split. lia.
716
+ - intros r Hr. replace ((A * q + r) mod A) with r; [reflexivity|].
717
+ apply (Nat.mod_unique _ _ q); lia.
718
+ Qed.
719
+
720
+ Lemma host_up : forall b j r p z, valid (hblocks A) (nH A) (SRef b j r) -> In (p, z) (sin (sunit (hblocks A) b j r)) ->
721
+ cdh (SRef b j r) <= clh p.
722
+ Proof. intros b j r p z Hv Hin. exact (proj2 (proj1 (host_unit_ok b j r Hv) p z Hin)). Qed.
723
+
724
+ Lemma host_low : forall x, valid (hblocks A) (nH A) x -> (forall i, i < nH A -> hout A i <> x) ->
725
+ clh x = 0 \/ exists b j r z, valid (hblocks A) (nH A) (SRef b j r) /\ In (x, z) (sin (sunit (hblocks A) b j r))
726
+ /\ cdh (SRef b j r) = clh x.
727
+ Proof. intros x Hx Hno. right. exact (host_reader x Hx Hno). Qed.
728
+
729
+ (* the sum over the units, block by block: the 17 blocks before the carry terms, the A - 1 carry blocks, the 15 after *)
730
+ Lemma bsum_host : forall g, bsum (hblocks A) g =
731
+ nsum 17 (fun b => nsum (bcount (nth b (hpre A) blk0)) (fun j => nsum (bsize (nth b (hpre A) blk0)) (fun r => g (SRef b j r))))
732
+ + nsum (A - 1) (fun i => nsum (S (S i)) (fun r => g (SRef (17 + i) 0 r)))
733
+ + nsum 15 (fun i => nsum (bcount (nth i (hpost A) blk0)) (fun j => nsum (bsize (nth i (hpost A) blk0))
734
+ (fun r => g (SRef (tb A + i) j r)))).
735
+ Proof.
736
+ intro g. unfold bsum, cnt, sz. rewrite length_hblocks by lia. replace (tb A + 15) with (17 + (A - 1) + 15) by (unfold tb; lia).
737
+ rewrite !nsum_split. f_equal; [f_equal|].
738
+ all: apply nsum_ext; intros i Hi;
739
+ first [ rewrite nth_hb_pre by lia; reflexivity
740
+ | replace (17 + i) with (16 + S i) by lia; rewrite nth_hb_T by lia; cbn [bcount bsize blk_T nsum]; reflexivity
741
+ | replace (17 + (A - 1) + i) with (tb A + i) by (unfold tb; lia); rewrite nth_hb_post by lia; reflexivity ].
742
+ Qed.
743
+
744
+ (* the rows of layer l that the units of each block contribute *)
745
+ Definition psum (l b : nat) : nat :=
746
+ nsum (bcount (nth b (hpre A) blk0)) (fun j => nsum (bsize (nth b (hpre A) blk0)) (fun r => occ (cd_pre b) (cl_pre b j) l)).
747
+ Definition qsum (l i : nat) : nat :=
748
+ nsum (bcount (nth i (hpost A) blk0)) (fun j => nsum (bsize (nth i (hpost A) blk0))
749
+ (fun r => occ (cd_post i j r) (cl_post i j r) l)).
750
+
751
+ Ltac pq := intro l; unfold psum, qsum;
752
+ cbn [nth hpre hpost bcount bsize blk_P blk_HP blk_FA blk_Q blk_F blk_PA blk_PB blk_AC blk_W blk_RX blk_RY blk_KP blk_X
753
+ blk_Y blk_PR blk_C blk_AX blk_NX blk_XN blk_EQ blk_R0 blk_H blk_R blk_LEQ blk_TA blk_TB blk_NP blk_HAB blk_WR
754
+ blk_NM cd_pre cl_pre cd_post cl_post].
755
+ Ltac pconst := rewrite !nsum_const; lia.
756
+
757
+ Lemma psum0 : forall l, psum l 0 = (SW A - 1) * occ 1 2 l + occ 1 12 l.
758
+ Proof.
759
+ pq. rewrite (nsum_ext (SW A) _ (fun j => if Nat.eqb j (SW A - 4) then occ 1 12 l else occ 1 2 l)).
760
+ - apply nsum_eq_split. pose proof SW_ge8. lia.
761
+ - intros j _. cbn [nsum]. destruct (Nat.eqb j (SW A - 4)); reflexivity.
762
+ Qed.
763
+ Lemma psum1 : forall l, psum l 1 = A * occ 1 13 l. Proof. pq. pconst. Qed.
764
+ Lemma psum2 : forall l, psum l 2 = A * SW A * occ 2 3 l. Proof. pq. pconst. Qed.
765
+ Lemma psum3 : forall l, psum l 3 = A * SW A * occ 2 3 l. Proof. pq. pconst. Qed.
766
+ Lemma psum4 : forall l, psum l 4 = A * SW A * occ 2 3 l. Proof. pq. pconst. Qed.
767
+ Lemma psum5 : forall l, psum l 5 = A * occ 2 12 l. Proof. pq. pconst. Qed.
768
+ Lemma psum6 : forall l, psum l 6 = 2 * A * occ 3 4 l + A * occ 3 12 l.
769
+ Proof.
770
+ pq. rewrite (nsum_ext (3 * A) _ (fun j => if j <? 2 * A then occ 3 4 l else occ 3 12 l)).
771
+ - rewrite nsum_lt_split by lia. lia.
772
+ - intros j _. cbn [nsum]. destruct (j <? 2 * A); reflexivity.
773
+ Qed.
774
+ Lemma psum7 : forall l, psum l 7 = SW A * occ 4 5 l. Proof. pq. pconst. Qed.
775
+ Lemma psum8 : forall l, psum l 8 = SW A * occ 4 5 l. Proof. pq. pconst. Qed.
776
+ Lemma psum9 : forall l, psum l 9 = occ 4 12 l. Proof. pq. pconst. Qed.
777
+ Lemma psum10 : forall l, psum l 10 = SW A * occ 5 12 l. Proof. pq. pconst. Qed.
778
+ Lemma psum11 : forall l, psum l 11 = A * SW A * occ 5 6 l. Proof. pq. pconst. Qed.
779
+ Lemma psum12 : forall l, psum l 12 = A * SW A * occ 5 6 l. Proof. pq. pconst. Qed.
780
+ Lemma psum13 : forall l, psum l 13 = SW A * occ 6 10 l + SW A * (A - 1) * occ 6 13 l.
781
+ Proof.
782
+ pq. rewrite (nsum_ext (SW A * A) _ (fun j => if Nat.eqb (j mod A) (A - 1) then occ 6 10 l else occ 6 13 l)).
783
+ - apply nsum_mod_split.
784
+ - intros j _. cbn [nsum]. destruct (Nat.eqb (j mod A) (A - 1)); reflexivity.
785
+ Qed.
786
+ Lemma psum14 : forall l, psum l 14 = occ 6 8 l + (A - 1) * occ 6 10 l.
787
+ Proof.
788
+ pq. rewrite (nsum_ext A _ (fun j => if Nat.eqb j (A - 1) then occ 6 8 l else occ 6 10 l)).
789
+ - rewrite nsum_eq_split by lia. lia.
790
+ - intros j _. cbn [nsum]. destruct (Nat.eqb j (A - 1)); reflexivity.
791
+ Qed.
792
+ Lemma psum15 : forall l, psum l 15 = occ 6 8 l + (A - 1) * occ 6 10 l.
793
+ Proof.
794
+ pq. rewrite (nsum_ext A _ (fun j => if Nat.eqb j (A - 1) then occ 6 8 l else occ 6 10 l)).
795
+ - rewrite nsum_eq_split by lia. lia.
796
+ - intros j _. cbn [nsum]. destruct (Nat.eqb j (A - 1)); reflexivity.
797
+ Qed.
798
+ Lemma psum16 : forall l, psum l 16 = (A - 1) * occ 7 8 l. Proof. pq. pconst. Qed.
799
+
800
+ Lemma qsum0 : forall l, qsum l 0 = (A - 1) * occ 9 10 l. Proof. pq. pconst. Qed.
801
+ Lemma qsum1 : forall l, qsum l 1 = A * occ 7 8 l. Proof. pq. pconst. Qed.
802
+ Lemma qsum2 : forall l, qsum l 2 = A * occ 7 8 l. Proof. pq. pconst. Qed.
803
+ Lemma qsum3 : forall l, qsum l 3 = A * occ 8 9 l. Proof. pq. pconst. Qed.
804
+ Lemma qsum4 : forall l, qsum l 4 = occ 9 11 l. Proof. pq. pconst. Qed.
805
+ Lemma qsum5 : forall l, qsum l 5 = 2 * occ 7 8 l + occ 8 9 l. Proof. pq. cbn [nsum Nat.ltb Nat.leb]. lia. Qed.
806
+ Lemma qsum6 : forall l, qsum l 6 = (A - 1) * (3 * occ 10 11 l). Proof. pq. pconst. Qed.
807
+ Lemma qsum7 : forall l, qsum l 7 = (A - 1) * occ 11 12 l. Proof. pq. pconst. Qed.
808
+ Lemma qsum8 : forall l, qsum l 8 = occ 11 12 l. Proof. pq. pconst. Qed.
809
+ Lemma qsum9 : forall l, qsum l 9 = A * occ 12 13 l. Proof. pq. pconst. Qed.
810
+ Lemma qsum10 : forall l, qsum l 10 = A * occ 12 13 l. Proof. pq. pconst. Qed.
811
+ Lemma qsum11 : forall l, qsum l 11 = A * occ 13 14 l. Proof. pq. pconst. Qed.
812
+ Lemma qsum12 : forall l, qsum l 12 = 2 * occ 12 13 l + occ 13 14 l. Proof. pq. cbn [nsum Nat.ltb Nat.leb]. lia. Qed.
813
+ Lemma qsum13 : forall l, qsum l 13 = SW A * occ 9 10 l + SW A * (A - 1) * occ 12 13 l.
814
+ Proof.
815
+ pq. rewrite (nsum_ext (SW A * A) _ (fun j => if Nat.eqb (j mod A) (A - 1) then occ 9 10 l else occ 12 13 l)).
816
+ - apply nsum_mod_split.
817
+ - intros j _. cbn [nsum]. destruct (Nat.eqb (j mod A) (A - 1)); reflexivity.
818
+ Qed.
819
+ Lemma qsum14 : forall l, qsum l 14 = SW A * occ 10 14 l + SW A * (A - 1) * occ 13 14 l.
820
+ Proof.
821
+ pq. rewrite (nsum_ext (SW A * A) _ (fun j => if Nat.eqb (j mod A) (A - 1) then occ 10 14 l else occ 13 14 l)).
822
+ - apply nsum_mod_split.
823
+ - intros j _. cbn [nsum]. destruct (Nat.eqb (j mod A) (A - 1)); reflexivity.
824
+ Qed.
825
+
826
+ Theorem host_width : forall l, 1 <= l -> width (nH A) (host_units A) (host_next A) l = wform l.
827
+ Proof.
828
+ intros l Hl. pose proof SW_ge8 as HS.
829
+ change (host_units A) with (fus (hblocks A) (nH A)). change (host_next A) with (fnx (hblocks A) (nH A) (hout A)).
830
+ rewrite (width_bsum (hblocks A) (nH A) (hout A) host_wf' hout_valid cdh host_dep host_need 13 host_dmax clh host_up
831
+ clh_out host_low l Hl).
832
+ rewrite bsum_host. unfold wform.
833
+ (* the state bits *)
834
+ assert (Hst : nsum (nH A) (fun i => Nat.b2n (Nat.ltb (cdh (SIn i)) l && Nat.ltb l (clh (SIn i))))
835
+ = A * occs 1 l + occs 13 l + SW A * A * occs 6 l).
836
+ { unfold nH. rewrite !nsum_split.
837
+ rewrite (nsum_ext A _ (fun _ => occs 1 l)) by (intros i Hi; cbn [cdh clh]; destruct (Nat.ltb_spec i A); [reflexivity | lia]).
838
+ rewrite (nsum_ext 1 _ (fun _ => occs 13 l))
839
+ by (intros i Hi; cbn [cdh clh]; destruct (Nat.ltb_spec (A + i) A); [lia|];
840
+ destruct (Nat.eqb_spec (A + i) A); [reflexivity | lia]).
841
+ rewrite (nsum_ext (SW A * A) _ (fun _ => occs 6 l))
842
+ by (intros i Hi; cbn [cdh clh]; destruct (Nat.ltb_spec (A + 1 + i) A); [lia|];
843
+ destruct (Nat.eqb_spec (A + 1 + i) A); [lia | reflexivity]).
844
+ rewrite !nsum_const. lia. }
845
+ rewrite Hst. clear Hst.
846
+ (* the carry terms *)
847
+ assert (HT : nsum (A - 1) (fun i => nsum (S (S i)) (fun r =>
848
+ Nat.b2n (Nat.eqb (cdh (SRef (17 + i) 0 r)) l || Nat.ltb (cdh (SRef (17 + i) 0 r)) l
849
+ && Nat.ltb l (clh (SRef (17 + i) 0 r)))))
850
+ = tri * occ 8 9 l + (A - 1) * occ 7 9 l).
851
+ { rewrite (nsum_ext (A - 1) _ (fun i => S i * occ 8 9 l + occ 7 9 l)).
852
+ - assert (Hm : nsum (A - 1) (fun i => S i * occ 8 9 l) = tri * occ 8 9 l) by (unfold tri; apply nsum_mulc).
853
+ rewrite nsum_add, Hm, nsum_const. lia.
854
+ - intros i Hi. replace (17 + i) with (16 + S i) by lia.
855
+ rewrite (nsum_ext (S (S i)) _ (fun r => occ (cd_T (S i) r) 9 l))
856
+ by (intros r Hr; rewrite cdh_T, clh_T by lia; reflexivity).
857
+ rewrite nsum_succ.
858
+ rewrite (nsum_ext (S i) _ (fun _ => occ 8 9 l))
859
+ by (intros r Hr; unfold cd_T; destruct (Nat.eqb_spec r 0); [reflexivity|];
860
+ destruct (Nat.eqb_spec r (S i)); [lia | reflexivity]).
861
+ rewrite nsum_const. unfold cd_T. rewrite Nat.eqb_refl. cbn [Nat.eqb]. lia. }
862
+ rewrite HT. clear HT.
863
+ (* the blocks before and after the carry terms *)
864
+ rewrite (nsum_ext 17 _ (psum l)).
865
+ 2: { intros b Hb. unfold psum. apply nsum_ext. intros j Hj. apply nsum_ext. intros r Hr.
866
+ rewrite cdh_pre, clh_pre by exact Hb. reflexivity. }
867
+ rewrite (nsum_ext 15 _ (qsum l)).
868
+ 2: { intros i Hi. unfold qsum. apply nsum_ext. intros j Hj. apply nsum_ext. intros r Hr.
869
+ rewrite cdh_post, clh_post. reflexivity. }
870
+ cbn [nsum].
871
+ rewrite psum0, psum1, psum2, psum3, psum4, psum5, psum6, psum7, psum8, psum9, psum10, psum11, psum12, psum13,
872
+ psum14, psum15, psum16.
873
+ rewrite qsum0, qsum1, qsum2, qsum3, qsum4, qsum5, qsum6, qsum7, qsum8, qsum9, qsum10, qsum11, qsum12, qsum13, qsum14.
874
+ lia.
875
+ Qed.
876
+
877
+ Lemma tri_eq : 2 * tri = A * (A - 1).
878
+ Proof.
879
+ unfold tri. assert (G : forall k, 2 * nsum k (fun i => S i) = k * (k + 1)) by (induction k as [|k IH]; cbn [nsum]; nia).
880
+ rewrite G. replace (A - 1 + 1) with A by lia. lia.
881
+ Qed.
882
+
883
+ Lemma host_next_len : length (host_next A) = nH A.
884
+ Proof. unfold host_next. rewrite length_map, length_seq. reflexivity. Qed.
885
+
886
+ (* the layers of Lev(H_A): twelve of the widths above and one of the n state bits *)
887
+ Theorem host_lev_widths : map (@length tu) (lev (nH A) (host_units A) (host_next A)) = map wform (seq 1 12) ++ [nH A].
888
+ Proof.
889
+ rewrite lev_widths by exact host_next_len. rewrite host_dmax. cbn [Nat.sub]. f_equal.
890
+ apply map_ext_in. intros l Hl. apply in_seq in Hl. apply host_width. lia.
891
+ Qed.
892
+
893
+ (* Lev(H_A) has (19A + 10) 2^A + (A^2 + 109A + 54)/2 rows *)
894
+ Theorem host_lev_rows : 2 * fold_right Nat.add 0 (map (@length tu) (lev (nH A) (host_units A) (host_next A)))
895
+ = (38 * A + 20) * SW A + A * A + 109 * A + 54.
896
+ Proof.
897
+ rewrite host_lev_widths. cbn [seq map fold_right app]. unfold wform, occ, occs.
898
+ cbn [Nat.eqb Nat.ltb Nat.leb Nat.b2n andb orb]. pose proof tri_eq. pose proof SW_ge8. unfold nH.
899
+ assert (Ea : exists a, A = S a) by (exists (A - 1); lia). destruct Ea as [a Ea]. rewrite Ea in *.
900
+ cbn [Nat.sub] in *. rewrite Nat.sub_0_r in *. nia.
901
+ Qed.
902
+
903
+ End HL.
904
+
905
+ (* ---- the host with eight-bit words, in binary numbers ------------------------------------------------------ *)
906
+ Definition lev_host_widths (A : nat) : list N := map N.of_nat (map (@length tu) (lev (nH A) (host_units A) (host_next A))).
907
+
908
+ Lemma host_lev_widths_8 : lev_host_widths 8
909
+ = [2313; 8210; 2090; 2587; 6427; 2347; 2379; 2389; 2609; 2353; 2339; 3867; 2057]%N.
910
+ Proof. unfold lev_host_widths. rewrite host_lev_widths by lia. vm_compute. reflexivity. Qed.
911
+
912
+ Lemma host_lev_rows_8 : fold_right N.add 0%N (lev_host_widths 8) = 41967%N.
913
+ Proof. rewrite host_lev_widths_8. reflexivity. Qed.
914
+
915
+ (* the entries of the layers as dense matrices: each layer has as many columns as the layer before has rows *)
916
+ Fixpoint dense (prev : N) (ws : list N) : N := match ws with [] => 0%N | w :: t => (prev * w + dense w t)%N end.
917
+
918
+ Lemma host_lev_dense_8 : dense (N.of_nat (nH 8)) (lev_host_widths 8) = 124165940%N.
919
+ Proof. rewrite host_lev_widths_8. vm_compute. reflexivity. Qed.
920
+
921
+ Lemma host_lev_widest_8 : fold_right N.max 0%N (lev_host_widths 8) = 8210%N.
922
+ Proof. rewrite host_lev_widths_8. reflexivity. Qed.
rocq/HostSem.v CHANGED
@@ -1,5 +1,5 @@
1
  (* The host netlist computes one step of SUBLEQ on 2^A words of A bits, from every state, for
2
- every A >= 3 (Proposition 3.9). *)
3
  From Stdlib Require Import List Bool Arith ZArith Lia.
4
  Import ListNotations.
5
  From TH Require Import TwoHead Net Gates PhysSem Host HostWF Adder.
 
1
  (* The host netlist computes one step of SUBLEQ on 2^A words of A bits, from every state, for
2
+ every A >= 3 (Proposition 3.8). *)
3
  From Stdlib Require Import List Bool Arith ZArith Lia.
4
  Import ListNotations.
5
  From TH Require Import TwoHead Net Gates PhysSem Host HostWF Adder.
rocq/Lev.v ADDED
@@ -0,0 +1,692 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* Levelization (Lemma 2.6): a clocked netlist whose units have maximal depth d >= 1 is computed by a layered map
2
+ of depth d. Each unit that contributes to a next value occurs in it with its weights and bias, once if its
3
+ depth is less than d and once for each state bit whose next value it is if its depth is d, and every other row
4
+ is an identity unit. *)
5
+ From Stdlib Require Import List Bool Arith ZArith Lia.
6
+ Import ListNotations.
7
+ From TH Require Import TwoHead Net.
8
+
9
+ (* ---- layered maps (Definition 2.3) ----------------------------------------------------------------------- *)
10
+ (* a layer: rows reading the outputs of the layer before by position *)
11
+ Definition lfire (L : list tu) (y : list bool) : list bool := map (fun u => fire u (fun i => nth i y false)) L.
12
+ Definition lmap (Ls : list (list tu)) (x : list bool) : list bool := fold_left (fun y L => lfire L y) Ls x.
13
+
14
+ (* the rows of each layer read positions of the layer before, distinct ones, with weights -1 or 1 *)
15
+ Definition rowok (w : nat) (u : tu) : Prop :=
16
+ NoDup (map fst (tin u)) /\ forall i z, In (i, z) (tin u) -> i < w /\ (z = 1 \/ z = -1)%Z.
17
+ Fixpoint lwf (w : nat) (Ls : list (list tu)) : Prop :=
18
+ match Ls with [] => True | L :: t => Forall (rowok w) L /\ lwf (length L) t end.
19
+
20
+ Lemma lmap_app : forall Ls L x, lmap (Ls ++ [L]) x = lfire L (lmap Ls x).
21
+ Proof. intros Ls L x. unfold lmap. rewrite fold_left_app. reflexivity. Qed.
22
+
23
+ (* ---- depth -------------------------------------------------------------------------------------------- *)
24
+ Fixpoint maxl (l : list nat) : nat := match l with [] => 0 | x :: t => Nat.max x (maxl t) end.
25
+
26
+ Lemma maxl_ge : forall l a, In a l -> a <= maxl l.
27
+ Proof. induction l as [|x t IH]; intros a H; [destruct H|]. destruct H as [<-|H]; cbn [maxl]; [lia|]. specialize (IH a H). lia. Qed.
28
+
29
+ Lemma maxl_le : forall l c, (forall a, In a l -> a <= c) -> maxl l <= c.
30
+ Proof.
31
+ induction l as [|x t IH]; intros c H; cbn [maxl]; [lia|].
32
+ pose proof (H x (or_introl eq_refl)). pose proof (IH c (fun a Ha => H a (or_intror Ha))). lia.
33
+ Qed.
34
+
35
+ Lemma maxl_pos : forall l, 1 <= maxl l -> exists a, In a l /\ 1 <= a.
36
+ Proof.
37
+ induction l as [|x t IH]; cbn [maxl]; intro H; [lia|].
38
+ destruct (Nat.le_gt_cases 1 x) as [Hx|Hx]; [exists x; split; [left; reflexivity | exact Hx]|].
39
+ destruct (IH ltac:(lia)) as (a & Ha & H1). exists a. split; [right; exact Ha | exact H1].
40
+ Qed.
41
+
42
+ (* the depth of a signal: 0 for a state bit, one more than its deepest predecessor for a unit *)
43
+ Fixpoint depf (us : list tu) (m : nat) (D : nat -> nat) : nat -> nat :=
44
+ match us with
45
+ | [] => D
46
+ | u :: t => depf t (S m) (fun i => if Nat.eqb i m then S (maxl (map (fun p => D (fst p)) (tin u))) else D i)
47
+ end.
48
+
49
+ Lemma depf_prefix : forall us m D i, i < m -> depf us m D i = D i.
50
+ Proof.
51
+ induction us as [|u t IH]; intros m D i H; cbn [depf]; [reflexivity|].
52
+ rewrite IH by lia. destruct (Nat.eqb_spec i m); [lia | reflexivity].
53
+ Qed.
54
+
55
+ Lemma depf_at : forall us m D j, j < length us ->
56
+ (forall k, k < length us -> reads_below (nth k us tu0) (m + k)) ->
57
+ depf us m D (m + j) = S (maxl (map (fun p => depf us m D (fst p)) (tin (nth j us tu0)))).
58
+ Proof.
59
+ induction us as [|u t IH]; intros m D j Hj Hwf; cbn [length] in Hj, Hwf; [lia|].
60
+ destruct j as [|j].
61
+ - cbn [nth depf]. rewrite Nat.add_0_r, depf_prefix by lia. rewrite Nat.eqb_refl. f_equal. f_equal.
62
+ apply map_ext_in. intros [i z] Hin. cbn [fst].
63
+ pose proof (Hwf 0 ltac:(lia) i z Hin) as Hi. cbn [nth] in Hi.
64
+ rewrite depf_prefix by lia. destruct (Nat.eqb_spec i m); [lia | reflexivity].
65
+ - cbn [nth depf]. replace (m + S j) with (S m + j) by lia. apply IH; [lia|].
66
+ intros k Hk i z Hin. specialize (Hwf (S k) ltac:(lia) i z Hin). lia.
67
+ Qed.
68
+
69
+ Lemma map_nth_self : forall (l : list nat) d, map (fun i => nth i l d) (seq 0 (length l)) = l.
70
+ Proof.
71
+ induction l as [|a t IH]; intro d; [reflexivity|]. cbn [length seq map nth]. f_equal.
72
+ rewrite <- seq_shift, map_map. apply IH.
73
+ Qed.
74
+
75
+ Section Lev.
76
+ Variable n : nat.
77
+ Variable us : list tu.
78
+ Variable nx : list nat.
79
+
80
+ Definition NS : nat := n + length us.
81
+ Definition wfn : Prop := forall k, k < length us -> reads_below (nth k us tu0) (n + k).
82
+
83
+ Definition dep : nat -> nat := depf us n (fun _ => 0).
84
+ Definition dmax : nat := maxl (map (fun k => dep (n + k)) (seq 0 (length us))).
85
+
86
+ (* unit k reads signal s *)
87
+ Definition reads (k s : nat) : bool := existsb (fun p => Nat.eqb (fst p) s) (tin (nth k us tu0)).
88
+
89
+ Lemma reads_in : forall k s, reads k s = true <-> exists z, In (s, z) (tin (nth k us tu0)).
90
+ Proof.
91
+ intros k s. unfold reads. rewrite existsb_exists. split.
92
+ - intros ([i z] & Hin & E). cbn [fst] in E. apply Nat.eqb_eq in E. subst i. exists z. exact Hin.
93
+ - intros (z & Hin). exists (s, z). split; [exact Hin | apply Nat.eqb_refl].
94
+ Qed.
95
+
96
+ Lemma dep_state : forall i, i < n -> dep i = 0.
97
+ Proof. intros i H. unfold dep. rewrite depf_prefix by exact H. reflexivity. Qed.
98
+
99
+ Lemma dep_unit : wfn -> forall k, k < length us ->
100
+ dep (n + k) = S (maxl (map (fun p => dep (fst p)) (tin (nth k us tu0)))).
101
+ Proof. intros Hwf k Hk. unfold dep. apply depf_at; assumption. Qed.
102
+
103
+ Lemma dep_pred : wfn -> forall k p z, k < length us -> In (p, z) (tin (nth k us tu0)) -> dep p < dep (n + k).
104
+ Proof.
105
+ intros Hwf k p z Hk Hin. rewrite dep_unit by assumption. apply Nat.lt_succ_r.
106
+ apply maxl_ge. apply in_map_iff. exists (p, z). split; [reflexivity | exact Hin].
107
+ Qed.
108
+
109
+ Lemma dep_le_dmax : forall k, k < length us -> dep (n + k) <= dmax.
110
+ Proof. intros k Hk. apply maxl_ge. apply in_map_iff. exists k. split; [reflexivity | apply in_seq; lia]. Qed.
111
+
112
+ Lemma dep_unit_pos : wfn -> forall k, k < length us -> 1 <= dep (n + k).
113
+ Proof. intros Hwf k Hk. rewrite dep_unit by assumption. lia. Qed.
114
+
115
+ Lemma dep_zero : wfn -> forall s, s < NS -> dep s = 0 -> s < n.
116
+ Proof.
117
+ intros Hwf s Hs H. destruct (Nat.lt_ge_cases s n) as [Hl|Hg]; [exact Hl|].
118
+ pose proof (dep_unit_pos Hwf (s - n) ltac:(unfold NS in Hs; lia)). replace (n + (s - n)) with s in H0 by lia. lia.
119
+ Qed.
120
+
121
+ Lemma dep_le : forall s, s < NS -> dep s <= dmax.
122
+ Proof.
123
+ intros s Hs. destruct (Nat.lt_ge_cases s n) as [Hl|Hg]; [rewrite dep_state by exact Hl; lia|].
124
+ replace s with (n + (s - n)) by lia. apply dep_le_dmax. unfold NS in Hs. lia.
125
+ Qed.
126
+
127
+ (* ---- the signals some next value depends on -------------------------------------------------------- *)
128
+ Fixpoint needf (vs : list tu) (m : nat) (S0 : nat -> bool) : nat -> bool :=
129
+ match vs with
130
+ | [] => S0
131
+ | u :: t => let N' := needf t (S m) S0 in
132
+ fun i => N' i || (N' m && existsb (fun p => Nat.eqb (fst p) i) (tin u))
133
+ end.
134
+
135
+ Definition need : nat -> bool := needf us n (fun i => existsb (Nat.eqb i) nx).
136
+
137
+ Lemma needf_seed : forall vs m S0 i, S0 i = true -> needf vs m S0 i = true.
138
+ Proof. induction vs as [|u t IH]; intros m S0 i H; cbn [needf]; [exact H|]. rewrite IH by exact H. reflexivity. Qed.
139
+
140
+ Lemma needf_closed : forall vs m S0 k p z, k < length vs ->
141
+ (forall j, j < length vs -> reads_below (nth j vs tu0) (m + j)) ->
142
+ needf vs m S0 (m + k) = true -> In (p, z) (tin (nth k vs tu0)) -> needf vs m S0 p = true.
143
+ Proof.
144
+ induction vs as [|u t IH]; intros m S0 k p z Hk Hwf Hn Hin; cbn [length] in Hk; [lia|].
145
+ assert (Hu : forall i z', In (i, z') (tin u) -> i < m) by (intros i z' H; specialize (Hwf 0 ltac:(cbn; lia) i z' H); cbn [nth] in Hwf; lia).
146
+ assert (Hm : existsb (fun p0 => Nat.eqb (fst p0) (m + k)) (tin u) = true -> False).
147
+ { intro E. apply existsb_exists in E as ([i z'] & Hi & E). cbn [fst] in E. apply Nat.eqb_eq in E. subst i.
148
+ specialize (Hu _ _ Hi). lia. }
149
+ cbn [needf] in *. destruct k as [|k].
150
+ - cbn [nth] in Hin. rewrite Nat.add_0_r in Hn. apply orb_true_iff in Hn as [Hn|Hn].
151
+ + apply orb_true_iff. right. rewrite Hn. cbn [andb]. apply existsb_exists. exists (p, z). split; [exact Hin|].
152
+ apply Nat.eqb_refl.
153
+ + apply andb_true_iff in Hn as [Hn _]. apply orb_true_iff. right. rewrite Hn. cbn [andb].
154
+ apply existsb_exists. exists (p, z). split; [exact Hin | apply Nat.eqb_refl].
155
+ - cbn [nth] in Hin. apply orb_true_iff in Hn as [Hn|Hn].
156
+ + apply orb_true_iff. left. replace (m + S k) with (S m + k) in Hn by lia.
157
+ apply (IH (S m) S0 k p z); [lia | | exact Hn | exact Hin].
158
+ intros j Hj. specialize (Hwf (S j) ltac:(cbn; lia)). cbn [nth] in Hwf. replace (S m + j) with (m + S j) by lia. exact Hwf.
159
+ + apply andb_true_iff in Hn as [_ Hn]. exfalso. apply Hm. replace (m + k) with (m + k) by lia.
160
+ replace (m + S k) with (m + S k) in Hn by lia. apply existsb_exists in Hn as ([i z'] & Hi & E).
161
+ cbn [fst] in E. apply Nat.eqb_eq in E. subst i. specialize (Hu _ _ Hi). lia.
162
+ Qed.
163
+
164
+ Lemma needf_step : forall vs m S0 i, needf vs m S0 i = true ->
165
+ S0 i = true \/ exists k z, k < length vs /\ needf vs m S0 (m + k) = true /\ In (i, z) (tin (nth k vs tu0)).
166
+ Proof.
167
+ induction vs as [|u t IH]; intros m S0 i H; cbn [needf] in *; [left; exact H|].
168
+ apply orb_true_iff in H as [H|H].
169
+ - destruct (IH (S m) S0 i H) as [H0|(k & z & Hk & Hn & Hin)]; [left; exact H0|].
170
+ right. exists (S k), z. cbn [length nth]. split; [lia|]. split; [|exact Hin].
171
+ replace (m + S k) with (S m + k) by lia. rewrite Hn. reflexivity.
172
+ - apply andb_true_iff in H as [H1 H2]. apply existsb_exists in H2 as ([i' z] & Hi & E). cbn [fst] in E.
173
+ apply Nat.eqb_eq in E. subst i'. right. exists 0, z. cbn [length nth]. split; [lia|]. split; [|exact Hi].
174
+ rewrite Nat.add_0_r, H1. reflexivity.
175
+ Qed.
176
+
177
+ (* contributing to a next value: being one, or a predecessor of a unit that contributes *)
178
+ Inductive contrib : nat -> Prop :=
179
+ | contrib_out : forall s, In s nx -> contrib s
180
+ | contrib_pred : forall k s z, k < length us -> contrib (n + k) -> In (s, z) (tin (nth k us tu0)) -> contrib s.
181
+
182
+ Lemma need_nx : forall s, In s nx -> need s = true.
183
+ Proof.
184
+ intros s H. apply needf_seed. apply existsb_exists. exists s. split; [exact H | apply Nat.eqb_refl].
185
+ Qed.
186
+
187
+ Lemma need_pred : wfn -> forall k p z, k < length us -> need (n + k) = true -> In (p, z) (tin (nth k us tu0)) ->
188
+ need p = true.
189
+ Proof. intros Hwf k p z Hk Hn Hin. exact (needf_closed us n _ k p z Hk Hwf Hn Hin). Qed.
190
+
191
+ Theorem need_contrib : wfn -> forall s, need s = true <-> contrib s.
192
+ Proof.
193
+ intros Hwf s. split.
194
+ - (* by induction on the distance to the last signal *)
195
+ assert (G : forall d s, NS - s <= d -> need s = true -> contrib s \/ NS <= s).
196
+ { induction d as [|d IH]; intros s' Hd Hn.
197
+ - right. lia.
198
+ - destruct (needf_step us n _ s' Hn) as [H0|(k & z & Hk & Hk2 & Hin)].
199
+ + left. apply contrib_out. apply existsb_exists in H0 as (y & Hy & E). apply Nat.eqb_eq in E. subst. exact Hy.
200
+ + assert (Hs : s' < n + k) by (exact (Hwf k Hk s' z Hin)).
201
+ destruct (IH (n + k) ltac:(unfold NS in *; lia) Hk2) as [Hc|Hc]; [|unfold NS in Hc; lia].
202
+ left. exact (contrib_pred k s' z Hk Hc Hin). }
203
+ intro Hn. destruct (Nat.lt_ge_cases s NS) as [Hl|Hg].
204
+ + destruct (G (NS - s) s (le_n _) Hn) as [Hc|Hc]; [exact Hc | lia].
205
+ + destruct (needf_step us n _ s Hn) as [H0|(k & z & Hk & _ & Hin)].
206
+ * apply contrib_out. apply existsb_exists in H0 as (y & Hy & E). apply Nat.eqb_eq in E. subst. exact Hy.
207
+ * exfalso. specialize (Hwf k Hk s z Hin). unfold NS in Hg. lia.
208
+ - intro Hc. induction Hc as [s Hs|k s z Hk Hc IH Hin]; [apply need_nx; exact Hs|].
209
+ exact (need_pred Hwf k s z Hk IH Hin).
210
+ Qed.
211
+
212
+ (* ---- the last layer that reads a signal ------------------------------------------------------------ *)
213
+ Definition lam (s : nat) : nat :=
214
+ Nat.max (if existsb (Nat.eqb s) nx then S dmax else 0)
215
+ (maxl (map (fun k => if need (n + k) && reads k s then dep (n + k) else 0) (seq 0 (length us)))).
216
+
217
+ Lemma lam_nx : forall s, In s nx -> S dmax <= lam s.
218
+ Proof.
219
+ intros s H. unfold lam. replace (existsb (Nat.eqb s) nx) with true; [lia|].
220
+ symmetry. apply existsb_exists. exists s. split; [exact H | apply Nat.eqb_refl].
221
+ Qed.
222
+
223
+ Lemma lam_reader : forall k s z, k < length us -> need (n + k) = true -> In (s, z) (tin (nth k us tu0)) ->
224
+ dep (n + k) <= lam s.
225
+ Proof.
226
+ intros k s z Hk Hn Hin. unfold lam. apply Nat.max_le_iff. right.
227
+ replace (dep (n + k)) with (if need (n + k) && reads k s then dep (n + k) else 0).
228
+ - apply maxl_ge. apply in_map_iff. exists k. split; [reflexivity | apply in_seq; lia].
229
+ - rewrite Hn. replace (reads k s) with true; [reflexivity|]. symmetry. apply reads_in. exists z. exact Hin.
230
+ Qed.
231
+
232
+ Lemma lam_need : wfn -> forall s, 1 <= lam s -> need s = true.
233
+ Proof.
234
+ intros Hwf s H. unfold lam in H. destruct (existsb (Nat.eqb s) nx) eqn:E.
235
+ - apply existsb_exists in E as (y & Hy & E). apply Nat.eqb_eq in E. subst. apply need_nx. exact Hy.
236
+ - cbn [Nat.max] in H. destruct (maxl_pos _ H) as (a & Ha & H1). apply in_map_iff in Ha as (k & Ea & Hk).
237
+ apply in_seq in Hk. destruct (need (n + k) && reads k s) eqn:F; [|lia].
238
+ apply andb_true_iff in F as [F1 F2]. apply reads_in in F2 as (z & Hin).
239
+ exact (need_pred Hwf k s z ltac:(lia) F1 Hin).
240
+ Qed.
241
+
242
+ (* ---- the layers ----------------------------------------------------------------------------------- *)
243
+ Definition isunit (l s : nat) : bool := (n <=? s) && (dep s =? l).
244
+ Definition live (l s : nat) : bool := isunit l s && need s || (dep s <? l) && (l <? lam s).
245
+ Definition pos (l s : nat) : nat := match l with O => s | _ => length (filter (live l) (seq 0 s)) end.
246
+
247
+ Definition idr (p : nat) : tu := TU (-1) [(p, 1%Z)].
248
+ Definition reidx (l : nat) (u : tu) : tu := TU (tb u) (map (fun p => (pos l (fst p), snd p)) (tin u)).
249
+
250
+ (* the source of a row: a copy of a signal, or a unit *)
251
+ Inductive src := Cp (s : nat) | Un (s : nat).
252
+ Definition srcof (l s : nat) : src := if isunit l s then Un s else Cp s.
253
+ Definition srcs (l : nat) : list src := map (srcof l) (filter (live l) (seq 0 NS)).
254
+ Definition srcd : list src := map (fun i => srcof dmax (nth i nx 0)) (seq 0 n).
255
+ Definition mkrow (l : nat) (c : src) : tu :=
256
+ match c with Cp s => idr (pos (l - 1) s) | Un s => reidx (l - 1) (nth (s - n) us tu0) end.
257
+
258
+ (* layers 1 .. d - 1 hold the live signals, layer d one row for each state bit *)
259
+ Definition lsrc : list (nat * list src) := map (fun l => (l, srcs l)) (seq 1 (dmax - 1)) ++ [(dmax, srcd)].
260
+ Definition lev : list (list tu) := map (fun p => map (mkrow (fst p)) (snd p)) lsrc.
261
+
262
+ (* ---- positions --------------------------------------------------------------------------------------- *)
263
+ Lemma seq_split : forall s M, s < M -> seq 0 M = seq 0 s ++ s :: seq (S s) (M - S s).
264
+ Proof. intros s M H. replace M with (s + S (M - S s)) at 1 by lia. rewrite seq_app. reflexivity. Qed.
265
+
266
+ Lemma nth_filter_count : forall (f : nat -> bool) s M d, s < M -> f s = true ->
267
+ nth (length (filter f (seq 0 s))) (filter f (seq 0 M)) d = s.
268
+ Proof.
269
+ intros f s M d Hs Hf. rewrite (seq_split s M Hs).
270
+ rewrite filter_app. cbn [filter]. rewrite Hf. rewrite app_nth2 by lia. rewrite Nat.sub_diag. reflexivity.
271
+ Qed.
272
+
273
+ Lemma count_lt : forall (f : nat -> bool) s M, s < M -> f s = true ->
274
+ length (filter f (seq 0 s)) < length (filter f (seq 0 M)).
275
+ Proof.
276
+ intros f s M Hs Hf. rewrite (seq_split s M Hs).
277
+ rewrite filter_app, length_app. cbn [filter]. rewrite Hf. cbn [length]. lia.
278
+ Qed.
279
+
280
+ Lemma count_mono : forall (f : nat -> bool) a b, a <= b -> length (filter f (seq 0 a)) <= length (filter f (seq 0 b)).
281
+ Proof.
282
+ intros f a b H. replace b with (a + (b - a)) by lia. rewrite seq_app, filter_app, length_app. lia.
283
+ Qed.
284
+
285
+ Lemma pos_inj : forall l s1 s2, 1 <= l -> live l s1 = true -> live l s2 = true -> pos l s1 = pos l s2 -> s1 = s2.
286
+ Proof.
287
+ intros l s1 s2 Hl H1 H2 E. destruct l as [|l]; [lia|]. cbn [pos] in E.
288
+ destruct (Nat.lt_trichotomy s1 s2) as [Hlt|[Heq|Hgt]]; [|exact Heq|].
289
+ - pose proof (count_lt (live (S l)) s1 s2 Hlt H1). lia.
290
+ - pose proof (count_lt (live (S l)) s2 s1 Hgt H2). lia.
291
+ Qed.
292
+
293
+ (* ---- firing the rows ------------------------------------------------------------------------------ *)
294
+ Lemma wsum_reidx : forall l ins E,
295
+ wsum (map (fun p => (pos l (fst p), snd p)) ins) E = wsum ins (fun i => E (pos l i)).
296
+ Proof. intros l ins E. induction ins as [|[i z] t IH]; cbn [map wsum fst snd]; [reflexivity|]. rewrite IH. reflexivity. Qed.
297
+
298
+ Lemma fire_reidx : forall l u E, fire (reidx l u) E = fire u (fun i => E (pos l i)).
299
+ Proof. intros l u E. unfold fire, reidx. cbn [tb tin]. rewrite wsum_reidx. reflexivity. Qed.
300
+
301
+ Lemma fire_idr : forall p E, fire (idr p) E = E p.
302
+ Proof. intros p E. unfold fire, idr. cbn [tb tin wsum]. destruct (E p); reflexivity. Qed.
303
+
304
+ Lemma lfire_nth : forall L y r, r < length L -> nth r (lfire L y) false = fire (nth r L tu0) (fun i => nth i y false).
305
+ Proof.
306
+ intros L y r Hr. unfold lfire. rewrite (nth_indep _ false (fire tu0 (fun i => nth i y false))) by (rewrite length_map; exact Hr).
307
+ exact (map_nth (fun u => fire u (fun i => nth i y false)) L tu0 r).
308
+ Qed.
309
+
310
+ (* a signal has a row in layer l, l <= d - 1 *)
311
+ Definition at_layer (l s : nat) : Prop := s < NS /\ (match l with O => s < n | _ => live l s = true end).
312
+
313
+ (* the predecessors of a unit of depth l + 1 that contributes, and a signal live at l + 1 or a next value of depth
314
+ at most l, have rows in layer l *)
315
+ Lemma pred_at : wfn -> forall l k p z, k < length us -> need (n + k) = true -> dep (n + k) = S l ->
316
+ In (p, z) (tin (nth k us tu0)) -> at_layer l p.
317
+ Proof.
318
+ intros Hwf l k p z Hk Hn Hdk Hin. pose proof (dep_pred Hwf k p z Hk Hin) as Hlt.
319
+ assert (Hp : p < NS) by (pose proof (Hwf k Hk p z Hin); unfold NS; lia).
320
+ split; [exact Hp|]. destruct l as [|l].
321
+ - apply (dep_zero Hwf p Hp). lia.
322
+ - unfold live. pose proof (lam_reader k p z Hk Hn Hin) as Hlam.
323
+ destruct (Nat.eq_dec (dep p) (S l)) as [E|E].
324
+ + apply orb_true_iff. left. apply andb_true_iff. split; [|exact (need_pred Hwf k p z Hk Hn Hin)].
325
+ unfold isunit. apply andb_true_iff. split; [|apply Nat.eqb_eq; exact E].
326
+ apply Nat.leb_le. destruct (Nat.lt_ge_cases p n) as [Hl|Hg]; [rewrite dep_state in E by exact Hl; lia | exact Hg].
327
+ + apply orb_true_iff. right. apply andb_true_iff. split; apply Nat.ltb_lt; lia.
328
+ Qed.
329
+
330
+ Lemma copy_at : wfn -> forall l s, s < NS -> dep s <= l -> S l < lam s -> at_layer l s.
331
+ Proof.
332
+ intros Hwf l s Hs Hdl Hlam. split; [exact Hs|]. destruct l as [|l].
333
+ - apply (dep_zero Hwf s Hs). lia.
334
+ - unfold live. destruct (Nat.eq_dec (dep s) (S l)) as [E|E].
335
+ + apply orb_true_iff. left. apply andb_true_iff. split; [|apply lam_need; [exact Hwf | lia]].
336
+ unfold isunit. apply andb_true_iff. split; [|apply Nat.eqb_eq; exact E].
337
+ apply Nat.leb_le. destruct (Nat.lt_ge_cases s n) as [Hl|Hg]; [rewrite dep_state in E by exact Hl; lia | exact Hg].
338
+ + apply orb_true_iff. right. apply andb_true_iff. split; apply Nat.ltb_lt; lia.
339
+ Qed.
340
+
341
+ Section Sem.
342
+ Hypothesis Hwf : wfn.
343
+ Hypothesis Hnx : Forall (fun s => s < NS) nx.
344
+ Hypothesis Hlen : length nx = n.
345
+ Hypothesis Hd : 1 <= dmax.
346
+
347
+ Variable x : list bool.
348
+ Hypothesis Hx : length x = n.
349
+
350
+ Let F : nat -> bool := run us n (fun i => nth i x false).
351
+
352
+ Lemma F_unit : forall k, k < length us -> F (n + k) = fire (nth k us tu0) F.
353
+ Proof. intros k Hk. unfold F. apply run_at; [exact Hk | exact Hwf]. Qed.
354
+
355
+ Lemma F_state : forall i, i < n -> F i = nth i x false.
356
+ Proof. intros i Hi. unfold F. apply run_prefix. exact Hi. Qed.
357
+
358
+ (* the outputs after the first l layers, 0 <= l <= d - 1 *)
359
+ Definition yl (l : nat) : list bool := lmap (map (fun l' => map (mkrow l') (srcs l')) (seq 1 l)) x.
360
+
361
+ (* firing a row from the outputs of the layer before *)
362
+ Lemma fire_row : forall l (y : list bool) c,
363
+ (forall s, at_layer l s -> nth (pos l s) y false = F s) ->
364
+ (forall s, c = Un s -> exists k, k < length us /\ s = n + k /\ need s = true /\ dep s = S l) ->
365
+ (forall s, c = Cp s -> at_layer l s) ->
366
+ fire (mkrow (S l) c) (fun i => nth i y false) = F (match c with Cp s => s | Un s => s end).
367
+ Proof.
368
+ intros l y c Hy HU HC. destruct c as [s|s]; cbn [mkrow]; replace (S l - 1) with l by lia.
369
+ - rewrite fire_idr. apply Hy. apply HC. reflexivity.
370
+ - destruct (HU s eq_refl) as (k & Hk & -> & Hn & Hdk). replace (n + k - n) with k by lia.
371
+ rewrite fire_reidx, F_unit by exact Hk. apply fire_ext. intros p z Hin. apply Hy. exact (pred_at Hwf l k p z Hk Hn Hdk Hin).
372
+ Qed.
373
+
374
+ Lemma yl_spec : forall l, l <= dmax - 1 ->
375
+ length (yl l) = (match l with O => n | _ => length (filter (live l) (seq 0 NS)) end)
376
+ /\ forall s, at_layer l s -> nth (pos l s) (yl l) false = F s.
377
+ Proof.
378
+ induction l as [|l IH]; intros Hl.
379
+ - unfold yl. cbn. split; [exact Hx|]. intros s [Hs Hn]. symmetry. apply F_state. exact Hn.
380
+ - destruct (IH ltac:(lia)) as [IL IY].
381
+ assert (E : yl (S l) = lfire (map (mkrow (S l)) (srcs (S l))) (yl l)).
382
+ { unfold yl. rewrite seq_S, map_app. cbn [map]. replace (1 + l) with (S l) by lia. apply lmap_app. }
383
+ rewrite E. unfold lfire, srcs. rewrite !length_map. split; [reflexivity|].
384
+ intros s [Hs Hlv]. cbn [pos]. fold (lfire (map (mkrow (S l)) (map (srcof (S l)) (filter (live (S l)) (seq 0 NS)))) (yl l)).
385
+ pose proof (count_lt (live (S l)) s NS Hs Hlv) as Hc.
386
+ rewrite lfire_nth by (rewrite !length_map; exact Hc).
387
+ rewrite nth_map_d with (d' := Cp 0) by (rewrite length_map; exact Hc).
388
+ rewrite nth_map_d with (d' := 0) by exact Hc. rewrite nth_filter_count by assumption.
389
+ assert (Hfs : F s = F (match srcof (S l) s with Cp s' => s' | Un s' => s' end))
390
+ by (unfold srcof; destruct (isunit (S l) s); reflexivity).
391
+ rewrite Hfs. apply fire_row; [exact IY | |].
392
+ + intros s' Hs'. unfold srcof in Hs'. destruct (isunit (S l) s) eqn:Hu; [|discriminate]. injection Hs' as <-.
393
+ unfold isunit in Hu. apply andb_true_iff in Hu as [H1 H2]. apply Nat.leb_le in H1. apply Nat.eqb_eq in H2.
394
+ exists (s - n). split; [unfold NS in Hs; lia|]. split; [lia|]. split; [|exact H2].
395
+ unfold live in Hlv. apply orb_true_iff in Hlv as [Hlv|Hlv].
396
+ * apply andb_true_iff in Hlv as [_ Hlv]. exact Hlv.
397
+ * apply andb_true_iff in Hlv as [Hlv _]. apply Nat.ltb_lt in Hlv. lia.
398
+ + intros s' Hs'. unfold srcof in Hs'. destruct (isunit (S l) s) eqn:Hu; [discriminate|]. injection Hs' as <-.
399
+ unfold live in Hlv. rewrite Hu in Hlv. cbn [andb orb] in Hlv. apply andb_true_iff in Hlv as [H1 H2].
400
+ apply Nat.ltb_lt in H1, H2. apply (copy_at Hwf); [exact Hs | lia | lia].
401
+ Qed.
402
+
403
+ Theorem lev_correct : lmap lev x = netstep n us nx x.
404
+ Proof.
405
+ unfold lev, lsrc. rewrite map_app. cbn [map fst snd]. rewrite lmap_app.
406
+ fold (yl (dmax - 1)). destruct (yl_spec (dmax - 1) (le_n _)) as [_ IY].
407
+ unfold netstep. fold F. unfold lfire, srcd. rewrite !map_map.
408
+ transitivity (map F (map (fun i => nth i nx 0) (seq 0 n))).
409
+ 2: { f_equal. rewrite <- Hlen. apply map_nth_self. }
410
+ rewrite map_map. apply map_ext_in. intros i Hi. apply in_seq in Hi.
411
+ set (s := nth i nx 0).
412
+ assert (Hs : s < NS) by (rewrite Forall_forall in Hnx; apply Hnx; apply nth_In; lia).
413
+ assert (Hin : In s nx) by (apply nth_In; lia).
414
+ assert (Hfs : F s = F (match srcof dmax s with Cp s' => s' | Un s' => s' end))
415
+ by (unfold srcof; destruct (isunit dmax s); reflexivity).
416
+ rewrite Hfs. replace (mkrow dmax) with (mkrow (S (dmax - 1))) by (f_equal; lia).
417
+ apply fire_row; [exact IY | |].
418
+ - intros s' Hs'. unfold srcof in Hs'. destruct (isunit dmax s) eqn:Hu; [|discriminate]. injection Hs' as <-.
419
+ unfold isunit in Hu. apply andb_true_iff in Hu as [H1 H2]. apply Nat.leb_le in H1. apply Nat.eqb_eq in H2.
420
+ exists (s - n). split; [unfold NS in Hs; lia|]. split; [lia|]. split; [apply need_nx; exact Hin | lia].
421
+ - intros s' Hs'. unfold srcof in Hs'. destruct (isunit dmax s) eqn:Hu; [discriminate|]. injection Hs' as <-.
422
+ pose proof (lam_nx s Hin). pose proof (dep_le s Hs).
423
+ assert (dep s <> dmax \/ s < n) as Hne.
424
+ { unfold isunit in Hu. apply andb_false_iff in Hu as [Hu|Hu]; [right; apply Nat.leb_gt in Hu; exact Hu|].
425
+ left. apply Nat.eqb_neq in Hu. lia. }
426
+ apply (copy_at Hwf); [exact Hs | | lia].
427
+ destruct Hne as [Hne|Hne]; [lia | rewrite dep_state by exact Hne; lia].
428
+ Qed.
429
+
430
+ End Sem.
431
+
432
+ (* ---- the shape of the layered map ----------------------------------------------------------------------- *)
433
+ Lemma length_lev : 1 <= dmax -> length lev = dmax.
434
+ Proof. intro H. unfold lev, lsrc. rewrite length_map, length_app, length_map, length_seq. cbn [length]. lia. Qed.
435
+
436
+ (* the width of layer l, 0 <= l <= d - 1 *)
437
+ Definition width (l : nat) : nat := match l with O => n | _ => length (filter (live l) (seq 0 NS)) end.
438
+
439
+ Lemma pos_lt : forall l s, at_layer l s -> pos l s < width l.
440
+ Proof.
441
+ intros l s [Hs Hl]. destruct l as [|l]; cbn [pos width]; [exact Hl|]. apply count_lt; assumption.
442
+ Qed.
443
+
444
+ Lemma pos_inj_at : forall l s1 s2, at_layer l s1 -> at_layer l s2 -> pos l s1 = pos l s2 -> s1 = s2.
445
+ Proof.
446
+ intros l s1 s2 [_ H1] [_ H2] E. destruct l as [|l]; [exact E|]. apply (pos_inj (S l)); [lia | exact H1 | exact H2 | exact E].
447
+ Qed.
448
+
449
+ Lemma nodup_map_inj : forall (f : nat -> nat) (P : nat -> Prop) l, NoDup l -> (forall a, In a l -> P a) ->
450
+ (forall a b, P a -> P b -> f a = f b -> a = b) -> NoDup (map f l).
451
+ Proof.
452
+ intros f P l Hnd. induction Hnd as [|a t Ha Hnd IH]; intros HP Hinj; cbn [map]; constructor.
453
+ - intro Hin. apply in_map_iff in Hin as (b & Eb & Hb). apply Ha.
454
+ rewrite (Hinj b a (HP b (or_intror Hb)) (HP a (or_introl eq_refl)) Eb) in Hb. exact Hb.
455
+ - apply IH; [intros b Hb; apply HP; right; exact Hb | exact Hinj].
456
+ Qed.
457
+
458
+ (* a row built from a source of layer l + 1 reads distinct positions of layer l with weights -1 or 1 *)
459
+ Lemma mkrow_ok : wfn -> Forall (fun u => NoDup (map fst (tin u)) /\ forall i z, In (i, z) (tin u) -> z = 1%Z \/ z = (-1)%Z) us ->
460
+ forall l c, (forall s, c = Un s -> exists k, k < length us /\ s = n + k /\ need s = true /\ dep s = S l) ->
461
+ (forall s, c = Cp s -> at_layer l s) -> rowok (width l) (mkrow (S l) c).
462
+ Proof.
463
+ intros Hwf Hus l c HU HC. destruct c as [s|s]; cbn [mkrow]; replace (S l - 1) with l by lia.
464
+ - specialize (HC s eq_refl). unfold rowok, idr. cbn [tin map fst]. split; [constructor; [intros []|constructor]|].
465
+ intros i z [E|[]]. injection E as <- <-. split; [apply pos_lt; exact HC | left; reflexivity].
466
+ - destruct (HU s eq_refl) as (k & Hk & -> & Hn & Hdk). replace (n + k - n) with k by lia.
467
+ rewrite Forall_forall in Hus. destruct (Hus (nth k us tu0) (nth_In _ _ Hk)) as [Hnd Hz].
468
+ unfold rowok, reidx. cbn [tin]. split.
469
+ + rewrite map_map. cbn [fst]. rewrite <- (map_map fst (pos l)).
470
+ apply (nodup_map_inj (pos l) (at_layer l) (map fst (tin (nth k us tu0)))); [exact Hnd | |].
471
+ * intros p Hp. apply in_map_iff in Hp as ([p' z] & <- & Hin). exact (pred_at Hwf l k p' z Hk Hn Hdk Hin).
472
+ * intros a b Ha Hb E. exact (pos_inj_at l a b Ha Hb E).
473
+ + intros i z Hin. apply in_map_iff in Hin as ([p z'] & E & Hin). cbn [fst snd] in E. injection E as <- <-.
474
+ split; [apply pos_lt; exact (pred_at Hwf l k p z' Hk Hn Hdk Hin) | exact (Hz p z' Hin)].
475
+ Qed.
476
+
477
+ Lemma srcs_spec : forall l c, In c (srcs l) ->
478
+ (forall s, c = Un s -> exists k, k < length us /\ s = n + k /\ need s = true /\ dep s = l)
479
+ /\ (forall s, c = Cp s -> s < NS /\ dep s < l < lam s).
480
+ Proof.
481
+ intros l c Hc. unfold srcs in Hc. apply in_map_iff in Hc as (s & <- & Hs). apply filter_In in Hs as [Hs Hlv].
482
+ apply in_seq in Hs. unfold srcof. destruct (isunit l s) eqn:Hu; split; intros s' E; try discriminate; injection E as <-.
483
+ - unfold isunit in Hu. apply andb_true_iff in Hu as [H1 H2]. apply Nat.leb_le in H1. apply Nat.eqb_eq in H2.
484
+ exists (s - n). split; [unfold NS in Hs; lia|]. split; [lia|]. split; [|exact H2].
485
+ unfold live in Hlv. apply orb_true_iff in Hlv as [Hlv|Hlv].
486
+ + apply andb_true_iff in Hlv as [_ Hlv]. exact Hlv.
487
+ + apply andb_true_iff in Hlv as [Hlv _]. apply Nat.ltb_lt in Hlv. lia.
488
+ - unfold live in Hlv. rewrite Hu in Hlv. cbn [andb orb] in Hlv. apply andb_true_iff in Hlv as [H1 H2].
489
+ apply Nat.ltb_lt in H1, H2. split; [lia | lia].
490
+ Qed.
491
+
492
+ Lemma srcd_spec : Forall (fun s => s < NS) nx -> length nx = n -> 1 <= dmax -> forall c, In c srcd ->
493
+ (forall s, c = Un s -> exists k, k < length us /\ s = n + k /\ need s = true /\ dep s = dmax)
494
+ /\ (forall s, c = Cp s -> s < NS /\ dep s < dmax /\ S dmax <= lam s).
495
+ Proof.
496
+ intros Hnx Hlen Hd c Hc. unfold srcd in Hc. apply in_map_iff in Hc as (i & <- & Hi). apply in_seq in Hi.
497
+ set (s := nth i nx 0). assert (Hs : s < NS) by (rewrite Forall_forall in Hnx; apply Hnx; apply nth_In; lia).
498
+ assert (Hin : In s nx) by (apply nth_In; lia).
499
+ unfold srcof. destruct (isunit dmax s) eqn:Hu; split; intros s' E; try discriminate; injection E as <-.
500
+ - unfold isunit in Hu. apply andb_true_iff in Hu as [H1 H2]. apply Nat.leb_le in H1. apply Nat.eqb_eq in H2.
501
+ exists (s - n). split; [unfold NS in Hs; lia|]. split; [lia|]. split; [apply need_nx; exact Hin | exact H2].
502
+ - split; [exact Hs|]. split; [|apply lam_nx; exact Hin]. pose proof (dep_le s Hs).
503
+ unfold isunit in Hu. apply andb_false_iff in Hu as [Hu|Hu].
504
+ + apply Nat.leb_gt in Hu. rewrite dep_state by exact Hu. lia.
505
+ + apply Nat.eqb_neq in Hu. lia.
506
+ Qed.
507
+
508
+ (* Lemma 2.6: the layered map has depth d, every row reads distinct rows of the layer before with weights -1 or 1,
509
+ and it computes the next state of the netlist *)
510
+ Theorem lev_ok : wfn -> Forall (fun s => s < NS) nx -> length nx = n -> 1 <= dmax ->
511
+ Forall (fun u => NoDup (map fst (tin u)) /\ forall i z, In (i, z) (tin u) -> z = 1%Z \/ z = (-1)%Z) us ->
512
+ length lev = dmax /\ lwf n lev /\ length (last lev []) = n
513
+ /\ forall x, length x = n -> lmap lev x = netstep n us nx x.
514
+ Proof.
515
+ intros Hwf Hnx Hlen Hd Hus. split; [apply length_lev; exact Hd|]. split; [|split].
516
+ - (* layer l + 1 reads layer l *)
517
+ assert (G : forall m, m <= dmax - 1 ->
518
+ lwf (width m) (map (fun p => map (mkrow (fst p)) (snd p))
519
+ (map (fun l => (l, srcs l)) (seq (S m) (dmax - 1 - m)) ++ [(dmax, srcd)]))).
520
+ { intros m Hm. remember (dmax - 1 - m) as c eqn:Ec. revert m Hm Ec. induction c as [|c IH]; intros m Hm Ec.
521
+ - cbn [seq map app lwf fst snd]. split; [|exact I].
522
+ apply Forall_forall. intros r Hr. apply in_map_iff in Hr as (c & <- & Hc).
523
+ destruct (srcd_spec Hnx Hlen Hd c Hc) as [HU HC].
524
+ replace dmax with (S m) by lia. apply mkrow_ok; [exact Hwf | exact Hus | |].
525
+ + intros s E. destruct (HU s E) as (k & Hk & Es & Hn & Hdk). exists k. repeat split; try assumption. lia.
526
+ + intros s E. destruct (HC s E) as (Hs & Hdl & Hlam). apply copy_at; [exact Hwf | exact Hs | lia | lia].
527
+ - cbn [seq map app lwf fst snd]. split.
528
+ + apply Forall_forall. intros r Hr. apply in_map_iff in Hr as (c' & <- & Hc).
529
+ destruct (srcs_spec (S m) c' Hc) as [HU HC]. apply mkrow_ok; [exact Hwf | exact Hus | exact HU |].
530
+ intros s E. destruct (HC s E) as (Hs & Hdl & Hlam). apply copy_at; [exact Hwf | exact Hs | lia | lia].
531
+ + rewrite length_map. unfold srcs. rewrite length_map.
532
+ replace (length (filter (live (S m)) (seq 0 NS))) with (width (S m)) by reflexivity.
533
+ apply IH; lia. }
534
+ specialize (G 0 ltac:(lia)). unfold lev, lsrc. replace (dmax - 1) with (dmax - 1 - 0) by lia. exact G.
535
+ - unfold lev, lsrc. rewrite map_app. cbn [map fst snd]. rewrite last_last. unfold srcd. rewrite !length_map, length_seq.
536
+ reflexivity.
537
+ - intros x Hx. apply lev_correct; assumption.
538
+ Qed.
539
+
540
+ (* every row is an identity unit H(x - 1) or a unit of the netlist with its bias and weights *)
541
+ Theorem lev_rows : forall l cs c, In (l, cs) lsrc -> In c cs ->
542
+ match c with
543
+ | Cp s => exists p, mkrow l c = idr p
544
+ | Un s => tb (mkrow l c) = tb (nth (s - n) us tu0) /\ map snd (tin (mkrow l c)) = map snd (tin (nth (s - n) us tu0))
545
+ end.
546
+ Proof.
547
+ intros l cs c _ _. destruct c as [s|s]; cbn [mkrow].
548
+ - eexists. reflexivity.
549
+ - unfold reidx. cbn [tb tin]. split; [reflexivity|]. rewrite map_map. reflexivity.
550
+ Qed.
551
+
552
+ (* the occurrences of unit s among the rows *)
553
+ Definition isun (s : nat) (c : src) : bool := match c with Un s' => Nat.eqb s' s | Cp _ => false end.
554
+
555
+ Lemma length_filter_map : forall (A B : Type) (p : B -> bool) (f : A -> B) (L : list A),
556
+ length (filter p (map f L)) = length (filter (fun a => p (f a)) L).
557
+ Proof. intros A B p f L. induction L as [|a t IH]; cbn [map filter]; [reflexivity|]. destruct (p (f a)); cbn [length]; lia. Qed.
558
+
559
+ Lemma length_filter_filter : forall (A : Type) (p q : A -> bool) (L : list A),
560
+ length (filter p (filter q L)) = length (filter (fun a => q a && p a) L).
561
+ Proof.
562
+ intros A p q L. induction L as [|a t IH]; [reflexivity|]. cbn [filter].
563
+ destruct (q a); cbn [andb filter]; [destruct (p a); cbn [length]; lia | exact IH].
564
+ Qed.
565
+
566
+ Lemma filter_eqb_seq : forall (g : nat -> bool) M s, s < M ->
567
+ length (filter (fun s' => g s' && Nat.eqb s' s) (seq 0 M)) = if g s then 1 else 0.
568
+ Proof.
569
+ intros g M s Hs. rewrite (seq_split s M Hs), filter_app, length_app. cbn [filter]. rewrite Nat.eqb_refl, andb_true_r.
570
+ assert (Z : forall a k, (a > s \/ a + k <= s) -> length (filter (fun s' => g s' && Nat.eqb s' s) (seq a k)) = 0).
571
+ { intros a k Hak. revert a Hak. induction k as [|k IH]; intros a Hak; [reflexivity|]. cbn [seq filter].
572
+ destruct (Nat.eqb_spec a s); [lia|]. rewrite andb_false_r. apply IH. lia. }
573
+ rewrite (Z 0 s) by lia. destruct (g s); cbn [length]; rewrite (Z (S s) (M - S s)) by lia; reflexivity.
574
+ Qed.
575
+
576
+ Lemma count_srcs : forall l s, s < NS -> length (filter (isun s) (srcs l)) = if isunit l s && need s then 1 else 0.
577
+ Proof.
578
+ intros l s Hs. unfold srcs. rewrite length_filter_map, length_filter_filter.
579
+ rewrite (filter_ext _ (fun a => (live l a && isunit l a) && Nat.eqb a s)).
580
+ - rewrite filter_eqb_seq by exact Hs. destruct (isunit l s) eqn:Hu.
581
+ + unfold live. rewrite Hu. unfold isunit in Hu. apply andb_true_iff in Hu as [_ Hu]. apply Nat.eqb_eq in Hu.
582
+ rewrite Hu, Nat.ltb_irrefl. destruct (need s); reflexivity.
583
+ + rewrite andb_false_r. reflexivity.
584
+ - intro a. unfold srcof. destruct (isunit l a); cbn [isun]; [rewrite andb_true_r; reflexivity|].
585
+ rewrite !andb_false_r. reflexivity.
586
+ Qed.
587
+
588
+ Lemma count_map_srcof : forall d s (L : list nat),
589
+ length (filter (fun a => isun s (srcof d a)) L) = if isunit d s then length (filter (fun a => Nat.eqb a s) L) else 0.
590
+ Proof.
591
+ intros d s L. induction L as [|a t IH]; [destruct (isunit d s); reflexivity|]. cbn [filter].
592
+ destruct (Nat.eqb_spec a s) as [->|E].
593
+ - assert (Hs : isun s (srcof d s) = isunit d s)
594
+ by (unfold srcof; destruct (isunit d s); cbn [isun]; [apply Nat.eqb_refl | reflexivity]).
595
+ rewrite Hs. destruct (isunit d s) eqn:Hu.
596
+ + cbn [length]. rewrite IH. reflexivity.
597
+ + exact IH.
598
+ - assert (Hf : isun s (srcof d a) = false)
599
+ by (unfold srcof; destruct (isunit d a); cbn [isun]; [apply Nat.eqb_neq; exact E | reflexivity]).
600
+ rewrite Hf. exact IH.
601
+ Qed.
602
+
603
+ Lemma count_srcd : length nx = n -> forall s,
604
+ length (filter (isun s) srcd) = if isunit dmax s then length (filter (fun a => Nat.eqb a s) nx) else 0.
605
+ Proof.
606
+ intros Hlen s. unfold srcd. rewrite <- (map_map (fun i => nth i nx 0) (srcof dmax)).
607
+ rewrite <- Hlen, map_nth_self, length_filter_map. apply count_map_srcof.
608
+ Qed.
609
+
610
+ Lemma length_filter_concat : forall (A : Type) (p : A -> bool) (L : list (list A)),
611
+ length (filter p (concat L)) = fold_right Nat.add 0 (map (fun l => length (filter p l)) L).
612
+ Proof.
613
+ intros A p L. induction L as [|l t IH]; [reflexivity|]. cbn [concat map fold_right]. rewrite filter_app, length_app, IH.
614
+ reflexivity.
615
+ Qed.
616
+
617
+ Lemma sum_indicator : forall x a k, fold_right Nat.add 0 (map (fun l => if Nat.eqb x l then 1 else 0) (seq a k))
618
+ = if (a <=? x) && (x <? a + k) then 1 else 0.
619
+ Proof.
620
+ intros x a k. revert a. induction k as [|k IH]; intro a.
621
+ - cbn [seq map fold_right]. destruct (Nat.leb_spec a x), (Nat.ltb_spec x (a + 0)); cbn [andb]; lia.
622
+ - cbn [seq map fold_right]. rewrite IH. destruct (Nat.eqb_spec x a) as [->|E].
623
+ + rewrite Nat.leb_refl. destruct (Nat.leb_spec (S a) a); [lia|]. cbn [andb]. destruct (Nat.ltb_spec a (a + S k)); lia.
624
+ + destruct (Nat.leb_spec (S a) x), (Nat.ltb_spec x (S a + k)), (Nat.leb_spec a x), (Nat.ltb_spec x (a + S k));
625
+ cbn [andb]; lia.
626
+ Qed.
627
+
628
+ Lemma sum_zero : forall (L : list nat) (f : nat -> nat), (forall l, In l L -> f l = 0) ->
629
+ fold_right Nat.add 0 (map f L) = 0.
630
+ Proof.
631
+ intros L f H. induction L as [|a t IH]; [reflexivity|]. cbn [map fold_right].
632
+ rewrite (H a (or_introl eq_refl)), IH by (intros l Hl; apply H; right; exact Hl). reflexivity.
633
+ Qed.
634
+
635
+ Lemma filter_none : forall (L : list nat) s, (forall a, In a L -> a <> s) -> length (filter (fun a => Nat.eqb a s) L) = 0.
636
+ Proof.
637
+ intros L s H. induction L as [|a t IH]; [reflexivity|]. cbn [filter].
638
+ destruct (Nat.eqb_spec a s) as [E|E]; [exfalso; exact (H a (or_introl eq_refl) E)|].
639
+ apply IH. intros b Hb. apply H. right. exact Hb.
640
+ Qed.
641
+
642
+ (* each unit that contributes occurs once if its depth is less than d and once for each state bit whose next value it
643
+ is if its depth is d; no other unit occurs *)
644
+ Theorem lev_units : wfn -> length nx = n -> forall s, n <= s < NS ->
645
+ length (filter (isun s) (concat (map snd lsrc)))
646
+ = if need s then (if dep s <? dmax then 1 else length (filter (fun a => Nat.eqb a s) nx)) else 0.
647
+ Proof.
648
+ intros Hwf Hlen s Hs. unfold lsrc. rewrite map_app, concat_app, filter_app, length_app, map_map. cbn [map snd concat].
649
+ rewrite app_nil_r, count_srcd by exact Hlen. rewrite length_filter_concat, map_map.
650
+ pose proof (dep_unit_pos Hwf (s - n) ltac:(unfold NS in Hs; lia)) as Hpos. replace (n + (s - n)) with s in Hpos by lia.
651
+ pose proof (dep_le s (proj2 Hs)) as Hle.
652
+ assert (Hu : forall l, isunit l s = Nat.eqb (dep s) l)
653
+ by (intro l; unfold isunit; destruct (Nat.leb_spec n s); [reflexivity | lia]).
654
+ rewrite Hu. destruct (need s) eqn:Hn.
655
+ - rewrite (map_ext_in _ (fun l => if Nat.eqb (dep s) l then 1 else 0)).
656
+ 2: { intros l Hl. rewrite count_srcs by lia. rewrite Hu, Hn, andb_true_r. reflexivity. }
657
+ rewrite sum_indicator. destruct (Nat.ltb_spec (dep s) dmax) as [Hlt|Hge].
658
+ + replace ((1 <=? dep s) && (dep s <? 1 + (dmax - 1))) with true
659
+ by (symmetry; apply andb_true_iff; split; [apply Nat.leb_le | apply Nat.ltb_lt]; lia).
660
+ destruct (Nat.eqb_spec (dep s) dmax); [lia | reflexivity].
661
+ + replace ((1 <=? dep s) && (dep s <? 1 + (dmax - 1))) with false
662
+ by (symmetry; apply andb_false_iff; right; apply Nat.ltb_ge; lia).
663
+ destruct (Nat.eqb_spec (dep s) dmax); [reflexivity | lia].
664
+ - rewrite sum_zero by (intros l _; rewrite count_srcs by lia; rewrite Hn, andb_false_r; reflexivity).
665
+ destruct (Nat.eqb (dep s) dmax); [|reflexivity]. rewrite filter_none; [reflexivity|].
666
+ intros a Ha E. subst a. rewrite (need_nx s Ha) in Hn. discriminate.
667
+ Qed.
668
+
669
+ (* the number of rows of each layer *)
670
+ Theorem lev_widths : length nx = n -> map (@length tu) lev = map width (seq 1 (dmax - 1)) ++ [n].
671
+ Proof.
672
+ intro Hlen. unfold lev, lsrc. rewrite map_app, map_app, !map_map. cbn [map fst snd]. f_equal.
673
+ - apply map_ext_in. intros l Hl. apply in_seq in Hl. unfold srcs. rewrite !length_map.
674
+ destruct l as [|l]; [lia | reflexivity].
675
+ - unfold srcd. rewrite !length_map, length_seq. reflexivity.
676
+ Qed.
677
+
678
+ (* the size of the layered map: its rows are those of the layers 1 .. d - 1 and one for each state bit *)
679
+ Theorem lev_size : length nx = n ->
680
+ fold_right Nat.add 0 (map (@length tu) lev) = fold_right Nat.add 0 (map width (seq 1 (dmax - 1))) + n.
681
+ Proof.
682
+ intro Hlen. unfold lev, lsrc. rewrite map_app, map_app, fold_right_app, !map_map. cbn [map fold_right fst snd].
683
+ unfold srcd. rewrite !length_map, length_seq.
684
+ assert (G : forall (L : list nat) c, (forall l, In l L -> 1 <= l) ->
685
+ fold_right Nat.add c (map (fun l => length (map (mkrow l) (srcs l))) L) = fold_right Nat.add 0 (map width L) + c).
686
+ { intros L c HL. induction L as [|a t IH]; [reflexivity|]. cbn [map fold_right].
687
+ rewrite IH by (intros l Hl; apply HL; right; exact Hl). unfold srcs. rewrite !length_map.
688
+ destruct a as [|a]; [specialize (HL 0 (or_introl eq_refl)); lia|]. cbn [width]. lia. }
689
+ rewrite G by (intros l Hl; apply in_seq in Hl; lia). lia.
690
+ Qed.
691
+
692
+ End Lev.
rocq/Lower.v ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* Depth lower bounds (Section 3): no threshold unit, whatever its real weights, reads a memory word or
2
+ computes a one-hot disjunction of conjunctions (Lemma 3.6), and no ternary unit computes the branch
3
+ predicate on three or more bits, which one unit with integer weights computes (Remark 3.4). *)
4
+ From Stdlib Require Import Reals Lra ZArith Lia List Bool.
5
+ Import ListNotations.
6
+
7
+ (* ---- units with real weights ------------------------------------------------------------------------------ *)
8
+ (* the pre-activation without bias of the unit with weights w on the inputs x_i, i in l *)
9
+ Fixpoint rsum (w : nat -> R) (x : nat -> bool) (l : list nat) : R :=
10
+ match l with [] => 0%R | i :: t => ((if x i then w i else 0) + rsum w x t)%R end.
11
+
12
+ Definition rfire (N : nat) (w : nat -> R) (b : R) (x : nat -> bool) : bool :=
13
+ if Rle_dec 0 (rsum w x (seq 0 N) + b) then true else false.
14
+
15
+ (* two inputs whose ones, counted with multiplicity, are those of two others have the same summed sums *)
16
+ Lemma rsum_swap : forall w x1 x2 x3 x4 l,
17
+ (forall i, (Nat.b2n (x1 i) + Nat.b2n (x2 i) = Nat.b2n (x3 i) + Nat.b2n (x4 i))%nat) ->
18
+ (rsum w x1 l + rsum w x2 l = rsum w x3 l + rsum w x4 l)%R.
19
+ Proof.
20
+ intros w x1 x2 x3 x4 l H. induction l as [|i t IH]; cbn [rsum]; [lra|].
21
+ specialize (H i). destruct (x1 i), (x2 i), (x3 i), (x4 i); cbn [Nat.b2n] in H; try lia; lra.
22
+ Qed.
23
+
24
+ Lemma rfire_swap : forall N w b x1 x2 x3 x4,
25
+ (forall i, (Nat.b2n (x1 i) + Nat.b2n (x2 i) = Nat.b2n (x3 i) + Nat.b2n (x4 i))%nat) ->
26
+ rfire N w b x1 = true -> rfire N w b x2 = true -> rfire N w b x3 = false -> rfire N w b x4 = false -> False.
27
+ Proof.
28
+ intros N w b x1 x2 x3 x4 H. unfold rfire. pose proof (rsum_swap w x1 x2 x3 x4 (seq 0 N) H).
29
+ destruct (Rle_dec 0 (rsum w x1 (seq 0 N) + b)), (Rle_dec 0 (rsum w x2 (seq 0 N) + b)),
30
+ (Rle_dec 0 (rsum w x3 (seq 0 N) + b)), (Rle_dec 0 (rsum w x4 (seq 0 N) + b));
31
+ intros; try discriminate; lra.
32
+ Qed.
33
+
34
+ (* ---- Lemma 3.6 --------------------------------------------------------------------------------------------- *)
35
+ (* the address alpha in the inputs 0 .. A - 1, least significant first, the words mu in the inputs A .. *)
36
+ Fixpoint bval (x : nat -> bool) (k : nat) : nat :=
37
+ match k with O => 0 | S k' => bval x k' + Nat.b2n (x k') * 2 ^ k' end.
38
+
39
+ Definition select (A : nat) (x : nat -> bool) : bool := x (A + bval x A)%nat.
40
+
41
+ Lemma bval_low : forall x k, (forall i, (1 <= i)%nat -> x i = false) -> bval x k = match k with O => O | S _ => Nat.b2n (x 0%nat) end.
42
+ Proof.
43
+ intros x k H. induction k as [|k IH]; [reflexivity|]. cbn [bval]. rewrite IH.
44
+ destruct k as [|k]; [cbn; lia|]. rewrite (H (S k)) by lia. cbn [Nat.b2n]. lia.
45
+ Qed.
46
+
47
+ Theorem read_needs_two_levels : forall A w b, (1 <= A)%nat ->
48
+ ~ (forall x, rfire (A + 2 ^ A) w b x = select A x).
49
+ Proof.
50
+ intros A w b HA H.
51
+ set (pt := fun (a m0 m1 : bool) i => (a && Nat.eqb i 0) || (m0 && Nat.eqb i A) || (m1 && Nat.eqb i (S A))).
52
+ assert (Hlow : forall a m0 m1 i, (1 <= i)%nat -> (i < A)%nat -> pt a m0 m1 i = false).
53
+ { intros a m0 m1 i H1 H2. unfold pt. destruct (Nat.eqb_spec i 0), (Nat.eqb_spec i A), (Nat.eqb_spec i (S A));
54
+ try lia; rewrite !andb_false_r; reflexivity. }
55
+ assert (Hsel : forall a m0 m1, select A (pt a m0 m1) = if a then m1 else m0).
56
+ { intros a m0 m1. unfold select.
57
+ assert (E : bval (pt a m0 m1) A = Nat.b2n a).
58
+ { assert (G : forall k, (k <= A)%nat -> bval (pt a m0 m1) k = match k with O => O | S _ => Nat.b2n a end).
59
+ { induction k as [|k IH]; intros Hk; [reflexivity|]. cbn [bval]. rewrite IH by lia.
60
+ destruct k as [|k].
61
+ - unfold pt. rewrite Nat.eqb_refl. destruct (Nat.eqb_spec 0 A), (Nat.eqb_spec 0 (S A)); try lia.
62
+ rewrite !andb_false_r, !orb_false_r, andb_true_r. destruct a; reflexivity.
63
+ - rewrite (Hlow a m0 m1 (S k)) by lia. cbn [Nat.b2n]. lia. }
64
+ rewrite (G A (le_n _)). destruct A; [lia | reflexivity]. }
65
+ rewrite E. unfold pt. destruct a; cbn [Nat.b2n].
66
+ - replace (A + 1)%nat with (S A) by lia. rewrite Nat.eqb_refl.
67
+ destruct (Nat.eqb_spec (S A) 0), (Nat.eqb_spec (S A) A); try lia. rewrite !andb_false_r, andb_true_r. reflexivity.
68
+ - rewrite Nat.add_0_r, Nat.eqb_refl. destruct (Nat.eqb_spec A 0), (Nat.eqb_spec A (S A)); try lia.
69
+ rewrite !andb_false_r, andb_true_r, orb_false_r. reflexivity. }
70
+ apply (rfire_swap (A + 2 ^ A) w b (pt false true false) (pt true false true) (pt false false true) (pt true true false)).
71
+ - intro i. unfold pt. destruct (Nat.eqb_spec i 0), (Nat.eqb_spec i A), (Nat.eqb_spec i (S A));
72
+ cbn [andb orb Nat.b2n]; lia.
73
+ - rewrite H, Hsel. reflexivity.
74
+ - rewrite H, Hsel. reflexivity.
75
+ - rewrite H, Hsel. reflexivity.
76
+ - rewrite H, Hsel. reflexivity.
77
+ Qed.
78
+
79
+ (* the one-hot form: the lines s in the inputs 0 .. n - 1, the bits mu in the inputs n .. 2n - 1 *)
80
+ Definition onehot (n : nat) (x : nat -> bool) : Prop := exists j, (j < n)%nat /\ forall i, (i < n)%nat -> x i = Nat.eqb i j.
81
+
82
+ Definition orsel (n : nat) (x : nat -> bool) : bool := existsb (fun j => x j && x (n + j)%nat) (seq 0 n).
83
+
84
+ Theorem onehot_needs_two_levels : forall n w b, (2 <= n)%nat ->
85
+ ~ (forall x, onehot n x -> rfire (n + n) w b x = orsel n x).
86
+ Proof.
87
+ intros n w b Hn H.
88
+ set (pt := fun (s m : nat) i => Nat.eqb i s || Nat.eqb i (n + m)%nat).
89
+ assert (Hoh : forall s m, (s < n)%nat -> onehot n (pt s m)).
90
+ { intros s m Hs. exists s. split; [exact Hs|]. intros i Hi. unfold pt.
91
+ destruct (Nat.eqb_spec i (n + m)); [lia|]. apply orb_false_r. }
92
+ assert (Hval : forall s m, (s < 2)%nat -> (m < 2)%nat -> orsel n (pt s m) = Nat.eqb s m).
93
+ { intros s m Hs Hm. unfold orsel, pt.
94
+ destruct (Nat.eqb_spec s m) as [<-|E].
95
+ - apply existsb_exists. exists s. split; [apply in_seq; lia|]. rewrite !Nat.eqb_refl, orb_true_l, orb_true_r.
96
+ reflexivity.
97
+ - apply not_true_is_false. intro Hx. apply existsb_exists in Hx as (j & Hj & Hx). apply in_seq in Hj.
98
+ apply andb_true_iff in Hx as [H1 H2]. apply orb_true_iff in H1, H2.
99
+ destruct H1 as [H1|H1], H2 as [H2|H2]; apply Nat.eqb_eq in H1, H2; lia. }
100
+ apply (rfire_swap (n + n) w b (pt 0 0) (pt 1 1) (pt 0 1) (pt 1 0))%nat.
101
+ - intro i. unfold pt. destruct (Nat.eqb_spec i 0), (Nat.eqb_spec i 1), (Nat.eqb_spec i (n + 0)),
102
+ (Nat.eqb_spec i (n + 1)); cbn; lia.
103
+ - rewrite H by (apply Hoh; lia). rewrite Hval by lia. reflexivity.
104
+ - rewrite H by (apply Hoh; lia). rewrite Hval by lia. reflexivity.
105
+ - rewrite H by (apply Hoh; lia). rewrite Hval by lia. reflexivity.
106
+ - rewrite H by (apply Hoh; lia). rewrite Hval by lia. reflexivity.
107
+ Qed.
108
+
109
+ (* ---- Remark 3.4 ------------------------------------------------------------------------------------------- *)
110
+ Open Scope Z_scope.
111
+
112
+ Fixpoint zsum (w : nat -> Z) (x : nat -> bool) (l : list nat) : Z :=
113
+ match l with [] => 0 | i :: t => (if x i then w i else 0) + zsum w x t end.
114
+
115
+ Definition zfire (n : nat) (w : nat -> Z) (b : Z) (x : nat -> bool) : bool := Z.leb 0 (zsum w x (seq 0 n) + b).
116
+
117
+ (* the value of r_0 .. r_(n-1) in two's complement, and the branch predicate [value <= 0] *)
118
+ Fixpoint uval (r : nat -> bool) (k : nat) : Z :=
119
+ match k with O => 0 | S k' => uval r k' + Z.b2z (r k') * 2 ^ Z.of_nat k' end.
120
+
121
+ Definition tval (n : nat) (r : nat -> bool) : Z := uval r (n - 1) - Z.b2z (r (n - 1)%nat) * 2 ^ Z.of_nat (n - 1).
122
+
123
+ Definition branch (n : nat) (r : nat -> bool) : bool := Z.leb (tval n r) 0.
124
+
125
+ (* with integer weights one unit computes it *)
126
+ Lemma branch_one_unit : forall n r,
127
+ branch n r = Z.leb 0 (Z.b2z (r (n - 1)%nat) * 2 ^ Z.of_nat (n - 1) - uval r (n - 1)).
128
+ Proof. intros n r. unfold branch, tval. apply eq_true_iff_eq. rewrite !Z.leb_le. lia. Qed.
129
+
130
+ Lemma zsum_ext : forall w x x' l, (forall i, In i l -> x i = x' i) -> zsum w x l = zsum w x' l.
131
+ Proof.
132
+ intros w x x' l H. induction l as [|i t IH]; cbn [zsum]; [reflexivity|].
133
+ rewrite (H i (or_introl eq_refl)), IH by (intros j Hj; apply H; right; exact Hj). reflexivity.
134
+ Qed.
135
+
136
+ Lemma zsum_zero : forall w l, zsum w (fun _ => false) l = 0.
137
+ Proof. intros w l. induction l as [|i t IH]; cbn [zsum]; lia. Qed.
138
+
139
+ Lemma zsum_one : forall w k l, NoDup l -> In k l -> zsum w (fun i => Nat.eqb i k) l = w k.
140
+ Proof.
141
+ intros w k l Hnd. induction Hnd as [|i t Hi Hnd IH]; intros Hk; [destruct Hk|]. cbn [zsum].
142
+ destruct (Nat.eqb_spec i k) as [->|E].
143
+ - rewrite (zsum_ext w _ (fun _ => false)), zsum_zero; [lia|].
144
+ intros j Hj. destruct (Nat.eqb_spec j k); [subst; contradiction | reflexivity].
145
+ - destruct Hk as [Hk|Hk]; [contradiction|]. rewrite IH by exact Hk. lia.
146
+ Qed.
147
+
148
+ Lemma zsum_all : forall w l, zsum w (fun _ => true) l = fold_right Z.add 0 (map w l).
149
+ Proof. intros w l. induction l as [|i t IH]; cbn [zsum map fold_right]; lia. Qed.
150
+
151
+ Lemma uval_ext : forall r r' k, (forall i, (i < k)%nat -> r i = r' i) -> uval r k = uval r' k.
152
+ Proof.
153
+ intros r r' k H. induction k as [|k IH]; cbn [uval]; [reflexivity|].
154
+ rewrite IH by (intros i Hi; apply H; lia). rewrite (H k) by lia. reflexivity.
155
+ Qed.
156
+
157
+ Lemma uval_one : forall j k, (j < k)%nat -> uval (fun i => Nat.eqb i j) k = 2 ^ Z.of_nat j.
158
+ Proof.
159
+ intros j k Hjk. induction k as [|k IH]; [lia|]. cbn [uval].
160
+ destruct (Nat.eqb_spec k j) as [->|E].
161
+ - rewrite (uval_ext _ (fun _ => false)).
162
+ + assert (Z0 : forall m, uval (fun _ => false) m = 0) by (induction m as [|m IHm]; cbn [uval]; [reflexivity | rewrite IHm; reflexivity]).
163
+ rewrite Z0. cbn [Z.b2z]. lia.
164
+ + intros i Hi. destruct (Nat.eqb_spec i j); [lia | reflexivity].
165
+ - rewrite IH by lia. cbn [Z.b2z]. lia.
166
+ Qed.
167
+
168
+ Lemma uval_all : forall k, uval (fun _ => true) k = 2 ^ Z.of_nat k - 1.
169
+ Proof.
170
+ induction k as [|k IH]; cbn [uval]; [reflexivity|]. rewrite IH. cbn [Z.b2z].
171
+ rewrite Nat2Z.inj_succ, Z.pow_succ_r by lia. lia.
172
+ Qed.
173
+
174
+ Lemma sum_ternary_lower : forall (w : nat -> Z) (l : list nat), (forall i, In i l -> w i = -1) -> fold_right Z.add 0 (map w l) = - Z.of_nat (length l).
175
+ Proof.
176
+ intros w l H. induction l as [|i t IH]; cbn [map fold_right length]; [reflexivity|].
177
+ rewrite (H i (or_introl eq_refl)), IH by (intros j Hj; apply H; right; exact Hj). lia.
178
+ Qed.
179
+
180
+ Theorem branch_not_ternary : forall n w b, (3 <= n)%nat -> (forall i, -1 <= w i <= 1) ->
181
+ ~ (forall r, zfire n w b r = branch n r).
182
+ Proof.
183
+ intros n w b Hn Hw H.
184
+ (* r = 0 has value 0, so b >= 0 *)
185
+ assert (Hb : 0 <= b).
186
+ { specialize (H (fun _ => false)). unfold zfire, branch, tval in H. rewrite zsum_zero in H.
187
+ assert (Z0 : forall m, uval (fun _ => false) m = 0) by (induction m as [|m IHm]; cbn [uval]; [reflexivity | rewrite IHm; reflexivity]).
188
+ rewrite Z0 in H. cbn [Z.b2z] in H. replace (0 - 0 * 2 ^ Z.of_nat (n - 1)) with 0 in H by lia.
189
+ cbn in H. apply Z.leb_le. rewrite H. reflexivity. }
190
+ (* each unit vector e_i, i < n - 1, has value 2^i > 0, so w_i = -1 and b = 0 *)
191
+ assert (He : forall i, (i < n - 1)%nat -> w i + b < 0).
192
+ { intros i Hi. specialize (H (fun k => Nat.eqb k i)). unfold zfire, branch, tval in H.
193
+ rewrite zsum_one in H by (apply seq_NoDup || (apply in_seq; lia)).
194
+ rewrite uval_one in H by exact Hi. destruct (Nat.eqb_spec (n - 1) i) as [E|E]; [lia|]. cbn [Z.b2z] in H.
195
+ assert (P : 0 < 2 ^ Z.of_nat i) by (apply Z.pow_pos_nonneg; lia).
196
+ replace (2 ^ Z.of_nat i - 0 * 2 ^ Z.of_nat (n - 1) <=? 0) with false in H
197
+ by (symmetry; apply Z.leb_gt; lia).
198
+ apply Z.leb_gt. exact H. }
199
+ assert (Hw1 : forall i, (i < n - 1)%nat -> w i = -1) by (intros i Hi; specialize (He i Hi); specialize (Hw i); lia).
200
+ assert (Hb0 : b = 0) by (specialize (He 0%nat ltac:(lia)); rewrite Hw1 in He by lia; lia).
201
+ (* the vector of ones has value -1, so w_(n-1) >= n - 1 >= 2 *)
202
+ specialize (H (fun _ => true)). unfold zfire, branch, tval in H.
203
+ rewrite zsum_all, uval_all in H. cbn [Z.b2z] in H.
204
+ replace (seq 0 n) with (seq 0 (n - 1) ++ [(n - 1)%nat]) in H
205
+ by (replace n with (S (n - 1)) at 3 by lia; rewrite seq_S; reflexivity).
206
+ rewrite map_app, fold_right_app in H. cbn [map fold_right] in H.
207
+ assert (Hs : forall (l : list Z) c, fold_right Z.add c l = fold_right Z.add 0 l + c).
208
+ { intros l c. induction l as [|y t IH]; cbn [fold_right]; lia. }
209
+ rewrite Hs, sum_ternary_lower, length_seq in H by (intros i Hi; apply in_seq in Hi; apply Hw1; lia).
210
+ replace (2 ^ Z.of_nat (n - 1) - 1 - 1 * 2 ^ Z.of_nat (n - 1) <=? 0) with true in H by (symmetry; apply Z.leb_le; lia).
211
+ apply Z.leb_le in H. specialize (Hw (n - 1)%nat). lia.
212
+ Qed.
rocq/Margin.v ADDED
@@ -0,0 +1,781 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* Section 6, the deterministic part: an orbit of integer pre-activations survives every perturbation below one half
2
+ (Theorem 6.2), weight and bias errors (Proposition 6.3), and the r-fold amplification, which multiplies every margin
3
+ by r (Definition 6.6, Proposition 6.7, Theorem 6.8 (i)). *)
4
+ From Stdlib Require Import List Bool Arith ZArith Reals Lia Lra.
5
+ Import ListNotations.
6
+ From TH Require Import TwoHead Net Lev.
7
+
8
+ Local Open Scope R_scope.
9
+
10
+ (* ---- thresholding at -1/2 ------------------------------------------------------------------------------------ *)
11
+ Definition H12 (z : R) : bool := if Rle_dec (-1/2) z then true else false.
12
+
13
+ (* a perturbation e fails a row of integer pre-activation z when it carries z across -1/2 *)
14
+ Definition fails (z : Z) (e : R) : Prop :=
15
+ ((0 <= z)%Z /\ IZR z + e < -1/2) \/ ((z <= -1)%Z /\ -1/2 <= IZR z + e).
16
+
17
+ Lemma H12_ok : forall z e, ~ fails z e -> H12 (IZR z + e) = Z.leb 0 z.
18
+ Proof.
19
+ intros z e Hf. unfold H12.
20
+ destruct (Rle_dec (-1/2) (IZR z + e)) as [H|H]; destruct (Z.leb_spec 0 z) as [Hz|Hz]; try reflexivity.
21
+ - exfalso. apply Hf. right. split; [lia | exact H].
22
+ - exfalso. apply Hf. left. split; [exact Hz | lra].
23
+ Qed.
24
+
25
+ (* the distance of an integer pre-activation from the comparator is at least 1/2 *)
26
+ Lemma dist_half : forall z : Z, 1/2 <= Rabs (IZR z + 1/2).
27
+ Proof.
28
+ intro z. destruct (Z.le_gt_cases 0 z) as [Hz|Hz].
29
+ - apply IZR_le in Hz. rewrite Rabs_right by lra. lra.
30
+ - assert (Hz' : (z <= -1)%Z) by lia. apply IZR_le in Hz'. rewrite Rabs_left by lra. lra.
31
+ Qed.
32
+
33
+ (* a perturbation smaller than the distance from the comparator never fails *)
34
+ Lemma no_fail : forall z e, Rabs e < Rabs (IZR z + 1/2) -> ~ fails z e.
35
+ Proof.
36
+ intros z e H [[Hz Hl]|[Hz Hl]].
37
+ - apply IZR_le in Hz. rewrite (Rabs_right (IZR z + 1/2)) in H by lra.
38
+ pose proof (Rle_abs (- e)) as Ha. rewrite Rabs_Ropp in Ha. lra.
39
+ - apply IZR_le in Hz. rewrite (Rabs_left (IZR z + 1/2)) in H by lra. pose proof (Rle_abs e). lra.
40
+ Qed.
41
+
42
+ Lemma no_fail_half : forall z e, Rabs e < 1/2 -> ~ fails z e.
43
+ Proof. intros z e H. apply no_fail. pose proof (dist_half z). lra. Qed.
44
+
45
+ (* a perturbation of +1/2 at a row of pre-activation -1 changes its output *)
46
+ Lemma half_tight : H12 (IZR (-1) + 1/2) <> Z.leb 0 (-1).
47
+ Proof. unfold H12. destruct (Rle_dec (-1/2) (IZR (-1) + 1/2)) as [H|H]; [discriminate | exfalso; apply H; lra]. Qed.
48
+
49
+ (* ---- perturbed layers and maps (Definition 6.1) ---------------------------------------------------------------- *)
50
+ Definition pre (u : tu) (y : list bool) : Z := (tb u + wsum (tin u) (fun i => nth i y false))%Z.
51
+
52
+ (* a layer whose row i is perturbed by e i, which may depend on the input *)
53
+ Definition lfirep (L : list tu) (e : nat -> list bool -> R) (y : list bool) : list bool :=
54
+ map (fun i => H12 (IZR (pre (nth i L tu0) y) + e i y)) (seq 0 (length L)).
55
+
56
+ Lemma map_seq_nth : forall (A B : Type) (f : A -> B) l d, map f l = map (fun i => f (nth i l d)) (seq 0 (length l)).
57
+ Proof.
58
+ intros A B f l d. induction l as [|a t IH]; [reflexivity|]. cbn [map length seq nth]. f_equal.
59
+ rewrite IH, <- seq_shift, map_map. reflexivity.
60
+ Qed.
61
+
62
+ Lemma lfire_seq : forall L y, lfire L y = map (fun i => Z.leb 0 (pre (nth i L tu0) y)) (seq 0 (length L)).
63
+ Proof. intros L y. unfold lfire. rewrite (map_seq_nth _ _ _ L tu0). reflexivity. Qed.
64
+
65
+ Lemma lfirep_ok : forall L e y, (forall i, (i < length L)%nat -> ~ fails (pre (nth i L tu0) y) (e i y)) ->
66
+ lfirep L e y = lfire L y.
67
+ Proof.
68
+ intros L e y H. rewrite lfire_seq. unfold lfirep. apply map_ext_in. intros i Hi. apply in_seq in Hi.
69
+ apply H12_ok. apply H. lia.
70
+ Qed.
71
+
72
+ (* the layers from l on, layer l + k perturbed by E (l + k) *)
73
+ Fixpoint lmapp (Ls : list (list tu)) (l : nat) (E : nat -> nat -> list bool -> R) (y : list bool) : list bool :=
74
+ match Ls with [] => y | L :: t => lmapp t (S l) E (lfirep L (E l) y) end.
75
+
76
+ (* the input of layer l on the orbit *)
77
+ Definition lin (Ls : list (list tu)) (x : list bool) (l : nat) : list bool := lmap (firstn l Ls) x.
78
+
79
+ Lemma lmapp_ok : forall Ls l E x,
80
+ (forall k i, (k < length Ls)%nat -> (i < length (nth k Ls []))%nat ->
81
+ ~ fails (pre (nth i (nth k Ls []) tu0) (lin Ls x k)) (E (l + k)%nat i (lin Ls x k))) ->
82
+ lmapp Ls l E x = lmap Ls x.
83
+ Proof.
84
+ induction Ls as [|L t IH]; intros l E x H; [reflexivity|]. cbn [lmapp].
85
+ rewrite lfirep_ok.
86
+ - unfold lmap. cbn [fold_left]. apply (IH (S l) E (lfire L x)). intros k i Hk Hi.
87
+ specialize (H (S k) i ltac:(cbn [length]; lia) Hi). replace (S l + k)%nat with (l + S k)%nat by lia. exact H.
88
+ - intros i Hi. specialize (H 0%nat i ltac:(cbn [length]; lia) Hi). rewrite Nat.add_0_r in H. exact H.
89
+ Qed.
90
+
91
+ (* ---- trajectories ------------------------------------------------------------------------------------------------ *)
92
+ Fixpoint trajp (Ls : list (list tu)) (E : nat -> nat -> nat -> list bool -> R) (x0 : list bool) (t : nat) : list bool :=
93
+ match t with O => x0 | S t' => lmapp Ls 0 (E t') (trajp Ls E x0 t') end.
94
+
95
+ Definition orbit (Ls : list (list tu)) (x0 : list bool) (t : nat) : list bool := Nat.iter t (lmap Ls) x0.
96
+
97
+ (* the layers read the perturbations of their own rows only *)
98
+ Lemma lmapp_ext : forall Ls l E1 E2 y,
99
+ (forall k i y', (k < length Ls)%nat -> (i < length (nth k Ls []))%nat -> E1 (l + k)%nat i y' = E2 (l + k)%nat i y') ->
100
+ lmapp Ls l E1 y = lmapp Ls l E2 y.
101
+ Proof.
102
+ induction Ls as [|L t IH]; intros l E1 E2 y H; [reflexivity|]. cbn [lmapp].
103
+ replace (lfirep L (E1 l) y) with (lfirep L (E2 l) y).
104
+ - apply IH. intros k i y' Hk Hi. replace (S l + k)%nat with (l + S k)%nat by lia. apply H; cbn [length nth]; lia || exact Hi.
105
+ - unfold lfirep. apply map_ext_in. intros i Hi. apply in_seq in Hi. f_equal. f_equal. symmetry.
106
+ rewrite <- (Nat.add_0_r l) at 1 2. apply H; cbn [length nth]; lia.
107
+ Qed.
108
+
109
+ Lemma trajp_ext : forall Ls E1 E2 x0 t,
110
+ (forall t' l i y, (t' < t)%nat -> (l < length Ls)%nat -> (i < length (nth l Ls []))%nat -> E1 t' l i y = E2 t' l i y) ->
111
+ trajp Ls E1 x0 t = trajp Ls E2 x0 t.
112
+ Proof.
113
+ intros Ls E1 E2 x0 t. induction t as [|t IH]; intro H; [reflexivity|]. cbn [trajp].
114
+ rewrite IH by (intros t' l i y Ht' Hl Hi; apply H; lia || assumption). apply lmapp_ext.
115
+ intros k i y' Hk Hi. apply H; lia || assumption.
116
+ Qed.
117
+
118
+ (* row i of layer l fails at step t when its perturbation, on the input the orbit gives it, crosses -1/2 *)
119
+ Definition rfail (Ls : list (list tu)) (E : nat -> nat -> nat -> list bool -> R) (x0 : list bool) (t l i : nat) : Prop :=
120
+ fails (pre (nth i (nth l Ls []) tu0) (lin Ls (orbit Ls x0 t) l)) (E t l i (lin Ls (orbit Ls x0 t) l)).
121
+
122
+ (* if no row of the first T steps fails, the trajectory follows the orbit for T steps *)
123
+ Theorem traj_ok : forall Ls E x0 T,
124
+ (forall t l i, (t < T)%nat -> (l < length Ls)%nat -> (i < length (nth l Ls []))%nat -> ~ rfail Ls E x0 t l i) ->
125
+ forall t, (t <= T)%nat -> trajp Ls E x0 t = orbit Ls x0 t.
126
+ Proof.
127
+ intros Ls E x0 T H. induction t as [|t IH]; intro Ht; [reflexivity|].
128
+ cbn [trajp]. rewrite IH by lia. cbn [orbit Nat.iter]. apply lmapp_ok.
129
+ intros k i Hk Hi. exact (H t k i ltac:(lia) Hk Hi).
130
+ Qed.
131
+
132
+ (* Theorem 6.2: perturbations below 1/2 leave every orbit exact *)
133
+ Theorem margin : forall Ls E x0 eps, eps < 1/2 -> (forall t l i y, Rabs (E t l i y) <= eps) ->
134
+ forall t, trajp Ls E x0 t = orbit Ls x0 t.
135
+ Proof.
136
+ intros Ls E x0 eps He HE t. apply (traj_ok Ls E x0 t); [|lia].
137
+ intros t' l i _ _ _. apply no_fail_half. specialize (HE t' l i (lin Ls (orbit Ls x0 t') l)). lra.
138
+ Qed.
139
+
140
+ (* the constant 1/2 cannot be increased *)
141
+ Theorem margin_tight : forall u y, pre u y = (-1)%Z -> H12 (IZR (pre u y) + 1/2) <> Z.leb 0 (pre u y).
142
+ Proof. intros u y E. rewrite E. exact half_tight. Qed.
143
+
144
+ (* ---- weight and bias errors (Proposition 6.3) ------------------------------------------------------------------- *)
145
+ Fixpoint rsum (k : nat) (g : nat -> R) : R := match k with O => 0 | S k' => rsum k' g + g k' end.
146
+
147
+ Lemma rsum_le : forall k g h, (forall j, (j < k)%nat -> g j <= h j) -> rsum k g <= rsum k h.
148
+ Proof. induction k as [|k IH]; intros g h H; cbn [rsum]; [lra|]. pose proof (IH g h (fun j Hj => H j ltac:(lia))). pose proof (H k ltac:(lia)). lra. Qed.
149
+
150
+ Lemma rsum_abs : forall k g, Rabs (rsum k g) <= rsum k (fun j => Rabs (g j)).
151
+ Proof.
152
+ induction k as [|k IH]; intro g; cbn [rsum]; [rewrite Rabs_R0; lra|].
153
+ pose proof (Rabs_triang (rsum k g) (g k)). pose proof (IH g). lra.
154
+ Qed.
155
+
156
+ (* the number of j < k with f j *)
157
+ Fixpoint ncnt (k : nat) (f : nat -> bool) : nat := match k with O => O | S k' => (ncnt k' f + if f k' then 1 else 0)%nat end.
158
+
159
+ Definition b2r (b : bool) : R := if b then 1 else 0.
160
+
161
+ Lemma rsum_cnt : forall k (p b : nat -> bool) a c,
162
+ rsum k (fun j => (if p j then a else c) * b2r (b j)) = INR (ncnt k (fun j => p j && b j)) * a
163
+ + INR (ncnt k (fun j => negb (p j) && b j)) * c.
164
+ Proof.
165
+ induction k as [|k IH]; intros p b a c; cbn [rsum ncnt]; [cbn [INR]; lra|]. rewrite IH, !plus_INR.
166
+ unfold b2r. destruct (p k), (b k); cbn [andb negb INR]; lra.
167
+ Qed.
168
+
169
+ Lemma rsum_cnt1 : forall k (p : nat -> bool) a c,
170
+ rsum k (fun j => if p j then a else c) = INR (ncnt k p) * a + INR (ncnt k (fun j => negb (p j))) * c.
171
+ Proof.
172
+ induction k as [|k IH]; intros p a c; cbn [rsum ncnt]; [cbn [INR]; lra|]. rewrite IH, !plus_INR.
173
+ destruct (p k); cbn [negb INR]; lra.
174
+ Qed.
175
+
176
+ Lemma firstn_snoc : forall (A : Type) (l : list A) k d, (k < length l)%nat -> firstn (S k) l = firstn k l ++ [nth k l d].
177
+ Proof.
178
+ intros A l. induction l as [|a t IH]; intros k d Hk; [cbn [length] in Hk; lia|].
179
+ destruct k as [|k]; [reflexivity|]. change (firstn (S (S k)) (a :: t)) with (a :: firstn (S k) t).
180
+ rewrite (IH k d) by (cbn [length] in Hk; lia). reflexivity.
181
+ Qed.
182
+
183
+ Lemma last_nth' : forall (A : Type) (l : list A) d, l <> [] -> last l d = nth (length l - 1) l d.
184
+ Proof.
185
+ intros A l d. induction l as [|a t IH]; intro H; [contradiction|]. destruct t as [|b t]; [reflexivity|].
186
+ change (last (a :: b :: t) d) with (last (b :: t) d). rewrite IH by discriminate. cbn [length].
187
+ replace (S (S (length t)) - 1)%nat with (S (S (length t) - 1)) by lia. reflexivity.
188
+ Qed.
189
+
190
+ Section Mismatch.
191
+ Variable Ls : list (list tu).
192
+ Variable n : nat.
193
+
194
+ (* the width of the input of layer l *)
195
+ Definition win (l : nat) : nat := match l with O => n | S l' => length (nth l' Ls []) end.
196
+ (* the entries row u programs: the inputs it reads with a nonzero weight *)
197
+ Definition prog (u : tu) (j : nat) : bool := existsb (fun p => Nat.eqb (fst p) j && negb (Z.eqb (snd p) 0)) (tin u).
198
+ Definition row (l i : nat) : tu := nth i (nth l Ls []) tu0.
199
+
200
+ Lemma lin_len : forall x l, length x = n -> (l <= length Ls)%nat -> length (lin Ls x l) = win l.
201
+ Proof.
202
+ intros x l Hx. induction l as [|l IH]; intro Hl; [exact Hx|].
203
+ unfold lin. rewrite (firstn_snoc _ Ls l []) by lia. rewrite lmap_app. unfold lfire. rewrite length_map. reflexivity.
204
+ Qed.
205
+
206
+ (* a map whose last layer has n rows keeps the orbits on n bits *)
207
+ Lemma orbit_len : length (last Ls []) = n -> Ls <> [] -> forall x0 t, length x0 = n -> length (orbit Ls x0 t) = n.
208
+ Proof.
209
+ intros Hlast Hne x0 t Hx. induction t as [|t IH]; [exact Hx|].
210
+ change (orbit Ls x0 (S t)) with (lmap Ls (orbit Ls x0 t)).
211
+ assert (E : lmap Ls (orbit Ls x0 t) = lin Ls (orbit Ls x0 t) (length Ls)) by (unfold lin; rewrite firstn_all; reflexivity).
212
+ rewrite E, lin_len by (exact IH || lia). rewrite <- Hlast, (last_nth' _ Ls []) by exact Hne.
213
+ destruct (length Ls) as [|m] eqn:Em; [destruct Ls; [contradiction | discriminate]|]. cbn [win].
214
+ replace (S m - 1)%nat with m by lia. reflexivity.
215
+ Qed.
216
+
217
+ (* the realized layers: row i of layer l reads input j with weight W_ij + D l i j and has bias b_i + be l i *)
218
+ Variables (D : nat -> nat -> nat -> R) (be : nat -> nat -> R) (eps gam eta : R).
219
+ Hypothesis HD : forall l i j, Rabs (D l i j) <= if prog (row l i) j then eps else gam.
220
+ Hypothesis Hbe : forall l i, Rabs (be l i) <= eta.
221
+
222
+ Definition rerr (t l i : nat) (y : list bool) : R := rsum (length y) (fun j => D l i j * b2r (nth j y false)) + be l i.
223
+
224
+ (* the error of a realized row: at most eps per active programmed input, gam per active other input, eta in the bias *)
225
+ Lemma rerr_bound : forall t l i y,
226
+ Rabs (rerr t l i y) <= eps * INR (ncnt (length y) (fun j => prog (row l i) j && nth j y false))
227
+ + gam * INR (ncnt (length y) (fun j => negb (prog (row l i) j) && nth j y false)) + eta.
228
+ Proof.
229
+ intros t l i y. unfold rerr. pose proof (Hbe l i).
230
+ pose proof (Rabs_triang (rsum (length y) (fun j => D l i j * b2r (nth j y false))) (be l i)).
231
+ pose proof (rsum_abs (length y) (fun j => D l i j * b2r (nth j y false))) as H1.
232
+ assert (H2 : rsum (length y) (fun j => Rabs (D l i j * b2r (nth j y false)))
233
+ <= rsum (length y) (fun j => (if prog (row l i) j then eps else gam) * b2r (nth j y false))).
234
+ { apply rsum_le. intros j _. rewrite Rabs_mult. unfold b2r. destruct (nth j y false).
235
+ - rewrite Rabs_R1, !Rmult_1_r. apply HD.
236
+ - rewrite Rabs_R0, !Rmult_0_r. lra. }
237
+ rewrite rsum_cnt in H2. lra.
238
+ Qed.
239
+
240
+ (* Proposition 6.3 (i): errors whose worst case stays below 1/2 in every row leave every orbit exact *)
241
+ Theorem mismatch_all : length (last Ls []) = n -> Ls <> [] -> 0 <= eps -> 0 <= gam ->
242
+ (forall l i, (l < length Ls)%nat -> (i < length (nth l Ls []))%nat ->
243
+ eps * INR (ncnt (win l) (prog (row l i))) + gam * INR (ncnt (win l) (fun j => negb (prog (row l i) j))) + eta < 1/2) ->
244
+ forall x0, length x0 = n -> forall t, trajp Ls rerr x0 t = orbit Ls x0 t.
245
+ Proof.
246
+ intros Hlast Hne He Hg H x0 Hx t. apply (traj_ok Ls rerr x0 t); [|lia]. intros t' l i _ Hl Hi. apply no_fail_half.
247
+ set (y := lin Ls (orbit Ls x0 t') l). pose proof (rerr_bound t' l i y) as B.
248
+ assert (Hy : length y = win l) by (apply lin_len; [apply orbit_len; assumption | lia]).
249
+ assert (C : INR (ncnt (length y) (fun j => prog (row l i) j && nth j y false)) * eps
250
+ + INR (ncnt (length y) (fun j => negb (prog (row l i) j) && nth j y false)) * gam
251
+ <= INR (ncnt (win l) (prog (row l i))) * eps + INR (ncnt (win l) (fun j => negb (prog (row l i) j))) * gam).
252
+ { rewrite <- rsum_cnt, <- rsum_cnt1, Hy. apply rsum_le. intros j _. unfold b2r.
253
+ destruct (prog (row l i) j), (nth j y false); lra. }
254
+ specialize (H l i Hl Hi). unfold rfail. fold y. lra.
255
+ Qed.
256
+
257
+ (* Proposition 6.3 (ii): along a run it suffices to bound the active inputs *)
258
+ Theorem mismatch_run : forall x0 T Kst Ast,
259
+ (forall t l i, (t < T)%nat -> (l < length Ls)%nat -> (i < length (nth l Ls []))%nat ->
260
+ let y := lin Ls (orbit Ls x0 t) l in
261
+ (ncnt (length y) (fun j => prog (row l i) j && nth j y false) <= Kst)%nat /\
262
+ (ncnt (length y) (fun j => negb (prog (row l i) j) && nth j y false) <= Ast)%nat) ->
263
+ 0 <= eps -> 0 <= gam -> eps * INR Kst + gam * INR Ast + eta < 1/2 ->
264
+ forall t, (t <= T)%nat -> trajp Ls rerr x0 t = orbit Ls x0 t.
265
+ Proof.
266
+ intros x0 T Kst Ast HK He Hg H. apply traj_ok. intros t l i Ht Hl Hi. apply no_fail_half.
267
+ destruct (HK t l i Ht Hl Hi) as [K1 A1]. apply le_INR in K1, A1.
268
+ pose proof (rerr_bound t l i (lin Ls (orbit Ls x0 t) l)) as B.
269
+ pose proof (Rmult_le_compat_l eps _ _ He K1). pose proof (Rmult_le_compat_l gam _ _ Hg A1). lra.
270
+ Qed.
271
+
272
+ End Mismatch.
273
+
274
+ (* ---- the r-fold amplification (Definition 6.6) ----------------------------------------------------------------- *)
275
+ (* rho_r: copy c of the state at positions c n, ..., c n + n - 1 *)
276
+ Definition rep (r : nat) (x : list bool) : list bool := concat (repeat x r).
277
+
278
+ (* row (c, i) reads every copy of input j with the weight of row i; its bias is r b + (r - 1)/2 *)
279
+ Definition arow (r w : nat) (u : tu) : tu :=
280
+ TU (Z.of_nat r * tb u + Z.of_nat ((r - 1) / 2))%Z
281
+ (concat (map (fun c => map (fun p => ((c * w + fst p)%nat, snd p)) (tin u)) (seq 0 r))).
282
+
283
+ (* copy c of row i at c |L| + i *)
284
+ Definition alayer (r w : nat) (L : list tu) : list tu := concat (repeat (map (arow r w) L) r).
285
+
286
+ Fixpoint amap (r w : nat) (Ls : list (list tu)) : list (list tu) :=
287
+ match Ls with [] => [] | L :: t => alayer r w L :: amap r (length L) t end.
288
+
289
+ Lemma length_rep : forall r x, length (rep r x) = (r * length x)%nat.
290
+ Proof. intros r x. unfold rep. induction r as [|r IH]; [reflexivity|]. cbn [repeat concat]. rewrite length_app, IH. lia. Qed.
291
+
292
+ Lemma nth_rep : forall r x c j, (c < r)%nat -> (j < length x)%nat -> nth (c * length x + j) (rep r x) false = nth j x false.
293
+ Proof.
294
+ intros r x c j Hc Hj. unfold rep. revert c Hc. induction r as [|r IH]; intros c Hc; [lia|]. cbn [repeat concat].
295
+ destruct c as [|c].
296
+ - rewrite app_nth1 by lia. reflexivity.
297
+ - rewrite app_nth2 by nia. replace (S c * length x + j - length x)%nat with (c * length x + j)%nat by nia. apply IH. lia.
298
+ Qed.
299
+
300
+ Lemma wsum_app : forall a b E, wsum (a ++ b) E = (wsum a E + wsum b E)%Z.
301
+ Proof. induction a as [|[i w] t IH]; intros b E; cbn [app wsum]; [reflexivity|]. rewrite IH. lia. Qed.
302
+
303
+ Lemma wsum_shift : forall ins k E, wsum (map (fun p => ((k + fst p)%nat, snd p)) ins) E = wsum ins (fun j => E (k + j)%nat).
304
+ Proof. induction ins as [|[i w] t IH]; intros k E; cbn [map wsum fst snd]; [reflexivity|]. rewrite IH. reflexivity. Qed.
305
+
306
+ Definition reads_lt (w : nat) (u : tu) : Prop := forall j z, In (j, z) (tin u) -> (j < w)%nat.
307
+
308
+ (* Proposition 6.7 (ii): on rho_r(y) the pre-activation of row (c, i) is r z + (r - 1)/2 *)
309
+ Lemma pre_arow : forall r u y, reads_lt (length y) u ->
310
+ pre (arow r (length y) u) (rep r y) = (Z.of_nat r * pre u y + Z.of_nat ((r - 1) / 2))%Z.
311
+ Proof.
312
+ intros r u y Hu. unfold pre, arow. cbn [tb tin].
313
+ assert (G : forall k, (k <= r)%nat -> wsum (concat (map (fun c => map (fun p => ((c * length y + fst p)%nat, snd p)) (tin u)) (seq 0 k)))
314
+ (fun i => nth i (rep r y) false) = (Z.of_nat k * wsum (tin u) (fun i => nth i y false))%Z).
315
+ { induction k as [|k IH]; intro Hk; [reflexivity|]. rewrite seq_S, map_app, concat_app, wsum_app, IH by lia.
316
+ cbn [map concat]. rewrite app_nil_r, (wsum_shift (tin u) (k * length y)).
317
+ rewrite (wsum_ext (tin u) (fun j => nth (k * length y + j) (rep r y) false) (fun i => nth i y false)).
318
+ - rewrite Nat2Z.inj_succ. lia.
319
+ - intros j z Hin. apply nth_rep; [lia | exact (Hu j z Hin)]. }
320
+ rewrite G by lia. lia.
321
+ Qed.
322
+
323
+ Lemma count_shift : forall r y c (ins : list (nat * Z)), (c < r)%nat -> (forall j z, In (j, z) ins -> (j < length y)%nat) ->
324
+ length (filter (fun p => nth (fst p) (rep r y) false) (map (fun p => ((c * length y + fst p)%nat, snd p)) ins))
325
+ = length (filter (fun p => nth (fst p) y false) ins).
326
+ Proof.
327
+ intros r y c ins Hc. induction ins as [|[j z] t IH]; intro H; [reflexivity|]. cbn [map filter fst].
328
+ rewrite nth_rep by (exact Hc || exact (H j z (or_introl eq_refl))).
329
+ assert (Ht : forall j' z', In (j', z') t -> (j' < length y)%nat) by (intros j' z' H'; exact (H j' z' (or_intror H'))).
330
+ destruct (nth j y false); cbn [length]; rewrite (IH Ht); reflexivity.
331
+ Qed.
332
+
333
+ (* on rho_r(y) the amplified row reads r times as many inputs holding 1 as the row reads on y *)
334
+ Lemma count_arow : forall r u y, reads_lt (length y) u ->
335
+ length (filter (fun p => nth (fst p) (rep r y) false) (tin (arow r (length y) u)))
336
+ = (r * length (filter (fun p => nth (fst p) y false) (tin u)))%nat.
337
+ Proof.
338
+ intros r u y Hu. unfold arow. cbn [tin].
339
+ assert (C : forall c, (c < r)%nat ->
340
+ length (filter (fun p => nth (fst p) (rep r y) false) (map (fun p => ((c * length y + fst p)%nat, snd p)) (tin u)))
341
+ = length (filter (fun p => nth (fst p) y false) (tin u))) by (intros c Hc; apply count_shift; assumption).
342
+ assert (G : forall k, (k <= r)%nat ->
343
+ length (filter (fun p => nth (fst p) (rep r y) false)
344
+ (concat (map (fun c => map (fun p => ((c * length y + fst p)%nat, snd p)) (tin u)) (seq 0 k))))
345
+ = (k * length (filter (fun p => nth (fst p) y false) (tin u)))%nat).
346
+ { induction k as [|k IH]; intro Hk; [reflexivity|]. rewrite seq_S, map_app, concat_app, filter_app, length_app, IH by lia.
347
+ cbn [map concat Nat.add]. rewrite app_nil_r, C by lia. lia. }
348
+ apply G. lia.
349
+ Qed.
350
+
351
+ (* for odd r the amplified row fires exactly when the row does *)
352
+ Lemma odd_sign : forall r z, Nat.odd r = true -> Z.leb 0 (Z.of_nat r * z + Z.of_nat ((r - 1) / 2)) = Z.leb 0 z.
353
+ Proof.
354
+ intros r z Ho. apply Nat.odd_spec in Ho as (h & ->). replace ((2 * h + 1 - 1) / 2)%nat with h.
355
+ - destruct (Z.leb_spec 0 z), (Z.leb_spec 0 (Z.of_nat (2 * h + 1) * z + Z.of_nat h)); try reflexivity; nia.
356
+ - replace (2 * h + 1 - 1)%nat with (h * 2)%nat by lia. rewrite Nat.div_mul by lia. reflexivity.
357
+ Qed.
358
+
359
+ (* the distance of the amplified pre-activation from the comparator is r times that of the row, at least r/2 *)
360
+ Lemma odd_dist : forall r z, Nat.odd r = true ->
361
+ Rabs (IZR (Z.of_nat r * z + Z.of_nat ((r - 1) / 2)) + 1/2) = INR r * Rabs (IZR z + 1/2).
362
+ Proof.
363
+ intros r z Ho. apply Nat.odd_spec in Ho as (h & ->). replace ((2 * h + 1 - 1) / 2)%nat with h.
364
+ - rewrite plus_IZR, mult_IZR, <- !INR_IZR_INZ. rewrite <- (Rabs_right (INR (2 * h + 1))) at 2 by (apply Rle_ge, pos_INR).
365
+ rewrite <- Rabs_mult. f_equal. rewrite plus_INR, mult_INR. cbn [INR]. lra.
366
+ - replace (2 * h + 1 - 1)%nat with (h * 2)%nat by lia. rewrite Nat.div_mul by lia. reflexivity.
367
+ Qed.
368
+
369
+ Lemma lfire_concat_repeat : forall L r y, lfire (concat (repeat L r)) y = concat (repeat (lfire L y) r).
370
+ Proof.
371
+ intros L r y. induction r as [|r IH]; [reflexivity|]. cbn [repeat concat]. unfold lfire in *. rewrite map_app, IH. reflexivity.
372
+ Qed.
373
+
374
+ (* Proposition 6.7 (i), one layer *)
375
+ Lemma lfire_alayer : forall r L y, Nat.odd r = true -> Forall (reads_lt (length y)) L ->
376
+ lfire (alayer r (length y) L) (rep r y) = rep r (lfire L y).
377
+ Proof.
378
+ intros r L y Ho HL. unfold alayer, rep. rewrite lfire_concat_repeat. f_equal. f_equal.
379
+ unfold lfire. rewrite map_map. apply map_ext_in. intros u Hu. unfold fire.
380
+ change (tb (arow r (length y) u) + wsum (tin (arow r (length y) u)) (fun i => nth i (concat (repeat y r)) false))%Z
381
+ with (pre (arow r (length y) u) (rep r y)).
382
+ rewrite pre_arow by (rewrite Forall_forall in HL; exact (HL u Hu)). apply odd_sign. exact Ho.
383
+ Qed.
384
+
385
+ (* the rows of each layer read only the layer before *)
386
+ Fixpoint lreads (w : nat) (Ls : list (list tu)) : Prop :=
387
+ match Ls with [] => True | L :: t => Forall (reads_lt w) L /\ lreads (length L) t end.
388
+
389
+ (* Proposition 6.7 (i): F^(r) o rho_r = rho_r o F *)
390
+ Theorem amap_rep : forall r Ls x, Nat.odd r = true -> lreads (length x) Ls ->
391
+ lmap (amap r (length x) Ls) (rep r x) = rep r (lmap Ls x).
392
+ Proof.
393
+ intros r Ls. induction Ls as [|L t IH]; intros x Ho HL; [reflexivity|]. destruct HL as [HL Ht].
394
+ cbn [amap]. unfold lmap. cbn [fold_left]. rewrite lfire_alayer by assumption. fold (lmap t (rep r (lfire L x))).
395
+ fold (lmap t (lfire L x)). replace (length L) with (length (lfire L x)) by (unfold lfire; apply length_map).
396
+ apply IH; [exact Ho|]. unfold lfire. rewrite length_map. exact Ht.
397
+ Qed.
398
+
399
+ (* ---- Proposition 6.7 (iii): each wrong input copy moves a pre-activation by at most one ------------------------------ *)
400
+ Definition differs (y1 y2 : list bool) (k : nat) : bool := negb (Bool.eqb (nth k y1 false) (nth k y2 false)).
401
+
402
+ Lemma wsum_diff : forall ins E1 E2, (forall j z, In (j, z) ins -> (z = 1 \/ z = -1)%Z) ->
403
+ (Z.abs (wsum ins E1 - wsum ins E2) <= Z.of_nat (length (filter (fun p => negb (Bool.eqb (E1 (fst p)) (E2 (fst p)))) ins)))%Z.
404
+ Proof.
405
+ induction ins as [|[j z] t IH]; intros E1 E2 Hw; cbn [wsum filter fst]; [lia|].
406
+ specialize (IH E1 E2 (fun j' z' H => Hw j' z' (or_intror H))).
407
+ destruct (Hw j z (or_introl eq_refl)) as [-> | ->]; destruct (E1 j), (E2 j); cbn [Bool.eqb negb b2z length];
408
+ rewrite ?Nat2Z.inj_succ; lia.
409
+ Qed.
410
+
411
+ Lemma ncnt_filter : forall m P, length (filter P (seq 0 m)) = ncnt m P.
412
+ Proof.
413
+ induction m as [|m IH]; intro P; [reflexivity|]. rewrite seq_S, filter_app, length_app, IH. cbn [filter ncnt Nat.add].
414
+ destruct (P m); cbn [length]; lia.
415
+ Qed.
416
+
417
+ Lemma filter_fst : forall (ins : list (nat * Z)) (P : nat -> bool),
418
+ map fst (filter (fun p => P (fst p)) ins) = filter P (map fst ins).
419
+ Proof. induction ins as [|[j z] t IH]; intro P; [reflexivity|]. cbn [filter map fst]. destruct (P j); cbn [map fst]; rewrite IH; reflexivity. Qed.
420
+
421
+ (* the positions a row reads, distinct and below m, count at most the positions below m *)
422
+ Lemma filter_pos_le : forall (ins : list (nat * Z)) (P : nat -> bool) m,
423
+ NoDup (map fst ins) -> (forall j z, In (j, z) ins -> (j < m)%nat) -> (length (filter (fun p => P (fst p)) ins) <= ncnt m P)%nat.
424
+ Proof.
425
+ intros ins P m Hnd Hlt. rewrite <- ncnt_filter, <- (length_map fst), filter_fst.
426
+ apply NoDup_incl_length; [apply NoDup_filter; exact Hnd|]. intros j Hj. apply filter_In in Hj as [Hj Pj].
427
+ apply filter_In. split; [|exact Pj]. apply in_map_iff in Hj as ([j' z] & <- & Hin). apply in_seq. cbn [fst].
428
+ pose proof (Hlt j' z Hin). lia.
429
+ Qed.
430
+
431
+ Lemma nodup_shift : forall (l : list nat) k, NoDup l -> NoDup (map (fun j => (k + j)%nat) l).
432
+ Proof.
433
+ induction l as [|a t IH]; intros k H; cbn [map]; [constructor|]. inversion H as [|? ? Ha Ht]; subst.
434
+ constructor; [|apply IH; exact Ht]. intro Hin. apply in_map_iff in Hin as (b & E & Hb). assert (b = a) by lia. subst. contradiction.
435
+ Qed.
436
+
437
+ (* an amplified ternary row reads r w distinct positions with weights -1 or 1 *)
438
+ Lemma arow_ok : forall r w u, rowok w u -> rowok (r * w) (arow r w u).
439
+ Proof.
440
+ intros r w u [Hnd Hlt]. unfold arow. cbn [tin]. split.
441
+ - assert (G : forall k, NoDup (map fst (concat (map (fun c => map (fun p => ((c * w + fst p)%nat, snd p)) (tin u)) (seq 0 k))))
442
+ /\ forall j, In j (map fst (concat (map (fun c => map (fun p => ((c * w + fst p)%nat, snd p)) (tin u)) (seq 0 k)))) ->
443
+ (j < k * w)%nat).
444
+ { induction k as [|k [IHn IHl]]; [split; [constructor | intros j []]|].
445
+ assert (Ek : map fst (map (fun p => ((k * w + fst p)%nat, snd p)) (tin u)) = map (fun j => (k * w + j)%nat) (map fst (tin u)))
446
+ by (rewrite !map_map; reflexivity).
447
+ rewrite seq_S, map_app, concat_app, map_app. cbn [map concat Nat.add]. rewrite app_nil_r, Ek. split.
448
+ - apply NoDup_app; [exact IHn | apply nodup_shift; exact Hnd|]. intros j H1 H2. apply IHl in H1.
449
+ apply in_map_iff in H2 as (j' & <- & _). lia.
450
+ - intros j Hj. apply in_app_or in Hj as [Hj|Hj]; [pose proof (IHl j Hj); nia|].
451
+ apply in_map_iff in Hj as (j' & <- & Hj'). apply in_map_iff in Hj' as ([j'' z] & <- & Hin).
452
+ cbn [fst]. pose proof (proj1 (Hlt j'' z Hin)). nia. }
453
+ exact (proj1 (G r)).
454
+ - intros j z Hin. apply in_concat in Hin as (l & Hl & Hin). apply in_map_iff in Hl as (c & <- & Hc). apply in_seq in Hc.
455
+ apply in_map_iff in Hin as ([j' z'] & E & Hin). cbn [fst snd] in E. injection E as <- <-.
456
+ destruct (Hlt j' z' Hin) as [Hj' Hz]. split; [nia | exact Hz].
457
+ Qed.
458
+
459
+ Lemma pre_diff : forall r w u y1 y2, rowok w u -> length y1 = (r * w)%nat ->
460
+ (Z.abs (pre (arow r w u) y1 - pre (arow r w u) y2) <= Z.of_nat (ncnt (r * w) (differs y1 y2)))%Z.
461
+ Proof.
462
+ intros r w u y1 y2 Hu Hl. destruct (arow_ok r w u Hu) as [Hnd Hlt]. unfold pre.
463
+ replace (tb (arow r w u) + wsum (tin (arow r w u)) (fun i => nth i y1 false)
464
+ - (tb (arow r w u) + wsum (tin (arow r w u)) (fun i => nth i y2 false)))%Z
465
+ with (wsum (tin (arow r w u)) (fun i => nth i y1 false) - wsum (tin (arow r w u)) (fun i => nth i y2 false))%Z by lia.
466
+ eapply Z.le_trans; [apply wsum_diff; intros j z Hin; exact (proj2 (Hlt j z Hin))|]. apply Nat2Z.inj_le.
467
+ apply (filter_pos_le (tin (arow r w u)) (differs y1 y2) (r * w)); [exact Hnd | intros j z Hin; exact (proj1 (Hlt j z Hin))].
468
+ Qed.
469
+
470
+ (* Proposition 6.7 (iii): a row whose inputs carry f < r/2 wrong copies computes its value on rho_r(y) under every
471
+ perturbation below r/2 - f *)
472
+ Theorem amp_wrong : forall r w u y y' (e : R), Nat.odd r = true -> rowok w u -> length y = w -> length y' = (r * w)%nat ->
473
+ Rabs e < INR r / 2 - INR (ncnt (r * w) (differs y' (rep r y))) ->
474
+ H12 (IZR (pre (arow r w u) y') + e) = Z.leb 0 (pre u y).
475
+ Proof.
476
+ intros r w u y y' e Ho Hu Hy Hy' He.
477
+ assert (Hr : reads_lt (length y) u) by (intros j z Hin; rewrite Hy; exact (proj1 (proj2 Hu j z Hin))).
478
+ pose proof (pre_diff r w u y' (rep r y) Hu Hy') as D. subst w.
479
+ set (z0 := pre (arow r (length y) u) (rep r y)). set (d := (pre (arow r (length y) u) y' - z0)%Z).
480
+ replace (pre (arow r (length y) u) y') with (z0 + d)%Z by (unfold d; lia).
481
+ rewrite plus_IZR, Rplus_assoc. rewrite H12_ok.
482
+ - unfold z0. rewrite pre_arow by exact Hr. apply odd_sign. exact Ho.
483
+ - apply no_fail. unfold z0. rewrite pre_arow by exact Hr. rewrite odd_dist by exact Ho.
484
+ pose proof (dist_half (pre u y)). apply IZR_le in D. rewrite abs_IZR, <- INR_IZR_INZ in D.
485
+ pose proof (Rabs_triang (IZR d) e). pose proof (pos_INR (length (rep r y))).
486
+ assert (INR r * (1/2) <= INR r * Rabs (IZR (pre u y) + 1/2)) by (apply Rmult_le_compat_l; [apply pos_INR | exact H]).
487
+ change (pre (arow r (length y) u) y' - pre (arow r (length y) u) (rep r y))%Z with d in D. lra.
488
+ Qed.
489
+
490
+ (* ---- Theorem 6.8 (i): the amplified map tolerates every perturbation below r/2 ------------------------------------- *)
491
+ Lemma length_concat_repeat : forall (A : Type) (M : list A) k, length (concat (repeat M k)) = (k * length M)%nat.
492
+ Proof. intros A M k. induction k as [|k IH]; [reflexivity|]. cbn [repeat concat]. rewrite length_app, IH. lia. Qed.
493
+
494
+ Lemma nth_concat_repeat : forall (A : Type) (M : list A) k i d, (i < k * length M)%nat ->
495
+ nth i (concat (repeat M k)) d = nth (i mod length M) M d.
496
+ Proof.
497
+ intros A M k. induction k as [|k IH]; intros i d Hi; [lia|]. cbn [repeat concat].
498
+ assert (HM : length M <> 0%nat) by (intro E; rewrite E in Hi; lia).
499
+ destruct (Nat.lt_ge_cases i (length M)) as [H|H].
500
+ - rewrite app_nth1 by exact H. rewrite Nat.mod_small by exact H. reflexivity.
501
+ - rewrite app_nth2 by exact H. rewrite IH by nia. f_equal.
502
+ replace i with ((i - length M) + 1 * length M)%nat at 2 by lia. rewrite Nat.Div0.mod_add. reflexivity.
503
+ Qed.
504
+
505
+ Lemma length_alayer : forall r w L, length (alayer r w L) = (r * length L)%nat.
506
+ Proof. intros r w L. unfold alayer. rewrite length_concat_repeat, length_map. reflexivity. Qed.
507
+
508
+ Lemma nth_alayer : forall r w L i, (i < r * length L)%nat ->
509
+ nth i (alayer r w L) tu0 = arow r w (nth (i mod length L) L tu0).
510
+ Proof.
511
+ intros r w L i Hi. assert (HL : length L <> 0%nat) by (intro E; rewrite E in Hi; lia).
512
+ unfold alayer. rewrite nth_concat_repeat by (rewrite length_map; exact Hi). rewrite length_map.
513
+ pose proof (Nat.mod_upper_bound i (length L) HL).
514
+ rewrite (nth_indep _ _ (arow r w tu0)) by (rewrite length_map; exact H). apply map_nth.
515
+ Qed.
516
+
517
+ Lemma firstn_amap : forall r w Ls l, firstn l (amap r w Ls) = amap r w (firstn l Ls).
518
+ Proof.
519
+ intros r w Ls. revert w. induction Ls as [|L t IH]; intros w l; [rewrite !firstn_nil; reflexivity|].
520
+ destruct l as [|l]; [reflexivity|]. cbn [amap firstn]. rewrite IH. reflexivity.
521
+ Qed.
522
+
523
+ Lemma lreads_firstn : forall Ls w l, lreads w Ls -> lreads w (firstn l Ls).
524
+ Proof.
525
+ induction Ls as [|L t IH]; intros w l H; [rewrite firstn_nil; exact I|].
526
+ destruct l as [|l]; [exact I|]. destruct H as [H1 H2]. cbn [firstn lreads]. split; [exact H1 | apply IH; exact H2].
527
+ Qed.
528
+
529
+ Lemma lin_amp : forall r Ls x l, Nat.odd r = true -> lreads (length x) Ls ->
530
+ lin (amap r (length x) Ls) (rep r x) l = rep r (lin Ls x l).
531
+ Proof.
532
+ intros r Ls x l Ho H. unfold lin. rewrite firstn_amap. apply amap_rep; [exact Ho | apply lreads_firstn; exact H].
533
+ Qed.
534
+
535
+ Lemma nth_amap : forall r Ls n l, (l < length Ls)%nat -> nth l (amap r n Ls) [] = alayer r (win Ls n l) (nth l Ls []).
536
+ Proof.
537
+ intros r Ls. induction Ls as [|L t IH]; intros n l Hl; [cbn [length] in Hl; lia|].
538
+ destruct l as [|l]; [reflexivity|]. cbn [amap nth]. rewrite IH by (cbn [length] in Hl; lia).
539
+ destruct l as [|l]; reflexivity.
540
+ Qed.
541
+
542
+ Lemma lin_len' : forall Ls x l, (l <= length Ls)%nat -> length (lin Ls x l) = win Ls (length x) l.
543
+ Proof.
544
+ intros Ls x l. induction l as [|l IH]; intro Hl; [reflexivity|].
545
+ unfold lin. rewrite (firstn_snoc _ Ls l []) by lia. rewrite lmap_app. unfold lfire. rewrite length_map. reflexivity.
546
+ Qed.
547
+
548
+ Lemma lreads_nth : forall Ls w l, lreads w Ls -> (l < length Ls)%nat -> Forall (reads_lt (win Ls w l)) (nth l Ls []).
549
+ Proof.
550
+ induction Ls as [|L t IH]; intros w l H Hl; [cbn [length] in Hl; lia|]. destruct H as [H1 H2].
551
+ destruct l as [|l]; [exact H1|]. cbn [nth]. specialize (IH (length L) l H2 ltac:(cbn [length] in Hl; lia)).
552
+ destruct l as [|l]; exact IH.
553
+ Qed.
554
+
555
+ Lemma length_amap : forall r w Ls, length (amap r w Ls) = length Ls.
556
+ Proof. intros r w Ls. revert w. induction Ls as [|L t IH]; intro w; [reflexivity|]. cbn [amap length]. rewrite IH. reflexivity. Qed.
557
+
558
+ Lemma length_nth_amap : forall r Ls n l, (l < length Ls)%nat ->
559
+ length (nth l (amap r n Ls) []) = (r * length (nth l Ls []))%nat.
560
+ Proof. intros r Ls n l Hl. rewrite nth_amap by exact Hl. apply length_alayer. Qed.
561
+
562
+ Section Amp.
563
+ Variables (r : nat) (Ls : list (list tu)) (x0 : list bool) (n : nat).
564
+ Hypothesis Ho : Nat.odd r = true.
565
+ Hypothesis Hn : length x0 = n.
566
+ Hypothesis HL : lreads n Ls.
567
+ Hypothesis Hlast : length (last Ls []) = n.
568
+ Hypothesis Hne : Ls <> [].
569
+
570
+ Lemma orbit_len0 : forall t, length (orbit Ls x0 t) = n.
571
+ Proof. intro t. exact (orbit_len Ls n Hlast Hne x0 t Hn). Qed.
572
+
573
+ (* the amplified orbit is the replicated orbit *)
574
+ Lemma amp_orbit : forall t, orbit (amap r n Ls) (rep r x0) t = rep r (orbit Ls x0 t).
575
+ Proof.
576
+ intro t0. induction t0 as [|t0 IH]; [reflexivity|].
577
+ change (orbit (amap r n Ls) (rep r x0) (S t0)) with (lmap (amap r n Ls) (orbit (amap r n Ls) (rep r x0) t0)).
578
+ change (orbit Ls x0 (S t0)) with (lmap Ls (orbit Ls x0 t0)).
579
+ rewrite IH. rewrite <- (orbit_len0 t0) at 1. apply amap_rep; [exact Ho | rewrite orbit_len0; exact HL].
580
+ Qed.
581
+
582
+ (* row i of layer l of F^(r) at step t of its orbit has pre-activation r z + (r - 1)/2, z that of row i mod |L| of F *)
583
+ Definition zrow (t l i : nat) : Z :=
584
+ pre (nth (i mod length (nth l Ls [])) (nth l Ls []) tu0) (lin Ls (orbit Ls x0 t) l).
585
+
586
+ Lemma amp_pre : forall t l i, (l < length Ls)%nat -> (i < length (nth l (amap r n Ls) []))%nat ->
587
+ pre (nth i (nth l (amap r n Ls) []) tu0) (lin (amap r n Ls) (orbit (amap r n Ls) (rep r x0) t) l)
588
+ = (Z.of_nat r * zrow t l i + Z.of_nat ((r - 1) / 2))%Z.
589
+ Proof.
590
+ intros t l i Hl Hi. rewrite amp_orbit.
591
+ replace (lin (amap r n Ls) (rep r (orbit Ls x0 t)) l) with (rep r (lin Ls (orbit Ls x0 t) l))
592
+ by (symmetry; rewrite <- (orbit_len0 t); apply lin_amp; [exact Ho | rewrite orbit_len0; exact HL]).
593
+ rewrite (nth_amap r Ls n l Hl) in Hi |- *. rewrite length_alayer in Hi. rewrite nth_alayer by exact Hi.
594
+ set (y := lin Ls (orbit Ls x0 t) l).
595
+ assert (Hy : length y = win Ls n l) by (unfold y; rewrite lin_len' by lia; rewrite orbit_len0; reflexivity).
596
+ rewrite <- Hy. apply pre_arow. pose proof (lreads_nth Ls n l HL Hl) as F.
597
+ rewrite Forall_forall in F. rewrite Hy. apply F. apply nth_In. apply Nat.mod_upper_bound.
598
+ intro E0. rewrite E0 in Hi. lia.
599
+ Qed.
600
+
601
+ (* its distance from the comparator is r times that of the row of F, at least r/2 *)
602
+ Lemma amp_dist : forall t l i, (l < length Ls)%nat -> (i < length (nth l (amap r n Ls) []))%nat ->
603
+ Rabs (IZR (pre (nth i (nth l (amap r n Ls) []) tu0) (lin (amap r n Ls) (orbit (amap r n Ls) (rep r x0) t) l)) + 1/2)
604
+ = INR r * Rabs (IZR (zrow t l i) + 1/2).
605
+ Proof. intros t l i Hl Hi. rewrite amp_pre by assumption. apply odd_dist. exact Ho. Qed.
606
+
607
+ (* Theorem 6.8 (i): the amplified map tolerates every perturbation below r/2 *)
608
+ Theorem amp_margin : forall E eps, eps < INR r / 2 -> (forall t l i y, Rabs (E t l i y) <= eps) ->
609
+ forall t, trajp (amap r n Ls) E (rep r x0) t = rep r (orbit Ls x0 t).
610
+ Proof.
611
+ intros E eps He HE t. rewrite (traj_ok _ E (rep r x0) t); [apply amp_orbit | | lia].
612
+ intros t' l i _ Hl Hi. rewrite length_amap in Hl. unfold rfail. apply no_fail. rewrite amp_dist by assumption.
613
+ pose proof (dist_half (zrow t' l i)). specialize (HE t' l i (lin (amap r n Ls) (orbit (amap r n Ls) (rep r x0) t') l)).
614
+ assert (INR r * (1/2) <= INR r * Rabs (IZR (zrow t' l i) + 1/2)) by (apply Rmult_le_compat_l; [apply pos_INR | exact H]).
615
+ lra.
616
+ Qed.
617
+
618
+ End Amp.
619
+
620
+ (* ---- output flips (Proposition 6.10): every evaluation outputs its value xor a flip --------------------------------- *)
621
+ Definition xorv (x : list bool) (f : nat -> bool) : list bool := map (fun k => xorb (nth k x false) (f k)) (seq 0 (length x)).
622
+
623
+ Definition lfiref (L : list tu) (f : nat -> bool) (y : list bool) : list bool :=
624
+ map (fun k => xorb (Z.leb 0 (pre (nth k L tu0) y)) (f k)) (seq 0 (length L)).
625
+
626
+ Fixpoint lmapf (Ls : list (list tu)) (l : nat) (Fl : nat -> nat -> bool) (y : list bool) : list bool :=
627
+ match Ls with [] => y | L :: t => lmapf t (S l) Fl (lfiref L (Fl l) y) end.
628
+
629
+ Fixpoint trajf (Ls : list (list tu)) (Fl : nat -> nat -> nat -> bool) (x0 : list bool) (t : nat) : list bool :=
630
+ match t with O => x0 | S t' => lmapf Ls 0 (Fl t') (trajf Ls Fl x0 t') end.
631
+
632
+ (* the state of F^(r) read by majority: bit j is 1 when more than r/2 of its copies are *)
633
+ Definition maj (r n : nat) (x : list bool) : list bool :=
634
+ map (fun j => Nat.ltb (r / 2) (ncnt r (fun c => nth (c * n + j) x false))) (seq 0 n).
635
+
636
+ Lemma xorv_false : forall x, xorv x (fun _ => false) = x.
637
+ Proof.
638
+ intro x. unfold xorv. transitivity (map (fun b : bool => b) x); [|apply map_id].
639
+ rewrite (map_seq_nth _ _ (fun b : bool => b) x false). apply map_ext. intro k. apply xorb_false_r.
640
+ Qed.
641
+
642
+ Lemma length_xorv : forall x f, length (xorv x f) = length x.
643
+ Proof. intros x f. unfold xorv. rewrite length_map, length_seq. reflexivity. Qed.
644
+
645
+ Lemma nth_xorv : forall x f k, (k < length x)%nat -> nth k (xorv x f) false = xorb (nth k x false) (f k).
646
+ Proof.
647
+ intros x f k Hk. unfold xorv. rewrite nth_map_seq by exact Hk. reflexivity.
648
+ Qed.
649
+
650
+ Lemma nth_rep_mod : forall r x k, (k < r * length x)%nat -> nth k (rep r x) false = nth (k mod length x) x false.
651
+ Proof. intros r x k Hk. unfold rep. apply nth_concat_repeat. exact Hk. Qed.
652
+
653
+ (* a ternary row of F^(r) moves by at most one per read input that differs *)
654
+ Lemma pre_diff_read : forall r w u y1 y2, rowok w u ->
655
+ (Z.abs (pre (arow r w u) y1 - pre (arow r w u) y2) <= Z.of_nat (length (filter (fun p => differs y1 y2 (fst p)) (tin (arow r w u)))))%Z.
656
+ Proof.
657
+ intros r w u y1 y2 Hu. destruct (arow_ok r w u Hu) as [_ Hlt]. unfold pre.
658
+ replace (tb (arow r w u) + wsum (tin (arow r w u)) (fun i => nth i y1 false)
659
+ - (tb (arow r w u) + wsum (tin (arow r w u)) (fun i => nth i y2 false)))%Z
660
+ with (wsum (tin (arow r w u)) (fun i => nth i y1 false) - wsum (tin (arow r w u)) (fun i => nth i y2 false))%Z by lia.
661
+ apply wsum_diff. intros j z Hin. exact (proj2 (Hlt j z Hin)).
662
+ Qed.
663
+
664
+ (* one layer of F^(r) on rho_r(y) with flipped copies psi: if every row reads at most (r - 1)/2 flipped copies, every row
665
+ computes its value on rho_r(y), and the output is rho_r of the layer of F with the flips of this layer *)
666
+ Lemma layer_flip : forall r w L Y psi f, Nat.odd r = true -> length Y = w -> Forall (rowok w) L ->
667
+ (forall i, (i < length L)%nat -> (length (filter (fun p => psi (fst p)) (tin (arow r w (nth i L tu0)))) <= r / 2)%nat) ->
668
+ lfiref (alayer r w L) f (xorv (rep r Y) psi) = xorv (rep r (lfire L Y)) f.
669
+ Proof.
670
+ intros r w L Y psi f Ho HY HL Hc. unfold lfiref, xorv at 2. rewrite length_alayer, length_rep.
671
+ replace (length (lfire L Y)) with (length L) by (unfold lfire; rewrite length_map; reflexivity).
672
+ apply map_ext_in. intros k Hk. apply in_seq in Hk. f_equal.
673
+ assert (HL0 : length L <> 0%nat) by lia. pose proof (Nat.mod_upper_bound k (length L) HL0) as Hm.
674
+ set (u := nth (k mod length L) L tu0).
675
+ assert (Hu : rowok w u) by (rewrite Forall_forall in HL; apply HL; apply nth_In; exact Hm).
676
+ assert (Hr : reads_lt (length Y) u) by (intros j z Hin; rewrite HY; exact (proj1 (proj2 Hu j z Hin))).
677
+ rewrite nth_alayer by lia. fold u.
678
+ rewrite nth_rep_mod by (unfold lfire; rewrite length_map; lia).
679
+ replace (length (lfire L Y)) with (length L) by (unfold lfire; rewrite length_map; reflexivity).
680
+ rewrite lfire_seq, nth_map_seq by exact Hm. fold u.
681
+ (* the pre-activation on the flipped input differs from that on rho_r(y) by at most the flipped copies read *)
682
+ pose proof (pre_diff_read r w u (xorv (rep r Y) psi) (rep r Y) Hu) as D.
683
+ destruct (arow_ok r w u Hu) as [_ Hlt].
684
+ assert (Ecount : length (filter (fun p => differs (xorv (rep r Y) psi) (rep r Y) (fst p)) (tin (arow r w u)))
685
+ = length (filter (fun p => psi (fst p)) (tin (arow r w u)))).
686
+ { f_equal. apply filter_ext_in. intros [q z] Hin. cbn [fst]. destruct (Hlt q z Hin) as [Hq _].
687
+ unfold differs. rewrite nth_xorv by (rewrite length_rep; lia). destruct (nth q (rep r Y) false), (psi q); reflexivity. }
688
+ rewrite Ecount in D. pose proof (Hc (k mod length L) Hm) as C. fold u in C.
689
+ rewrite <- HY in D, C |- *. rewrite pre_arow in D by exact Hr.
690
+ set (z := pre u Y) in *. set (h := Z.of_nat ((r - 1) / 2)) in *.
691
+ set (Z1 := pre (arow r (length Y) u) (xorv (rep r Y) psi)) in *.
692
+ rewrite <- (odd_sign r z Ho). fold h.
693
+ (* both sides as thresholds of integers that differ by at most (r - 1)/2 < r/2, the distance from the comparator *)
694
+ apply Nat.odd_spec in Ho as (hh & Er). assert (Hh : (r / 2)%nat = hh) by (rewrite Er; replace (2 * hh + 1)%nat with (1 + hh * 2)%nat by lia;
695
+ rewrite Nat.div_add by lia; reflexivity).
696
+ rewrite Hh in C. apply (Nat2Z.inj_le) in C.
697
+ assert (Hhh : h = Z.of_nat hh) by (unfold h; rewrite Er; f_equal; replace (2 * hh + 1 - 1)%nat with (hh * 2)%nat by lia;
698
+ rewrite Nat.div_mul by lia; reflexivity).
699
+ rewrite Hhh in D |- *. assert (Hr' : Z.of_nat r = (2 * Z.of_nat hh + 1)%Z) by lia.
700
+ rewrite Hr' in D |- *. clear Hr'. apply Z.abs_le in D.
701
+ destruct (Z.le_gt_cases 0 z) as [Hz|Hz];
702
+ destruct (Z.leb_spec 0 Z1), (Z.leb_spec 0 ((2 * Z.of_nat hh + 1) * z + Z.of_nat hh)); try reflexivity; nia.
703
+ Qed.
704
+
705
+ (* the input flips of layer k: psi for the first layer, the flips of layer k - 1 for the others *)
706
+ Definition pin (psi : nat -> bool) (Fl : nat -> nat -> bool) (l0 k : nat) : nat -> bool :=
707
+ match k with O => psi | S k' => Fl (l0 + k')%nat end.
708
+
709
+ Lemma map_flip : forall r Ls w Y psi Fl l0, Nat.odd r = true -> length Y = w -> lwf w Ls -> Ls <> [] ->
710
+ (forall k i, (k < length Ls)%nat -> (i < length (nth k Ls []))%nat ->
711
+ (length (filter (fun p => pin psi Fl l0 k (fst p)) (tin (arow r (win Ls w k) (nth i (nth k Ls []) tu0)))) <= r / 2)%nat) ->
712
+ lmapf (amap r w Ls) l0 Fl (xorv (rep r Y) psi) = xorv (rep r (lmap Ls Y)) (Fl (l0 + length Ls - 1)%nat).
713
+ Proof.
714
+ intros r Ls. induction Ls as [|L t IH]; intros w Y psi Fl l0 Ho HY HL Hne Hc; [contradiction|].
715
+ destruct HL as [HL1 HL2]. cbn [amap lmapf].
716
+ rewrite layer_flip; [| exact Ho | exact HY | exact HL1 |].
717
+ 2: { intros i Hi. exact (Hc 0%nat i ltac:(cbn [length]; lia) Hi). }
718
+ destruct t as [|L' t'].
719
+ - cbn [amap lmapf length]. replace (l0 + 1 - 1)%nat with l0 by lia. reflexivity.
720
+ - unfold lmap. cbn [fold_left]. fold (lmap (L' :: t') (lfire L Y)).
721
+ rewrite (IH (length L) (lfire L Y) (Fl l0) Fl (S l0)); [| exact Ho | unfold lfire; apply length_map | exact HL2 | discriminate |].
722
+ + f_equal. f_equal. cbn [length]. lia.
723
+ + intros k i Hk Hi. specialize (Hc (S k) i ltac:(cbn [length] in *; lia) Hi). unfold pin in *.
724
+ destruct k as [|k]; cbn [win] in *.
725
+ * rewrite Nat.add_0_r in Hc. exact Hc.
726
+ * replace (S l0 + k)%nat with (l0 + S k)%nat by lia. exact Hc.
727
+ Qed.
728
+
729
+ Lemma ncnt_ext : forall k f g, (forall c, (c < k)%nat -> f c = g c) -> ncnt k f = ncnt k g.
730
+ Proof. induction k as [|k IH]; intros f g H; cbn [ncnt]; [reflexivity|]. rewrite (IH f g), (H k) by (lia || (intros; apply H; lia)). reflexivity. Qed.
731
+
732
+ Lemma ncnt_le : forall k f, (ncnt k f <= k)%nat.
733
+ Proof. induction k as [|k IH]; intro f; cbn [ncnt]; [lia|]. specialize (IH f). destruct (f k); lia. Qed.
734
+
735
+ Lemma ncnt_xorb : forall k b g, ncnt k (fun c => xorb b (g c)) = if b then (k - ncnt k g)%nat else ncnt k g.
736
+ Proof.
737
+ induction k as [|k IH]; intros b g; cbn [ncnt]; [destruct b; reflexivity|]. rewrite IH. pose proof (ncnt_le k g).
738
+ destruct b, (g k); cbn [xorb]; lia.
739
+ Qed.
740
+
741
+ (* the majority of r copies, of which at most (r - 1)/2 are flipped, is the value *)
742
+ Lemma maj_ok : forall r n X phi, Nat.odd r = true -> length X = n ->
743
+ (forall j, (j < n)%nat -> (ncnt r (fun c => phi (c * n + j)%nat) <= r / 2)%nat) -> maj r n (xorv (rep r X) phi) = X.
744
+ Proof.
745
+ intros r n X phi Ho HX H. unfold maj. transitivity (map (fun b : bool => b) X); [|apply map_id].
746
+ rewrite (map_seq_nth _ _ (fun b : bool => b) X false). rewrite HX. apply map_ext_in. intros j Hj. apply in_seq in Hj.
747
+ rewrite (ncnt_ext r _ (fun c => xorb (nth j X false) (phi (c * n + j)%nat))).
748
+ - rewrite ncnt_xorb. specialize (H j ltac:(lia)). pose proof (ncnt_le r (fun c => phi (c * n + j)%nat)).
749
+ apply Nat.odd_spec in Ho as (hh & ->). replace ((2 * hh + 1) / 2)%nat with hh in *
750
+ by (replace (2 * hh + 1)%nat with (1 + hh * 2)%nat by lia; rewrite Nat.div_add by lia; reflexivity).
751
+ destruct (nth j X false); [apply Nat.ltb_lt | apply Nat.ltb_ge]; lia.
752
+ - intros c Hc. rewrite nth_xorv by (rewrite length_rep, HX; nia). rewrite <- HX. rewrite nth_rep by lia. reflexivity.
753
+ Qed.
754
+
755
+ (* Proposition 6.10, the deterministic part: if no row of F^(r) reads (r + 1)/2 flipped copies and no state bit has
756
+ (r + 1)/2 flipped copies in the first T steps, the state read by majority follows the orbit *)
757
+ Theorem flip_ok : forall r Ls x0 n Fl T, Nat.odd r = true -> length x0 = n -> lwf n Ls -> length (last Ls []) = n -> Ls <> [] ->
758
+ (forall t k i, (t < T)%nat -> (k < length Ls)%nat -> (i < length (nth k Ls []))%nat ->
759
+ (length (filter (fun p => pin (fun q => match t with O => false | S t' => Fl t' (length Ls - 1)%nat q end) (Fl t) 0 k (fst p))
760
+ (tin (arow r (win Ls n k) (nth i (nth k Ls []) tu0)))) <= r / 2)%nat) ->
761
+ (forall t j, (t < T)%nat -> (j < n)%nat -> (ncnt r (fun c => Fl t (length Ls - 1)%nat (c * n + j)%nat) <= r / 2)%nat) ->
762
+ forall t, (t <= T)%nat -> maj r n (trajf (amap r n Ls) Fl (rep r x0) t) = orbit Ls x0 t.
763
+ Proof.
764
+ intros r Ls x0 n Fl T Ho Hx HL Hlast Hne Hc Hs.
765
+ set (phi := fun t q => match t with O => false | S t' => Fl t' (length Ls - 1)%nat q end).
766
+ assert (Inv : forall t, (t <= T)%nat -> trajf (amap r n Ls) Fl (rep r x0) t = xorv (rep r (orbit Ls x0 t)) (phi t)).
767
+ { induction t as [|t IH]; intro Ht.
768
+ - cbn [trajf orbit Nat.iter]. unfold phi. rewrite xorv_false. reflexivity.
769
+ - cbn [trajf]. rewrite IH by lia.
770
+ rewrite <- (orbit_len Ls n Hlast Hne x0 t Hx) at 1.
771
+ rewrite map_flip; [| exact Ho | reflexivity | rewrite (orbit_len Ls n Hlast Hne x0 t Hx); exact HL | exact Hne |].
772
+ + reflexivity.
773
+ + intros k i Hk Hi. rewrite (orbit_len Ls n Hlast Hne x0 t Hx). exact (Hc t k i ltac:(lia) Hk Hi). }
774
+ intros t Ht. rewrite Inv by exact Ht. apply maj_ok; [exact Ho | apply (orbit_len Ls n Hlast Hne x0 t Hx)|].
775
+ intros j Hj. destruct t as [|t]; unfold phi.
776
+ - assert (Z : forall k, ncnt k (fun _ => false) = 0%nat) by (induction k as [|k IHk]; cbn [ncnt]; [reflexivity | rewrite IHk; reflexivity]).
777
+ rewrite Z. lia.
778
+ - exact (Hs t j ltac:(lia) Hj).
779
+ Qed.
780
+
781
+
rocq/Noise.v ADDED
@@ -0,0 +1,957 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* Section 6, the random part. The perturbations are random variables X g on a probability space: P is monotone,
2
+ subadditive, vanishes on the empty event and is 1 on the sure one, multiplies on events that depend on disjoint
3
+ sets of variables, and is complementary on the events built from the threshold events c <= X g; the product of
4
+ Gaussian laws with its outer measure is such a space. On it: the union bound (Proposition 6.4), the profile bound
5
+ (Proposition 6.5), and fault tolerance by amplification (Theorem 6.8 (ii) and (iii)). *)
6
+ From Stdlib Require Import List Bool Arith ZArith Reals Lia Lra.
7
+ Import ListNotations.
8
+ From TH Require Import TwoHead Net Lev Margin Erfc Choose.
9
+
10
+ Local Open Scope R_scope.
11
+
12
+ (* ---- finite sums and products ------------------------------------------------------------------------------------ *)
13
+ Fixpoint rprod (k : nat) (g : nat -> R) : R := match k with O => 1 | S k' => rprod k' g * g k' end.
14
+
15
+ Lemma rsum_ext : forall k g h, (forall j, (j < k)%nat -> g j = h j) -> rsum k g = rsum k h.
16
+ Proof. induction k as [|k IH]; intros g h H; cbn [rsum]; [reflexivity|]. rewrite (IH g h), (H k); [reflexivity | lia |]. intros j Hj. apply H. lia. Qed.
17
+
18
+ Lemma rprod_ext : forall k g h, (forall j, (j < k)%nat -> g j = h j) -> rprod k g = rprod k h.
19
+ Proof. induction k as [|k IH]; intros g h H; cbn [rprod]; [reflexivity|]. rewrite (IH g h), (H k); [reflexivity | lia |]. intros j Hj. apply H. lia. Qed.
20
+
21
+ Lemma rsum_const : forall k c, rsum k (fun _ => c) = INR k * c.
22
+ Proof. induction k as [|k IH]; intro c; cbn [rsum]; [cbn [INR]; lra|]. rewrite IH, S_INR. lra. Qed.
23
+
24
+ Lemma rsum_nonneg : forall k g, (forall j, (j < k)%nat -> 0 <= g j) -> 0 <= rsum k g.
25
+ Proof. induction k as [|k IH]; intros g H; cbn [rsum]; [lra|]. pose proof (IH g (fun j Hj => H j ltac:(lia))). pose proof (H k ltac:(lia)). lra. Qed.
26
+
27
+ Lemma rsum_scal : forall k g c, rsum k (fun j => c * g j) = c * rsum k g.
28
+ Proof. induction k as [|k IH]; intros g c; cbn [rsum]; [lra|]. rewrite IH. lra. Qed.
29
+
30
+ Lemma rsum_plus : forall k g h, rsum k (fun j => g j + h j) = rsum k g + rsum k h.
31
+ Proof. induction k as [|k IH]; intros g h; cbn [rsum]; [lra|]. rewrite IH. lra. Qed.
32
+
33
+ Lemma rsum_shift : forall k g, rsum (S k) g = g 0%nat + rsum k (fun j => g (S j)).
34
+ Proof. induction k as [|k IH]; intro g; cbn [rsum] in *; [lra|]. rewrite IH. cbn [rsum]. lra. Qed.
35
+
36
+ Lemma rprod_range : forall k g, (forall j, (j < k)%nat -> 0 <= g j <= 1) -> 0 <= rprod k g <= 1.
37
+ Proof.
38
+ induction k as [|k IH]; intros g H; cbn [rprod]; [lra|]. destruct (IH g (fun j Hj => H j ltac:(lia))).
39
+ destruct (H k ltac:(lia)). split; [nra|]. nra.
40
+ Qed.
41
+
42
+ Lemma rprod_nonneg : forall k g, (forall j, (j < k)%nat -> 0 <= g j) -> 0 <= rprod k g.
43
+ Proof.
44
+ induction k as [|k IH]; intros g H; cbn [rprod]; [lra|]. pose proof (IH g (fun j Hj => H j ltac:(lia))) as A.
45
+ pose proof (H k ltac:(lia)) as B. nra.
46
+ Qed.
47
+
48
+ Lemma rprod_mono : forall k g h, (forall j, (j < k)%nat -> 0 <= g j <= h j) -> rprod k g <= rprod k h.
49
+ Proof.
50
+ induction k as [|k IH]; intros g h H; cbn [rprod]; [lra|]. pose proof (IH g h (fun j Hj => H j ltac:(lia))) as A.
51
+ destruct (H k ltac:(lia)) as [B1 B2].
52
+ pose proof (rprod_nonneg k g (fun j Hj => proj1 (H j ltac:(lia)))) as C. nra.
53
+ Qed.
54
+
55
+ (* 1 - prod (1 - q_j) <= sum q_j for 0 <= q_j <= 1 *)
56
+ Lemma one_minus_prod : forall k a, (forall j, (j < k)%nat -> 0 <= a j <= 1) -> 1 - rprod k a <= rsum k (fun j => 1 - a j).
57
+ Proof.
58
+ induction k as [|k IH]; intros a H; cbn [rprod rsum]; [lra|]. pose proof (IH a (fun j Hj => H j ltac:(lia))).
59
+ destruct (rprod_range k a (fun j Hj => H j ltac:(lia))). destruct (H k ltac:(lia)). nra.
60
+ Qed.
61
+
62
+ (* the sum over i < r m of f (i mod m) is r times the sum over i < m *)
63
+ Lemma rsum_mod : forall r m f, (0 < m)%nat -> rsum (r * m) (fun i => f (i mod m)) = INR r * rsum m f.
64
+ Proof.
65
+ induction r as [|r IH]; intros m f Hm; [cbn [Nat.mul rsum INR]; lra|].
66
+ assert (G : forall k, (k <= m)%nat -> rsum (r * m + k) (fun i => f (i mod m)) = rsum (r * m) (fun i => f (i mod m)) + rsum k f).
67
+ { induction k as [|k IHk]; intro Hk; [rewrite Nat.add_0_r; cbn [rsum]; lra|].
68
+ replace (r * m + S k)%nat with (S (r * m + k)) by lia. cbn [rsum]. rewrite IHk by lia.
69
+ replace ((r * m + k) mod m)%nat with k; [lra|]. symmetry. rewrite Nat.add_comm.
70
+ rewrite Nat.Div0.mod_add. apply Nat.mod_small. lia. }
71
+ replace (S r * m)%nat with (r * m + m)%nat by lia. rewrite G by lia. rewrite IH by exact Hm. rewrite S_INR. lra.
72
+ Qed.
73
+
74
+ (* ---- the probability space ------------------------------------------------------------------------------------------ *)
75
+ Section Space.
76
+ Variable Omega : Type.
77
+ Variable P : (Omega -> Prop) -> R.
78
+ Hypothesis P_mono : forall A B : Omega -> Prop, (forall w, A w -> B w) -> P A <= P B.
79
+ Hypothesis P_or : forall A B : Omega -> Prop, P (fun w => A w \/ B w) <= P A + P B.
80
+ Hypothesis P_empty : P (fun _ => False) = 0.
81
+ Hypothesis P_true : P (fun _ => True) = 1.
82
+ Variable X : nat -> Omega -> R.
83
+
84
+ (* A depends only on the variables in I *)
85
+ Definition dep (I : nat -> Prop) (A : Omega -> Prop) : Prop :=
86
+ forall w w', (forall g, I g -> X g w = X g w') -> (A w <-> A w').
87
+
88
+ Hypothesis P_indep : forall (I J : nat -> Prop) (A B : Omega -> Prop), (forall g, I g -> J g -> False) ->
89
+ dep I A -> dep J B -> P (fun w => A w /\ B w) = P A * P B.
90
+
91
+ (* the events built from the threshold events *)
92
+ Inductive meas : (Omega -> Prop) -> Prop :=
93
+ | meas_ge : forall g c, meas (fun w => c <= X g w)
94
+ | meas_not : forall A, meas A -> meas (fun w => ~ A w)
95
+ | meas_and : forall A B, meas A -> meas B -> meas (fun w => A w /\ B w)
96
+ | meas_or : forall A B, meas A -> meas B -> meas (fun w => A w \/ B w)
97
+ | meas_ext : forall A B, meas A -> (forall w, A w <-> B w) -> meas B.
98
+
99
+ Hypothesis P_compl : forall A, meas A -> P (fun w => ~ A w) = 1 - P A.
100
+
101
+ Lemma P_ext : forall A B : Omega -> Prop, (forall w, A w <-> B w) -> P A = P B.
102
+ Proof. intros A B H. apply Rle_antisym; apply P_mono; intros w; apply H. Qed.
103
+
104
+ Lemma P_nonneg : forall A, 0 <= P A.
105
+ Proof. intro A. rewrite <- P_empty. apply P_mono. intros w []. Qed.
106
+
107
+ Lemma P_le1 : forall A, P A <= 1.
108
+ Proof. intro A. rewrite <- P_true. apply P_mono. intros. exact I. Qed.
109
+
110
+ (* the union bound over k < n *)
111
+ Lemma P_exists : forall n (A : nat -> Omega -> Prop), P (fun w => exists k, (k < n)%nat /\ A k w) <= rsum n (fun k => P (A k)).
112
+ Proof.
113
+ induction n as [|n IH]; intro A; cbn [rsum].
114
+ - rewrite <- P_empty. apply P_mono. intros w (k & Hk & _). lia.
115
+ - eapply Rle_trans; [|apply Rplus_le_compat_r; apply IH]. eapply Rle_trans; [|apply P_or].
116
+ apply P_mono. intros w (k & Hk & Ha). destruct (Nat.eq_dec k n) as [->|E]; [right; exact Ha|].
117
+ left. exists k. split; [lia | exact Ha].
118
+ Qed.
119
+
120
+ (* independent events multiply *)
121
+ Lemma P_forall : forall n (A : nat -> Omega -> Prop) (Ix : nat -> nat -> Prop),
122
+ (forall k, dep (Ix k) (A k)) -> (forall k k' g, k <> k' -> Ix k g -> Ix k' g -> False) ->
123
+ P (fun w => forall k, (k < n)%nat -> A k w) = rprod n (fun k => P (A k)).
124
+ Proof.
125
+ induction n as [|n IH]; intros A Ix Hd Hdis; cbn [rprod].
126
+ - rewrite <- P_true. apply P_ext. intro w. split; [intros; exact Logic.I | intros _ k Hk; lia].
127
+ - rewrite (P_ext _ (fun w => (forall k, (k < n)%nat -> A k w) /\ A n w)).
128
+ + rewrite (P_indep (fun g => exists k, (k < n)%nat /\ Ix k g) (Ix n)).
129
+ * rewrite (IH A Ix Hd Hdis). reflexivity.
130
+ * intros g (k & Hk & Hg) Hg'. exact (Hdis k n g ltac:(lia) Hg Hg').
131
+ * intros w w' Hww'. split; intros H k Hk; [apply (Hd k w w') | apply (Hd k w w')];
132
+ try (intros g Hg; apply Hww'; exists k; split; assumption); apply H; exact Hk.
133
+ * apply Hd.
134
+ + intro w. split; [intro H; split; [intros k Hk; apply H; lia | apply H; lia]|].
135
+ intros [H1 H2] k Hk. destruct (Nat.eq_dec k n) as [->|E]; [exact H2 | apply H1; lia].
136
+ Qed.
137
+
138
+ Lemma meas_false : meas (fun _ => False).
139
+ Proof. apply (meas_ext (fun w => 0 <= X 0%nat w /\ ~ 0 <= X 0%nat w)); [apply meas_and; [apply meas_ge | apply meas_not, meas_ge]|]. tauto. Qed.
140
+
141
+ Lemma meas_exists : forall n (A : nat -> Omega -> Prop), (forall k, meas (A k)) -> meas (fun w => exists k, (k < n)%nat /\ A k w).
142
+ Proof.
143
+ induction n as [|n IH]; intros A H.
144
+ - apply (meas_ext _ _ meas_false). intro w. split; [intros []|intros (k & Hk & _); lia].
145
+ - apply (meas_ext (fun w => (exists k, (k < n)%nat /\ A k w) \/ A n w)); [apply meas_or; [apply IH; exact H | apply H]|].
146
+ intro w. split.
147
+ + intros [(k & Hk & Ha)|Ha]; [exists k; split; [lia | exact Ha] | exists n; split; [lia | exact Ha]].
148
+ + intros (k & Hk & Ha). destruct (Nat.eq_dec k n) as [->|E]; [right; exact Ha | left; exists k; split; [lia | exact Ha]].
149
+ Qed.
150
+
151
+ (* ---- a finite search ------------------------------------------------------------------------------------------------- *)
152
+ Lemma search : forall n (A : nat -> Prop), (forall k, A k \/ ~ A k) ->
153
+ (exists k, (k < n)%nat /\ A k) \/ (forall k, (k < n)%nat -> ~ A k).
154
+ Proof.
155
+ induction n as [|n IH]; intros A Hd; [right; intros k Hk; lia|].
156
+ destruct (IH A Hd) as [(k & Hk & Ha)|Hn]; [left; exists k; split; [lia | exact Ha]|].
157
+ destruct (Hd n) as [Ha|Ha]; [left; exists n; split; [lia | exact Ha]|].
158
+ right. intros k Hk. destruct (Nat.eq_dec k n) as [->|E]; [exact Ha | apply Hn; lia].
159
+ Qed.
160
+
161
+ Lemma fails_dec : forall z e, fails z e \/ ~ fails z e.
162
+ Proof.
163
+ intros z e. unfold fails. destruct (Z_le_dec 0 z) as [Hz|Hz].
164
+ - destruct (Rlt_dec (IZR z + e) (-1/2)) as [H|H]; [left; left; split; assumption|].
165
+ right. intros [[_ H']|[H' _]]; [contradiction | lia].
166
+ - destruct (Rle_dec (-1/2) (IZR z + e)) as [H|H]; [left; right; split; [lia | exact H]|].
167
+ right. intros [[H' _]|[_ H']]; [lia | contradiction].
168
+ Qed.
169
+
170
+ (* ---- the trajectories ------------------------------------------------------------------------------------------------- *)
171
+ Section Traj.
172
+ Variable Ls : list (list tu).
173
+ Variable x0 : list bool.
174
+ (* evaluation (t, l, i) is perturbed by the variable gid t l i *)
175
+ Variable gid : nat -> nat -> nat -> nat.
176
+ Hypothesis gid_inj : forall t l i t' l' i', gid t l i = gid t' l' i' -> t = t' /\ l = l' /\ i = i'.
177
+
178
+ Definition EX (w : Omega) : nat -> nat -> nat -> list bool -> R := fun t l i _ => X (gid t l i) w.
179
+ Definition traj (w : Omega) (t : nat) : list bool := trajp Ls (EX w) x0 t.
180
+ Definition Agree (t : nat) (w : Omega) : Prop := forall t', (t' <= t)%nat -> traj w t' = orbit Ls x0 t'.
181
+
182
+ Definition nl (l : nat) : nat := length (nth l Ls []).
183
+ Definition Mr : nat := fold_right Nat.add 0%nat (map (@length tu) Ls).
184
+
185
+ Lemma rsum_rows : forall c, rsum (length Ls) (fun l => INR (nl l) * c) = INR Mr * c.
186
+ Proof.
187
+ intro c. unfold nl, Mr. clear gid_inj. induction Ls as [|L t IH]; [cbn [rsum length map fold_right INR]; lra|].
188
+ cbn [length map fold_right]. rewrite rsum_shift. cbn [nth]. rewrite IH, plus_INR. lra.
189
+ Qed.
190
+
191
+ (* the pre-activation of row i of layer l on the orbit, and the event that the perturbation of step t fails it *)
192
+ Definition zr (t l i : nat) : Z := pre (nth i (nth l Ls []) tu0) (lin Ls (orbit Ls x0 t) l).
193
+ Definition rf (t l i : nat) (w : Omega) : Prop := fails (zr t l i) (X (gid t l i) w).
194
+
195
+ Lemma rf_dec : forall t l i w, rf t l i w \/ ~ rf t l i w.
196
+ Proof. intros. apply fails_dec. Qed.
197
+
198
+ Definition Frows (t : nat) (w : Omega) : Prop := exists l, (l < length Ls)%nat /\ exists i, (i < nl l)%nat /\ rf t l i w.
199
+
200
+ Lemma Frows_dec : forall t w, Frows t w \/ ~ Frows t w.
201
+ Proof.
202
+ intros t w. destruct (search (length Ls) (fun l => exists i, (i < nl l)%nat /\ rf t l i w)) as [H|H].
203
+ - intro l. destruct (search (nl l) (fun i => rf t l i w) (fun i => rf_dec t l i w)) as [H'|H']; [left; exact H'|].
204
+ right. intros (i & Hi & Hr). exact (H' i Hi Hr).
205
+ - left. exact H.
206
+ - right. intros (l & Hl & Hx). exact (H l Hl Hx).
207
+ Qed.
208
+
209
+ (* without a failing row in step t the trajectory takes the step of the orbit *)
210
+ Lemma step_ok : forall t w, Agree t w -> ~ Frows t w -> Agree (S t) w.
211
+ Proof.
212
+ intros t w Ha Hf t' Ht'. destruct (Nat.eq_dec t' (S t)) as [->|E]; [|apply Ha; lia].
213
+ unfold traj. cbn [trajp]. fold (traj w t). rewrite (Ha t (le_n t)). cbn [orbit Nat.iter]. fold (orbit Ls x0 t).
214
+ apply lmapp_ok. intros k i Hk Hi Hr. apply Hf. exists k. split; [exact Hk|]. exists i. split; [exact Hi | exact Hr].
215
+ Qed.
216
+
217
+ Lemma Agree0 : forall w, Agree 0 w.
218
+ Proof. intros w t' Ht'. assert (t' = 0%nat) by lia. subst. reflexivity. Qed.
219
+
220
+ Lemma Agree_dec : forall t w, Agree t w \/ ~ Agree t w.
221
+ Proof.
222
+ intros t w. destruct (search (S t) (fun t' => traj w t' <> orbit Ls x0 t')) as [H|H].
223
+ - intro t'. destruct (list_eq_dec bool_dec (traj w t') (orbit Ls x0 t')) as [E|E]; [right; intro C; exact (C E) | left; exact E].
224
+ - right. intro Ha. destruct H as (t' & Ht' & Hn). apply Hn. apply Ha. lia.
225
+ - left. intros t' Ht'. destruct (list_eq_dec bool_dec (traj w t') (orbit Ls x0 t')) as [E|E]; [exact E|].
226
+ exfalso. apply (H t' ltac:(lia) E).
227
+ Qed.
228
+
229
+ (* a trajectory that leaves the orbit within T steps has a failing row in one of them *)
230
+ Lemma dev_rows : forall w T, ~ Agree T w -> exists t, (t < T)%nat /\ Frows t w.
231
+ Proof.
232
+ intros w T. induction T as [|T IH]; intro Hn; [exfalso; apply Hn; apply Agree0|].
233
+ destruct (Agree_dec T w) as [Ha|Ha].
234
+ - destruct (Frows_dec T w) as [Hf|Hf]; [exists T; split; [lia | exact Hf]|].
235
+ exfalso. apply Hn. apply step_ok; assumption.
236
+ - destruct (IH Ha) as (t & Ht & Hf). exists t. split; [lia | exact Hf].
237
+ Qed.
238
+
239
+ (* the union bound over the rows of the first T steps *)
240
+ Theorem union_rows : forall T, P (fun w => ~ Agree T w) <= rsum T (fun t => rsum (length Ls) (fun l => rsum (nl l) (fun i => P (rf t l i)))).
241
+ Proof.
242
+ intro T.
243
+ eapply Rle_trans; [apply (P_mono _ (fun w => exists t, (t < T)%nat /\ Frows t w)); intros w Hw; exact (dev_rows w T Hw)|].
244
+ eapply Rle_trans; [apply P_exists|]. apply rsum_le. intros t Ht.
245
+ eapply Rle_trans; [apply P_exists|]. apply rsum_le. intros l Hl. apply P_exists.
246
+ Qed.
247
+
248
+ (* rows at distance at least delta from the comparator fail only under perturbations of size at least delta *)
249
+ Theorem union_bound_dist : forall T delta p,
250
+ (forall t l i, (l < length Ls)%nat -> (i < nl l)%nat -> delta <= Rabs (IZR (zr t l i) + 1/2)) ->
251
+ (forall g, P (fun w => delta <= Rabs (X g w)) <= p) ->
252
+ P (fun w => ~ Agree T w) <= INR T * INR Mr * p.
253
+ Proof.
254
+ intros T delta p Hd Hp. eapply Rle_trans; [apply union_rows|]. rewrite Rmult_assoc, <- rsum_const. apply rsum_le. intros t Ht.
255
+ rewrite <- rsum_rows. apply rsum_le. intros l Hl. rewrite <- rsum_const. apply rsum_le. intros i Hi.
256
+ eapply Rle_trans; [|apply (Hp (gid t l i))]. apply P_mono. intros w Hr.
257
+ destruct (Rlt_le_dec (Rabs (X (gid t l i) w)) delta) as [Hl'|Hl']; [|exact Hl'].
258
+ exfalso. apply (no_fail (zr t l i) (X (gid t l i) w)); [pose proof (Hd t l i Hl Hi); lra | exact Hr].
259
+ Qed.
260
+
261
+ (* Proposition 6.4: P(leaving the orbit within T steps) <= T M p *)
262
+ Theorem union_bound : forall T p, (forall g, P (fun w => 1/2 <= Rabs (X g w)) <= p) ->
263
+ P (fun w => ~ Agree T w) <= INR T * INR Mr * p.
264
+ Proof. intros T p Hp. apply (union_bound_dist T (1/2) p); [intros; apply dist_half | exact Hp]. Qed.
265
+
266
+ (* ---- the failures as events ------------------------------------------------------------------------------------------- *)
267
+ Lemma rf_meas : forall t l i, meas (rf t l i).
268
+ Proof.
269
+ intros t l i. unfold rf, fails. destruct (Z_le_dec 0 (zr t l i)) as [Hz|Hz].
270
+ - apply (meas_ext (fun w => ~ (-1/2 - IZR (zr t l i) <= X (gid t l i) w))); [apply meas_not, meas_ge|].
271
+ intro w. split.
272
+ + intro H. apply Rnot_le_lt in H. left. split; [exact Hz | lra].
273
+ + intros [[_ H]|[H _]]; [lra | lia].
274
+ - apply (meas_ext (fun w => -1/2 - IZR (zr t l i) <= X (gid t l i) w)); [apply meas_ge|].
275
+ intro w. split.
276
+ + intro H. right. split; [lia | lra].
277
+ + intros [[H _]|[_ H]]; [lia | lra].
278
+ Qed.
279
+
280
+ Lemma Frows_meas : forall t, meas (Frows t).
281
+ Proof. intro t. apply meas_exists. intro l. apply meas_exists. intro i. apply rf_meas. Qed.
282
+
283
+ Definition past (t g : nat) : Prop := exists t' l i, (t' < t)%nat /\ g = gid t' l i.
284
+ Definition now (t g : nat) : Prop := exists l i, g = gid t l i.
285
+
286
+ Lemma past_now : forall t g, past t g -> now t g -> False.
287
+ Proof. intros t g (t' & l & i & Ht & ->) (l' & i' & E). apply gid_inj in E as (E & _ & _). lia. Qed.
288
+
289
+ Lemma dep_Agree : forall t, dep (past t) (Agree t).
290
+ Proof.
291
+ intros t w w' H.
292
+ assert (E : forall t', (t' <= t)%nat -> traj w t' = traj w' t').
293
+ { intros t' Ht'. unfold traj. apply trajp_ext. intros t'' l i y Ht'' Hl Hi. unfold EX. apply H.
294
+ exists t'', l, i. split; [lia | reflexivity]. }
295
+ split; intros Ha t' Ht'; [rewrite <- E | rewrite E]; try exact Ht'; apply Ha; exact Ht'.
296
+ Qed.
297
+
298
+ Lemma dep_Frows : forall t, dep (now t) (Frows t).
299
+ Proof.
300
+ intros t w w' H. unfold Frows, rf.
301
+ split; intros (l & Hl & i & Hi & Hr); exists l; split; try exact Hl; exists i; split; try exact Hi;
302
+ [rewrite <- (H (gid t l i)) | rewrite (H (gid t l i))]; try exact Hr; exists l, i; reflexivity.
303
+ Qed.
304
+
305
+ (* ---- Gaussian perturbations ---------------------------------------------------------------------------------------------- *)
306
+ Variable s : R.
307
+ Hypothesis Hs : 0 < s.
308
+ Hypothesis tail_ge : forall g c, P (fun w => c <= X g w) = Q (c / s).
309
+ Hypothesis tail_le : forall g c, P (fun w => X g w <= c) = Q (- c / s).
310
+
311
+ (* P(|X g| >= u) <= 2 Q(u/s) = erfc(u / (sqrt 2 s)) *)
312
+ Lemma P_abs : forall g u, 0 <= u -> P (fun w => u <= Rabs (X g w)) <= erfc (u / (sqrt 2 * s)).
313
+ Proof.
314
+ intros g u Hu. eapply Rle_trans; [apply (P_mono _ (fun w => u <= X g w \/ X g w <= - u))|].
315
+ - intros w H. destruct (Rle_dec 0 (X g w)) as [H0|H0]; [left; rewrite Rabs_right in H; lra|].
316
+ right. rewrite Rabs_left in H; lra.
317
+ - eapply Rle_trans; [apply P_or|]. rewrite tail_ge, tail_le, erfc_Q by exact Hs.
318
+ replace (- - u / s) with (u / s) by (field; lra). lra.
319
+ Qed.
320
+
321
+ Theorem union_gauss : forall T, P (fun w => ~ Agree T w) <= INR T * INR Mr * erfc (1 / (2 * sqrt 2 * s)).
322
+ Proof.
323
+ intro T. apply union_bound. intro g. pose proof sqrt2_pos.
324
+ replace (1 / (2 * sqrt 2 * s)) with (1/2 / (sqrt 2 * s)) by (field; lra). apply P_abs. lra.
325
+ Qed.
326
+
327
+ (* the probability that the perturbation of step t fails row i of layer l: Q(d/s), d its distance from -1/2 *)
328
+ Definition qr (t l i : nat) : R := Q (Rabs (IZR (zr t l i) + 1/2) / s).
329
+
330
+ Lemma P_rf : forall t l i, P (rf t l i) <= qr t l i.
331
+ Proof.
332
+ intros t l i. unfold rf, qr, fails. destruct (Z_le_dec 0 (zr t l i)) as [Hz|Hz].
333
+ - pose proof (IZR_le _ _ Hz) as Hz'. rewrite Rabs_right by lra.
334
+ eapply Rle_trans; [apply (P_mono _ (fun w => X (gid t l i) w <= -1/2 - IZR (zr t l i)))|].
335
+ + intros w [[_ H]|[H _]]; [lra | lia].
336
+ + rewrite tail_le. right. f_equal. field. lra.
337
+ - assert (Hz' : (zr t l i <= -1)%Z) by lia. apply IZR_le in Hz'. rewrite Rabs_left by lra.
338
+ eapply Rle_trans; [apply (P_mono _ (fun w => -1/2 - IZR (zr t l i) <= X (gid t l i) w))|].
339
+ + intros w [[H _]|[_ H]]; [lia | lra].
340
+ + rewrite tail_ge. right. f_equal. field. lra.
341
+ Qed.
342
+
343
+ Lemma qr_range : forall t l i, 0 <= qr t l i <= 1.
344
+ Proof. intros. apply Q_range. Qed.
345
+
346
+ (* the profile bound: its product form b' and its sum b *)
347
+ Definition bsumq (t : nat) : R := rsum (length Ls) (fun l => rsum (nl l) (fun i => qr t l i)).
348
+ Definition bprodq (t : nat) : R := 1 - rprod (length Ls) (fun l => rprod (nl l) (fun i => 1 - qr t l i)).
349
+
350
+ (* Proposition 6.5: given agreement up to step t, step t + 1 leaves the orbit with probability at most b'(t) *)
351
+ Theorem profile_step : forall t, P (fun w => Agree t w /\ ~ Agree (S t) w) <= P (Agree t) * bprodq t.
352
+ Proof.
353
+ intro t.
354
+ eapply Rle_trans; [apply (P_mono _ (fun w => Agree t w /\ Frows t w))|].
355
+ { intros w [Ha Hn]. split; [exact Ha|]. destruct (Frows_dec t w) as [Hf|Hf]; [exact Hf|].
356
+ exfalso. apply Hn. apply step_ok; assumption. }
357
+ rewrite (P_indep (past t) (now t)); [| exact (past_now t) | apply dep_Agree | apply dep_Frows].
358
+ apply Rmult_le_compat_l; [apply P_nonneg|].
359
+ assert (E : P (Frows t) = 1 - P (fun w => ~ Frows t w)) by (rewrite P_compl by apply Frows_meas; ring).
360
+ rewrite E. unfold bprodq. apply Rplus_le_compat_l. apply Ropp_le_contravar.
361
+ rewrite (P_ext (fun w => ~ Frows t w) (fun w => forall l, (l < length Ls)%nat -> (fun l w => forall i, (i < nl l)%nat -> ~ rf t l i w) l w)).
362
+ 2: { intro w. unfold Frows. split.
363
+ - intros H l Hl i Hi Hr. apply H. exists l. split; [exact Hl|]. exists i. split; assumption.
364
+ - intros H (l & Hl & i & Hi & Hr). exact (H l Hl i Hi Hr). }
365
+ rewrite (P_forall (length Ls) (fun l w => forall i, (i < nl l)%nat -> ~ rf t l i w) (fun l g => exists i, g = gid t l i)).
366
+ - apply rprod_mono. intros l Hl. split.
367
+ + apply rprod_nonneg. intros i Hi. pose proof (qr_range t l i). lra.
368
+ + rewrite (P_forall (nl l) (fun i w => ~ rf t l i w) (fun i g => g = gid t l i)).
369
+ * apply rprod_mono. intros i Hi. pose proof (qr_range t l i). split; [lra|].
370
+ rewrite P_compl by apply rf_meas. pose proof (P_rf t l i). lra.
371
+ * intros i w w' H. unfold rf. rewrite (H (gid t l i) eq_refl). reflexivity.
372
+ * intros i i' g Hne -> Eg. apply gid_inj in Eg as (_ & _ & Eg). contradiction.
373
+ - intros l w w' H. split; intros H' i Hi Hr; apply (H' i Hi); unfold rf in *.
374
+ + rewrite (H (gid t l i) (ex_intro _ i eq_refl)). exact Hr.
375
+ + rewrite <- (H (gid t l i) (ex_intro _ i eq_refl)). exact Hr.
376
+ - intros l l' g Hne (i & ->) (i' & Eg). apply gid_inj in Eg as (_ & Eg & _). contradiction.
377
+ Qed.
378
+
379
+ Lemma qr_le : forall t l i, qr t l i <= Q (1 / (2 * s)).
380
+ Proof.
381
+ intros t l i. unfold qr. apply Q_decr. pose proof (dist_half (zr t l i)).
382
+ unfold Rdiv. rewrite Rmult_1_l, Rinv_mult. apply Rmult_le_compat_r; [apply Rlt_le, Rinv_0_lt_compat; lra | lra].
383
+ Qed.
384
+
385
+ (* b'(t) <= b(t) <= M p / 2, p = erfc(1/(2 sqrt 2 s)) *)
386
+ Theorem profile_le : forall t, bprodq t <= bsumq t /\ bsumq t <= INR Mr * (erfc (1 / (2 * sqrt 2 * s)) / 2).
387
+ Proof.
388
+ intro t. split.
389
+ - unfold bprodq, bsumq. eapply Rle_trans; [apply one_minus_prod|].
390
+ + intros l Hl. apply rprod_range. intros i Hi. pose proof (qr_range t l i). lra.
391
+ + apply rsum_le. intros l Hl. eapply Rle_trans; [apply one_minus_prod|].
392
+ * intros i Hi. pose proof (qr_range t l i). lra.
393
+ * right. apply rsum_ext. intros i Hi. ring.
394
+ - unfold bsumq. rewrite <- rsum_rows. apply rsum_le. intros l Hl. rewrite <- rsum_const. apply rsum_le.
395
+ intros i Hi. pose proof (qr_le t l i). pose proof sqrt2_pos.
396
+ replace (erfc (1 / (2 * sqrt 2 * s)) / 2) with (Q (1 / (2 * s))); [lra|].
397
+ replace (1 / (2 * sqrt 2 * s)) with ((1/2) / (sqrt 2 * s)) by (field; lra). rewrite erfc_Q by exact Hs.
398
+ replace (1/2 / s) with (1 / (2 * s)) by (field; lra). field.
399
+ Qed.
400
+
401
+ (* a copy stopped at its first deviation or after K steps deviates with probability at most
402
+ sum_{t < K} P(it runs past step t) b'(t) *)
403
+ Lemma first_dev : forall K w, ~ Agree K w -> exists t, (t < K)%nat /\ Agree t w /\ ~ Agree (S t) w.
404
+ Proof.
405
+ induction K as [|K IH]; intros w Hn; [exfalso; apply Hn; apply Agree0|].
406
+ destruct (Agree_dec K w) as [Ha|Ha]; [exists K; split; [lia | split; assumption]|].
407
+ destruct (IH w Ha) as (t & Ht & H). exists t. split; [lia | exact H].
408
+ Qed.
409
+
410
+ Theorem copy_bound : forall K, P (fun w => ~ Agree K w) <= rsum K (fun t => P (Agree t) * bprodq t).
411
+ Proof.
412
+ intro K. eapply Rle_trans; [apply (P_mono _ (fun w => exists t, (t < K)%nat /\ (Agree t w /\ ~ Agree (S t) w)))|].
413
+ - intros w Hn. exact (first_dev K w Hn).
414
+ - eapply Rle_trans; [apply P_exists|]. apply rsum_le. intros t Ht. apply profile_step.
415
+ Qed.
416
+
417
+ (* the union bound summed over the profile *)
418
+ Theorem union_profile : forall T, P (fun w => ~ Agree T w) <= rsum T bsumq.
419
+ Proof.
420
+ intro T. eapply Rle_trans; [apply union_rows|]. apply rsum_le. intros t Ht. apply rsum_le. intros l Hl.
421
+ apply rsum_le. intros i Hi. apply P_rf.
422
+ Qed.
423
+
424
+ End Traj.
425
+
426
+ (* ---- Theorem 6.8 (ii): the amplified map ---------------------------------------------------------------------------- *)
427
+ Lemma Mr_amap : forall r n Ls, Mr (amap r n Ls) = (r * Mr Ls)%nat.
428
+ Proof.
429
+ intros r n Ls. revert n. unfold Mr. induction Ls as [|L t IH]; intro n; [cbn; lia|]. cbn [amap map fold_right].
430
+ rewrite (IH (length L)), length_alayer. lia.
431
+ Qed.
432
+
433
+ Section AmpNoise.
434
+ Variables (r : nat) (Ls : list (list tu)) (x0 : list bool) (n : nat).
435
+ Variable gid : nat -> nat -> nat -> nat.
436
+ Hypothesis gid_inj : forall t l i t' l' i', gid t l i = gid t' l' i' -> t = t' /\ l = l' /\ i = i'.
437
+ Hypothesis Ho : Nat.odd r = true.
438
+ Hypothesis Hn : length x0 = n.
439
+ Hypothesis HL : lreads n Ls.
440
+ Hypothesis Hlast : length (last Ls []) = n.
441
+ Hypothesis Hne : Ls <> [].
442
+
443
+ Lemma amp_zr : forall t l i, (l < length (amap r n Ls))%nat -> (i < nl (amap r n Ls) l)%nat ->
444
+ Rabs (IZR (zr (amap r n Ls) (rep r x0) t l i) + 1/2) = INR r * Rabs (IZR (zr Ls x0 t l (i mod nl Ls l)) + 1/2).
445
+ Proof.
446
+ intros t l i Hl Hi. rewrite length_amap in Hl. unfold zr. apply (amp_dist r Ls x0 n Ho Hn HL Hlast Hne t l i Hl Hi).
447
+ Qed.
448
+
449
+ (* every row of F^(r) sits at distance at least r/2 from the comparator along the replicated orbit *)
450
+ Theorem amp_union : forall T phi, (forall g, P (fun w => INR r / 2 <= Rabs (X g w)) <= phi) ->
451
+ P (fun w => ~ Agree (amap r n Ls) (rep r x0) gid T w) <= INR T * INR r * INR (Mr Ls) * phi.
452
+ Proof.
453
+ intros T phi Hp. rewrite Rmult_assoc with (r1 := INR T), <- mult_INR, <- (Mr_amap r n Ls).
454
+ apply (union_bound_dist (amap r n Ls) (rep r x0) gid T (INR r / 2) phi); [|exact Hp].
455
+ intros t l i Hl Hi. rewrite amp_zr by assumption. pose proof (dist_half (zr Ls x0 t l (i mod nl Ls l))).
456
+ pose proof (pos_INR r). nra.
457
+ Qed.
458
+
459
+ Variable s : R.
460
+ Hypothesis Hs : 0 < s.
461
+ Hypothesis tail_ge : forall g c, P (fun w => c <= X g w) = Q (c / s).
462
+ Hypothesis tail_le : forall g c, P (fun w => X g w <= c) = Q (- c / s).
463
+
464
+ (* P(leaving rho_r of the orbit within T steps) <= T r M erfc(r / (2 sqrt 2 s)) *)
465
+ Theorem amp_gauss : forall T, P (fun w => ~ Agree (amap r n Ls) (rep r x0) gid T w)
466
+ <= INR T * INR r * INR (Mr Ls) * erfc (INR r / (2 * sqrt 2 * s)).
467
+ Proof.
468
+ intro T. apply amp_union. intro g. pose proof sqrt2_pos. pose proof (pos_INR r).
469
+ replace (INR r / (2 * sqrt 2 * s)) with (INR r / 2 / (sqrt 2 * s)) by (field; lra).
470
+ apply (P_abs s Hs tail_ge tail_le). lra.
471
+ Qed.
472
+
473
+ (* and at most r sum_t sum_i Q(r d_{t,i} / s) over the profile of F *)
474
+ Theorem amp_profile : forall T, P (fun w => ~ Agree (amap r n Ls) (rep r x0) gid T w)
475
+ <= INR r * rsum T (fun t => rsum (length Ls) (fun l => rsum (nl Ls l) (fun i =>
476
+ Q (INR r * Rabs (IZR (zr Ls x0 t l i) + 1/2) / s)))).
477
+ Proof.
478
+ intro T. eapply Rle_trans; [apply (union_profile (amap r n Ls) (rep r x0) gid s Hs tail_ge tail_le)|].
479
+ rewrite <- rsum_scal. apply rsum_le. intros t Ht. unfold bsumq. rewrite length_amap, <- rsum_scal.
480
+ apply rsum_le. intros l Hl.
481
+ assert (Hnl : nl (amap r n Ls) l = (r * nl Ls l)%nat) by (unfold nl; apply length_nth_amap; exact Hl).
482
+ rewrite Hnl. destruct (Nat.eq_dec (nl Ls l) 0) as [Z|Z]; [rewrite Z, Nat.mul_0_r; cbn [rsum]; lra|].
483
+ set (f := fun i' => Q (INR r * Rabs (IZR (zr Ls x0 t l i') + 1/2) / s)).
484
+ rewrite (rsum_ext (r * nl Ls l) _ (fun i => f (i mod nl Ls l))).
485
+ - rewrite (rsum_mod r (nl Ls l) f) by lia. lra.
486
+ - intros i Hi. unfold qr, f. rewrite amp_zr; [reflexivity | rewrite length_amap; exact Hl | rewrite Hnl; exact Hi].
487
+ Qed.
488
+
489
+ End AmpNoise.
490
+
491
+ (* ---- the union bound for perturbations that depend on the input ---------------------------------------------------- *)
492
+ Section Gen.
493
+ Variable Ls : list (list tu).
494
+ Variable x0 : list bool.
495
+ Variable EW : Omega -> nat -> nat -> nat -> list bool -> R.
496
+
497
+ Definition trajw (w : Omega) (t : nat) : list bool := trajp Ls (EW w) x0 t.
498
+ Definition Agreew (T : nat) (w : Omega) : Prop := forall t, (t <= T)%nat -> trajw w t = orbit Ls x0 t.
499
+
500
+ Theorem union_gen : forall T, P (fun w => ~ Agreew T w)
501
+ <= rsum T (fun t => rsum (length Ls) (fun l => rsum (nl Ls l) (fun i => P (fun w => rfail Ls (EW w) x0 t l i)))).
502
+ Proof.
503
+ intro T. eapply Rle_trans; [apply (P_mono _ (fun w => exists t, (t < T)%nat /\ exists l, (l < length Ls)%nat /\
504
+ exists i, (i < nl Ls l)%nat /\ rfail Ls (EW w) x0 t l i))|].
505
+ - intros w Hn.
506
+ destruct (search T (fun t => exists l, (l < length Ls)%nat /\ exists i, (i < nl Ls l)%nat /\ rfail Ls (EW w) x0 t l i))
507
+ as [H|H]; [| exact H |].
508
+ + intro t. destruct (search (length Ls) (fun l => exists i, (i < nl Ls l)%nat /\ rfail Ls (EW w) x0 t l i)) as [H1|H1].
509
+ * intro l. destruct (search (nl Ls l) (fun i => rfail Ls (EW w) x0 t l i)) as [H2|H2];
510
+ [intro i; apply fails_dec | left; exact H2 | right; intros (i & Hi & Hr); exact (H2 i Hi Hr)].
511
+ * left; exact H1.
512
+ * right; intros (l & Hl & Hx); exact (H1 l Hl Hx).
513
+ + exfalso. apply Hn. intros t Ht. apply (traj_ok Ls (EW w) x0 T); [|exact Ht].
514
+ intros t' l i Ht' Hl Hi Hr. apply (H t' Ht'). exists l. split; [exact Hl|]. exists i. split; [exact Hi | exact Hr].
515
+ - eapply Rle_trans; [apply P_exists|]. apply rsum_le. intros t Ht.
516
+ eapply Rle_trans; [apply P_exists|]. apply rsum_le. intros l Hl. apply P_exists.
517
+ Qed.
518
+
519
+ End Gen.
520
+
521
+ (* ---- Corollary 6.9: noise on every synapse of F^(r) ------------------------------------------------------------------- *)
522
+ Lemma length_filter_map : forall (A B : Type) (g : B -> bool) (h : A -> B) (L : list A),
523
+ length (filter g (map h L)) = length (filter (fun x => g (h x)) L).
524
+ Proof. intros A B g h L. induction L as [|a t IH]; [reflexivity|]. cbn [map filter]. destruct (g (h a)); cbn [length]; rewrite IH; reflexivity. Qed.
525
+
526
+ Lemma len_filter_idx : forall (A : Type) (f : A -> bool) (l : list A) d,
527
+ length (filter (fun k => f (nth k l d)) (seq 0 (length l))) = length (filter f l).
528
+ Proof.
529
+ intros A f l d. induction l as [|a t IH]; [reflexivity|]. cbn [length seq filter nth].
530
+ rewrite <- seq_shift. destruct (f a); cbn [length]; rewrite length_filter_map; cbn [nth]; rewrite IH; reflexivity.
531
+ Qed.
532
+
533
+ Lemma nodup_map_inj : forall (A B : Type) (f : A -> B) (l : list A),
534
+ (forall x y, In x l -> In y l -> f x = f y -> x = y) -> NoDup l -> NoDup (map f l).
535
+ Proof.
536
+ intros A B f l. induction l as [|a t IH]; intros Hi Hn; cbn [map]; [constructor|]. inversion Hn as [|? ? Ha Ht]; subst.
537
+ constructor.
538
+ - intro Hin. apply in_map_iff in Hin as (b & E & Hb). apply Ha. rewrite (Hi a b (or_introl eq_refl) (or_intror Hb) (eq_sym E)). exact Hb.
539
+ - apply IH; [intros x y Hx Hy E; apply Hi; [right; exact Hx | right; exact Hy | exact E] | exact Ht].
540
+ Qed.
541
+
542
+ Section Synapse.
543
+ Variables (r : nat) (Ls : list (list tu)) (x0 : list bool) (n : nat).
544
+ Hypothesis Ho : Nat.odd r = true.
545
+ Hypothesis Hn : length x0 = n.
546
+ Hypothesis HL : lreads n Ls.
547
+ Hypothesis Hlast : length (last Ls []) = n.
548
+ Hypothesis Hne : Ls <> [].
549
+
550
+ (* the error of synapse k of row i of layer l of F^(r) at step t is the variable sid t l i k *)
551
+ Variable sid : nat -> nat -> nat -> nat -> nat.
552
+ Hypothesis sid_inj : forall t l i k t' l' i' k', sid t l i k = sid t' l' i' k' -> t = t' /\ l = l' /\ i = i' /\ k = k'.
553
+
554
+ Definition arow_at (l i : nat) : tu := nth i (nth l (amap r n Ls) []) tu0.
555
+
556
+ (* the inputs of the row that hold 1, by their position in its list *)
557
+ Definition active (l i : nat) (y : list bool) : list nat :=
558
+ filter (fun k => nth (fst (nth k (tin (arow_at l i)) (0%nat, 0%Z))) y false) (seq 0 (length (tin (arow_at l i)))).
559
+
560
+ (* the realized row reads each of its programmed inputs with weight w + e, so its error is the sum of the e at the
561
+ inputs that hold 1 *)
562
+ Definition ES (w : Omega) (t l i : nat) (y : list bool) : R := fold_right Rplus 0 (map (fun k => X (sid t l i k) w) (active l i y)).
563
+
564
+ Variable sw : R.
565
+ Hypothesis Hsw : 0 < sw.
566
+ (* a sum of m independent centred Gaussians of deviation sw is a centred Gaussian of deviation sw sqrt m *)
567
+ Hypothesis sum_ge : forall S c, NoDup S -> (1 <= length S)%nat ->
568
+ P (fun w => c <= fold_right Rplus 0 (map (fun g => X g w) S)) = Q (c / (sw * sqrt (INR (length S)))).
569
+ Hypothesis sum_le : forall S c, NoDup S -> (1 <= length S)%nat ->
570
+ P (fun w => fold_right Rplus 0 (map (fun g => X g w) S) <= c) = Q (- c / (sw * sqrt (INR (length S)))).
571
+
572
+ Variables (T Kst : nat).
573
+ Hypothesis HKst : (1 <= Kst)%nat.
574
+ (* every row of F reads at most Kst inputs holding 1 along the first T steps of the orbit *)
575
+ Hypothesis HK : forall t l i, (t < T)%nat -> (l < length Ls)%nat -> (i < nl Ls l)%nat ->
576
+ (length (filter (fun p => nth (fst p) (lin Ls (orbit Ls x0 t) l) false) (tin (nth i (nth l Ls []) tu0))) <= Kst)%nat.
577
+
578
+ Lemma active_len : forall l i y, length (active l i y) = length (filter (fun p => nth (fst p) y false) (tin (arow_at l i))).
579
+ Proof. intros l i y. unfold active. exact (len_filter_idx _ (fun p => nth (fst p) y false) (tin (arow_at l i)) (0%nat, 0%Z)). Qed.
580
+
581
+ Lemma active_nodup : forall t l i y, NoDup (map (sid t l i) (active l i y)).
582
+ Proof.
583
+ intros t l i y. apply nodup_map_inj; [|apply NoDup_filter, seq_NoDup].
584
+ intros k k' _ _ E. apply sid_inj in E. tauto.
585
+ Qed.
586
+
587
+ (* a sum of m >= 1 of the errors exceeds u in absolute value with probability at most erfc(u / (sqrt 2 sw sqrt m)) *)
588
+ Lemma P_ES : forall t l i y u, 0 <= u -> (1 <= length (active l i y))%nat ->
589
+ P (fun w => u <= Rabs (ES w t l i y)) <= erfc (u / (sqrt 2 * (sw * sqrt (INR (length (active l i y)))))).
590
+ Proof.
591
+ intros t l i y u Hu Hm. set (S := map (sid t l i) (active l i y)).
592
+ assert (HS : forall w, ES w t l i y = fold_right Rplus 0 (map (fun g => X g w) S)) by (intro w; unfold ES, S; rewrite map_map; reflexivity).
593
+ assert (Hl : length S = length (active l i y)) by (unfold S; apply length_map).
594
+ assert (Hsq : 0 < sqrt (INR (length S))) by (apply sqrt_lt_R0; apply lt_0_INR; lia).
595
+ eapply Rle_trans; [apply (P_mono _ (fun w => u <= fold_right Rplus 0 (map (fun g => X g w) S) \/
596
+ fold_right Rplus 0 (map (fun g => X g w) S) <= - u))|].
597
+ - intros w H. rewrite HS in H. destruct (Rle_dec 0 (fold_right Rplus 0 (map (fun g => X g w) S))) as [H0|H0];
598
+ [left; rewrite Rabs_right in H; lra | right; rewrite Rabs_left in H; lra].
599
+ - eapply Rle_trans; [apply P_or|]. rewrite sum_ge, sum_le by (apply active_nodup || lia). rewrite Hl in *.
600
+ set (sg := sw * sqrt (INR (length (active l i y)))).
601
+ assert (Hsg : 0 < sg) by (unfold sg; apply Rmult_lt_0_compat; [exact Hsw | exact Hsq]).
602
+ rewrite erfc_Q by exact Hsg. replace (- - u / sg) with (u / sg) by (field; lra). lra.
603
+ Qed.
604
+
605
+ Lemma ES_nil : forall w t l i y, length (active l i y) = 0%nat -> ES w t l i y = 0.
606
+ Proof. intros w t l i y H. unfold ES. destruct (active l i y); [reflexivity | discriminate]. Qed.
607
+
608
+ (* Corollary 6.9: P(leaving rho_r of the orbit within T steps) <= T r M erfc(sqrt r / (2 sqrt (2 Kst) sw)) *)
609
+ Theorem synapse_bound : P (fun w => ~ Agreew (amap r n Ls) (rep r x0) ES T w)
610
+ <= INR T * INR r * INR (Mr Ls) * erfc (sqrt (INR r) / (2 * sqrt (2 * INR Kst) * sw)).
611
+ Proof.
612
+ set (Bd := erfc (sqrt (INR r) / (2 * sqrt (2 * INR Kst) * sw))).
613
+ assert (Hr : (1 <= r)%nat) by (destruct r; [discriminate | lia]).
614
+ eapply Rle_trans; [apply union_gen|].
615
+ rewrite Rmult_assoc with (r1 := INR T), <- mult_INR, <- (Mr_amap r n Ls), Rmult_assoc, <- rsum_const.
616
+ apply rsum_le. intros t Ht. rewrite <- rsum_rows. rewrite length_amap. apply rsum_le. intros l Hl.
617
+ rewrite <- rsum_const. apply rsum_le. intros i Hi.
618
+ assert (Hi' : (i < length (nth l (amap r n Ls) []))%nat) by exact Hi.
619
+ (* the input of the row on the orbit of F^(r) is rho_r of the input of row i mod |L| on the orbit of F *)
620
+ set (y := lin Ls (orbit Ls x0 t) l).
621
+ assert (EY : lin (amap r n Ls) (orbit (amap r n Ls) (rep r x0) t) l = rep r y).
622
+ { rewrite (amp_orbit r Ls x0 n Ho Hn HL Hlast Hne). unfold y.
623
+ rewrite <- (orbit_len0 Ls x0 n Hn Hlast Hne t) at 1. apply lin_amp; [exact Ho|].
624
+ rewrite (orbit_len0 Ls x0 n Hn Hlast Hne). exact HL. }
625
+ assert (Hy : length y = win Ls n l) by (unfold y; rewrite lin_len' by lia; rewrite (orbit_len0 Ls x0 n Hn Hlast Hne); reflexivity).
626
+ assert (Hnl : (0 < nl Ls l)%nat) by (unfold nl; rewrite (length_nth_amap r Ls n l Hl) in Hi'; destruct (length (nth l Ls [])); lia).
627
+ set (u0 := nth (i mod nl Ls l) (nth l Ls []) tu0).
628
+ assert (Hrow : arow_at l i = arow r (length y) u0).
629
+ { unfold arow_at, u0. rewrite (nth_amap r Ls n l Hl). rewrite nth_alayer; [rewrite Hy; reflexivity|].
630
+ rewrite (length_nth_amap r Ls n l Hl) in Hi'. exact Hi'. }
631
+ assert (Hu0 : reads_lt (length y) u0).
632
+ { pose proof (lreads_nth Ls n l HL Hl) as F. rewrite Forall_forall in F. rewrite Hy. apply F. apply nth_In.
633
+ apply Nat.mod_upper_bound. unfold nl in *. lia. }
634
+ (* the number of inputs holding 1 *)
635
+ assert (Hm : (length (active l i (rep r y)) <= r * Kst)%nat).
636
+ { rewrite active_len, Hrow, count_arow by exact Hu0. apply Nat.mul_le_mono_l. apply HK; [exact Ht | exact Hl |].
637
+ apply Nat.mod_upper_bound. lia. }
638
+ (* the distance of the row from the comparator *)
639
+ assert (Hd : INR r / 2 <= Rabs (IZR (pre (arow_at l i) (rep r y)) + 1/2)).
640
+ { unfold arow_at. rewrite <- EY. rewrite (amp_dist r Ls x0 n Ho Hn HL Hlast Hne t l i Hl Hi').
641
+ pose proof (dist_half (zrow Ls x0 t l i)). pose proof (pos_INR r). nra. }
642
+ unfold rfail. fold (arow_at l i). rewrite EY.
643
+ destruct (Nat.eq_dec (length (active l i (rep r y))) 0) as [Z|Z].
644
+ - eapply Rle_trans; [apply (P_mono _ (fun _ => False))|].
645
+ + intros w Hf. apply (no_fail (pre (arow_at l i) (rep r y)) (ES w t l i (rep r y))); [|exact Hf].
646
+ rewrite ES_nil by exact Z. rewrite Rabs_R0. pose proof (pos_INR r). assert (0 < INR r) by (apply lt_0_INR; lia). lra.
647
+ + rewrite P_empty. unfold Bd. apply erfc_range.
648
+ - eapply Rle_trans; [apply (P_mono _ (fun w => INR r / 2 <= Rabs (ES w t l i (rep r y))))|].
649
+ + intros w Hf. destruct (Rlt_le_dec (Rabs (ES w t l i (rep r y))) (INR r / 2)) as [Hlt|Hge]; [|exact Hge].
650
+ exfalso. apply (no_fail (pre (arow_at l i) (rep r y)) (ES w t l i (rep r y))); [lra | exact Hf].
651
+ + eapply Rle_trans; [apply P_ES; [pose proof (pos_INR r); lra | lia]|]. unfold Bd. apply erfc_decr.
652
+ (* sqrt r / (2 sqrt (2 K) sw) <= (r/2) / (sqrt 2 sw sqrt m) as m <= r K *)
653
+ set (m := length (active l i (rep r y))). assert (Hm0 : (1 <= m)%nat) by lia.
654
+ pose proof sqrt2_pos. assert (HR : 0 < INR r) by (apply lt_0_INR; lia). assert (HK0 : 0 < INR Kst) by (apply lt_0_INR; lia).
655
+ assert (HM0 : 0 < INR m) by (apply lt_0_INR; lia).
656
+ assert (Hmr : INR m <= INR r * INR Kst) by (rewrite <- mult_INR; apply le_INR; exact Hm).
657
+ assert (Hsm : sqrt (INR m) <= sqrt (INR r) * sqrt (INR Kst)) by (rewrite <- sqrt_mult by lra; apply sqrt_le_1_alt; exact Hmr).
658
+ pose proof (sqrt_lt_R0 _ HR) as Sr. pose proof (sqrt_lt_R0 _ HK0) as Sk. pose proof (sqrt_lt_R0 _ HM0) as Sm.
659
+ rewrite sqrt_mult by lra. rewrite <- (sqrt_sqrt (INR r)) at 2 by lra.
660
+ set (a := sqrt (INR r)) in *. set (k := sqrt (INR Kst)) in *. set (mm := sqrt (INR m)) in *. set (q := sqrt 2) in *.
661
+ assert (Eq : a * a / 2 / (q * (sw * mm)) - a / (2 * (q * k) * sw) = a * (a * k - mm) / (2 * q * sw * mm * k)).
662
+ { field. repeat split; apply Rgt_not_eq; assumption. }
663
+ assert (0 <= a * (a * k - mm) / (2 * q * sw * mm * k)).
664
+ { apply Rmult_le_pos; [apply Rmult_le_pos; lra|]. apply Rlt_le, Rinv_0_lt_compat.
665
+ repeat apply Rmult_lt_0_compat; lra. }
666
+ lra.
667
+ Qed.
668
+
669
+ End Synapse.
670
+
671
+ (* ---- Proposition 6.10: output flips ------------------------------------------------------------------------------------ *)
672
+ Lemma P_exists_list : forall (T0 : Type) (cs : list T0) (A : T0 -> Omega -> Prop),
673
+ P (fun w => exists c, In c cs /\ A c w) <= fold_right Rplus 0 (map (fun c => P (A c)) cs).
674
+ Proof.
675
+ intros T0 cs A. induction cs as [|c cs IH]; cbn [map fold_right].
676
+ - rewrite <- P_empty. apply P_mono. intros w (c & [] & _).
677
+ - eapply Rle_trans; [|apply Rplus_le_compat_l; exact IH]. eapply Rle_trans; [|apply P_or].
678
+ apply P_mono. intros w (c' & [<-|Hc] & Ha); [left; exact Ha | right; exists c'; split; assumption].
679
+ Qed.
680
+
681
+ Lemma P_forall_list : forall (gs : list nat) (A : nat -> Omega -> Prop), NoDup gs -> (forall g, dep (fun g' => g' = g) (A g)) ->
682
+ P (fun w => forall g, In g gs -> A g w) = fold_right Rmult 1 (map (fun g => P (A g)) gs).
683
+ Proof.
684
+ intros gs A. induction gs as [|g gs IH]; intros Hn Hd; cbn [map fold_right].
685
+ - rewrite <- P_true. apply P_ext. intro w. split; [intros; exact Logic.I | intros _ g []].
686
+ - inversion Hn as [|? ? Hg Hgs]; subst.
687
+ rewrite (P_ext _ (fun w => A g w /\ (forall g', In g' gs -> A g' w))).
688
+ + rewrite (P_indep (fun g' => g' = g) (fun g' => In g' gs)).
689
+ * rewrite IH by assumption. reflexivity.
690
+ * intros g' -> Hin. exact (Hg Hin).
691
+ * apply Hd.
692
+ * intros w w' H. split; intros H' g' Hg'; [apply (Hd g' w w') | apply (Hd g' w w')];
693
+ try (intros g'' ->; apply H; exact Hg'); apply H'; exact Hg'.
694
+ + intro w. split; [intro H; split; [apply H; left; reflexivity | intros g' Hg'; apply H; right; exact Hg']|].
695
+ intros [H1 H2] g' [<-|Hg']; [exact H1 | exact (H2 g' Hg')].
696
+ Qed.
697
+
698
+ Lemma fold_mult_le : forall (gs : list nat) (f : nat -> R) eps, (forall g, 0 <= f g <= eps) ->
699
+ fold_right Rmult 1 (map f gs) <= eps ^ length gs.
700
+ Proof.
701
+ intros gs f eps H. induction gs as [|g gs IH]; cbn [map fold_right length pow]; [lra|].
702
+ destruct (H g). assert (0 <= fold_right Rmult 1 (map f gs)).
703
+ { clear IH. induction gs as [|g' gs IH']; cbn [map fold_right]; [lra|]. destruct (H g'). nra. }
704
+ apply Rmult_le_compat; assumption.
705
+ Qed.
706
+
707
+ (* at least j of the independent events A g, g in gs, each of probability at most eps: probability at most C(|gs|, j) eps^j *)
708
+ Lemma P_atleast : forall (gs : list nat) (A : nat -> Omega -> Prop) (Ab : Omega -> nat -> bool) j eps,
709
+ NoDup gs -> (forall g w, Ab w g = true <-> A g w) -> (forall g, dep (fun g' => g' = g) (A g)) ->
710
+ (forall g, P (A g) <= eps) -> 0 <= eps ->
711
+ P (fun w => (j <= length (filter (Ab w) gs))%nat) <= INR (binom (length gs) j) * eps ^ j.
712
+ Proof.
713
+ intros gs A Ab j eps Hn HA Hd Hp He.
714
+ eapply Rle_trans; [apply (P_mono _ (fun w => exists c, In c (choose j gs) /\ (forall g, In g c -> A g w)))|].
715
+ - intros w Hw. destruct (choose_spec _ (Ab w) gs j Hw) as (c & Hc & Hf). exists c. split; [exact Hc|].
716
+ intros g Hg. apply HA. exact (Hf g Hg).
717
+ - eapply Rle_trans; [apply P_exists_list|]. rewrite <- length_choose.
718
+ assert (G : forall cs, (forall c, In c cs -> In c (choose j gs)) ->
719
+ fold_right Rplus 0 (map (fun c => P (fun w => forall g, In g c -> A g w)) cs) <= INR (length cs) * eps ^ j).
720
+ { induction cs as [|c cs IH]; intro Hcs; cbn [map fold_right length]; [cbn [INR]; lra|].
721
+ rewrite S_INR. assert (Hc : In c (choose j gs)) by (apply Hcs; left; reflexivity).
722
+ rewrite P_forall_list; [| exact (choose_nodup _ gs j c Hn Hc) | exact Hd].
723
+ pose proof (fold_mult_le c (fun g => P (A g)) eps (fun g => conj (P_nonneg (A g)) (Hp g))) as F.
724
+ rewrite (choose_length _ gs j c Hc) in F.
725
+ pose proof (IH (fun c' Hc' => Hcs c' (or_intror Hc'))). lra. }
726
+ apply G. tauto.
727
+ Qed.
728
+
729
+ Lemma binom_mono : forall m m' j, (m <= m')%nat -> (binom m j <= binom m' j)%nat.
730
+ Proof.
731
+ intros m m' j H. induction H as [|m' H IH]; [lia|]. eapply Nat.le_trans; [exact IH|].
732
+ destruct j as [|j]; [destruct m'; cbn; lia|]. cbn [binom]. lia.
733
+ Qed.
734
+
735
+ Lemma length_tin_arow : forall r w u, length (tin (arow r w u)) = (r * length (tin u))%nat.
736
+ Proof.
737
+ intros r w u. unfold arow. cbn [tin].
738
+ assert (G : forall k, length (concat (map (fun c => map (fun p => ((c * w + fst p)%nat, snd p)) (tin u)) (seq 0 k)))
739
+ = (k * length (tin u))%nat).
740
+ { induction k as [|k IH]; [reflexivity|]. rewrite seq_S, map_app, concat_app, length_app, IH. cbn [map concat].
741
+ rewrite app_nil_r, length_map. lia. }
742
+ apply G.
743
+ Qed.
744
+
745
+ Section Flip.
746
+ Variables (r : nat) (Ls : list (list tu)) (x0 : list bool) (n : nat).
747
+ Hypothesis Ho : Nat.odd r = true.
748
+ Hypothesis Hn : length x0 = n.
749
+ Hypothesis HL : lwf n Ls.
750
+ Hypothesis Hlast : length (last Ls []) = n.
751
+ Hypothesis Hne : Ls <> [].
752
+
753
+ (* evaluation of row q of layer l of F^(r) at step t flips when its variable fid t l q is at least 1 *)
754
+ Variable fid : nat -> nat -> nat -> nat.
755
+ Hypothesis fid_inj : forall t l q t' l' q', fid t l q = fid t' l' q' -> t = t' /\ l = l' /\ q = q'.
756
+ Variable eps : R.
757
+ Hypothesis Heps : 0 <= eps.
758
+ Hypothesis Hflip : forall g, P (fun w => 1 <= X g w) <= eps.
759
+ (* the largest effective fan-in of a row of F *)
760
+ Variable kst : nat.
761
+ Hypothesis Hk1 : (1 <= kst)%nat.
762
+ Hypothesis Hfan : forall k i, (k < length Ls)%nat -> (i < length (nth k Ls []))%nat -> (length (tin (nth i (nth k Ls []) tu0)) <= kst)%nat.
763
+
764
+ Definition fb (w : Omega) (g : nat) : bool := if Rle_dec 1 (X g w) then true else false.
765
+ Definition Fl (w : Omega) (t l q : nat) : bool := fb w (fid t l q).
766
+
767
+ Lemma fb_iff : forall g w, fb w g = true <-> 1 <= X g w.
768
+ Proof. intros g w. unfold fb. destruct (Rle_dec 1 (X g w)); split; intro H; (discriminate || assumption || reflexivity || contradiction). Qed.
769
+
770
+ Lemma dep_flip : forall g, dep (fun g' => g' = g) (fun w => 1 <= X g w).
771
+ Proof. intros g w w' H. rewrite (H g eq_refl). reflexivity. Qed.
772
+
773
+ Definition jflip : nat := (r / 2 + 1)%nat.
774
+ Definition Bflip : R := (2 * exp 1 * INR kst * eps) ^ jflip.
775
+
776
+ Lemma jflip_odd : jflip = ((r + 1) / 2)%nat.
777
+ Proof.
778
+ unfold jflip. apply Nat.odd_spec in Ho as (hh & ->).
779
+ replace (2 * hh + 1)%nat with (1 + hh * 2)%nat by lia. rewrite Nat.div_add by lia.
780
+ replace (1 + hh * 2 + 1)%nat with (hh * 2 + 2)%nat by lia. replace (hh * 2 + 2)%nat with ((hh + 1) * 2)%nat by lia.
781
+ rewrite Nat.div_mul by lia. reflexivity.
782
+ Qed.
783
+
784
+ (* C(m, j) eps^j <= (2 e kst eps)^j when m <= r kst *)
785
+ Lemma binom_flip : forall m, (m <= r * kst)%nat -> INR (binom m jflip) * eps ^ jflip <= Bflip.
786
+ Proof.
787
+ intros m Hm. unfold Bflip. assert (Hj : (1 <= jflip)%nat) by (unfold jflip; lia).
788
+ eapply Rle_trans; [apply Rmult_le_compat_r; [apply pow_le; exact Heps | apply le_INR; apply (binom_mono m (r * kst) jflip Hm)]|].
789
+ eapply Rle_trans; [apply binom_bound; [exact Hj | exact Heps]|]. apply pow_incr. split.
790
+ - pose proof (exp_pos 1). pose proof (pos_INR (r * kst)). assert (0 < INR jflip) by (apply lt_0_INR; lia).
791
+ apply Rmult_le_pos; [|apply Rlt_le, Rinv_0_lt_compat; lra]. apply Rmult_le_pos; [nra | exact Heps].
792
+ - rewrite mult_INR. assert (HJ : 0 < INR jflip) by (apply lt_0_INR; lia).
793
+ assert (Hr2n : (r <= 2 * jflip)%nat)
794
+ by (unfold jflip; pose proof (Nat.div_mod r 2 ltac:(lia)); pose proof (Nat.mod_upper_bound r 2 ltac:(lia)); lia).
795
+ apply le_INR in Hr2n. rewrite mult_INR in Hr2n. assert (Hr2 : INR r <= 2 * INR jflip) by (cbn [INR] in Hr2n; lra).
796
+ pose proof (exp_pos 1). pose proof (pos_INR kst).
797
+ apply (Rmult_le_reg_r (INR jflip)); [exact HJ|]. unfold Rdiv. rewrite Rmult_assoc, Rinv_l, Rmult_1_r by lra.
798
+ assert (0 <= exp 1 * INR kst * eps) by (apply Rmult_le_pos; [nra | exact Heps]). nra.
799
+ Qed.
800
+
801
+ Lemma Bflip_nonneg : 0 <= Bflip.
802
+ Proof. unfold Bflip. apply pow_le. pose proof (exp_pos 1). pose proof (pos_INR kst). apply Rmult_le_pos; [nra | exact Heps]. Qed.
803
+
804
+ (* the flip patterns of Theorem flip_ok *)
805
+ Definition ppat (w : Omega) (t k : nat) : nat -> bool :=
806
+ pin (fun q => match t with O => false | S t' => Fl w t' (length Ls - 1) q end) (Fl w t) 0 k.
807
+
808
+ Definition urow (k i : nat) : tu := nth i (nth k Ls []) tu0.
809
+
810
+ Definition Ebad (t k i : nat) (w : Omega) : Prop :=
811
+ (r / 2 < length (filter (fun p => ppat w t k (fst p)) (tin (arow r (win Ls n k) (urow k i)))))%nat.
812
+ Definition Sbad (t j : nat) (w : Omega) : Prop := (r / 2 < ncnt r (fun c => Fl w t (length Ls - 1) (c * n + j)%nat))%nat.
813
+
814
+ Lemma urow_ok : forall k i, (k < length Ls)%nat -> (i < length (nth k Ls []))%nat -> rowok (win Ls n k) (urow k i).
815
+ Proof.
816
+ intros k i Hk Hi. unfold urow. clear -HL Hk Hi. revert n HL k Hk i Hi. induction Ls as [|L t IH]; intros w HL k Hk i Hi;
817
+ [cbn [length] in Hk; lia|]. destruct HL as [H1 H2]. destruct k as [|k].
818
+ - rewrite Forall_forall in H1. apply H1. apply nth_In. exact Hi.
819
+ - cbn [nth win length] in *. specialize (IH (length L) H2 k ltac:(lia) i Hi). destruct k; exact IH.
820
+ Qed.
821
+
822
+ (* the copies that a row of F^(r) reads are distinct flip variables *)
823
+ Lemma P_Ebad : forall t k i, (k < length Ls)%nat -> (i < length (nth k Ls []))%nat -> P (Ebad t k i) <= Bflip.
824
+ Proof.
825
+ intros t k i Hk Hi. pose proof (urow_ok k i Hk Hi) as Hu. destruct (arow_ok r _ _ Hu) as [Hnd _].
826
+ set (ins := tin (arow r (win Ls n k) (urow k i))).
827
+ assert (Hlen : (length ins <= r * kst)%nat) by (unfold ins; rewrite length_tin_arow; apply Nat.mul_le_mono_l; apply Hfan; assumption).
828
+ (* the source of each read position: a layer of step t, or the last layer of step t - 1 *)
829
+ assert (Gen : forall (src : nat -> nat), (forall q q', src q = src q' -> q = q') ->
830
+ (forall w, ppat w t k = fun q => fb w (src q)) -> P (Ebad t k i) <= Bflip).
831
+ { intros src Hsrc Hp. unfold Ebad.
832
+ rewrite (P_ext _ (fun w => (jflip <= length (filter (fb w) (map (fun p => src (fst p)) ins)))%nat)).
833
+ - eapply Rle_trans; [apply (P_atleast (map (fun p => src (fst p)) ins) (fun g w => 1 <= X g w) fb jflip eps)|].
834
+ + rewrite <- map_map. apply nodup_map_inj; [intros q q' _ _ E; exact (Hsrc q q' E) | exact Hnd].
835
+ + intros g w. apply fb_iff.
836
+ + exact dep_flip.
837
+ + exact Hflip.
838
+ + exact Heps.
839
+ + rewrite length_map. apply binom_flip. exact Hlen.
840
+ - intro w. rewrite length_filter_map, Hp. fold ins. unfold jflip. lia. }
841
+ destruct k as [|k].
842
+ - destruct t as [|t].
843
+ + eapply Rle_trans; [apply (P_mono _ (fun _ => False))|].
844
+ * intros w H. unfold Ebad, ppat, pin in H. cbv beta iota in H.
845
+ assert (Z : forall l : list (nat * Z), length (filter (fun _ => false) l) = 0%nat)
846
+ by (intro l; induction l as [|a l IHl]; [reflexivity | exact IHl]).
847
+ rewrite Z in H. lia.
848
+ * rewrite P_empty. apply Bflip_nonneg.
849
+ + apply (Gen (fid t (length Ls - 1))); [intros q q' E; apply fid_inj in E; tauto | reflexivity].
850
+ - apply (Gen (fid t k)); [intros q q' E; apply fid_inj in E; tauto | reflexivity].
851
+ Qed.
852
+
853
+ Lemma P_Sbad : forall t j, (j < n)%nat -> P (Sbad t j) <= Bflip.
854
+ Proof.
855
+ intros t j Hj. unfold Sbad.
856
+ rewrite (P_ext _ (fun w => (jflip <= length (filter (fb w) (map (fun c => fid t (length Ls - 1) (c * n + j)%nat) (seq 0 r))))%nat)).
857
+ - eapply Rle_trans; [apply (P_atleast _ (fun g w => 1 <= X g w) fb jflip eps)|].
858
+ + apply nodup_map_inj; [|apply seq_NoDup]. intros c c' Hc Hc' E. apply fid_inj in E as (_ & _ & E).
859
+ apply in_seq in Hc, Hc'. nia.
860
+ + intros g w. apply fb_iff.
861
+ + exact dep_flip.
862
+ + exact Hflip.
863
+ + exact Heps.
864
+ + rewrite length_map, length_seq. apply binom_flip. nia.
865
+ - intro w. rewrite length_filter_map, <- ncnt_filter. unfold jflip, Fl. lia.
866
+ Qed.
867
+
868
+ (* Proposition 6.10: the state read by majority leaves the orbit within T steps with probability at most
869
+ T (M + n) (2 e k* eps)^((r + 1)/2) *)
870
+ Theorem flip_bound : forall T, P (fun w => exists t, (t <= T)%nat /\ maj r n (trajf (amap r n Ls) (Fl w) (rep r x0) t) <> orbit Ls x0 t)
871
+ <= INR T * INR (Mr Ls + n) * (2 * exp 1 * INR kst * eps) ^ ((r + 1) / 2).
872
+ Proof.
873
+ intro T. rewrite <- jflip_odd. fold Bflip.
874
+ eapply Rle_trans; [apply (P_mono _ (fun w => (exists t, (t < T)%nat /\ exists k, (k < length Ls)%nat /\ exists i, (i < nl Ls k)%nat /\ Ebad t k i w)
875
+ \/ (exists t, (t < T)%nat /\ exists j, (j < n)%nat /\ Sbad t j w)))|].
876
+ - intros w (t0 & Ht0 & Hne0).
877
+ destruct (search T (fun t => exists k, (k < length Ls)%nat /\ exists i, (i < nl Ls k)%nat /\ Ebad t k i w)) as [H|H].
878
+ + intro t. destruct (search (length Ls) (fun k => exists i, (i < nl Ls k)%nat /\ Ebad t k i w)) as [H1|H1].
879
+ * intro k. destruct (search (nl Ls k) (fun i => Ebad t k i w)) as [H2|H2];
880
+ [intro i; unfold Ebad; lia | left; exact H2 | right; intros (i & Hi & He); exact (H2 i Hi He)].
881
+ * left. exact H1.
882
+ * right. intros (k & Hk & Hx). exact (H1 k Hk Hx).
883
+ + left. exact H.
884
+ + destruct (search T (fun t => exists j, (j < n)%nat /\ Sbad t j w)) as [H'|H'].
885
+ * intro t. destruct (search n (fun j => Sbad t j w)) as [H2|H2];
886
+ [intro j; unfold Sbad; lia | left; exact H2 | right; intros (j & Hj & Hs); exact (H2 j Hj Hs)].
887
+ * right. exact H'.
888
+ * exfalso. apply Hne0. apply (flip_ok r Ls x0 n (Fl w) T Ho Hn HL Hlast Hne); [| | exact Ht0].
889
+ -- intros t k i Ht Hk Hi. destruct (Nat.le_gt_cases (length (filter (fun p => ppat w t k (fst p)) (tin (arow r (win Ls n k) (urow k i))))) (r / 2)) as [Hc|Hc];
890
+ [exact Hc|]. exfalso. apply (H t Ht). exists k. split; [exact Hk|]. exists i. split; [exact Hi | exact Hc].
891
+ -- intros t j Ht Hj. destruct (Nat.le_gt_cases (ncnt r (fun c => Fl w t (length Ls - 1) (c * n + j)%nat)) (r / 2)) as [Hc|Hc];
892
+ [exact Hc|]. exfalso. apply (H' t Ht). exists j. split; [exact Hj | exact Hc].
893
+ - eapply Rle_trans; [apply P_or|]. rewrite plus_INR, Rmult_plus_distr_l, Rmult_plus_distr_r. apply Rplus_le_compat.
894
+ + eapply Rle_trans; [apply P_exists|]. rewrite Rmult_assoc, <- rsum_const. apply rsum_le. intros t Ht.
895
+ eapply Rle_trans; [apply P_exists|]. rewrite <- rsum_rows. apply rsum_le. intros k Hk.
896
+ eapply Rle_trans; [apply P_exists|]. rewrite <- rsum_const. apply rsum_le. intros i Hi. apply P_Ebad; assumption.
897
+ + eapply Rle_trans; [apply P_exists|]. rewrite Rmult_assoc, <- rsum_const. apply rsum_le. intros t Ht.
898
+ eapply Rle_trans; [apply P_exists|]. rewrite <- rsum_const. apply rsum_le. intros j Hj. apply P_Sbad. exact Hj.
899
+ Qed.
900
+
901
+ End Flip.
902
+
903
+ End Space.
904
+
905
+ (* the redundancy that suffices against flips: N q^j <= delta when 0 < q < 1 and j >= ln(N/delta) / ln(1/q) *)
906
+ Theorem flip_choose : forall N q delta j, 0 < N -> 0 < q < 1 -> 0 < delta ->
907
+ ln (N / delta) / ln (1 / q) <= INR j -> N * q ^ j <= delta.
908
+ Proof.
909
+ intros N q delta j HN Hq Hd H. assert (Hl : 0 < ln (1 / q)) by (rewrite <- ln_1; apply ln_increasing; [lra|];
910
+ apply (Rmult_lt_reg_r q); [lra|]; field_simplify; lra).
911
+ assert (Hj : ln (N / delta) <= INR j * ln (1 / q)) by (apply (Rmult_le_reg_r (/ ln (1 / q))); [apply Rinv_0_lt_compat; lra|];
912
+ unfold Rdiv in H; rewrite Rmult_assoc, Rinv_r by lra; lra).
913
+ replace (q ^ j) with (exp (- (INR j * ln (1 / q)))).
914
+ - assert (exp (- (INR j * ln (1 / q))) <= delta / N).
915
+ { replace (delta / N) with (exp (- ln (N / delta))) by (rewrite exp_Ropp, exp_ln by (apply Rdiv_lt_0_compat; lra); field; lra).
916
+ apply exp_le. lra. }
917
+ apply (Rmult_le_compat_l N) in H0; [|lra]. replace (N * (delta / N)) with delta in H0 by (field; lra). exact H0.
918
+ - replace (1 / q) with (/ q) by (field; lra). rewrite ln_Rinv by lra.
919
+ replace (- (INR j * - ln q)) with (INR j * ln q) by ring. rewrite <- exp_pow_nat, exp_ln by lra. reflexivity.
920
+ Qed.
921
+
922
+
923
+ (* ---- Theorem 6.8 (iii): the redundancy that suffices ---------------------------------------------------------------- *)
924
+ (* with Gaussian perturbations, r >= 2 sqrt 2 s sqrt(ln(N/delta)) gives N erfc(r / (2 sqrt 2 s)) <= delta, N = T r M *)
925
+ Theorem amp_choose : forall N s delta r, 0 <= N -> 0 < s -> 0 < delta -> 0 <= r ->
926
+ 2 * sqrt 2 * s * sqrt (ln (N / delta)) <= r -> N * erfc (r / (2 * sqrt 2 * s)) <= delta.
927
+ Proof.
928
+ intros N s delta r HN Hs Hd Hr H. pose proof sqrt2_pos.
929
+ set (x := r / (2 * sqrt 2 * s)). assert (Hx : 0 <= x) by (unfold x; apply Rmult_le_pos; [lra | apply Rlt_le, Rinv_0_lt_compat; nra]).
930
+ destruct (erfc_le_exp x Hx) as [E1 E2].
931
+ destruct (Rle_lt_dec N delta) as [Hle|Hlt].
932
+ - assert (exp (- (x * x)) <= 1) by (rewrite <- exp_0; apply exp_le; nra). nra.
933
+ - assert (Hpos : 0 < N) by lra. assert (Hq : 1 < N / delta) by (apply (Rmult_lt_reg_r delta); [lra|]; field_simplify; lra).
934
+ assert (Hln : 0 < ln (N / delta)) by (rewrite <- ln_1; apply ln_increasing; lra).
935
+ assert (Hsx : sqrt (ln (N / delta)) <= x).
936
+ { unfold x. apply (Rmult_le_reg_r (2 * sqrt 2 * s)); [nra|]. field_simplify; [|lra]. nra. }
937
+ assert (Hxx : ln (N / delta) <= x * x).
938
+ { pose proof (sqrt_pos (ln (N / delta))). rewrite <- (sqrt_sqrt (ln (N / delta))) by lra. nra. }
939
+ assert (Hexp : exp (- (x * x)) <= delta / N).
940
+ { replace (delta / N) with (exp (- ln (N / delta))).
941
+ - apply exp_le. lra.
942
+ - rewrite exp_Ropp, exp_ln by lra. field. lra. }
943
+ assert (N * erfc x <= N * (delta / N)) by (apply Rmult_le_compat_l; lra).
944
+ replace (N * (delta / N)) with delta in H1 by (field; lra). exact H1.
945
+ Qed.
946
+
947
+ (* with tails P(|e| >= u) <= exp(-u/lambda), r >= 2 lambda ln(N/delta) gives N exp(-(r/2)/lambda) <= delta *)
948
+ Theorem amp_choose_exp : forall N lam delta r, 0 < N -> 0 < lam -> 0 < delta ->
949
+ 2 * lam * ln (N / delta) <= r -> N * exp (- (r / 2) / lam) <= delta.
950
+ Proof.
951
+ intros N lam delta r HN Hl Hd H.
952
+ assert (Hexp : exp (- (r / 2) / lam) <= delta / N).
953
+ { replace (delta / N) with (exp (- ln (N / delta))).
954
+ - apply exp_le. apply (Rmult_le_reg_r (2 * lam)); [lra|]. field_simplify; lra.
955
+ - rewrite exp_Ropp, exp_ln by (apply Rdiv_lt_0_compat; lra). field. lra. }
956
+ apply (Rmult_le_compat_l N) in Hexp; [|lra]. replace (N * (delta / N)) with delta in Hexp by (field; lra). exact Hexp.
957
+ Qed.
rocq/NoiseNum.v ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* The numbers of Sections 6 and 8 that follow from the bounds on erfc: the failure probability p at s = 0.05, the
2
+ union bounds over the self-reproducing run of the host, the threshold for output flips, the redundancy for noise on
3
+ every synapse, and the deviations up to which a generation of the stored host runs exactly (Corollary 8.9).
4
+ Each is evaluated between the bounds lo1 <= erfc <= up3 with the interval tactic. *)
5
+ From Stdlib Require Import Reals Lra.
6
+ From Interval Require Import Tactic.
7
+ Set Warnings "-ambiguous-paths".
8
+ From TH Require Import Erfc.
9
+ Set Warnings "ambiguous-paths".
10
+
11
+ Local Open Scope R_scope.
12
+
13
+ Lemma erfc_between : forall x, 0 < x -> lo1 x <= erfc x <= up3 x.
14
+ Proof. intros x Hx. split; [apply erfc_lower1 | apply erfc_upper3]; exact Hx. Qed.
15
+
16
+ Ltac erfc_upper x := let H := fresh in pose proof (proj2 (erfc_between x ltac:(interval))) as H; unfold up3 in H.
17
+ Ltac erfc_lower x := let H := fresh in pose proof (proj1 (erfc_between x ltac:(interval))) as H; unfold lo1 in H.
18
+
19
+ (* ---- Section 6.1: the host, M = 41,967 rows, over the T = 1,664,939 steps of its self-reproducing run ---------------- *)
20
+ (* p = erfc(1/(2 sqrt 2 s)) at s = 0.05 *)
21
+ Theorem p_005 : 1.52e-23 <= erfc (1 / (2 * sqrt 2 * 0.05)) <= 1.53e-23.
22
+ Proof.
23
+ erfc_lower (1 / (2 * sqrt 2 * 0.05)). erfc_upper (1 / (2 * sqrt 2 * 0.05)).
24
+ split; [eapply Rle_trans; [|eassumption] | eapply Rle_trans; [eassumption|]]; interval with (i_prec 80).
25
+ Qed.
26
+
27
+ (* Proposition 6.4 bounds a deviation over the run by T M p <= 1.1e-12 at s = 0.05; at s = 0.10 the bound exceeds one *)
28
+ Theorem TMp_005 : 1664939 * 41967 * erfc (1 / (2 * sqrt 2 * 0.05)) <= 1.1e-12.
29
+ Proof.
30
+ erfc_upper (1 / (2 * sqrt 2 * 0.05)).
31
+ eapply Rle_trans; [apply Rmult_le_compat_l; [lra | eassumption]|]. interval with (i_prec 80).
32
+ Qed.
33
+
34
+ Theorem TMp_010 : 1 < 1664939 * 41967 * erfc (1 / (2 * sqrt 2 * 0.10)).
35
+ Proof.
36
+ erfc_lower (1 / (2 * sqrt 2 * 0.10)).
37
+ eapply Rlt_le_trans; [|apply Rmult_le_compat_l; [lra | eassumption]]. interval with (i_prec 80).
38
+ Qed.
39
+
40
+ (* Proposition 6.10 for the host, whose largest fan-in is 256: the threshold 1/(2 e 256) is below 7.2e-4 *)
41
+ Theorem flip_threshold : 1 / (2 * exp 1 * 256) < 7.2e-4.
42
+ Proof. interval. Qed.
43
+
44
+ (* Corollary 6.9 with K* = 8: the bound falls below 1e-3 with r = 5 at s_w = 0.05 and with r = 21 at s_w = 0.10,
45
+ and not with r = 3 and r = 19 *)
46
+ Theorem synapse_005 :
47
+ 1664939 * 5 * 41967 * erfc (sqrt 5 / (2 * sqrt (2 * 8) * 0.05)) < 1e-3
48
+ /\ 1e-3 < 1664939 * 3 * 41967 * erfc (sqrt 3 / (2 * sqrt (2 * 8) * 0.05)).
49
+ Proof.
50
+ erfc_upper (sqrt 5 / (2 * sqrt (2 * 8) * 0.05)). erfc_lower (sqrt 3 / (2 * sqrt (2 * 8) * 0.05)). split.
51
+ - eapply Rle_lt_trans; [apply Rmult_le_compat_l; [lra | eassumption]|]. interval with (i_prec 80).
52
+ - eapply Rlt_le_trans; [|apply Rmult_le_compat_l; [lra | eassumption]]. interval with (i_prec 80).
53
+ Qed.
54
+
55
+ Theorem synapse_010 :
56
+ 1664939 * 21 * 41967 * erfc (sqrt 21 / (2 * sqrt (2 * 8) * 0.10)) < 1e-3
57
+ /\ 1e-3 < 1664939 * 19 * 41967 * erfc (sqrt 19 / (2 * sqrt (2 * 8) * 0.10)).
58
+ Proof.
59
+ erfc_upper (sqrt 21 / (2 * sqrt (2 * 8) * 0.10)). erfc_lower (sqrt 19 / (2 * sqrt (2 * 8) * 0.10)). split.
60
+ - eapply Rle_lt_trans; [apply Rmult_le_compat_l; [lra | eassumption]|]. interval with (i_prec 80).
61
+ - eapply Rlt_le_trans; [|apply Rmult_le_compat_l; [lra | eassumption]]. interval with (i_prec 80).
62
+ Qed.
63
+
64
+ (* Theorem 6.8 (ii) for N_3 over the run: 1.54e-39, 3.19e-12, 1.34e-2 and more than 4e2 at s = 0.10, 0.15, 0.20, 0.25 *)
65
+ Theorem N3_first_order :
66
+ 1.53e-39 <= 1664939 * 3 * 41967 * erfc (3 / (2 * sqrt 2 * 0.10)) <= 1.55e-39
67
+ /\ 3.18e-12 <= 1664939 * 3 * 41967 * erfc (3 / (2 * sqrt 2 * 0.15)) <= 3.20e-12
68
+ /\ 1.33e-2 <= 1664939 * 3 * 41967 * erfc (3 / (2 * sqrt 2 * 0.20)) <= 1.35e-2
69
+ /\ 4.1e2 <= 1664939 * 3 * 41967 * erfc (3 / (2 * sqrt 2 * 0.25)) <= 4.2e2.
70
+ Proof.
71
+ erfc_lower (3 / (2 * sqrt 2 * 0.10)). erfc_upper (3 / (2 * sqrt 2 * 0.10)).
72
+ erfc_lower (3 / (2 * sqrt 2 * 0.15)). erfc_upper (3 / (2 * sqrt 2 * 0.15)).
73
+ erfc_lower (3 / (2 * sqrt 2 * 0.20)). erfc_upper (3 / (2 * sqrt 2 * 0.20)).
74
+ erfc_lower (3 / (2 * sqrt 2 * 0.25)). erfc_upper (3 / (2 * sqrt 2 * 0.25)).
75
+ repeat split;
76
+ first [ eapply Rle_trans; [|apply Rmult_le_compat_l; [lra | eassumption]]; interval with (i_prec 80)
77
+ | eapply Rle_trans; [apply Rmult_le_compat_l; [lra | eassumption]|]; interval with (i_prec 80) ].
78
+ Qed.
79
+
80
+ (* ---- Corollary 8.9: a generation of the stored host, T = 95,762,842,100 applications of a network of
81
+ M = 470,604,761 rows, runs exactly with probability at least 0.999 for s <= 0.050, and its threefold and fivefold
82
+ amplifications for s <= 0.148 and s <= 0.247 -------------------------------------------------------------------------- *)
83
+ Lemma erfc_at_most : forall r s s0, 0 < r -> 0 < s -> s <= s0 -> erfc (r / (2 * sqrt 2 * s)) <= erfc (r / (2 * sqrt 2 * s0)).
84
+ Proof.
85
+ intros r s s0 Hr Hs Hle. apply erfc_decr. pose proof sqrt2_pos.
86
+ apply Rmult_le_compat_l; [lra|]. apply Rinv_le_contravar; [nra | nra].
87
+ Qed.
88
+
89
+ Lemma generation_1_at : 95762842100 * 470604761 * erfc (1 / (2 * sqrt 2 * 0.050)) <= 1e-3.
90
+ Proof.
91
+ erfc_upper (1 / (2 * sqrt 2 * 0.050)).
92
+ eapply Rle_trans; [apply Rmult_le_compat_l; [lra | eassumption]|]. interval with (i_prec 100).
93
+ Qed.
94
+
95
+ Lemma generation_3_at : 95762842100 * 3 * 470604761 * erfc (3 / (2 * sqrt 2 * 0.148)) <= 1e-3.
96
+ Proof.
97
+ erfc_upper (3 / (2 * sqrt 2 * 0.148)).
98
+ eapply Rle_trans; [apply Rmult_le_compat_l; [lra | eassumption]|]. interval with (i_prec 100).
99
+ Qed.
100
+
101
+ Lemma generation_5_at : 95762842100 * 5 * 470604761 * erfc (5 / (2 * sqrt 2 * 0.247)) <= 1e-3.
102
+ Proof.
103
+ erfc_upper (5 / (2 * sqrt 2 * 0.247)).
104
+ eapply Rle_trans; [apply Rmult_le_compat_l; [lra | eassumption]|]. interval with (i_prec 120).
105
+ Qed.
106
+
107
+ Theorem generation_1 : forall s, 0 < s <= 0.050 ->
108
+ 95762842100 * 470604761 * erfc (1 / (2 * sqrt 2 * s)) <= 1e-3.
109
+ Proof.
110
+ intros s [Hs Hle]. eapply Rle_trans; [apply Rmult_le_compat_l; [lra | apply (erfc_at_most 1 s 0.050); lra]|].
111
+ exact generation_1_at.
112
+ Qed.
113
+
114
+ Theorem generation_3 : forall s, 0 < s <= 0.148 ->
115
+ 95762842100 * 3 * 470604761 * erfc (3 / (2 * sqrt 2 * s)) <= 1e-3.
116
+ Proof.
117
+ intros s [Hs Hle]. eapply Rle_trans; [apply Rmult_le_compat_l; [lra | apply (erfc_at_most 3 s 0.148); lra]|].
118
+ exact generation_3_at.
119
+ Qed.
120
+
121
+ Theorem generation_5 : forall s, 0 < s <= 0.247 ->
122
+ 95762842100 * 5 * 470604761 * erfc (5 / (2 * sqrt 2 * s)) <= 1e-3.
123
+ Proof.
124
+ intros s [Hs Hle]. eapply Rle_trans; [apply Rmult_le_compat_l; [lra | apply (erfc_at_most 5 s 0.247); lra]|].
125
+ exact generation_5_at.
126
+ Qed.
rocq/PhysLev.v ADDED
@@ -0,0 +1,1075 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* The ring network levelized (Theorem 7.2 and Corollary 8.9): N^alpha_{K,S,L} has depth 19 and the stated number of
2
+ edges, every unit but the decode lines of the output addresses 0 and 1 contributes to a next value, and
3
+ Lev(N^alpha_{K,S,L}) has depth 19 and the number of rows given below. *)
4
+ From Stdlib Require Import List Bool Arith ZArith Lia NArith.
5
+ Import ListNotations.
6
+ From TH Require Import TwoHead Net Gates Phys PhysWF PhysSem Lev BlockLev.
7
+
8
+ Section PL.
9
+ Variables al K S0 L : nat.
10
+ Hypothesis Hal : 4 <= al.
11
+ Hypothesis HK : 2 <= K.
12
+ Hypothesis HS : 1 <= S0.
13
+ Hypothesis HL : 1 <= L.
14
+
15
+ Local Notation bsP := (phys_blocks al K S0 L).
16
+ Local Notation nP := (nst al K S0 L).
17
+ Local Notation Bw := (B al).
18
+ Local Notation Nb := (N al S0).
19
+
20
+ (* ---- the depth of each unit ---------------------------------------------------------------------------------- *)
21
+ Definition cdp (x : sref) : nat :=
22
+ match x with
23
+ | SIn _ => 0
24
+ | SRef b j r =>
25
+ match b with
26
+ | 0 => 1
27
+ | 1 => if r <? S0 then 1 else 2
28
+ | 2 => if r <? K then 3 else 4
29
+ | 3 => if r <? L then 1 else 2
30
+ | 4 => if r <? Bw then 3 else 4
31
+ | 5 => if r <? K then (if Nat.eqb j 1 then 5 else 3) else (if Nat.eqb j 1 then 6 else 4)
32
+ | 6 | 7 | 8 | 13 | 14 | 18 => 5
33
+ | 9 | 11 => if Nat.eqb j 2 then 7 else 6
34
+ | 10 | 12 => 8
35
+ | 15 | 16 => 9
36
+ | 17 => 10
37
+ | 19 => if Nat.eqb r 0 then 5 else 6
38
+ | 20 => 11
39
+ | 21 => 12
40
+ | 22 => match r with 0 => 13 | 1 => 6 | _ => 14 end
41
+ | 23 => if r <? 2 then 15 else 16
42
+ | 24 => if Nat.eqb r 0 then 6 else 15
43
+ | 25 => match r with 0 => 7 | 3 => 17 | _ => 16 end
44
+ | 26 => match r with 2 => 16 | 3 => 17 | _ => 15 end
45
+ | 27 => match r with 2 => 16 | 3 => 19 | _ => 18 end
46
+ | 28 => if Nat.eqb r 3 then 17 else 16
47
+ | 29 => match r with 0 => 6 | 4 | 7 => 16 | _ => 15 end
48
+ | 30 => match r with 0 => 7 | 3 => 17 | _ => 16 end
49
+ | _ => if Nat.eqb r 3 then 18 else 17
50
+ end
51
+ end.
52
+
53
+ (* the units that contribute to a next value: all but the decode lines of the output addresses 0 and 1 *)
54
+ Definition ndp (x : sref) : bool :=
55
+ match x with SRef 8 j _ => negb (j <? 2) | _ => true end.
56
+
57
+ (* ---- the last layer that reads each signal ----------------------------------------------------------------------- *)
58
+ Definition clp (x : sref) : nat :=
59
+ match x with
60
+ | SIn i =>
61
+ if i <? nw al then 6
62
+ else if i <? nw al + K then 17
63
+ else if i <? nw al + K + K * bsz al S0 then
64
+ (let p := (i - (nw al + K)) mod bsz al S0 in if p <? Nb then 16 else if p <? Nb + S0 then 18 else 16)
65
+ else (let p := (i - (nw al + K + K * bsz al S0)) mod (2 * L) in if p <? L then 16 else 17)
66
+ | SRef b j r =>
67
+ match b with
68
+ | 0 => 20
69
+ | 1 => if r <? S0 then 2 else 3
70
+ | 2 => if r <? K then 4 else (if Nat.eqb j 4 then 6 else 5)
71
+ | 3 => if r <? L then 2 else 3
72
+ | 4 => if r <? Bw then 4 else 5
73
+ | 5 => if r <? K then (if Nat.eqb j 1 then 6 else 4) else (if Nat.eqb j 1 then 7 else 6)
74
+ | 6 | 7 => if Nat.eqb j 2 then 7 else 6
75
+ | 8 => if j <? 2 then 0 else if j <? 4 then 6 else 13
76
+ | 9 | 11 => 8
77
+ | 10 | 12 | 13 | 14 => 9
78
+ | 15 | 16 => 10
79
+ | 17 | 19 => 11
80
+ | 18 => 6
81
+ | 20 => 12
82
+ | 21 => 16
83
+ | 22 => if r <? 2 then 14 else (if j + 4 <=? HO then 15 else 20)
84
+ | 23 => if r <? 2 then 16 else 20
85
+ | 24 => if Nat.eqb r 0 then 7 else 16
86
+ | 25 => match r with 0 => 16 | 3 => 20 | _ => 17 end
87
+ | 26 => match r with 0 | 3 => 18 | 1 => 16 | _ => 17 end
88
+ | 27 => if Nat.eqb r 3 then 20 else 19
89
+ | 28 => if Nat.eqb r 3 then 20 else 17
90
+ | 29 => match r with 0 => 7 | 4 | 7 => 17 | _ => 16 end
91
+ | 30 => match r with 0 => 16 | 3 => 20 | _ => 17 end
92
+ | _ => if Nat.eqb r 3 then 20 else 18
93
+ end
94
+ end.
95
+
96
+ Lemma B_ge : 20 <= Bw.
97
+ Proof. unfold B, recw. lia. Qed.
98
+
99
+ Lemma W_ge16 : 16 <= W al.
100
+ Proof. apply W_ge. exact Hal. Qed.
101
+
102
+ (* the state bits the units name *)
103
+ Lemma cl_win : forall c, c < nw al -> clp (SIn c) = 6.
104
+ Proof. intros c H. cbn [clp]. destruct (Nat.ltb_spec c (nw al)); [reflexivity | lia]. Qed.
105
+
106
+ Lemma cl_act : forall k, clp (act al K k) = 17.
107
+ Proof.
108
+ intro k. unfold act, okap. cbn [clp]. pose proof (Nat.mod_upper_bound k K ltac:(lia)).
109
+ destruct (Nat.ltb_spec (nw al + k mod K) (nw al)); [lia|]. destruct (Nat.ltb_spec (nw al + k mod K) (nw al + K)); [reflexivity | lia].
110
+ Qed.
111
+
112
+ Lemma cl_idl : forall k, clp (idl al K k) = 17.
113
+ Proof.
114
+ intro k. unfold idl, okap. cbn [clp]. pose proof (Nat.mod_upper_bound (k + K - 1) K ltac:(lia)).
115
+ destruct (Nat.ltb_spec (nw al + (k + K - 1) mod K) (nw al)); [lia|].
116
+ destruct (Nat.ltb_spec (nw al + (k + K - 1) mod K) (nw al + K)); [reflexivity | lia].
117
+ Qed.
118
+
119
+ Lemma bank_mod : forall k q, k < K -> q < bsz al S0 ->
120
+ (nw al + K + k * bsz al S0 + q - (nw al + K)) mod bsz al S0 = q.
121
+ Proof.
122
+ intros k q Hk Hq. replace (nw al + K + k * bsz al S0 + q - (nw al + K)) with (k * bsz al S0 + q) by lia.
123
+ exact (proj2 (divmod_pair k q _ Hq)).
124
+ Qed.
125
+
126
+ Lemma bank_lt : forall k q, k < K -> q < bsz al S0 -> nw al + K + k * bsz al S0 + q < nw al + K + K * bsz al S0.
127
+ Proof. intros k q Hk Hq. assert (k * bsz al S0 + bsz al S0 <= K * bsz al S0) by nia. lia. Qed.
128
+
129
+ Lemma cl_qref : forall k p, k < K -> p < Nb -> clp (qref al K S0 k p) = 16.
130
+ Proof.
131
+ intros k p Hk Hp. unfold qref, obank. cbn [clp]. assert (Hq : p < bsz al S0) by (unfold bsz; lia).
132
+ pose proof (bank_lt k p Hk Hq).
133
+ destruct (Nat.ltb_spec (nw al + K + k * bsz al S0 + p) (nw al)); [lia|].
134
+ destruct (Nat.ltb_spec (nw al + K + k * bsz al S0 + p) (nw al + K)); [nia|].
135
+ destruct (Nat.ltb_spec (nw al + K + k * bsz al S0 + p) (nw al + K + K * bsz al S0)); [|lia].
136
+ rewrite bank_mod by assumption. destruct (Nat.ltb_spec p Nb); [reflexivity | lia].
137
+ Qed.
138
+
139
+ Lemma cl_href : forall k s, k < K -> s < S0 -> clp (href al K S0 k s) = 18.
140
+ Proof.
141
+ intros k s Hk Hs. unfold href, obank. cbn [clp]. assert (Hq : Nb + s < bsz al S0) by (unfold bsz; lia).
142
+ replace (nw al + K + k * bsz al S0 + Nb + s) with (nw al + K + k * bsz al S0 + (Nb + s)) by lia.
143
+ pose proof (bank_lt k (Nb + s) Hk Hq).
144
+ destruct (Nat.ltb_spec (nw al + K + k * bsz al S0 + (Nb + s)) (nw al)); [lia|].
145
+ destruct (Nat.ltb_spec (nw al + K + k * bsz al S0 + (Nb + s)) (nw al + K)); [lia|].
146
+ destruct (Nat.ltb_spec (nw al + K + k * bsz al S0 + (Nb + s)) (nw al + K + K * bsz al S0)); [|lia].
147
+ rewrite bank_mod by assumption. destruct (Nat.ltb_spec (Nb + s) Nb); [lia|].
148
+ destruct (Nat.ltb_spec (Nb + s) (Nb + S0)); [reflexivity | lia].
149
+ Qed.
150
+
151
+ Lemma cl_jref : forall k j, k < K -> j < Bw -> clp (jref al K S0 k j) = 16.
152
+ Proof.
153
+ intros k j Hk Hj. unfold jref, obank. cbn [clp]. assert (Hq : Nb + S0 + j < bsz al S0) by (unfold bsz; lia).
154
+ replace (nw al + K + k * bsz al S0 + Nb + S0 + j) with (nw al + K + k * bsz al S0 + (Nb + S0 + j)) by lia.
155
+ pose proof (bank_lt k (Nb + S0 + j) Hk Hq).
156
+ destruct (Nat.ltb_spec (nw al + K + k * bsz al S0 + (Nb + S0 + j)) (nw al)); [lia|].
157
+ destruct (Nat.ltb_spec (nw al + K + k * bsz al S0 + (Nb + S0 + j)) (nw al + K)); [lia|].
158
+ destruct (Nat.ltb_spec (nw al + K + k * bsz al S0 + (Nb + S0 + j)) (nw al + K + K * bsz al S0)); [|lia].
159
+ rewrite bank_mod by assumption. destruct (Nat.ltb_spec (Nb + S0 + j) Nb); [lia|].
160
+ destruct (Nat.ltb_spec (Nb + S0 + j) (Nb + S0)); [lia | reflexivity].
161
+ Qed.
162
+
163
+ Lemma tape_shape : forall k q, k < K -> q < 2 * L ->
164
+ otape al K S0 L k + q < nst al K S0 L /\ nw al + K + K * bsz al S0 <= otape al K S0 L k + q
165
+ /\ (otape al K S0 L k + q - (nw al + K + K * bsz al S0)) mod (2 * L) = q.
166
+ Proof.
167
+ intros k q Hk Hq. unfold otape, nst. assert (k * (2 * L) + 2 * L <= K * (2 * L)) by nia.
168
+ split; [lia|]. split; [lia|].
169
+ replace (nw al + K + K * bsz al S0 + k * (2 * L) + q - (nw al + K + K * bsz al S0)) with (k * (2 * L) + q) by lia.
170
+ exact (proj2 (divmod_pair k q _ Hq)).
171
+ Qed.
172
+
173
+ Lemma cl_dref : forall k i, k < K -> i < L -> clp (dref al K S0 L k i) = 16.
174
+ Proof.
175
+ intros k i Hk Hi. unfold dref. destruct (tape_shape k i Hk ltac:(lia)) as (_ & H2 & H3). cbn [clp].
176
+ destruct (Nat.ltb_spec (otape al K S0 L k + i) (nw al)); [lia|].
177
+ destruct (Nat.ltb_spec (otape al K S0 L k + i) (nw al + K)); [lia|].
178
+ destruct (Nat.ltb_spec (otape al K S0 L k + i) (nw al + K + K * bsz al S0)); [lia|].
179
+ rewrite H3. destruct (Nat.ltb_spec i L); [reflexivity | lia].
180
+ Qed.
181
+
182
+ Lemma cl_tref : forall k i, k < K -> i < L -> clp (tref al K S0 L k i) = 17.
183
+ Proof.
184
+ intros k i Hk Hi. unfold tref. replace (otape al K S0 L k + L + i) with (otape al K S0 L k + (L + i)) by lia.
185
+ destruct (tape_shape k (L + i) Hk ltac:(lia)) as (_ & H2 & H3). cbn [clp].
186
+ destruct (Nat.ltb_spec (otape al K S0 L k + (L + i)) (nw al)); [lia|].
187
+ destruct (Nat.ltb_spec (otape al K S0 L k + (L + i)) (nw al + K)); [lia|].
188
+ destruct (Nat.ltb_spec (otape al K S0 L k + (L + i)) (nw al + K + K * bsz al S0)); [lia|].
189
+ rewrite H3. destruct (Nat.ltb_spec (L + i) L); [lia | reflexivity].
190
+ Qed.
191
+
192
+ Lemma cl_fld : forall x, clp (fld K x) = if Nat.eqb x 4 then 6 else 5.
193
+ Proof. intro x. unfold fld. cbn [clp]. rewrite Nat.ltb_irrefl. reflexivity. Qed.
194
+
195
+ Lemma cl_req : forall c, 4 <= c <= HO -> clp (req c) = 15.
196
+ Proof. intros c Hc. unfold req. cbn [clp]. destruct (Nat.leb_spec (c - 4 + 4) HO); [reflexivity | lia]. Qed.
197
+
198
+ (* ---- every unit lies one layer above its deepest input and no later than the last reader of each input ---------- *)
199
+ Lemma and_in : forall (ls : list lit) x pol, In (x, pol) ls -> In (x, if pol then 1%Z else (-1)%Z) (sin (sAND ls)).
200
+ Proof. intros ls x pol H. cbn [sin sAND]. exact (in_map lw ls (x, pol) H). Qed.
201
+
202
+ Lemma or_in : forall (ls : list lit) x pol, In (x, pol) ls -> In (x, if pol then 1%Z else (-1)%Z) (sin (sOR ls)).
203
+ Proof. intros ls x pol H. cbn [sin sOR]. exact (in_map lw ls (x, pol) H). Qed.
204
+
205
+ Definition uok (b j r : nat) : Prop :=
206
+ (forall p z, In (p, z) (sin (sunit bsP b j r)) ->
207
+ S (cdp p) <= cdp (SRef b j r) /\ (ndp (SRef b j r) = true -> cdp (SRef b j r) <= clp p) /\ ndp p = true)
208
+ /\ (sin (sunit bsP b j r) = [] /\ cdp (SRef b j r) = 1
209
+ \/ exists p z, In (p, z) (sin (sunit bsP b j r)) /\ S (cdp p) = cdp (SRef b j r)).
210
+
211
+ Ltac split32 b := destruct b as [|b]; [idtac | first [exfalso; lia | split32 b]].
212
+
213
+ Ltac blk Hj Hr := cbn [phys_blocks nth bcount bsize bshape blk_zero blk_rec blk_fld blk_tc blk_ac blk_head blk_dec
214
+ blk_term blk_xs blk_pos blk_neg blk_mt blk_nt blk_pge blk_b4 blk_bge blk_vand blk_v blk_xhat blk_kap blk_bw blk_q blk_hq
215
+ blk_hs blk_hj blk_tw blk_d blk_t track mux3] in Hj, Hr |- *.
216
+
217
+ Ltac cls := rewrite ?cl_act, ?cl_idl, ?cl_fld;
218
+ repeat first
219
+ [ rewrite cl_href by (assumption || lia)
220
+ | rewrite cl_qref by (assumption || lia)
221
+ | rewrite cl_jref by (assumption || lia)
222
+ | rewrite cl_dref by (assumption || lia)
223
+ | rewrite cl_tref by (assumption || lia)
224
+ | rewrite cl_win by (assumption || (unfold nw in *; lia))
225
+ | rewrite cl_req by (unfold HO, AR, AA, AC, RR, RA, RC, CB, CT; lia) ].
226
+
227
+ Ltac ev := cbn [cdp ndp clp fld vref req zero xsref act idl href qref jref dref tref Nat.eqb negb].
228
+
229
+ Ltac fin := cls; unfold ARM, CPY, HO, xsref; ev; unfold HO;
230
+ repeat (match goal with
231
+ | |- context [Nat.ltb ?a ?b] => destruct (Nat.ltb_spec a b)
232
+ | |- context [Nat.leb ?a ?b] => destruct (Nat.leb_spec a b)
233
+ | |- context [Nat.eqb ?a ?b] => destruct (Nat.eqb_spec a b)
234
+ end; ev);
235
+ repeat split; intros; first [reflexivity | lia | discriminate].
236
+
237
+ Ltac lit_in := cbv beta iota delta [In]; repeat (first [left; reflexivity | right]).
238
+
239
+ Ltac wit P pol := exists P, (if pol then 1%Z else (-1)%Z); split;
240
+ [first [apply (and_in _ _ pol) | apply (or_in _ _ pol)]; lit_in |].
241
+
242
+ Ltac wmap P s := exists P, 1%Z; split;
243
+ [first [apply (and_in _ _ true) | apply (or_in _ _ true)]; apply in_map_iff; exists s; split; [reflexivity | apply in_seq; lia] |].
244
+
245
+ Ltac preds := let p := fresh "p" in let z := fresh "z" in let Hin := fresh "Hin" in let pol := fresh "pol" in
246
+ let Hp := fresh "Hp" in intros p z Hin;
247
+ first [ destruct (in_and _ _ _ Hin) as (pol & Hp) | destruct (in_or _ _ _ Hin) as (pol & Hp) ]; in_list Hp; fin.
248
+
249
+ Ltac pmap := let p := fresh "p" in let z := fresh "z" in let Hin := fresh "Hin" in let s := fresh "s" in
250
+ let Hs := fresh "Hs" in intros p z Hin; destruct (in_or_map _ _ _ _ Hin) as (s & Hs & ->); fin.
251
+
252
+ Theorem phys_unit_ok : forall b j r, valid bsP nP (SRef b j r) -> uok b j r.
253
+ Proof.
254
+ intros b j r (Hb & Hj & Hr). rewrite phys_length in Hb. unfold uok, sunit.
255
+ pose proof B_ge as HB. pose proof W_ge16 as HW.
256
+ split32 b; blk Hj Hr.
257
+ - (* 0: the unit that never fires *)
258
+ destruct r as [|r]; [|lia]. cbn [nth]. split; [intros p z Hin; destruct Hin | left; split; reflexivity].
259
+ - (* 1: the record bits under the slot heads *)
260
+ assert (Hk : j / Bw < K) by (apply Nat.Div0.div_lt_upper_bound; nia).
261
+ assert (Hm : j mod Bw < Bw) by (apply Nat.mod_upper_bound; lia).
262
+ destruct (Nat.lt_ge_cases r S0) as [R|R].
263
+ + rewrite nth_map_seq_app by exact R. assert (Hq : r * Bw + j mod Bw < Nb) by (unfold N; nia).
264
+ split; [preds | right; wit (href al K S0 (j / Bw) r) true; fin].
265
+ + assert (r = S0) by lia. subst r. rewrite nth_map_seq_last. split; [pmap | right; wmap (SRef 1 j 0) 0; fin].
266
+ - (* 2: the record of the active bank *)
267
+ destruct (Nat.lt_ge_cases r K) as [R|R].
268
+ + rewrite nth_map_seq_app by exact R. split; [preds | right; wit (SRef 1 (r * Bw + j) S0) true; fin].
269
+ + assert (r = K) by lia. subst r. rewrite nth_map_seq_last. split; [pmap | right; wmap (SRef 2 j 0) 0; fin].
270
+ - (* 3: the cells under the tape heads *)
271
+ destruct (Nat.lt_ge_cases r L) as [R|R].
272
+ + rewrite nth_map_seq_app by exact R. split; [preds | right; wit (tref al K S0 L j r) true; fin].
273
+ + assert (r = L) by lia. subst r. rewrite nth_map_seq_last. split; [pmap | right; wmap (SRef 3 j 0) 0; fin].
274
+ - (* 4: the bits under the arms *)
275
+ destruct (Nat.lt_ge_cases r Bw) as [R|R].
276
+ + rewrite nth_map_seq_app by exact R. split; [preds | right; wit (SRef 1 (j * Bw + r) S0) true; fin].
277
+ + assert (r = Bw) by lia. subst r. rewrite nth_map_seq_last. split; [pmap | right; wmap (SRef 4 j 0) 0; fin].
278
+ - (* 5: the cells under the read head, the arm and the copy head *)
279
+ destruct (Nat.lt_ge_cases r K) as [R|R].
280
+ + rewrite nth_map_seq_app by exact R. destruct j as [|[|[|j]]]; [| | |lia]; cbn [headsel].
281
+ * split; [preds | right; wit (SRef 3 r L) true; fin].
282
+ * split; [preds | right; wit (SRef 4 r Bw) true; fin].
283
+ * split; [preds | right; wit (SRef 3 r L) true; fin].
284
+ + assert (r = K) by lia. subst r. rewrite nth_map_seq_last. split; [pmap | right; wmap (SRef 5 j 0) 0; fin].
285
+ - (* 6: the decode lines of a0 *)
286
+ destruct r as [|r]; [|lia]. cbn [nth]. split.
287
+ + intros p z Hin. destruct (in_and_map _ _ _ _ Hin) as (t & pol & Ht & E). injection E as <- _. fin.
288
+ + right. exists (fld K (8 + 0)), (if bitsof al j 0 then 1%Z else (-1)%Z). split; [|fin].
289
+ apply (and_in _ _ (bitsof al j 0)). apply (in_map (fun t => (fld K (8 + t), bitsof al j t))). apply in_seq. lia.
290
+ - (* 7: the decode lines of a1 *)
291
+ destruct r as [|r]; [|lia]. cbn [nth]. split.
292
+ + intros p z Hin. destruct (in_and_map _ _ _ _ Hin) as (t & pol & Ht & E). injection E as <- _. fin.
293
+ + right. exists (fld K (8 + al + 0)), (if bitsof al j 0 then 1%Z else (-1)%Z). split; [|fin].
294
+ apply (and_in _ _ (bitsof al j 0)). apply (in_map (fun t => (fld K (8 + al + t), bitsof al j t))). apply in_seq. lia.
295
+ - (* 8: the decode lines of ao *)
296
+ destruct r as [|r]; [|lia]. cbn [nth]. split.
297
+ + intros p z Hin. destruct (in_and_map _ _ _ _ Hin) as (t & pol & Ht & E). injection E as <- _. fin.
298
+ + right. exists (fld K (8 + 2 * al + 0)), (if bitsof al j 0 then 1%Z else (-1)%Z). split; [|fin].
299
+ apply (and_in _ _ (bitsof al j 0)). apply (in_map (fun t => (fld K (8 + 2 * al + t), bitsof al j t))). apply in_seq. lia.
300
+ - (* 9: the terms of the first operand *)
301
+ destruct r as [|r]; [|lia]. cbn [nth]. destruct (Nat.lt_ge_cases j 4) as [J|J].
302
+ + destruct j as [|[|[|[|j]]]]; [| | | |lia]; cbn [cellref Nat.eqb orb];
303
+ split; [preds | right | preds | right | preds | right | preds | right].
304
+ * wit (SRef 6 0 0) true. fin.
305
+ * wit (SRef 6 1 0) true. fin.
306
+ * wit (SRef 5 1 K) true. fin.
307
+ * wit (SRef 6 3 0) true. fin.
308
+ + assert (E : cellref K j = SIn (j - 4)).
309
+ { unfold cellref. destruct (Nat.eqb_spec j 0); [lia|]. destruct (Nat.eqb_spec j 1); [lia|].
310
+ destruct (Nat.eqb_spec j 2); [lia|]. destruct (Nat.eqb_spec j 3); [lia|]. reflexivity. }
311
+ rewrite E. split; [preds | right; wit (SRef 6 j 0) true; fin].
312
+ - (* 10: the first operand *)
313
+ destruct r as [|r]; [|lia]. cbn [nth]. split; [pmap | right; wmap (SRef 9 2 0) 2; fin].
314
+ - (* 11: the terms of the second operand *)
315
+ destruct r as [|r]; [|lia]. cbn [nth]. destruct (Nat.lt_ge_cases j 4) as [J|J].
316
+ + destruct j as [|[|[|[|j]]]]; [| | | |lia]; cbn [cellref Nat.eqb orb];
317
+ split; [preds | right | preds | right | preds | right | preds | right].
318
+ * wit (SRef 7 0 0) true. fin.
319
+ * wit (SRef 7 1 0) true. fin.
320
+ * wit (SRef 5 1 K) true. fin.
321
+ * wit (SRef 7 3 0) true. fin.
322
+ + assert (E : cellref K j = SIn (j - 4)).
323
+ { unfold cellref. destruct (Nat.eqb_spec j 0); [lia|]. destruct (Nat.eqb_spec j 1); [lia|].
324
+ destruct (Nat.eqb_spec j 2); [lia|]. destruct (Nat.eqb_spec j 3); [lia|]. reflexivity. }
325
+ rewrite E. split; [preds | right; wit (SRef 7 j 0) true; fin].
326
+ - (* 12: the second operand *)
327
+ destruct r as [|r]; [|lia]. cbn [nth]. split; [pmap | right; wmap (SRef 11 2 0) 2; fin].
328
+ - (* 13 *) destruct r as [|r]; [|lia]. cbn [nth]. split; [preds | right; wit (fld K (2 * j)) false; fin].
329
+ - (* 14 *) destruct r as [|r]; [|lia]. cbn [nth]. split; [preds | right; wit (fld K (2 * j)) true; fin].
330
+ - (* 15 *) destruct r as [|r]; [|lia]. cbn [nth]. split; [preds | right; wit (xsref j) true; fin].
331
+ - (* 16 *) destruct r as [|r]; [|lia]. cbn [nth]. split; [preds | right; wit (xsref j) true; fin].
332
+ - (* 17: the comparisons of the weighted sum *)
333
+ destruct r as [|r]; [|lia]. cbn [nth sin]. split.
334
+ + intros p z Hin. in_list Hin; fin.
335
+ + right. exists (SRef 15 0 0), 1%Z. split; [left; reflexivity | fin].
336
+ - (* 18 *)
337
+ do 4 (destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (fld K 5) true; fin] |]). lia.
338
+ - (* 19: the comparisons of the bias *)
339
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (fld K 4) false; fin] |].
340
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 18 0 0) true; fin] |].
341
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 18 0 1) true; fin] |].
342
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 18 0 2) true; fin] |].
343
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 18 0 3) true; fin] |]. lia.
344
+ - (* 20 *) destruct r as [|r]; [|lia]. cbn [nth]. split; [preds | right; wit (SRef 17 j 0) true; fin].
345
+ - (* 21: the value of the record *)
346
+ destruct r as [|r]; [|lia]. cbn [nth]. split; [pmap | right; wmap (SRef 20 0 0) 0; fin].
347
+ - (* 22: the window after the write *)
348
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit vref true; fin] |].
349
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 8 (j + 4) 0) false; fin] |].
350
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 22 j 0) true; fin] |]. lia.
351
+ - (* 23: the bank index *)
352
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (req HO) true; fin] |].
353
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (req HO) false; fin] |].
354
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 23 j 0) true; fin] |]. lia.
355
+ - (* 24 *)
356
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 8 ARM 0) true; fin] |].
357
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (req CB) true; fin] |]. lia.
358
+ - (* 25: the bits of the banks *)
359
+ assert (Hk : j / Nb < K) by (apply Nat.Div0.div_lt_upper_bound; nia).
360
+ assert (Hp : j mod Nb < Nb) by (apply Nat.mod_upper_bound; unfold N; nia).
361
+ assert (Hs : j mod Nb / Bw < S0) by (apply Nat.Div0.div_lt_upper_bound; unfold N in *; nia).
362
+ assert (Hm : j mod Nb mod Bw < Bw) by (apply Nat.mod_upper_bound; lia).
363
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 24 (j / Nb) 0) true; fin] |].
364
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 24 (j / Nb) 1) false; fin] |].
365
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 24 (j / Nb) 1) false; fin] |].
366
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 25 j 1) true; fin] |]. lia.
367
+ - (* 26: the heads of the banks *)
368
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (req RA) true; fin] |].
369
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (req RA) false; fin] |].
370
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 26 j 1) true; fin] |].
371
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 26 j 2) true; fin] |]. lia.
372
+ - (* 27: the slot heads *)
373
+ assert (Hk : j / S0 < K) by (apply Nat.Div0.div_lt_upper_bound; nia).
374
+ assert (Hm1 : j mod S0 < S0) by (apply Nat.mod_upper_bound; lia).
375
+ assert (Hm2 : (j mod S0 + S0 - 1) mod S0 < S0) by (apply Nat.mod_upper_bound; lia).
376
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 26 (j / S0) 3) true; fin] |].
377
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 26 (j / S0) 3) false; fin] |].
378
+ destruct r as [|r]; [cbn [nth]; destruct (Nat.eqb (j mod S0) 0);
379
+ split; [preds | right; wit (SRef 26 (j / S0) 0) true; fin | preds | right; wit (SRef 26 (j / S0) 0) true; fin] |].
380
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 27 j 0) true; fin] |]. lia.
381
+ - (* 28: the bit heads *)
382
+ assert (Hk : j / Bw < K) by (apply Nat.Div0.div_lt_upper_bound; nia).
383
+ assert (Hm1 : j mod Bw < Bw) by (apply Nat.mod_upper_bound; lia).
384
+ assert (Hm2 : (j mod Bw + Bw - 1) mod Bw < Bw) by (apply Nat.mod_upper_bound; lia).
385
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 26 (j / Bw) 1) true; fin] |].
386
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 26 (j / Bw) 0) false; fin] |].
387
+ destruct r as [|r]; [cbn [nth]; destruct (Nat.eqb (j mod Bw) 0);
388
+ split; [preds | right; wit (SRef 26 (j / Bw) 0) true; fin | preds | right; wit (SRef 26 (j / Bw) 0) true; fin] |].
389
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 28 j 0) true; fin] |]. lia.
390
+ - (* 29: the moves of the tapes *)
391
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 8 CPY 0) true; fin] |].
392
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (req CT) true; fin] |].
393
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (req RR) true; fin] |].
394
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (req RC) true; fin] |].
395
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 29 j 2) true; fin] |].
396
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (req RR) false; fin] |].
397
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (req RC) false; fin] |].
398
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 29 j 5) true; fin] |]. lia.
399
+ - (* 30: the cells of the tapes *)
400
+ assert (Hk : j / L < K) by (apply Nat.Div0.div_lt_upper_bound; nia).
401
+ assert (Hm1 : j mod L < L) by (apply Nat.mod_upper_bound; lia).
402
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 29 (j / L) 0) true; fin] |].
403
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 29 (j / L) 1) false; fin] |].
404
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 29 (j / L) 1) false; fin] |].
405
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 30 j 1) true; fin] |]. lia.
406
+ - (* 31: the tape heads *)
407
+ assert (Hk : j / L < K) by (apply Nat.Div0.div_lt_upper_bound; nia).
408
+ assert (Hm1 : j mod L < L) by (apply Nat.mod_upper_bound; lia).
409
+ assert (Hm2 : (j mod L + L - 1) mod L < L) by (apply Nat.mod_upper_bound; lia).
410
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 29 (j / L) 7) true; fin] |].
411
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 29 (j / L) 7) false; fin] |].
412
+ destruct r as [|r]; [cbn [nth]; destruct (Nat.eqb (j mod L) 0);
413
+ split; [preds | right; wit (SRef 29 (j / L) 4) true; fin | preds | right; wit (SRef 29 (j / L) 4) true; fin] |].
414
+ destruct r as [|r]; [cbn [nth]; split; [preds | right; wit (SRef 31 j 0) true; fin] |]. lia.
415
+ Qed.
416
+
417
+ (* ---- the next values -------------------------------------------------------------------------------------------- *)
418
+ Lemma dm : forall m n, n <> 0 -> m / n * n + m mod n = m.
419
+ Proof. intros m n H. pose proof (Nat.div_mod m n H). lia. Qed.
420
+
421
+ Lemma Nb_ge : 20 <= Nb.
422
+ Proof. unfold N. pose proof B_ge. nia. Qed.
423
+
424
+ Lemma out_win : forall c, c < nw al -> out_ref al K S0 L c = if c + 4 <=? HO then zero else SRef 22 c 2.
425
+ Proof. intros c Hc. unfold out_ref. destruct (Nat.ltb_spec c (nw al)); [reflexivity | lia]. Qed.
426
+
427
+ Lemma out_kap : forall k, k < K -> out_ref al K S0 L (nw al + k) = SRef 23 k 2.
428
+ Proof.
429
+ intros k Hk. unfold out_ref. destruct (Nat.ltb_spec (nw al + k) (nw al)); [lia|].
430
+ destruct (Nat.ltb_spec (nw al + k) (nw al + K)); [|lia]. f_equal. lia.
431
+ Qed.
432
+
433
+ Lemma out_bank : forall k q, k < K -> q < bsz al S0 ->
434
+ out_ref al K S0 L (nw al + K + k * bsz al S0 + q) =
435
+ if q <? Nb then SRef 25 (k * Nb + q) 3
436
+ else if q <? Nb + S0 then SRef 27 (k * S0 + (q - Nb)) 3 else SRef 28 (k * Bw + (q - Nb - S0)) 3.
437
+ Proof.
438
+ intros k q Hk Hq. pose proof (bank_lt k q Hk Hq). unfold out_ref. cbv zeta.
439
+ destruct (Nat.ltb_spec (nw al + K + k * bsz al S0 + q) (nw al)); [lia|].
440
+ destruct (Nat.ltb_spec (nw al + K + k * bsz al S0 + q) (nw al + K)); [lia|].
441
+ destruct (Nat.ltb_spec (nw al + K + k * bsz al S0 + q) (nw al + K + K * bsz al S0)); [|lia].
442
+ replace (nw al + K + k * bsz al S0 + q - (nw al + K)) with (k * bsz al S0 + q) by lia.
443
+ destruct (divmod_pair k q _ Hq) as [-> ->]. reflexivity.
444
+ Qed.
445
+
446
+ Lemma out_tape : forall k q, k < K -> q < 2 * L ->
447
+ out_ref al K S0 L (otape al K S0 L k + q) = if q <? L then SRef 30 (k * L + q) 3 else SRef 31 (k * L + (q - L)) 3.
448
+ Proof.
449
+ intros k q Hk Hq. destruct (tape_shape k q Hk Hq) as (H1 & H2 & _).
450
+ assert (E : otape al K S0 L k + q - (nw al + K + K * bsz al S0) = k * (2 * L) + q) by (unfold otape; lia).
451
+ unfold out_ref. cbv zeta.
452
+ destruct (Nat.ltb_spec (otape al K S0 L k + q) (nw al)); [lia|].
453
+ destruct (Nat.ltb_spec (otape al K S0 L k + q) (nw al + K)); [lia|].
454
+ destruct (Nat.ltb_spec (otape al K S0 L k + q) (nw al + K + K * bsz al S0)); [lia|].
455
+ rewrite E. destruct (divmod_pair k q _ Hq) as [-> ->]. reflexivity.
456
+ Qed.
457
+
458
+ (* every state bit is a window cell, a line of the bank index, a bit of a bank or a cell of a tape *)
459
+ Lemma state_cases : forall i, i < nP ->
460
+ i < nw al
461
+ \/ (exists k, k < K /\ i = nw al + k)
462
+ \/ (exists k q, k < K /\ q < bsz al S0 /\ i = nw al + K + k * bsz al S0 + q)
463
+ \/ (exists k q, k < K /\ q < 2 * L /\ i = otape al K S0 L k + q).
464
+ Proof.
465
+ intros i Hi. unfold nst in Hi.
466
+ destruct (Nat.lt_ge_cases i (nw al)) as [H|H]; [left; exact H|]. right.
467
+ destruct (Nat.lt_ge_cases i (nw al + K)) as [H'|H']; [left; exists (i - nw al); split; lia|]. right.
468
+ assert (Hz : bsz al S0 <> 0) by (unfold bsz; lia).
469
+ destruct (Nat.lt_ge_cases i (nw al + K + K * bsz al S0)) as [H''|H''].
470
+ - left. exists ((i - (nw al + K)) / bsz al S0), ((i - (nw al + K)) mod bsz al S0).
471
+ pose proof (dm (i - (nw al + K)) (bsz al S0) Hz).
472
+ split; [apply Nat.Div0.div_lt_upper_bound; nia|]. split; [apply Nat.mod_upper_bound; exact Hz|]. lia.
473
+ - right. exists ((i - (nw al + K + K * bsz al S0)) / (2 * L)), ((i - (nw al + K + K * bsz al S0)) mod (2 * L)).
474
+ pose proof (dm (i - (nw al + K + K * bsz al S0)) (2 * L) ltac:(lia)).
475
+ split; [apply Nat.Div0.div_lt_upper_bound; nia|]. split; [apply Nat.mod_upper_bound; lia|]. unfold otape. lia.
476
+ Qed.
477
+
478
+ Ltac bk := cbn [phys_blocks nth bcount bsize bshape blk_zero blk_rec blk_fld blk_tc blk_ac blk_head blk_dec blk_term
479
+ blk_xs blk_pos blk_neg blk_mt blk_nt blk_pge blk_b4 blk_bge blk_vand blk_v blk_xhat blk_kap blk_bw blk_q blk_hq blk_hs
480
+ blk_hj blk_tw blk_d blk_t track mux3 headsel].
481
+
482
+ Ltac vld := cbn [valid]; rewrite phys_length; bk; repeat split; unfold nw in *; nia.
483
+
484
+ Lemma out_valid : forall i, i < nP -> valid bsP nP (out_ref al K S0 L i).
485
+ Proof.
486
+ intros i Hi. pose proof W_ge16. pose proof B_ge. pose proof Nb_ge.
487
+ destruct (state_cases i Hi) as [Hw|[(k & Hk & ->)|[(k & q & Hk & Hq & ->)|(k & q & Hk & Hq & ->)]]].
488
+ - rewrite out_win by exact Hw. destruct (_ <=? _); unfold zero; vld.
489
+ - rewrite out_kap by exact Hk. vld.
490
+ - rewrite out_bank by assumption. unfold bsz in Hq.
491
+ destruct (Nat.ltb_spec q Nb); [vld|]. destruct (Nat.ltb_spec q (Nb + S0)); vld.
492
+ - rewrite out_tape by assumption. destruct (Nat.ltb_spec q L); vld.
493
+ Qed.
494
+
495
+ (* every next value is read at layer 20, after the last *)
496
+ Lemma cl_out : forall i, i < nP -> clp (out_ref al K S0 L i) = 20.
497
+ Proof.
498
+ intros i Hi.
499
+ destruct (state_cases i Hi) as [Hw|[(k & Hk & ->)|[(k & q & Hk & Hq & ->)|(k & q & Hk & Hq & ->)]]].
500
+ - rewrite out_win by exact Hw. destruct (Nat.leb_spec (i + 4) HO); [reflexivity|]. cbn [clp].
501
+ destruct (Nat.leb_spec (i + 4) HO); [lia | reflexivity].
502
+ - rewrite out_kap by exact Hk. reflexivity.
503
+ - rewrite out_bank by assumption. destruct (q <? Nb); [reflexivity|]. destruct (q <? Nb + S0); reflexivity.
504
+ - rewrite out_tape by assumption. destruct (q <? L); reflexivity.
505
+ Qed.
506
+
507
+ Lemma nd_out : forall i, i < nP -> ndp (out_ref al K S0 L i) = true.
508
+ Proof.
509
+ intros i Hi.
510
+ destruct (state_cases i Hi) as [Hw|[(k & Hk & ->)|[(k & q & Hk & Hq & ->)|(k & q & Hk & Hq & ->)]]].
511
+ - rewrite out_win by exact Hw. destruct (_ <=? _); reflexivity.
512
+ - rewrite out_kap by exact Hk. reflexivity.
513
+ - rewrite out_bank by assumption. destruct (q <? Nb); [reflexivity|]. destruct (q <? Nb + S0); reflexivity.
514
+ - rewrite out_tape by assumption. destruct (q <? L); reflexivity.
515
+ Qed.
516
+
517
+ (* ---- every signal but a next value has a contributing reader at its last reading layer ------------------------ *)
518
+ Ltac rdr B J R pol := right; exists B, J, R, (if pol then 1%Z else (-1)%Z); split; [vld | split; [reflexivity | split]].
519
+ Ltac su := unfold sunit; bk; cbn [nth].
520
+ Ltac lin pol := first [apply (and_in _ _ pol) | apply (or_in _ _ pol)]; lit_in.
521
+ Ltac lmap s := apply (or_in _ _ true); apply in_map_iff; exists s; split; [reflexivity | apply in_seq; lia].
522
+
523
+ Theorem phys_reader : forall x, valid bsP nP x -> (forall i, i < nP -> out_ref al K S0 L i <> x) ->
524
+ clp x = 0 \/ exists b j r z, valid bsP nP (SRef b j r) /\ ndp (SRef b j r) = true /\ In (x, z) (sin (sunit bsP b j r))
525
+ /\ cdp (SRef b j r) = clp x.
526
+ Proof.
527
+ intros x Hx Hno. pose proof B_ge as HB. pose proof W_ge16 as HW. pose proof Nb_ge as HN.
528
+ destruct x as [i|b j r].
529
+ - (* the state bits *)
530
+ cbn [valid] in Hx.
531
+ destruct (state_cases i Hx) as [Hw|[(k & Hk & ->)|[(k & q & Hk & Hq & ->)|(k & q & Hk & Hq & ->)]]].
532
+ + rdr 22 i 1 true; [su; lin true | fin].
533
+ + rdr 26 k 3 true;
534
+ replace (SIn (nw al + k)) with (act al K k) by (unfold act, okap; rewrite Nat.mod_small by lia; reflexivity);
535
+ [su; lin true | fin].
536
+ + destruct (Nat.lt_ge_cases q Nb) as [Q1|Q1]; [|destruct (Nat.lt_ge_cases q (Nb + S0)) as [Q2|Q2]].
537
+ * rdr 25 (k * Nb + q) 2 true; replace (SIn (nw al + K + k * bsz al S0 + q)) with (qref al K S0 k q) by reflexivity.
538
+ -- su. destruct (divmod_pair k q _ Q1) as [E1 E2]. rewrite E1, E2. lin true.
539
+ -- fin.
540
+ * assert (Q : q - Nb < S0) by lia.
541
+ rdr 27 (k * S0 + (q - Nb)) 1 true;
542
+ replace (SIn (nw al + K + k * bsz al S0 + q)) with (href al K S0 k (q - Nb)) by (unfold href, obank; f_equal; lia).
543
+ -- su. destruct (divmod_pair k (q - Nb) S0 Q) as [E1 E2]. rewrite E1, E2. lin true.
544
+ -- fin.
545
+ * assert (Q : q - Nb - S0 < Bw) by (unfold bsz in Hq; lia).
546
+ rdr 28 (k * Bw + (q - Nb - S0)) 1 true;
547
+ replace (SIn (nw al + K + k * bsz al S0 + q)) with (jref al K S0 k (q - Nb - S0)) by (unfold jref, obank; f_equal; lia).
548
+ -- su. destruct (divmod_pair k (q - Nb - S0) Bw Q) as [E1 E2]. rewrite E1, E2. lin true.
549
+ -- fin.
550
+ + destruct (Nat.lt_ge_cases q L) as [Q|Q].
551
+ * rdr 30 (k * L + q) 2 true; replace (SIn (otape al K S0 L k + q)) with (dref al K S0 L k q) by reflexivity.
552
+ -- su. destruct (divmod_pair k q L Q) as [E1 E2]. rewrite E1, E2. lin true.
553
+ -- fin.
554
+ * assert (Q' : q - L < L) by lia.
555
+ rdr 31 (k * L + (q - L)) 1 true;
556
+ replace (SIn (otape al K S0 L k + q)) with (tref al K S0 L k (q - L)) by (unfold tref; f_equal; lia).
557
+ -- su. destruct (divmod_pair k (q - L) L Q') as [E1 E2]. rewrite E1, E2. lin true.
558
+ -- fin.
559
+ - (* the units *)
560
+ destruct Hx as (Hb & Hj & Hr). rewrite phys_length in Hb.
561
+ split32 b; blk Hj Hr.
562
+ + (* 0 *) exfalso. apply (Hno 0); [unfold nst, nw; lia|]. rewrite out_win by (unfold nw; lia).
563
+ assert (j = 0) by lia. assert (r = 0) by lia. subst. reflexivity.
564
+ + (* 1 *) assert (Hk : j / Bw < K) by (apply Nat.Div0.div_lt_upper_bound; nia).
565
+ assert (Hm : j mod Bw < Bw) by (apply Nat.mod_upper_bound; lia).
566
+ destruct (Nat.lt_ge_cases r S0) as [R|R].
567
+ * rdr 1 j S0 true; [su; rewrite nth_map_seq_last; lmap r | fin].
568
+ * assert (r = S0) by lia. subst r.
569
+ rdr 2 (j mod Bw) (j / Bw) true; [su; rewrite nth_map_seq_app by exact Hk; rewrite dm by lia; lin true | fin].
570
+ + (* 2 *) destruct (Nat.lt_ge_cases r K) as [R|R].
571
+ * rdr 2 j K true; [su; rewrite nth_map_seq_last; lmap r | fin].
572
+ * assert (r = K) by lia. subst r. assert (Hj' : j < 8 + 3 * al) by (unfold B, recw in Hj; lia).
573
+ destruct (Nat.lt_ge_cases j 8) as [J|J].
574
+ -- destruct j as [|[|[|[|[|[|[|[|j]]]]]]]]; [| | | | | | | | lia].
575
+ ++ rdr 13 0 0 false; [su; lin false | fin].
576
+ ++ rdr 13 0 0 true; [su; lin true | fin].
577
+ ++ rdr 13 1 0 false; [su; lin false | fin].
578
+ ++ rdr 13 1 0 true; [su; lin true | fin].
579
+ ++ rdr 19 0 1 false; [su; lin false | fin].
580
+ ++ rdr 18 0 0 true; [su; lin true | fin].
581
+ ++ rdr 18 0 0 true; [su; lin true | fin].
582
+ ++ rdr 18 0 0 true; [su; lin true | fin].
583
+ -- destruct (Nat.lt_ge_cases j (8 + al)) as [J1|J1]; [|destruct (Nat.lt_ge_cases j (8 + 2 * al)) as [J2|J2]].
584
+ ++ rdr 6 0 0 (bitsof al 0 (j - 8)); [su | fin].
585
+ apply (and_in _ _ (bitsof al 0 (j - 8))). apply in_map_iff. exists (j - 8).
586
+ split; [unfold fld; f_equal; f_equal; lia | apply in_seq; lia].
587
+ ++ rdr 7 0 0 (bitsof al 0 (j - 8 - al)); [su | fin].
588
+ apply (and_in _ _ (bitsof al 0 (j - 8 - al))). apply in_map_iff. exists (j - 8 - al).
589
+ split; [unfold fld; f_equal; f_equal; lia | apply in_seq; lia].
590
+ ++ rdr 8 2 0 (bitsof al 2 (j - 8 - 2 * al)); [su | fin].
591
+ apply (and_in _ _ (bitsof al 2 (j - 8 - 2 * al))). apply in_map_iff. exists (j - 8 - 2 * al).
592
+ split; [unfold fld; f_equal; f_equal; lia | apply in_seq; lia].
593
+ + (* 3 *) destruct (Nat.lt_ge_cases r L) as [R|R].
594
+ * rdr 3 j L true; [su; rewrite nth_map_seq_last; lmap r | fin].
595
+ * assert (r = L) by lia. subst r. rdr 5 0 j true; [su; rewrite nth_map_seq_app by exact Hj; cbn [headsel]; lin true | fin].
596
+ + (* 4 *) destruct (Nat.lt_ge_cases r Bw) as [R|R].
597
+ * rdr 4 j (B al) true; [su; rewrite nth_map_seq_last; lmap r | fin].
598
+ * assert (r = Bw) by lia. subst r. rdr 5 1 j true; [su; rewrite nth_map_seq_app by exact Hj; cbn [headsel]; lin true | fin].
599
+ + (* 5 *) destruct (Nat.lt_ge_cases r K) as [R|R].
600
+ * rdr 5 j K true; [su; rewrite nth_map_seq_last; lmap r | fin].
601
+ * assert (r = K) by lia. subst r. destruct j as [|[|[|j]]]; [| | | lia].
602
+ -- rdr 9 1 0 true; [su; lin true | fin].
603
+ -- rdr 9 2 0 true; [su; lin true | fin].
604
+ -- rdr 9 3 0 true; [su; lin true | fin].
605
+ + (* 6 *) destruct r as [|r]; [|lia]. rdr 9 j 0 true; [su; lin true | fin].
606
+ + (* 7 *) destruct r as [|r]; [|lia]. rdr 11 j 0 true; [su; lin true | fin].
607
+ + (* 8 *) destruct r as [|r]; [|lia].
608
+ destruct (Nat.lt_ge_cases j 2) as [J|J]; [left; cbn [clp]; destruct (Nat.ltb_spec j 2); [reflexivity | lia]|].
609
+ destruct (Nat.lt_ge_cases j 4) as [J'|J'].
610
+ * destruct j as [|[|[|[|j]]]]; try lia.
611
+ -- rdr 24 0 0 true; [su; lin true | fin].
612
+ -- rdr 29 0 0 true; [su; lin true | fin].
613
+ * rdr 22 (j - 4) 0 true; [su; replace (j - 4 + 4) with j by lia; lin true | fin].
614
+ + (* 9 *) destruct r as [|r]; [|lia]. rdr 10 0 0 true; [su; lmap j | fin].
615
+ + (* 10 *) destruct j as [|j]; [|lia]. destruct r as [|r]; [|lia]. rdr 15 0 0 true; [su; lin true | fin].
616
+ + (* 11 *) destruct r as [|r]; [|lia]. rdr 12 0 0 true; [su; lmap j | fin].
617
+ + (* 12 *) destruct j as [|j]; [|lia]. destruct r as [|r]; [|lia]. rdr 15 1 0 true; [su; lin true | fin].
618
+ + (* 13 *) destruct r as [|r]; [|lia]. rdr 15 j 0 true; [su; lin true | fin].
619
+ + (* 14 *) destruct r as [|r]; [|lia]. rdr 16 j 0 true; [su; lin true | fin].
620
+ + (* 15 *) destruct r as [|r]; [|lia]. right. exists 17, 0, 0, 1%Z. split; [vld|]. split; [reflexivity|].
621
+ split; [su; cbn [sin]; destruct j as [|[|j]]; [left; reflexivity | right; left; reflexivity | lia] | fin].
622
+ + (* 16 *) destruct r as [|r]; [|lia]. right. exists 17, 0, 0, (-1)%Z. split; [vld|]. split; [reflexivity|].
623
+ split; [su; cbn [sin]; destruct j as [|[|j]]; [right; right; left; reflexivity | right; right; right; left; reflexivity | lia]
624
+ | fin].
625
+ + (* 17 *) destruct r as [|r]; [|lia]. rdr 20 j 0 true; [su; lin true | fin].
626
+ + (* 18 *) destruct j as [|j]; [|lia]. destruct r as [|[|[|[|r]]]]; [| | | | lia].
627
+ * rdr 19 0 1 true; [su; lin true | fin].
628
+ * rdr 19 0 2 true; [su; lin true | fin].
629
+ * rdr 19 0 3 true; [su; lin true | fin].
630
+ * rdr 19 0 4 true; [su; lin true | fin].
631
+ + (* 19 *) destruct j as [|j]; [|lia]. destruct r as [|[|[|[|[|r]]]]]; [| | | | | lia].
632
+ * rdr 20 2 0 true; [su; lin true | fin].
633
+ * rdr 20 1 0 true; [su; lin true | fin].
634
+ * rdr 20 0 0 true; [su; lin true | fin].
635
+ * rdr 20 3 0 true; [su; lin true | fin].
636
+ * rdr 20 4 0 true; [su; lin true | fin].
637
+ + (* 20 *) destruct r as [|r]; [|lia]. rdr 21 0 0 true; [su; lmap j | fin].
638
+ + (* 21 *) destruct j as [|j]; [|lia]. destruct r as [|r]; [|lia]. rdr 25 0 1 true; [su; lin true | fin].
639
+ + (* 22 *) destruct r as [|[|[|r]]]; [| | | lia].
640
+ * rdr 22 j 2 true; [su; lin true | fin].
641
+ * rdr 22 j 2 true; [su; lin true | fin].
642
+ * destruct (Nat.leb_spec (j + 4) HO) as [Jr|Jr].
643
+ -- unfold HO in Jr.
644
+ assert (Hc : j = 0 \/ j = 1 \/ j = 2 \/ j = 3 \/ j = 4 \/ j = 5 \/ j = 6 \/ j = 7 \/ j = 8) by lia.
645
+ destruct Hc as [->|[->|[->|[->|[->|[->|[->|[->| ->]]]]]]]].
646
+ ++ rdr 29 0 5 true; [su; lin true | fin].
647
+ ++ rdr 26 0 1 true; [su; lin true | fin].
648
+ ++ rdr 29 0 6 true; [su; lin true | fin].
649
+ ++ rdr 29 0 2 true; [su; lin true | fin].
650
+ ++ rdr 26 0 0 true; [su; lin true | fin].
651
+ ++ rdr 29 0 3 true; [su; lin true | fin].
652
+ ++ rdr 24 0 1 true; [su; lin true | fin].
653
+ ++ rdr 29 0 1 true; [su; lin true | fin].
654
+ ++ rdr 23 0 0 true; [su; lin true | fin].
655
+ -- exfalso. apply (Hno j); [unfold nst; lia|]. rewrite out_win by assumption.
656
+ destruct (Nat.leb_spec (j + 4) HO); [lia | reflexivity].
657
+ + (* 23 *) destruct r as [|[|[|r]]]; [| | | lia].
658
+ * rdr 23 j 2 true; [su; lin true | fin].
659
+ * rdr 23 j 2 true; [su; lin true | fin].
660
+ * exfalso. apply (Hno (nw al + j)); [unfold nst; lia | apply out_kap; exact Hj].
661
+ + (* 24 *) destruct r as [|[|r]]; [| | lia].
662
+ * rdr 25 (j * Nb) 0 true; [su; rewrite Nat.div_mul by lia; lin true | fin].
663
+ * rdr 25 (j * Nb) 1 false; [su; rewrite Nat.div_mul by lia; lin false | fin].
664
+ + (* 25 *) assert (Hk : j / Nb < K) by (apply Nat.Div0.div_lt_upper_bound; nia).
665
+ assert (Hp : j mod Nb < Nb) by (apply Nat.mod_upper_bound; lia).
666
+ destruct r as [|[|[|[|r]]]]; [| | | | lia].
667
+ * rdr 25 j 1 true; [su; lin true | fin].
668
+ * rdr 25 j 3 true; [su; lin true | fin].
669
+ * rdr 25 j 3 true; [su; lin true | fin].
670
+ * exfalso. apply (Hno (nw al + K + j / Nb * bsz al S0 + j mod Nb)).
671
+ -- pose proof (bank_lt (j / Nb) (j mod Nb) Hk ltac:(unfold bsz; lia)). unfold nst. lia.
672
+ -- rewrite out_bank by (unfold bsz; lia). destruct (Nat.ltb_spec (j mod Nb) Nb); [|lia]. rewrite dm by lia. reflexivity.
673
+ + (* 26 *) destruct r as [|[|[|[|r]]]]; [| | | | lia].
674
+ * rdr 27 (j * S0) 1 false; [su; rewrite Nat.div_mul by lia; lin false | fin].
675
+ * rdr 26 j 2 true; [su; lin true | fin].
676
+ * rdr 26 j 3 true; [su; lin true | fin].
677
+ * rdr 27 (j * S0) 0 true; [su; rewrite Nat.div_mul by lia; lin true | fin].
678
+ + (* 27 *) assert (Hk : j / S0 < K) by (apply Nat.Div0.div_lt_upper_bound; nia).
679
+ assert (Hs : j mod S0 < S0) by (apply Nat.mod_upper_bound; lia).
680
+ destruct r as [|[|[|[|r]]]]; [| | | | lia].
681
+ * rdr 27 j 3 true; [su; lin true | fin].
682
+ * rdr 27 j 3 true; [su; lin true | fin].
683
+ * rdr 27 j 3 true; [su; lin true | fin].
684
+ * exfalso. apply (Hno (nw al + K + j / S0 * bsz al S0 + (Nb + j mod S0))).
685
+ -- pose proof (bank_lt (j / S0) (Nb + j mod S0) Hk ltac:(unfold bsz; lia)). unfold nst. lia.
686
+ -- rewrite out_bank by (unfold bsz; lia). destruct (Nat.ltb_spec (Nb + j mod S0) Nb); [lia|].
687
+ destruct (Nat.ltb_spec (Nb + j mod S0) (Nb + S0)); [|lia].
688
+ replace (Nb + j mod S0 - Nb) with (j mod S0) by lia. rewrite dm by lia. reflexivity.
689
+ + (* 28 *) assert (Hk : j / Bw < K) by (apply Nat.Div0.div_lt_upper_bound; nia).
690
+ assert (Hs : j mod Bw < Bw) by (apply Nat.mod_upper_bound; lia).
691
+ destruct r as [|[|[|[|r]]]]; [| | | | lia].
692
+ * rdr 28 j 3 true; [su; lin true | fin].
693
+ * rdr 28 j 3 true; [su; lin true | fin].
694
+ * rdr 28 j 3 true; [su; lin true | fin].
695
+ * exfalso. apply (Hno (nw al + K + j / Bw * bsz al S0 + (Nb + S0 + j mod Bw))).
696
+ -- pose proof (bank_lt (j / Bw) (Nb + S0 + j mod Bw) Hk ltac:(unfold bsz; lia)). unfold nst. lia.
697
+ -- rewrite out_bank by (unfold bsz; lia). destruct (Nat.ltb_spec (Nb + S0 + j mod Bw) Nb); [lia|].
698
+ destruct (Nat.ltb_spec (Nb + S0 + j mod Bw) (Nb + S0)); [lia|].
699
+ replace (Nb + S0 + j mod Bw - Nb - S0) with (j mod Bw) by lia. rewrite dm by lia. reflexivity.
700
+ + (* 29 *) destruct r as [|[|[|[|[|[|[|[|r]]]]]]]]; [| | | | | | | | lia].
701
+ * rdr 30 (j * L) 0 true; [su; rewrite Nat.div_mul by lia; lin true | fin].
702
+ * rdr 30 (j * L) 1 false; [su; rewrite Nat.div_mul by lia; lin false | fin].
703
+ * rdr 29 j 4 true; [su; lin true | fin].
704
+ * rdr 29 j 4 true; [su; lin true | fin].
705
+ * rdr 31 (j * L) 1 false; [su; rewrite Nat.div_mul by lia; lin false | fin].
706
+ * rdr 29 j 7 true; [su; lin true | fin].
707
+ * rdr 29 j 7 true; [su; lin true | fin].
708
+ * rdr 31 (j * L) 0 true; [su; rewrite Nat.div_mul by lia; lin true | fin].
709
+ + (* 30 *) assert (Hk : j / L < K) by (apply Nat.Div0.div_lt_upper_bound; nia).
710
+ assert (Hm : j mod L < L) by (apply Nat.mod_upper_bound; lia).
711
+ destruct r as [|[|[|[|r]]]]; [| | | | lia].
712
+ * rdr 30 j 1 true; [su; lin true | fin].
713
+ * rdr 30 j 3 true; [su; lin true | fin].
714
+ * rdr 30 j 3 true; [su; lin true | fin].
715
+ * exfalso. apply (Hno (otape al K S0 L (j / L) + j mod L)).
716
+ -- destruct (tape_shape (j / L) (j mod L) Hk ltac:(lia)) as (H1 & _). exact H1.
717
+ -- rewrite out_tape by lia. destruct (Nat.ltb_spec (j mod L) L); [|lia]. rewrite dm by lia. reflexivity.
718
+ + (* 31 *) assert (Hk : j / L < K) by (apply Nat.Div0.div_lt_upper_bound; nia).
719
+ assert (Hm : j mod L < L) by (apply Nat.mod_upper_bound; lia).
720
+ destruct r as [|[|[|[|r]]]]; [| | | | lia].
721
+ * rdr 31 j 3 true; [su; lin true | fin].
722
+ * rdr 31 j 3 true; [su; lin true | fin].
723
+ * rdr 31 j 3 true; [su; lin true | fin].
724
+ * exfalso. apply (Hno (otape al K S0 L (j / L) + (L + j mod L))).
725
+ -- destruct (tape_shape (j / L) (L + j mod L) Hk ltac:(lia)) as (H1 & _). exact H1.
726
+ -- rewrite out_tape by lia. destruct (Nat.ltb_spec (L + j mod L) L); [lia|].
727
+ replace (L + j mod L - L) with (j mod L) by lia. rewrite dm by lia. reflexivity.
728
+ Qed.
729
+
730
+ (* ---- depth, contribution and last readers of the levelized ring network ------------------------------------- *)
731
+ Lemma phys_wf' : wf bsP nP.
732
+ Proof. apply phys_wf; lia. Qed.
733
+
734
+ Lemma phys_cd_rec : forall b j r, valid bsP nP (SRef b j r) ->
735
+ cdp (SRef b j r) = S (maxl (map (fun p => cdp (fst p)) (sin (sunit bsP b j r)))).
736
+ Proof.
737
+ intros b j r Hv. destruct (phys_unit_ok b j r Hv) as [Hall [[E C]|Hex]].
738
+ - rewrite E. exact C.
739
+ - apply cd_rec; [intros p z Hin; exact (proj1 (Hall p z Hin)) | exact Hex].
740
+ Qed.
741
+
742
+ Theorem phys_dep : forall x, valid bsP nP x -> dep nP (phys_units al K S0 L) (idx nP bsP x) = cdp x.
743
+ Proof. exact (dep_cd bsP nP phys_wf' cdp (fun i => eq_refl) phys_cd_rec). Qed.
744
+
745
+ Lemma cdp_le : forall x, cdp x <= 19.
746
+ Proof.
747
+ intros [i|b j r]; cbn [cdp]; [lia|].
748
+ repeat match goal with |- context [match ?t with _ => _ end] => destruct t end; lia.
749
+ Qed.
750
+
751
+ (* the step of N^alpha_{K,S,L} has depth 19 *)
752
+ Theorem phys_dmax : dmax nP (phys_units al K S0 L) = 19.
753
+ Proof.
754
+ apply (dmax_cd bsP nP phys_wf' cdp (fun i => eq_refl) phys_cd_rec 19).
755
+ - intros b j r _. apply cdp_le.
756
+ - exists 27, 0, 3. split; [pose proof W_ge16; vld | reflexivity].
757
+ Qed.
758
+
759
+ Lemma sref_dec : forall x y : sref, {x = y} + {x <> y}.
760
+ Proof. decide equality; apply Nat.eq_dec. Qed.
761
+
762
+ Lemma out_dec : forall x, {exists i, i < nP /\ out_ref al K S0 L i = x} + {forall i, i < nP -> out_ref al K S0 L i <> x}.
763
+ Proof.
764
+ intro x. destruct (in_dec sref_dec x (map (out_ref al K S0 L) (seq 0 nP))) as [H|H].
765
+ - left. apply in_map_iff in H as (i & E & Hi). apply in_seq in Hi. exists i. split; [lia | exact E].
766
+ - right. intros i Hi E. apply H. apply in_map_iff. exists i. split; [exact E | apply in_seq; lia].
767
+ Qed.
768
+
769
+ Lemma cl_pos : forall b j r, ndp (SRef b j r) = true -> 1 <= clp (SRef b j r).
770
+ Proof.
771
+ intros b j r Hn. destruct (Nat.eq_dec b 8) as [->|Hb].
772
+ - cbn [ndp clp] in *. destruct (Nat.ltb_spec j 2); [discriminate|]. destruct (Nat.ltb_spec j 4); lia.
773
+ - clear Hn. cbn [clp]. repeat match goal with |- context [match ?t with _ => _ end] => destruct t end; lia.
774
+ Qed.
775
+
776
+ (* every unit but the decode lines of the output addresses 0 and 1 contributes to a next value *)
777
+ Theorem phys_need : forall b j r, valid bsP nP (SRef b j r) ->
778
+ need nP (phys_units al K S0 L) (phys_next al K S0 L) (idx nP bsP (SRef b j r)) = ndp (SRef b j r).
779
+ Proof.
780
+ apply (need_eq bsP nP (out_ref al K S0 L) phys_wf' out_valid ndp).
781
+ - intros b j r Hv Hn. destruct (out_dec (SRef b j r)) as [(i & Hi & E)|Hno]; [left; exists i; split; assumption|].
782
+ right. destruct (phys_reader (SRef b j r) Hv Hno) as [Z|(b' & j' & r' & z & Hv' & Hn' & Hin & _)].
783
+ + pose proof (cl_pos b j r Hn). lia.
784
+ + exists b', j', r', z. split; [exact Hv'|]. split; [exact Hn' | exact Hin].
785
+ - intros b j r Hv Hn. split.
786
+ + intros i Hi E. pose proof (nd_out i Hi) as H. rewrite E, Hn in H. discriminate.
787
+ + intros b' j' r' z Hv' Hin. destruct (proj1 (phys_unit_ok b' j' r' Hv') (SRef b j r) z Hin) as (_ & _ & H).
788
+ rewrite Hn in H. discriminate.
789
+ Qed.
790
+
791
+ (* the last layer that reads each signal *)
792
+ Theorem phys_lam : forall x, valid bsP nP x ->
793
+ lam nP (phys_units al K S0 L) (phys_next al K S0 L) (idx nP bsP x) = clp x.
794
+ Proof.
795
+ apply (lam_cl2 bsP nP (out_ref al K S0 L) phys_wf' out_valid cdp phys_dep ndp phys_need 19 phys_dmax clp).
796
+ - intros b j r p z Hv Hn Hin. exact (proj1 (proj2 (proj1 (phys_unit_ok b j r Hv) p z Hin)) Hn).
797
+ - exact cl_out.
798
+ - exact phys_reader.
799
+ Qed.
800
+
801
+ (* ---- the rows of Lev(N^alpha_{K,S,L}) ---------------------------------------------------------------------------- *)
802
+ Lemma phys_up : forall b j r p z, valid bsP nP (SRef b j r) -> ndp (SRef b j r) = true ->
803
+ In (p, z) (sin (sunit bsP b j r)) -> cdp (SRef b j r) <= clp p.
804
+ Proof. intros b j r p z Hv Hn Hin. exact (proj1 (proj2 (proj1 (phys_unit_ok b j r Hv) p z Hin)) Hn). Qed.
805
+
806
+ Lemma phys_next_len : length (phys_next al K S0 L) = nP.
807
+ Proof. unfold phys_next. rewrite length_map, length_seq. reflexivity. Qed.
808
+
809
+ Lemma nsum_add1 : forall k g, nsum (k + 1) g = nsum k g + g k.
810
+ Proof. intros k g. rewrite Nat.add_1_r. reflexivity. Qed.
811
+
812
+ Lemma cl_kap : forall k, k < K -> clp (SIn (nw al + k)) = 17.
813
+ Proof. intros k Hk. rewrite <- (cl_act k). unfold act, okap. rewrite Nat.mod_small by exact Hk. reflexivity. Qed.
814
+
815
+ Lemma cl_bank : forall k q, k < K -> q < bsz al S0 ->
816
+ clp (SIn (nw al + K + (bsz al S0 * k + q))) = if q <? Nb then 16 else if q <? Nb + S0 then 18 else 16.
817
+ Proof.
818
+ intros k q Hk Hq. replace (nw al + K + (bsz al S0 * k + q)) with (nw al + K + k * bsz al S0 + q) by lia.
819
+ pose proof (bank_lt k q Hk Hq). cbn [clp].
820
+ destruct (Nat.ltb_spec (nw al + K + k * bsz al S0 + q) (nw al)); [lia|].
821
+ destruct (Nat.ltb_spec (nw al + K + k * bsz al S0 + q) (nw al + K)); [lia|].
822
+ destruct (Nat.ltb_spec (nw al + K + k * bsz al S0 + q) (nw al + K + K * bsz al S0)); [|lia].
823
+ rewrite bank_mod by assumption. reflexivity.
824
+ Qed.
825
+
826
+ Lemma cl_tape : forall k q, k < K -> q < 2 * L ->
827
+ clp (SIn (nw al + K + K * bsz al S0 + (2 * L * k + q))) = if q <? L then 16 else 17.
828
+ Proof.
829
+ intros k q Hk Hq. replace (nw al + K + K * bsz al S0 + (2 * L * k + q)) with (otape al K S0 L k + q) by (unfold otape; lia).
830
+ destruct (Nat.ltb_spec q L) as [Q|Q].
831
+ - change (SIn (otape al K S0 L k + q)) with (dref al K S0 L k q). apply cl_dref; assumption.
832
+ - replace (otape al K S0 L k + q) with (otape al K S0 L k + L + (q - L)) by lia.
833
+ change (SIn (otape al K S0 L k + L + (q - L))) with (tref al K S0 L k (q - L)). apply cl_tref; lia.
834
+ Qed.
835
+
836
+ (* the state bits: a window cell has rows in layers 1 to 5, a line of the bank index in 1 to 16, a bank bit, a bit head
837
+ line and a tape cell in 1 to 15, a slot head line in 1 to 17 and a tape head line in 1 to 16 *)
838
+ Lemma rows_state :
839
+ nsum nP (fun i => nsum 18 (fun l => Nat.b2n (Nat.ltb (cdp (SIn i)) (S l) && Nat.ltb (S l) (clp (SIn i)))))
840
+ = 5 * nw al + 16 * K + K * (15 * Nb + 17 * S0 + 15 * Bw) + K * (31 * L).
841
+ Proof.
842
+ unfold nst. rewrite !nsum_split.
843
+ rewrite (nsum_ext (nw al) _ (fun _ => 5)) by (intros i Hi; rewrite cl_win by exact Hi; reflexivity).
844
+ rewrite (nsum_ext K _ (fun _ => 16)) by (intros k Hk; rewrite cl_kap by exact Hk; reflexivity).
845
+ rewrite !nsum_const. rewrite (nsum_mul K (bsz al S0)), (nsum_mul K (2 * L)).
846
+ rewrite (nsum_ext K _ (fun _ => 15 * Nb + 17 * S0 + 15 * Bw)).
847
+ 2: { intros k Hk.
848
+ rewrite (nsum_ext (bsz al S0) _ (fun q => if q <? Nb then 15 else if q <? Nb + S0 then 17 else 15)).
849
+ - unfold bsz. rewrite !nsum_split.
850
+ rewrite (nsum_ext Nb _ (fun _ => 15)) by (intros q Hq; destruct (Nat.ltb_spec q Nb); [reflexivity | lia]).
851
+ rewrite (nsum_ext S0 _ (fun _ => 17))
852
+ by (intros q Hq; destruct (Nat.ltb_spec (Nb + q) Nb); [lia|];
853
+ destruct (Nat.ltb_spec (Nb + q) (Nb + S0)); [reflexivity | lia]).
854
+ rewrite (nsum_ext Bw _ (fun _ => 15))
855
+ by (intros q Hq; destruct (Nat.ltb_spec (Nb + S0 + q) Nb); [lia|];
856
+ destruct (Nat.ltb_spec (Nb + S0 + q) (Nb + S0)); [lia | reflexivity]).
857
+ rewrite !nsum_const. lia.
858
+ - intros q Hq. rewrite cl_bank by assumption. destruct (q <? Nb); [reflexivity|]. destruct (q <? Nb + S0); reflexivity. }
859
+ rewrite !nsum_const. rewrite (nsum_ext K _ (fun _ => 31 * L)).
860
+ 2: { intros k Hk.
861
+ rewrite (nsum_ext (2 * L) _ (fun q => if q <? L then 15 else 16)).
862
+ - replace (2 * L) with (L + L) by lia. rewrite nsum_split.
863
+ rewrite (nsum_ext L _ (fun _ => 15)) by (intros q Hq; destruct (Nat.ltb_spec q L); [reflexivity | lia]).
864
+ rewrite nsum_const.
865
+ rewrite (nsum_ext L _ (fun _ => 16)) by (intros q Hq; destruct (Nat.ltb_spec (L + q) L); [lia | reflexivity]).
866
+ rewrite !nsum_const. lia.
867
+ - intros q Hq. rewrite cl_tape by assumption. destruct (q <? L); reflexivity. }
868
+ rewrite !nsum_const. lia.
869
+ Qed.
870
+
871
+ (* the units: the rows a unit places in layers 1 to 18, as a unit and as copies *)
872
+ Definition rowsu (x : sref) : nat :=
873
+ nsum 18 (fun l => Nat.b2n (ndp x && Nat.eqb (cdp x) (S l) || Nat.ltb (cdp x) (S l) && Nat.ltb (S l) (clp x))).
874
+
875
+ Definition blkrows (b : nat) : nat :=
876
+ match b with
877
+ | 0 => 18 | 1 => K * Bw * (S0 + 1) | 2 => Bw * (K + 1) + 1 | 3 => K * (L + 1) | 4 => K * (Bw + 1) | 5 => 3 * K + 5
878
+ | 6 | 7 => W al + 1 | 8 => 8 * nw al + 2 | 9 | 11 => 2 * W al - 1 | 10 | 12 => 1 | 13 | 14 => 8 | 15 | 16 => 2
879
+ | 17 => 5 | 18 => 4 | 19 => 26 | 20 => 5 | 21 => 4 | 22 => 9 * 10 + (nw al - 9) * 14 | 23 => 5 * K | 24 => 2 * K
880
+ | 25 => 13 * (K * Nb) | 26 => 6 * K | 27 => 5 * (K * S0) | 28 => 5 * (K * Bw) | 29 => 8 * K | 30 => 13 * (K * L)
881
+ | _ => 4 * (K * L)
882
+ end.
883
+
884
+ Ltac uv := unfold rowsu; cbn [cdp clp ndp]; unfold HO;
885
+ repeat (match goal with
886
+ | |- context [Nat.ltb ?a ?b] => destruct (Nat.ltb_spec a b)
887
+ | |- context [Nat.leb ?a ?b] => destruct (Nat.leb_spec a b)
888
+ | |- context [Nat.eqb ?a ?b] => destruct (Nat.eqb_spec a b)
889
+ end); first [reflexivity | lia].
890
+
891
+ Ltac cst v := rewrite (nsum_ext _ _ (fun _ => v)); [rewrite nsum_const; lia|]; intros ? ?.
892
+
893
+ Lemma rows_blk : forall b, b < 32 -> nsum (cnt bsP b) (fun j => nsum (sz bsP b) (fun r => rowsu (SRef b j r))) = blkrows b.
894
+ Proof.
895
+ intros b Hb. pose proof B_ge as HB. pose proof W_ge16 as HW. pose proof Nb_ge as HN. unfold cnt, sz.
896
+ split32 b; bk; cbn [blkrows].
897
+ - reflexivity.
898
+ - cst (S0 + 1). cst 1. uv.
899
+ - rewrite (nsum_ext _ _ (fun j => if Nat.eqb j 4 then K + 2 else K + 1)).
900
+ + rewrite nsum_eq_split by lia. nia.
901
+ + intros j Hj. rewrite nsum_add1. rewrite (nsum_ext K _ (fun _ => 1)) by (intros r Hr; uv). rewrite nsum_const.
902
+ assert (E : rowsu (SRef 2 j K) = if Nat.eqb j 4 then 2 else 1) by uv. rewrite E. destruct (Nat.eqb j 4); lia.
903
+ - cst (L + 1). cst 1. uv.
904
+ - cst (Bw + 1). cst 1. uv.
905
+ - rewrite (nsum_ext _ _ (fun j => K + (if Nat.eqb j 1 then 1 else 2))).
906
+ + cbn [nsum Nat.eqb]. lia.
907
+ + intros j Hj. rewrite nsum_add1. rewrite (nsum_ext K _ (fun _ => 1)) by (intros r Hr; uv). rewrite nsum_const.
908
+ assert (E : rowsu (SRef 5 j K) = if Nat.eqb j 1 then 1 else 2) by uv. rewrite E. lia.
909
+ - rewrite (nsum_ext _ _ (fun j => if Nat.eqb j 2 then 2 else 1)); [rewrite nsum_eq_split by lia; lia|].
910
+ intros j Hj. cbn [nsum]. uv.
911
+ - rewrite (nsum_ext _ _ (fun j => if Nat.eqb j 2 then 2 else 1)); [rewrite nsum_eq_split by lia; lia|].
912
+ intros j Hj. cbn [nsum]. uv.
913
+ - rewrite (nsum_ext _ _ (fun j => if j <? 4 then (if j <? 2 then 0 else 1) else 8)).
914
+ + replace (W al) with (4 + nw al) by (unfold nw; lia). rewrite nsum_split. cbn [nsum Nat.ltb Nat.leb].
915
+ rewrite (nsum_ext (nw al) _ (fun _ => 8)) by (intros i Hi; destruct (Nat.ltb_spec (4 + i) 4); [lia | reflexivity]).
916
+ rewrite nsum_const. lia.
917
+ + intros j Hj. cbn [nsum]. uv.
918
+ - rewrite (nsum_ext _ _ (fun j => if Nat.eqb j 2 then 1 else 2)); [rewrite nsum_eq_split by lia; lia|].
919
+ intros j Hj. cbn [nsum]. uv.
920
+ - reflexivity.
921
+ - rewrite (nsum_ext _ _ (fun j => if Nat.eqb j 2 then 1 else 2)); [rewrite nsum_eq_split by lia; lia|].
922
+ intros j Hj. cbn [nsum]. uv.
923
+ - reflexivity.
924
+ - reflexivity.
925
+ - reflexivity.
926
+ - reflexivity.
927
+ - reflexivity.
928
+ - reflexivity.
929
+ - reflexivity.
930
+ - reflexivity.
931
+ - reflexivity.
932
+ - reflexivity.
933
+ - rewrite (nsum_ext _ _ (fun c => if c <? 9 then 10 else 14)).
934
+ + rewrite nsum_lt_split by (unfold nw; lia). reflexivity.
935
+ + intros c Hc. cbn [nsum]. uv.
936
+ - cst 5. cbn [nsum]. uv.
937
+ - cst 2. cbn [nsum]. uv.
938
+ - cst 13. cbn [nsum]. uv.
939
+ - cst 6. cbn [nsum]. uv.
940
+ - cst 5. cbn [nsum]. uv.
941
+ - cst 5. cbn [nsum]. uv.
942
+ - cst 8. cbn [nsum]. uv.
943
+ - cst 13. cbn [nsum]. uv.
944
+ - cst 4. cbn [nsum]. uv.
945
+ Qed.
946
+
947
+ Lemma rows_units : bsum bsP rowsu + 32 = 28 * W al + Bw + 26 * K + 8 * (K * Bw) + 14 * (K * Nb) + 5 * (K * S0) + 18 * (K * L).
948
+ Proof.
949
+ unfold bsum. rewrite phys_length. rewrite (nsum_ext 32 _ blkrows) by (intros b Hb; apply rows_blk; exact Hb).
950
+ cbn [nsum blkrows]. pose proof W_ge16. unfold nw, N. nia.
951
+ Qed.
952
+
953
+ (* Lev(N^alpha_{K,S,L}) has depth 19 and 34 W + b + 43 K + 24 K b + 30 K N + 23 K S + 51 K L - 56 rows *)
954
+ Theorem phys_lev_depth : length (lev nP (phys_units al K S0 L) (phys_next al K S0 L)) = 19.
955
+ Proof. rewrite length_lev by (rewrite phys_dmax; lia). exact phys_dmax. Qed.
956
+
957
+ Theorem phys_lev_rows :
958
+ fold_right Nat.add 0 (map (@length tu) (lev nP (phys_units al K S0 L) (phys_next al K S0 L))) + 56
959
+ = 34 * W al + Bw + 43 * K + 24 * (K * Bw) + 30 * (K * Nb) + 23 * (K * S0) + 51 * (K * L).
960
+ Proof.
961
+ rewrite lev_size by exact phys_next_len. rewrite phys_dmax. cbn [Nat.sub].
962
+ change (phys_units al K S0 L) with (fus bsP nP). change (phys_next al K S0 L) with (fnx bsP nP (out_ref al K S0 L)).
963
+ rewrite (rows_bsum bsP nP (out_ref al K S0 L) phys_wf' out_valid cdp phys_dep ndp phys_need 19 phys_dmax clp
964
+ phys_up cl_out phys_reader 18).
965
+ rewrite rows_state. pose proof rows_units as U. unfold rowsu in U. pose proof W_ge16. unfold nst, bsz, nw in *. nia.
966
+ Qed.
967
+
968
+ (* ---- the edges of N^alpha_{K,S,L} ------------------------------------------------------------------------------- *)
969
+ Definition edgu (x : sref) : nat := length (sin (usu bsP x)).
970
+
971
+ Definition blkedges (b : nat) : nat :=
972
+ match b with
973
+ | 0 => 0 | 1 => K * Bw * (3 * S0) | 2 => Bw * (3 * K) | 3 => K * (3 * L) | 4 => K * (3 * Bw) | 5 => 3 * (3 * K)
974
+ | 6 | 7 | 8 => W al * al | 9 | 11 => W al * 2 | 10 | 12 => W al | 13 | 14 | 15 | 16 => 4 | 17 => 20 | 18 => 10
975
+ | 19 => 9 | 20 => 10 | 21 => 5 | 22 => nw al * 6 | 23 => K * 6 | 24 => K * 4 | 25 => K * Nb * 11 | 26 => K * 9
976
+ | 27 => K * S0 * 8 + K * (2 * S0 - 1) | 28 => K * Bw * 8 + K * (2 * Bw - 1) | 29 => K * 18 | 30 => K * L * 10
977
+ | _ => K * L * 8 + K * (2 * L - 1)
978
+ end.
979
+
980
+ (* the third unit of a member of a track reads one signal at the first line and two elsewhere *)
981
+ Lemma nsum_track : forall c n, 1 <= n -> nsum (c * n) (fun m => if Nat.eqb (m mod n) 0 then 1 else 2) = c * (2 * n - 1).
982
+ Proof.
983
+ intros c n Hn. rewrite nsum_mul. rewrite (nsum_ext c _ (fun _ => 2 * n - 1)); [rewrite nsum_const; lia|].
984
+ intros k Hk. rewrite (nsum_ext n _ (fun q => if Nat.eqb q 0 then 1 else 2)).
985
+ - rewrite nsum_eq_split by lia. lia.
986
+ - intros q Hq. replace ((n * k + q) mod n) with q; [reflexivity|]. symmetry. rewrite Nat.mul_comm.
987
+ exact (proj2 (divmod_pair k q n Hq)).
988
+ Qed.
989
+
990
+ Ltac ue := unfold edgu, usu, sunit; bk; cbn [nth].
991
+
992
+ Lemma edges_blk : forall b, b < 32 -> nsum (cnt bsP b) (fun j => nsum (sz bsP b) (fun r => edgu (SRef b j r))) = blkedges b.
993
+ Proof.
994
+ intros b Hb. pose proof B_ge as HB. pose proof W_ge16 as HW. unfold cnt, sz.
995
+ split32 b; bk; cbn [blkedges].
996
+ - reflexivity.
997
+ - cst (3 * S0). rewrite nsum_add1.
998
+ rewrite (nsum_ext S0 _ (fun _ => 2)) by (intros r Hr; ue; rewrite nth_map_seq_app by exact Hr; reflexivity).
999
+ rewrite nsum_const. ue. rewrite nth_map_seq_last. cbn [sin sOR]. rewrite !length_map, length_seq. lia.
1000
+ - cst (3 * K). rewrite nsum_add1.
1001
+ rewrite (nsum_ext K _ (fun _ => 2)) by (intros r Hr; ue; rewrite nth_map_seq_app by exact Hr; reflexivity).
1002
+ rewrite nsum_const. ue. rewrite nth_map_seq_last. cbn [sin sOR]. rewrite !length_map, length_seq. lia.
1003
+ - cst (3 * L). rewrite nsum_add1.
1004
+ rewrite (nsum_ext L _ (fun _ => 2)) by (intros r Hr; ue; rewrite nth_map_seq_app by exact Hr; reflexivity).
1005
+ rewrite nsum_const. ue. rewrite nth_map_seq_last. cbn [sin sOR]. rewrite !length_map, length_seq. lia.
1006
+ - cst (3 * Bw). rewrite nsum_add1.
1007
+ rewrite (nsum_ext Bw _ (fun _ => 2)) by (intros r Hr; ue; rewrite nth_map_seq_app by exact Hr; reflexivity).
1008
+ rewrite nsum_const. ue. rewrite nth_map_seq_last. cbn [sin sOR]. rewrite !length_map, length_seq. lia.
1009
+ - rewrite (nsum_ext _ _ (fun _ => 3 * K)); [rewrite nsum_const; lia|]. intros m Hm. rewrite nsum_add1.
1010
+ rewrite (nsum_ext K _ (fun _ => 2))
1011
+ by (intros r Hr; ue; rewrite nth_map_seq_app by exact Hr; destruct m as [|[|m]]; reflexivity).
1012
+ rewrite nsum_const. ue. rewrite nth_map_seq_last. cbn [sin sOR]. rewrite !length_map, length_seq. lia.
1013
+ - cst al. cbn [nsum]. ue. cbn [sin sAND]. rewrite !length_map, length_seq. reflexivity.
1014
+ - cst al. cbn [nsum]. ue. cbn [sin sAND]. rewrite !length_map, length_seq. reflexivity.
1015
+ - cst al. cbn [nsum]. ue. cbn [sin sAND]. rewrite !length_map, length_seq. reflexivity.
1016
+ - cst 2. cbn [nsum]. ue. reflexivity.
1017
+ - cbn [nsum]. ue. cbn [sin sOR]. rewrite !length_map, length_seq. reflexivity.
1018
+ - cst 2. cbn [nsum]. ue. reflexivity.
1019
+ - cbn [nsum]. ue. cbn [sin sOR]. rewrite !length_map, length_seq. reflexivity.
1020
+ - reflexivity.
1021
+ - reflexivity.
1022
+ - reflexivity.
1023
+ - reflexivity.
1024
+ - reflexivity.
1025
+ - reflexivity.
1026
+ - reflexivity.
1027
+ - reflexivity.
1028
+ - reflexivity.
1029
+ - cst 6. cbn [nsum]. ue. reflexivity.
1030
+ - cst 6. cbn [nsum]. ue. reflexivity.
1031
+ - cst 4. cbn [nsum]. ue. reflexivity.
1032
+ - cst 11. cbn [nsum]. ue. reflexivity.
1033
+ - cst 9. cbn [nsum]. ue. reflexivity.
1034
+ - rewrite (nsum_ext _ _ (fun m => 8 + (if Nat.eqb (m mod S0) 0 then 1 else 2))).
1035
+ + rewrite nsum_add, nsum_const, nsum_track by lia. lia.
1036
+ + intros j Hj. cbn [nsum]. ue. destruct (Nat.eqb (j mod S0) 0); reflexivity.
1037
+ - rewrite (nsum_ext _ _ (fun m => 8 + (if Nat.eqb (m mod Bw) 0 then 1 else 2))).
1038
+ + rewrite nsum_add, nsum_const, nsum_track by lia. lia.
1039
+ + intros j Hj. cbn [nsum]. ue. destruct (Nat.eqb (j mod Bw) 0); reflexivity.
1040
+ - cst 18. cbn [nsum]. ue. reflexivity.
1041
+ - cst 10. cbn [nsum]. ue. reflexivity.
1042
+ - rewrite (nsum_ext _ _ (fun m => 8 + (if Nat.eqb (m mod L) 0 then 1 else 2))).
1043
+ + rewrite nsum_add, nsum_const, nsum_track by lia. lia.
1044
+ + intros j Hj. cbn [nsum]. ue. destruct (Nat.eqb (j mod L) 0); reflexivity.
1045
+ Qed.
1046
+
1047
+ (* N^alpha_{K,S,L} has 14 K N + 10 K S + 16 K b + 23 K L + 43 K + 3 alpha W + 12 W + 46 edges *)
1048
+ Theorem phys_edges : nsum (length (phys_units al K S0 L)) (fun k => length (tin (nth k (phys_units al K S0 L) tu0)))
1049
+ = 14 * (K * Nb) + 10 * (K * S0) + 16 * (K * Bw) + 23 * (K * L) + 43 * K + 3 * al * W al + 12 * W al + 46.
1050
+ Proof.
1051
+ change (phys_units al K S0 L) with (fus bsP nP). rewrite (edges_bsum bsP nP (out_ref al K S0 L) phys_wf' out_valid).
1052
+ change (bsum bsP (fun x => length (sin (usu bsP x)))) with (bsum bsP edgu).
1053
+ unfold bsum. rewrite phys_length. rewrite (nsum_ext 32 _ blkedges) by (intros b Hb; apply edges_blk; exact Hb).
1054
+ cbn [nsum blkedges]. pose proof W_ge16. pose proof B_ge. rewrite !Nat.mul_sub_distr_l. unfold nw, N. nia.
1055
+ Qed.
1056
+
1057
+ End PL.
1058
+
1059
+ (* ---- the member that holds the stored host: alpha = 15 and K = 3 ------------------------------------------------- *)
1060
+ Theorem phys_lev_rows_15 : forall S0 L, 1 <= S0 -> 1 <= L ->
1061
+ N.of_nat (fold_right Nat.add 0 (map (@length tu) (lev (nst 15 3 S0 L) (phys_units 15 3 S0 L) (phys_next 15 3 S0 L))))
1062
+ = (1118054 + 4839 * N.of_nat S0 + 153 * N.of_nat L)%N.
1063
+ Proof.
1064
+ intros S0 L HS HL. pose proof (phys_lev_rows 15 3 S0 L ltac:(lia) ltac:(lia) HS HL) as E.
1065
+ unfold N in E. replace (B 15) with 53 in E by reflexivity. replace (W 15) with (2 ^ 15) in E by reflexivity.
1066
+ apply (f_equal N.of_nat) in E. rewrite !Nat2N.inj_add, !Nat2N.inj_mul, Nat2N.inj_pow in E.
1067
+ change (N.of_nat 2 ^ N.of_nat 15)%N with 32768%N in E. cbn [N.of_nat Pos.of_succ_nat Pos.succ] in E. lia.
1068
+ Qed.
1069
+
1070
+ (* the member of Theorem 8.7 that holds S: S = G + 5 = 36,085 slots and L = 8 |tau_S| + 64 = 1,927,264 cells *)
1071
+ Theorem phys_lev_rows_S :
1072
+ N.of_nat (fold_right Nat.add 0 (map (@length tu)
1073
+ (lev (nst 15 3 (N.to_nat 36085) (N.to_nat 1927264)) (phys_units 15 3 (N.to_nat 36085) (N.to_nat 1927264))
1074
+ (phys_next 15 3 (N.to_nat 36085) (N.to_nat 1927264))))) = 470604761%N.
1075
+ Proof. rewrite phys_lev_rows_15 by lia. rewrite !N2Nat.id. reflexivity. Qed.
rocq/Pstar.v CHANGED
@@ -1,5 +1,5 @@
1
  (* The constructor P and the self-reproducing program P* on SUBLEQ_A with its device, for every A >= 8:
2
- Theorem 4.6, Theorem 5.2 and Proposition 5.4. *)
3
  From Stdlib Require Import List Bool Arith Lia.
4
  Import ListNotations.
5
  From TH Require Import Net Host HostWF HostSem Device.
@@ -958,7 +958,7 @@ Qed.
958
 
959
  End Prog.
960
 
961
- (* ---- Theorems 4.6 and 5.2 and Proposition 5.4 for SUBLEQ_A, A >= 8 ---------------------------- *)
962
  (* The constructor P halts on every recipe after the steps of Theorem 4.6 with the decoded string as output. *)
963
  Theorem constructor_run : forall A, 8 <= A -> forall ks, Forall tok_ok ks ->
964
  Reach A (init A (progP A) (recipe ks)) (dsteps ks + 8)
@@ -968,7 +968,7 @@ Proof.
968
  exact (run_P A HA (tailP A) ltac:(cbn; lia) (recipe ks) eq_refl ks Hks eq_refl).
969
  Qed.
970
 
971
- (* P* halts on every recipe after the steps of Proposition 5.4 with the decoded string and the recipe as
972
  output; it reads no byte at the end of the tape before it requests the rewind, and requests the rewind
973
  once, at the end of the tape. *)
974
  Theorem selfrep_run : forall A, 8 <= A -> forall ks, Forall tok_ok ks ->
 
1
  (* The constructor P and the self-reproducing program P* on SUBLEQ_A with its device, for every A >= 8:
2
+ Theorem 4.6, Theorem 5.2 and Proposition 5.3. *)
3
  From Stdlib Require Import List Bool Arith Lia.
4
  Import ListNotations.
5
  From TH Require Import Net Host HostWF HostSem Device.
 
958
 
959
  End Prog.
960
 
961
+ (* ---- Theorems 4.6 and 5.2 and Proposition 5.3 for SUBLEQ_A, A >= 8 ---------------------------- *)
962
  (* The constructor P halts on every recipe after the steps of Theorem 4.6 with the decoded string as output. *)
963
  Theorem constructor_run : forall A, 8 <= A -> forall ks, Forall tok_ok ks ->
964
  Reach A (init A (progP A) (recipe ks)) (dsteps ks + 8)
 
968
  exact (run_P A HA (tailP A) ltac:(cbn; lia) (recipe ks) eq_refl ks Hks eq_refl).
969
  Qed.
970
 
971
+ (* P* halts on every recipe after the steps of Proposition 5.3 with the decoded string and the recipe as
972
  output; it reads no byte at the end of the tape before it requests the rewind, and requests the rewind
973
  once, at the end of the tape. *)
974
  Theorem selfrep_run : forall A, 8 <= A -> forall ks, Forall tok_ok ks ->
rocq/Recipe.v ADDED
@@ -0,0 +1,335 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* Recipes (Section 4): the encoder describe of Lemma 4.4, as src/host.py computes it, with its decoding, its
2
+ length bound and the case of equality; the optimality of the bound for strings with no two equal adjacent
3
+ bytes (Proposition 4.3); and the completeness of the recipe language (Lemma 4.2). *)
4
+ From Stdlib Require Import List Bool Arith Lia.
5
+ Import ListNotations.
6
+ From TH Require Import Net Host HostWF HostSem Device Pstar.
7
+
8
+ Lemma nu_nu : forall b, b < 256 -> nu (nu b) = b.
9
+ Proof.
10
+ intros b Hb. unfold nu. destruct (Nat.eq_dec b 0) as [->|E]; [reflexivity|].
11
+ rewrite (Nat.mod_small (256 - b)) by lia. rewrite Nat.mod_small by lia. lia.
12
+ Qed.
13
+
14
+ Lemma nu_lt : forall b, nu b < 256.
15
+ Proof. intro b. unfold nu. apply Nat.mod_upper_bound. lia. Qed.
16
+
17
+ (* ---- the encoder ------------------------------------------------------------------------------------------ *)
18
+ (* the length of the run of bytes equal to x at the head of f *)
19
+ Fixpoint run_len (x : nat) (f : list nat) : nat :=
20
+ match f with [] => 0 | y :: f' => if Nat.eqb y x then S (run_len x f') else 0 end.
21
+
22
+ (* four equal bytes begin at the head of f *)
23
+ Definition four_at (f : list nat) : bool :=
24
+ match f with a :: b :: c :: d :: _ => Nat.eqb b a && Nat.eqb c a && Nat.eqb d a | _ => false end.
25
+
26
+ (* the bytes before the first position at which four equal bytes begin, at most cap of them *)
27
+ Fixpoint lit_scan (cap : nat) (f : list nat) : nat :=
28
+ match cap with
29
+ | O => 0
30
+ | S c => match f with [] => 0 | _ :: f' => if four_at f then 0 else S (lit_scan c f') end
31
+ end.
32
+
33
+ Fixpoint desc (fuel : nat) (f : list nat) : list token :=
34
+ match fuel with
35
+ | O => []
36
+ | S fu =>
37
+ match f with
38
+ | [] => []
39
+ | x :: _ =>
40
+ let l := Nat.min (run_len x f) 127 in
41
+ if Nat.leb 4 l then Rep (256 - l) (nu x) :: desc fu (skipn l f)
42
+ else let k := lit_scan 127 f in Lit (map nu (firstn k f)) :: desc fu (skipn k f)
43
+ end
44
+ end.
45
+
46
+ Definition describe (f : list nat) : list token := desc (length f) f.
47
+
48
+ (* the bound of Lemmas 4.2 and 4.4: |f| + ceil(|f| / 127) + 1 *)
49
+ Definition bound (n : nat) : nat := n + (n + 126) / 127 + 1.
50
+
51
+ Definition nofour (f : list nat) : Prop := forall p, four_at (skipn p f) = false.
52
+
53
+ (* ---- runs and scans ------------------------------------------------------------------------------------- *)
54
+ Lemma firstn_run : forall x f l, l <= run_len x f -> firstn l f = repeat x l.
55
+ Proof.
56
+ intros x f. induction f as [|y f IH]; intros l Hl; cbn [run_len] in Hl.
57
+ - assert (l = 0) by lia. subst. reflexivity.
58
+ - destruct l as [|l]; [reflexivity|]. destruct (Nat.eqb_spec y x) as [->|E]; [|lia].
59
+ cbn [firstn repeat]. rewrite IH by lia. reflexivity.
60
+ Qed.
61
+
62
+ Lemma run_le : forall x f, run_len x f <= length f.
63
+ Proof. intros x f. induction f as [|y f IH]; cbn [run_len length]; [lia|]. destruct (Nat.eqb y x); lia. Qed.
64
+
65
+ Lemma four_run : forall x f, four_at (x :: f) = Nat.leb 4 (run_len x (x :: f)).
66
+ Proof.
67
+ intros x [|b [|c [|d f]]]; cbn [four_at run_len]; rewrite Nat.eqb_refl; try reflexivity.
68
+ - destruct (Nat.eqb b x); reflexivity.
69
+ - destruct (Nat.eqb b x), (Nat.eqb c x); reflexivity.
70
+ - destruct (Nat.eqb b x), (Nat.eqb c x), (Nat.eqb d x); reflexivity.
71
+ Qed.
72
+
73
+ Lemma lit_scan_le : forall cap f, lit_scan cap f <= cap /\ lit_scan cap f <= length f.
74
+ Proof.
75
+ induction cap as [|c IH]; intros f; cbn [lit_scan]; [lia|]. destruct f as [|y f']; cbn [length]; [lia|].
76
+ destruct (four_at (y :: f')); [lia|]. specialize (IH f'). lia.
77
+ Qed.
78
+
79
+ Lemma lit_scan_none : forall cap f p, p < lit_scan cap f -> four_at (skipn p f) = false.
80
+ Proof.
81
+ induction cap as [|c IH]; intros f p Hp; cbn [lit_scan] in Hp; [lia|]. destruct f as [|y f']; [lia|].
82
+ destruct (four_at (y :: f')) eqn:E; [lia|]. destruct p as [|p]; [exact E|]. cbn [skipn]. apply (IH f'). lia.
83
+ Qed.
84
+
85
+ Lemma lit_scan_stop : forall cap f, lit_scan cap f = cap \/ lit_scan cap f = length f
86
+ \/ four_at (skipn (lit_scan cap f) f) = true.
87
+ Proof.
88
+ induction cap as [|c IH]; intros f; cbn [lit_scan]; [left; reflexivity|]. destruct f as [|y f']; [right; left; reflexivity|].
89
+ destruct (four_at (y :: f')) eqn:E; [right; right; exact E|]. cbn [skipn length].
90
+ destruct (IH f') as [H|[H|H]]; [left; lia | right; left; lia | right; right; exact H].
91
+ Qed.
92
+
93
+ Lemma lit_scan_pos : forall cap f, 1 <= cap -> f <> [] -> four_at f = false -> 1 <= lit_scan cap f.
94
+ Proof. intros [|c] [|y f] Hc Hf E; [lia | lia | contradiction Hf; reflexivity | cbn [lit_scan]; rewrite E; lia]. Qed.
95
+
96
+ Lemma nofour_skipn : forall f k, nofour f -> nofour (skipn k f).
97
+ Proof. intros f k H p. rewrite skipn_skipn. apply H. Qed.
98
+
99
+ Lemma Forall_take : forall (T : Type) (P : T -> Prop) l k, Forall P l -> Forall P (firstn k l).
100
+ Proof. intros T P l k H. rewrite <- (firstn_skipn k l) in H. apply Forall_app in H. exact (proj1 H). Qed.
101
+
102
+ Lemma Forall_drop : forall (T : Type) (P : T -> Prop) l k, Forall P l -> Forall P (skipn k l).
103
+ Proof. intros T P l k H. rewrite <- (firstn_skipn k l) in H. apply Forall_app in H. exact (proj2 H). Qed.
104
+
105
+ (* ---- the recipe of a token list ---------------------------------------------------------------------------- *)
106
+ Lemma length_recipe_cons : forall k ks, length (recipe (k :: ks)) = length (enc k) + length (recipe ks).
107
+ Proof. intros k ks. unfold recipe. cbn [map concat]. rewrite <- app_assoc, length_app. reflexivity. Qed.
108
+
109
+ Lemma delta_cons : forall k ks, delta (k :: ks) = dec k ++ delta ks.
110
+ Proof. reflexivity. Qed.
111
+
112
+ Lemma ceil_add : forall m, (127 + m + 126) / 127 = 1 + (m + 126) / 127.
113
+ Proof. intro m. replace (127 + m + 126) with (1 * 127 + (m + 126)) by lia. rewrite Nat.div_add_l by lia. reflexivity. Qed.
114
+
115
+ Lemma ceil_mono : forall a b, a <= b -> (a + 126) / 127 <= (b + 126) / 127.
116
+ Proof. intros a b H. apply Nat.Div0.div_le_mono. lia. Qed.
117
+
118
+ Lemma ceil_small : forall n, 1 <= n -> n <= 127 -> (n + 126) / 127 = 1.
119
+ Proof. intros n H1 H2. symmetry. apply Nat.div_unique with (r := n + 126 - 127); lia. Qed.
120
+
121
+ (* ---- Lemma 4.4 --------------------------------------------------------------------------------------------- *)
122
+ Lemma desc_spec : forall fuel f, length f <= fuel -> Forall (fun x => x < 256) f ->
123
+ let r := length (recipe (desc fuel f)) in
124
+ delta (desc fuel f) = f /\ Forall tok_ok (desc fuel f) /\ r <= bound (length f)
125
+ /\ (four_at f = true -> r + 2 <= bound (length f))
126
+ /\ (nofour f -> r = bound (length f)) /\ (r = bound (length f) -> nofour f).
127
+ Proof.
128
+ induction fuel as [|fu IH]; intros f Hl Hb r.
129
+ - assert (f = []) by (destruct f; [reflexivity | cbn in Hl; lia]). subst f. unfold r. cbn.
130
+ split; [reflexivity|]. split; [constructor|]. split; [lia|]. split; [discriminate|]. split; [reflexivity|].
131
+ intros _ p. destruct p; reflexivity.
132
+ - destruct f as [|x f0].
133
+ + unfold r. cbn.
134
+ split; [reflexivity|]. split; [constructor|]. split; [lia|]. split; [discriminate|]. split; [reflexivity|].
135
+ intros _ p. destruct p; reflexivity.
136
+ + assert (Hx : x < 256) by (inversion Hb; assumption).
137
+ unfold r. cbn [desc]. cbv zeta.
138
+ remember (x :: f0) as f eqn:Ef.
139
+ assert (Hfl : length f = S (length f0)) by (subst f; reflexivity).
140
+ set (l := Nat.min (run_len x f) 127).
141
+ assert (Hrun : run_len x f >= 1) by (subst f; cbn [run_len]; rewrite Nat.eqb_refl; lia).
142
+ pose proof (run_le x f) as Hrl.
143
+ destruct (Nat.leb_spec 4 l) as [H4|H4].
144
+ * (* a run of at least four: a repeat token *)
145
+ set (f2 := skipn l f).
146
+ assert (Hlf : length f = l + length f2) by (unfold f2; rewrite length_skipn; unfold l in *; lia).
147
+ destruct (IH f2 ltac:(lia) ltac:(unfold f2; apply Forall_drop; exact Hb)) as (D & T & B & B2 & E1 & E2).
148
+ cbv zeta in *. set (r2 := length (recipe (desc fu f2))) in *.
149
+ assert (Hdec : dec (Rep (256 - l) (nu x)) = firstn l f).
150
+ { cbn [dec]. rewrite nu_nu by exact Hx. replace (256 - (256 - l)) with l by (unfold l in *; lia).
151
+ symmetry. apply firstn_run. unfold l. lia. }
152
+ rewrite length_recipe_cons. cbn [enc length]. fold r2.
153
+ assert (Hb2 : bound (length f2) + 4 <= bound (length f)).
154
+ { unfold bound. rewrite Hlf. pose proof (ceil_mono (length f2) (l + length f2) ltac:(lia)). lia. }
155
+ refine (conj _ (conj _ (conj _ (conj _ (conj _ _))))).
156
+ -- rewrite delta_cons, D, Hdec. apply firstn_skipn.
157
+ -- constructor; [|exact T]. cbn [tok_ok]. split; [unfold l in *; lia | apply nu_lt].
158
+ -- lia.
159
+ -- intros _. lia.
160
+ -- intro Hn. exfalso. specialize (Hn 0). cbn [skipn] in Hn. subst f. rewrite four_run in Hn.
161
+ apply Nat.leb_gt in Hn. unfold l in *. lia.
162
+ -- intro E. lia.
163
+ * (* a literal token *)
164
+ assert (Hf4 : four_at f = false).
165
+ { subst f. rewrite four_run. apply Nat.leb_gt. unfold l in *. lia. }
166
+ set (k := lit_scan 127 f).
167
+ destruct (lit_scan_le 127 f) as [Hk1 Hk2]. fold k in Hk1, Hk2.
168
+ assert (Hk0 : 1 <= k) by (apply lit_scan_pos; [lia | subst f; discriminate | exact Hf4]).
169
+ set (f2 := skipn k f).
170
+ assert (Hlf : length f = k + length f2) by (unfold f2; rewrite length_skipn; lia).
171
+ destruct (IH f2 ltac:(lia) ltac:(unfold f2; apply Forall_drop; exact Hb)) as (D & T & B & B2 & E1 & E2).
172
+ cbv zeta in *. set (r2 := length (recipe (desc fu f2))) in *.
173
+ assert (Hg : Forall (fun x => x < 256) (firstn k f)) by (apply Forall_take; exact Hb).
174
+ rewrite length_recipe_cons. cbn [enc length]. rewrite length_map, length_firstn, Nat.min_l by lia. fold r2.
175
+ assert (Hnone : forall p, p < k -> four_at (skipn p f) = false) by (intros p Hp; apply (lit_scan_none 127); exact Hp).
176
+ assert (Hnf : nofour f2 -> nofour f).
177
+ { intros Hn p. destruct (Nat.lt_ge_cases p k) as [Hp|Hp]; [apply Hnone; exact Hp|].
178
+ replace p with ((p - k) + k) by lia. rewrite <- skipn_skipn. apply (Hn (p - k)). }
179
+ refine (conj _ (conj _ (conj _ (conj _ (conj _ _))))).
180
+ -- rewrite delta_cons, D. cbn [dec]. rewrite map_map.
181
+ rewrite (map_ext_in _ (fun x => x)) by (intros y Hy; rewrite Forall_forall in Hg; apply nu_nu, Hg, Hy).
182
+ rewrite map_id. apply firstn_skipn.
183
+ -- constructor; [|exact T]. cbn [tok_ok]. rewrite length_map, length_firstn, Nat.min_l by lia.
184
+ split; [lia|]. apply Forall_map, Forall_forall. intros y _. apply nu_lt.
185
+ -- destruct (lit_scan_stop 127 f) as [S1|[S1|S1]]; fold k in S1.
186
+ ++ assert (Hb' : bound (length f) = 128 + bound (length f2))
187
+ by (unfold bound; rewrite Hlf, S1, ceil_add; lia). lia.
188
+ ++ assert (Hf2 : length f2 = 0) by lia. rewrite Hf2 in B.
189
+ assert (Hc : (length f + 126) / 127 = 1) by (apply ceil_small; lia).
190
+ unfold bound in *. rewrite Hc. cbn in B. lia.
191
+ ++ destruct (Nat.eq_dec k 127) as [K7|K7].
192
+ ** assert (Hb' : bound (length f) = 128 + bound (length f2))
193
+ by (unfold bound; rewrite Hlf, K7, ceil_add; lia). lia.
194
+ ** specialize (B2 S1). unfold bound in *. rewrite Hlf. pose proof (ceil_mono (length f2) (k + length f2) ltac:(lia)). lia.
195
+ -- intro H. rewrite Hf4 in H. discriminate.
196
+ -- intro Hn. assert (Hn2 : nofour f2) by (apply nofour_skipn; exact Hn).
197
+ specialize (E1 Hn2). destruct (lit_scan_stop 127 f) as [S1|[S1|S1]]; fold k in S1.
198
+ ++ assert (Hb' : bound (length f) = 128 + bound (length f2))
199
+ by (unfold bound; rewrite Hlf, S1, ceil_add; lia). lia.
200
+ ++ assert (Hf2 : length f2 = 0) by lia. rewrite Hf2 in E1.
201
+ assert (Hc : (length f + 126) / 127 = 1) by (apply ceil_small; lia).
202
+ unfold bound in *. rewrite Hc. cbn in E1. lia.
203
+ ++ exfalso. specialize (Hn k). rewrite S1 in Hn. discriminate.
204
+ -- intro E. destruct (lit_scan_stop 127 f) as [S1|[S1|S1]]; fold k in S1.
205
+ ++ assert (Hb' : bound (length f) = 128 + bound (length f2))
206
+ by (unfold bound; rewrite Hlf, S1, ceil_add; lia).
207
+ apply Hnf, E2. lia.
208
+ ++ apply Hnf. intro p. unfold f2. rewrite skipn_skipn, skipn_all2 by lia. reflexivity.
209
+ ++ exfalso. specialize (B2 S1). unfold bound in *. rewrite Hlf in E.
210
+ pose proof (ceil_mono (length f2) (k + length f2) ltac:(lia)). lia.
211
+ Qed.
212
+
213
+ Theorem describe_spec : forall f, Forall (fun x => x < 256) f ->
214
+ delta (describe f) = f /\ Forall tok_ok (describe f) /\ length (recipe (describe f)) <= bound (length f)
215
+ /\ (length (recipe (describe f)) = bound (length f) <-> nofour f).
216
+ Proof.
217
+ intros f Hb. destruct (desc_spec (length f) f (le_n _) Hb) as (D & T & B & _ & E1 & E2).
218
+ unfold describe. refine (conj D (conj T (conj B (conj E2 E1)))).
219
+ Qed.
220
+
221
+ (* ---- the steps of P* on describe f (Theorem 8.7) ------------------------------------------------------------- *)
222
+ (* the steps of Proposition 5.3 on the recipe of ks *)
223
+ Definition psteps (ks : list token) : nat := dsteps ks + 7 + 1 + (6 * length (recipe ks) + 2).
224
+
225
+ Lemma psteps_nil : psteps [] = 16.
226
+ Proof. reflexivity. Qed.
227
+
228
+ Lemma psteps_cons : forall k ks, psteps (k :: ks) = tsteps k + 6 * length (enc k) + psteps ks.
229
+ Proof. intros k ks. unfold psteps. rewrite length_recipe_cons. cbn [dsteps fold_right]. fold (dsteps ks). lia. Qed.
230
+
231
+ Lemma desc_steps : forall fuel f, length f <= fuel -> Forall (fun x => x < 256) f ->
232
+ 2 * psteps (desc fuel f) <= 25 * length f + 58
233
+ /\ (four_at f = true -> 2 * psteps (desc fuel f) <= 25 * length f + 32)
234
+ /\ (nofour f -> psteps (desc fuel f) = 11 * length f + 13 * ((length f + 126) / 127) + 16).
235
+ Proof.
236
+ induction fuel as [|fu IH]; intros f Hl Hb.
237
+ - assert (f = []) by (destruct f; [reflexivity | cbn in Hl; lia]). subst f. cbn [desc length].
238
+ rewrite psteps_nil. split; [lia|]. split; [discriminate|]. intros _. reflexivity.
239
+ - destruct f as [|x f0].
240
+ + cbn [desc length]. rewrite psteps_nil. split; [lia|]. split; [discriminate|]. intros _. reflexivity.
241
+ + assert (Hx : x < 256) by (inversion Hb; assumption).
242
+ cbn [desc]. cbv zeta.
243
+ remember (x :: f0) as f eqn:Ef.
244
+ set (l := Nat.min (run_len x f) 127).
245
+ assert (Hrun : run_len x f >= 1) by (subst f; cbn [run_len]; rewrite Nat.eqb_refl; lia).
246
+ pose proof (run_le x f) as Hrl.
247
+ destruct (Nat.leb_spec 4 l) as [H4|H4].
248
+ * set (f2 := skipn l f).
249
+ assert (Hlf : length f = l + length f2) by (unfold f2; rewrite length_skipn; unfold l in *; lia).
250
+ destruct (IH f2 ltac:(lia) ltac:(unfold f2; apply Forall_drop; exact Hb)) as (B & _ & _).
251
+ rewrite psteps_cons. cbn [tsteps enc length]. replace (256 - (256 - l)) with l by (unfold l in *; lia).
252
+ split; [lia|]. split; [intros _; lia|].
253
+ intro Hn. exfalso. specialize (Hn 0). cbn [skipn] in Hn. subst f. rewrite four_run in Hn.
254
+ apply Nat.leb_gt in Hn. unfold l in *. lia.
255
+ * assert (Hf4 : four_at f = false).
256
+ { subst f. rewrite four_run. apply Nat.leb_gt. unfold l in *. lia. }
257
+ set (k := lit_scan 127 f).
258
+ destruct (lit_scan_le 127 f) as [Hk1 Hk2]. fold k in Hk1, Hk2.
259
+ assert (Hk0 : 1 <= k) by (apply lit_scan_pos; [lia | subst f; discriminate | exact Hf4]).
260
+ set (f2 := skipn k f).
261
+ assert (Hlf : length f = k + length f2) by (unfold f2; rewrite length_skipn; lia).
262
+ destruct (IH f2 ltac:(lia) ltac:(unfold f2; apply Forall_drop; exact Hb)) as (B & B4 & E).
263
+ rewrite psteps_cons. cbn [tsteps enc length]. rewrite length_map, length_firstn, Nat.min_l by lia.
264
+ assert (Hd2 : length f2 = 0 -> psteps (desc fu f2) = 16).
265
+ { intro H0. assert (Z : f2 = []) by (apply length_zero_iff_nil; exact H0).
266
+ rewrite Z. destruct fu; reflexivity. }
267
+ split; [|split; [intro H; rewrite Hf4 in H; discriminate|]].
268
+ -- destruct (lit_scan_stop 127 f) as [S1|[S1|S1]]; fold k in S1.
269
+ ++ lia.
270
+ ++ rewrite Hd2 by lia. lia.
271
+ ++ specialize (B4 S1). lia.
272
+ -- intro Hn. assert (Hn2 : nofour f2) by (apply nofour_skipn; exact Hn).
273
+ specialize (E Hn2). destruct (lit_scan_stop 127 f) as [S1|[S1|S1]]; fold k in S1.
274
+ ++ rewrite E, Hlf, S1, ceil_add. lia.
275
+ ++ rewrite Hd2 by lia. rewrite (ceil_small (length f)) by lia. lia.
276
+ ++ exfalso. specialize (Hn k). rewrite S1 in Hn. discriminate.
277
+ Qed.
278
+
279
+ (* every recipe of f takes at least 4 |f| steps *)
280
+ Lemma psteps_lower : forall ks, Forall tok_ok ks -> 4 * length (delta ks) <= psteps ks.
281
+ Proof.
282
+ induction ks as [|k ks IH]; intros Hok; [cbn; lia|]. apply Forall_cons_iff in Hok as [Hk Hok].
283
+ rewrite psteps_cons, delta_cons, length_app. specialize (IH Hok).
284
+ destruct k as [bs|t b]; cbn [tsteps enc dec length] in *; [rewrite length_map | rewrite repeat_length]; lia.
285
+ Qed.
286
+
287
+ Theorem describe_steps : forall f, Forall (fun x => x < 256) f ->
288
+ 2 * psteps (describe f) <= 25 * length f + 58
289
+ /\ (nofour f -> psteps (describe f) = 11 * length f + 13 * ((length f + 126) / 127) + 16).
290
+ Proof.
291
+ intros f Hb. destruct (desc_steps (length f) f (le_n _) Hb) as (B & _ & E). exact (conj B E).
292
+ Qed.
293
+
294
+ (* ---- Lemma 4.2 --------------------------------------------------------------------------------------------- *)
295
+ Corollary recipes_complete : forall f, Forall (fun x => x < 256) f ->
296
+ exists ks, Forall tok_ok ks /\ delta ks = f /\ length (recipe ks) <= bound (length f).
297
+ Proof.
298
+ intros f Hb. destruct (describe_spec f Hb) as (D & T & B & _). exists (describe f). exact (conj T (conj D B)).
299
+ Qed.
300
+
301
+ (* ---- Proposition 4.3 --------------------------------------------------------------------------------------- *)
302
+ Definition notwo (f : list nat) : Prop := forall p, S p < length f -> nth p f 0 <> nth (S p) f 0.
303
+
304
+ Lemma notwo_app : forall a b, notwo (a ++ b) -> notwo a /\ notwo b.
305
+ Proof.
306
+ intros a b H. split.
307
+ - intros p Hp. specialize (H p ltac:(rewrite length_app; lia)). rewrite !app_nth1 in H by lia. exact H.
308
+ - intros p Hp. specialize (H (length a + p) ltac:(rewrite length_app; lia)).
309
+ rewrite !app_nth2 in H by lia. replace (length a + p - length a) with p in H by lia.
310
+ replace (S (length a + p) - length a) with (S p) in H by lia. exact H.
311
+ Qed.
312
+
313
+ Lemma token_cost : forall k, tok_ok k -> notwo (dec k) ->
314
+ length (enc k) = length (dec k) + 1 /\ 1 <= length (dec k) <= 127.
315
+ Proof.
316
+ intros [bs|t b] Hk Hn; cbn [tok_ok] in Hk; destruct Hk as [Hk1 Hk2]; cbn [dec] in Hn; cbn [enc dec length].
317
+ - rewrite length_map. lia.
318
+ - rewrite repeat_length. destruct (Nat.eq_dec (256 - t) 1) as [E|E]; [lia|].
319
+ exfalso. apply (Hn 0); rewrite ?repeat_length; [lia|]. rewrite !nth_repeat_lt by lia. reflexivity.
320
+ Qed.
321
+
322
+ Theorem recipe_optimal : forall ks, Forall tok_ok ks -> notwo (delta ks) ->
323
+ bound (length (delta ks)) <= length (recipe ks).
324
+ Proof.
325
+ assert (G : forall ks, Forall tok_ok ks -> notwo (delta ks) ->
326
+ length (recipe ks) = length (delta ks) + length ks + 1 /\ length (delta ks) <= 127 * length ks).
327
+ { induction ks as [|k ks IH]; intros Hok Hn; [cbn; lia|].
328
+ apply Forall_cons_iff in Hok as [Hk Hok]. rewrite delta_cons in Hn. apply notwo_app in Hn as [Hn1 Hn2].
329
+ destruct (IH Hok Hn2) as [E1 E2]. destruct (token_cost k Hk Hn1) as [C1 C2].
330
+ rewrite length_recipe_cons, delta_cons, length_app, C1, E1. cbn [length]. lia. }
331
+ intros ks Hok Hn. destruct (G ks Hok Hn) as [E1 E2]. rewrite E1. unfold bound.
332
+ assert ((length (delta ks) + 126) / 127 < S (length ks)).
333
+ { apply Nat.Div0.div_lt_upper_bound. lia. }
334
+ lia.
335
+ Qed.
rocq/Restore.v ADDED
@@ -0,0 +1,1449 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* Proposition 6.14: the restoration bound for the threefold amplification. The rows of the layered map are unrolled
2
+ along a run, the first layer of each step reading the last layer of the step before through a device that writes
3
+ every copy of its cells with the values of the run. Under independent Gaussian perturbations of every
4
+ pre-activation of the threefold amplification, the probability that the state read by majority leaves the run
5
+ within T steps is at most the sum of the bounds b(t) that the recursion of the proposition computes along it.
6
+ The probability space is that of Noise.v, with P additive on the events built from the threshold events. *)
7
+ From Stdlib Require Import List Bool Arith ZArith Reals Lia Lra FunctionalExtensionality.
8
+ Import ListNotations.
9
+ Set Warnings "-ambiguous-paths".
10
+ From TH Require Import TwoHead Net Lev Margin Erfc Noise.
11
+ Set Warnings "ambiguous-paths".
12
+
13
+ Local Open Scope R_scope.
14
+
15
+ (* ---- counts and sums ------------------------------------------------------------------------------------------ *)
16
+ Lemma ncnt_pos : forall m f, (0 < ncnt m f)%nat -> exists k, (k < m)%nat /\ f k = true.
17
+ Proof.
18
+ induction m as [|m IH]; intros f H; cbn [ncnt] in H; [lia|].
19
+ destruct (f m) eqn:E; [exists m; split; [lia | exact E]|].
20
+ destruct (IH f ltac:(lia)) as (k & Hk & Hf). exists k. split; [lia | exact Hf].
21
+ Qed.
22
+
23
+ Lemma ncnt_false : forall k, ncnt k (fun _ => false) = 0%nat.
24
+ Proof. induction k as [|k IH]; cbn [ncnt]; [reflexivity | rewrite IH; reflexivity]. Qed.
25
+
26
+ Lemma ncnt_add : forall a b f, ncnt (a + b) f = (ncnt a f + ncnt b (fun k => f (a + k)%nat))%nat.
27
+ Proof.
28
+ intros a b f. induction b as [|b IH]; cbn [ncnt]; [rewrite Nat.add_0_r; lia|].
29
+ rewrite Nat.add_succ_r. cbn [ncnt]. rewrite IH. lia.
30
+ Qed.
31
+
32
+ Lemma ncnt_point : forall m f j, (j < m)%nat -> ncnt m (fun k => f k && Nat.eqb k j) = if f j then 1%nat else 0%nat.
33
+ Proof.
34
+ induction m as [|m IH]; intros f j Hj; [lia|]. cbn [ncnt].
35
+ destruct (Nat.eq_dec j m) as [->|E].
36
+ - rewrite Nat.eqb_refl, andb_true_r.
37
+ rewrite (ncnt_ext m _ (fun _ => false)) by (intros c Hc; destruct (Nat.eqb_spec c m); [lia | apply andb_false_r]).
38
+ rewrite ncnt_false. destruct (f m); reflexivity.
39
+ - rewrite IH by lia. destruct (Nat.eqb_spec m j); [lia|]. rewrite andb_false_r. destruct (f j); reflexivity.
40
+ Qed.
41
+
42
+ (* the positions c w + j, c < r, of one row j among r w positions *)
43
+ Lemma ncnt_row : forall r w j D, (j < w)%nat ->
44
+ ncnt (r * w) (fun q => D q && Nat.eqb (q mod w) j) = ncnt r (fun c => D (c * w + j)%nat).
45
+ Proof.
46
+ intros r w j D Hj. induction r as [|r IH]; [reflexivity|].
47
+ replace (S r * w)%nat with (r * w + w)%nat by lia. rewrite ncnt_add, IH. cbn [ncnt]. f_equal.
48
+ rewrite (ncnt_ext w _ (fun k => D (r * w + k)%nat && Nat.eqb k j)).
49
+ - exact (ncnt_point w (fun k => D (r * w + k)%nat) j Hj).
50
+ - intros k Hk. replace ((r * w + k) mod w)%nat with k; [reflexivity|].
51
+ rewrite Nat.add_comm, Nat.Div0.mod_add. symmetry. apply Nat.mod_small. exact Hk.
52
+ Qed.
53
+
54
+ Lemma ncnt_two : forall f, (2 <= ncnt 3 f)%nat -> exists c1 c2, (c1 < c2)%nat /\ (c2 < 3)%nat /\ f c1 = true /\ f c2 = true.
55
+ Proof.
56
+ intros f H. cbn [ncnt] in H. destruct (f 0%nat) eqn:E0, (f 1%nat) eqn:E1, (f 2%nat) eqn:E2; cbn [Nat.add] in H;
57
+ try lia; solve [exists 0%nat, 1%nat; auto | exists 0%nat, 2%nat; auto | exists 1%nat, 2%nat; auto].
58
+ Qed.
59
+
60
+ Lemma ncnt_three : forall f, ncnt 3 f = 3%nat -> f 0%nat = true /\ f 1%nat = true /\ f 2%nat = true.
61
+ Proof. intros f H. cbn [ncnt] in H. destruct (f 0%nat), (f 1%nat), (f 2%nat); cbn [Nat.add] in H; try lia; auto. Qed.
62
+
63
+ Lemma rsum_add : forall a b g, rsum (a + b) g = rsum a g + rsum b (fun k => g (a + k)%nat).
64
+ Proof.
65
+ intros a b g. induction b as [|b IH]; cbn [rsum]; [rewrite Nat.add_0_r; lra|].
66
+ rewrite Nat.add_succ_r. cbn [rsum]. rewrite IH. lra.
67
+ Qed.
68
+
69
+ Lemma rsum_blocks : forall T m g, rsum (T * m) g = rsum T (fun t => rsum m (fun l => g (t * m + l)%nat)).
70
+ Proof.
71
+ induction T as [|T IH]; intros m g; [cbn; lra|]. replace (S T * m)%nat with (T * m + m)%nat by lia.
72
+ rewrite rsum_add, IH. cbn [rsum]. reflexivity.
73
+ Qed.
74
+
75
+ (* the first index at which a test holds *)
76
+ Lemma first_true : forall (f : nat -> bool) a, f a = true ->
77
+ exists a0, (a0 <= a)%nat /\ f a0 = true /\ forall a', (a' < a0)%nat -> f a' = false.
78
+ Proof.
79
+ intros f a Ha. assert (Hd : forall k, f k = true \/ ~ f k = true) by (intro k; destruct (f k); [left | right]; congruence).
80
+ assert (G : forall m, (exists k, (k < m)%nat /\ f k = true) ->
81
+ exists a0, (a0 < m)%nat /\ f a0 = true /\ forall a', (a' < a0)%nat -> f a' = false).
82
+ { induction m as [|m IH]; intros (k & Hk & Hf); [lia|].
83
+ destruct (search m (fun k => f k = true) Hd) as [H|H].
84
+ - destruct (IH H) as (a0 & H0 & H1 & H2). exists a0. split; [lia | split; assumption].
85
+ - exists m. split; [lia|]. split.
86
+ + destruct (Nat.eq_dec k m) as [->|E]; [exact Hf | exfalso; exact (H k ltac:(lia) Hf)].
87
+ + intros a' Ha'. destruct (f a') eqn:E; [exfalso; exact (H a' Ha' E) | reflexivity]. }
88
+ destruct (G (S a) (ex_intro _ a (conj (Nat.lt_succ_diag_r a) Ha))) as (a0 & H0 & H1 & H2).
89
+ exists a0. split; [lia | split; assumption].
90
+ Qed.
91
+
92
+ (* ---- the inputs that move a row toward its comparator -------------------------------------------------------- *)
93
+ (* the weight with which a row reads position j, 0 if it does not *)
94
+ Definition wgt (u : tu) (j : nat) : Z := fold_right (fun p a => if Nat.eqb (fst p) j then snd p else a) 0%Z (tin u).
95
+
96
+ Lemma wgt_in : forall u j z, NoDup (map fst (tin u)) -> In (j, z) (tin u) -> wgt u j = z.
97
+ Proof.
98
+ intros [b ins] j z. unfold wgt. cbn [tin]. induction ins as [|[j' z'] t IH]; intros Hnd Hin; [destruct Hin|].
99
+ cbn [fold_right fst snd]. cbn [map fst] in Hnd. inversion Hnd as [|? ? Hj Ht]; subst. destruct Hin as [E|Hin].
100
+ - injection E as -> ->. rewrite Nat.eqb_refl. reflexivity.
101
+ - destruct (Nat.eqb_spec j' j) as [->|E]; [|apply IH; assumption].
102
+ exfalso. apply Hj. apply in_map_iff. exists (j, z). split; [reflexivity | exact Hin].
103
+ Qed.
104
+
105
+ (* the sign of z + 1/2 for an integer z *)
106
+ Definition sgn (z : Z) : Z := if Z.leb 0 z then 1%Z else (-1)%Z.
107
+
108
+ (* an error at an input of weight wt and value y moves a row of pre-activation z toward the comparator, that is
109
+ wt (1 - 2 y) (z + 1/2) < 0 *)
110
+ Definition tw (z wt : Z) (y : bool) : bool := (sgn z * wt * (1 - 2 * b2z y) <? 0)%Z.
111
+
112
+ Lemma tw_paper : forall z wt y, tw z wt y = (wt * (1 - 2 * b2z y) * (2 * z + 1) <? 0)%Z.
113
+ Proof.
114
+ intros z wt y. unfold tw, sgn. rewrite <- Z.mul_assoc. generalize (wt * (1 - 2 * b2z y))%Z as x. intro x.
115
+ destruct (Z.leb_spec 0 z) as [H|H].
116
+ - rewrite Z.mul_1_l. destruct (Z.ltb_spec x 0), (Z.ltb_spec (x * (2 * z + 1)) 0); try reflexivity; exfalso; nia.
117
+ - destruct (Z.ltb_spec (-1 * x) 0), (Z.ltb_spec (x * (2 * z + 1)) 0); try reflexivity; exfalso; nia.
118
+ Qed.
119
+
120
+ Lemma in_arow : forall r w u q z, In (q, z) (tin (arow r w u)) ->
121
+ exists c j, (c < r)%nat /\ In (j, z) (tin u) /\ q = (c * w + j)%nat.
122
+ Proof.
123
+ intros r w u q z Hin. unfold arow in Hin. cbn [tin] in Hin. apply in_concat in Hin as (l & Hl & Hin).
124
+ apply in_map_iff in Hl as (c & <- & Hc). apply in_seq in Hc. apply in_map_iff in Hin as ([j z'] & E & Hj).
125
+ cbn [fst snd] in E. injection E as <- <-. exists c, j. split; [lia | split; [exact Hj | reflexivity]].
126
+ Qed.
127
+
128
+ (* the inputs that differ move a weighted sum by their weights; those that move it against the sign sg number at most
129
+ the count of the toward inputs that differ *)
130
+ Lemma wsum_dir : forall ins E1 E2 (sg : Z), (sg = 1 \/ sg = -1)%Z -> (forall j z, In (j, z) ins -> (z = 1 \/ z = -1)%Z) ->
131
+ (- Z.of_nat (length (filter (fun p => negb (Bool.eqb (E1 (fst p)) (E2 (fst p)))
132
+ && (sg * snd p * (1 - 2 * b2z (E2 (fst p))) <? 0)%Z) ins))
133
+ <= sg * (wsum ins E1 - wsum ins E2))%Z.
134
+ Proof.
135
+ intros ins E1 E2 sg Hsg. induction ins as [|[j z] t IH]; intro Hw; cbn [wsum filter fst snd]; [lia|].
136
+ specialize (IH (fun j' z' H => Hw j' z' (or_intror H))).
137
+ destruct (negb (Bool.eqb (E1 j) (E2 j)) && (sg * z * (1 - 2 * b2z (E2 j)) <? 0)%Z) eqn:Hc; cbn [length];
138
+ rewrite ?Nat2Z.inj_succ; destruct (Hw j z (or_introl eq_refl)) as [-> | ->]; destruct Hsg as [-> | ->];
139
+ destruct (E1 j), (E2 j); cbn in Hc; try discriminate; cbn [b2z]; lia.
140
+ Qed.
141
+
142
+ (* a perturbation fails a copy of the threefold amplification of row u, whose input differs from rep 3 y in at most k
143
+ copies of inputs that move it toward the comparator, only beyond D - k on the far side, D = 3 |z + 1/2| *)
144
+ Definition far (z : Z) (k : nat) (e : R) : Prop :=
145
+ if Z.leb 0 z then e < - (3 * Rabs (IZR z + 1/2) - INR k) else 3 * Rabs (IZR z + 1/2) - INR k <= e.
146
+
147
+ Lemma far_core : forall u y y' e k, rowok (length y) u ->
148
+ (length (filter (fun p => negb (Bool.eqb (nth (fst p) y' false) (nth (fst p) (rep 3 y) false))
149
+ && tw (pre u y) (snd p) (nth (fst p) (rep 3 y) false)) (tin (arow 3 (length y) u))) <= k)%nat ->
150
+ H12 (IZR (pre (arow 3 (length y) u) y') + e) <> Z.leb 0 (pre u y) -> far (pre u y) k e.
151
+ Proof.
152
+ intros u y y' e k Hu Hk Hw.
153
+ assert (Hr : reads_lt (length y) u) by (intros j z Hin; exact (proj1 (proj2 Hu j z Hin))).
154
+ destruct (arow_ok 3 _ _ Hu) as [_ Hlt].
155
+ pose proof (wsum_dir (tin (arow 3 (length y) u)) (fun i => nth i y' false) (fun i => nth i (rep 3 y) false) (sgn (pre u y))
156
+ ltac:(unfold sgn; destruct (Z.leb 0 (pre u y)); [left | right]; reflexivity)
157
+ (fun j z Hin => proj2 (Hlt j z Hin))) as D.
158
+ cbv beta in D. unfold tw in Hk. apply Nat2Z.inj_le in Hk.
159
+ pose proof (pre_arow 3 u y Hr) as Hp0.
160
+ replace (Z.of_nat 3 * pre u y + Z.of_nat ((3 - 1) / 2))%Z with (3 * pre u y + 1)%Z in Hp0 by reflexivity.
161
+ assert (Ed : (pre (arow 3 (length y) u) y' - pre (arow 3 (length y) u) (rep 3 y))%Z
162
+ = (wsum (tin (arow 3 (length y) u)) (fun i => nth i y' false)
163
+ - wsum (tin (arow 3 (length y) u)) (fun i => nth i (rep 3 y) false))%Z) by (unfold pre; ring).
164
+ rewrite Hp0 in Ed.
165
+ set (zv := pre u y) in *. set (p' := pre (arow 3 (length y) u) y') in *. unfold far, sgn in *.
166
+ destruct (Z.leb_spec 0 zv) as [Hz|Hz]; unfold H12 in Hw.
167
+ - destruct (Rle_dec (-1/2) (IZR p' + e)) as [Hle|Hlt']; [exfalso; apply Hw; reflexivity|].
168
+ assert (Hp : (3 * zv + 1 - Z.of_nat k <= p')%Z) by lia.
169
+ apply IZR_le in Hp. rewrite minus_IZR, plus_IZR, mult_IZR, <- INR_IZR_INZ in Hp. apply IZR_le in Hz.
170
+ rewrite Rabs_right by lra. apply Rnot_le_lt in Hlt'. lra.
171
+ - destruct (Rle_dec (-1/2) (IZR p' + e)) as [Hle|Hlt']; [|exfalso; apply Hw; reflexivity].
172
+ assert (Hp : (p' <= 3 * zv + 1 + Z.of_nat k)%Z) by lia.
173
+ apply IZR_le in Hp. rewrite !plus_IZR, mult_IZR, <- INR_IZR_INZ in Hp.
174
+ assert (Hz' : (zv <= -1)%Z) by lia. apply IZR_le in Hz'. rewrite Rabs_left by lra. lra.
175
+ Qed.
176
+
177
+ (* ---- layers evaluated in sequence --------------------------------------------------------------------------------- *)
178
+ Lemma lmapp_app : forall A L l0 E y, lmapp (A ++ [L]) l0 E y = lfirep L (E (l0 + length A)%nat) (lmapp A l0 E y).
179
+ Proof.
180
+ induction A as [|L' A IH]; intros L l0 E y; cbn [app lmapp length]; [rewrite Nat.add_0_r; reflexivity|].
181
+ rewrite IH. replace (S l0 + length A)%nat with (l0 + S (length A))%nat by lia. reflexivity.
182
+ Qed.
183
+
184
+ Lemma nth_lfirep : forall L e y q, (q < length L)%nat -> nth q (lfirep L e y) false = H12 (IZR (pre (nth q L tu0) y) + e q y).
185
+ Proof. intros L e y q Hq. unfold lfirep. rewrite nth_map_seq by exact Hq. reflexivity. Qed.
186
+
187
+ Lemma length_lfirep : forall L e y, length (lfirep L e y) = length L.
188
+ Proof. intros L e y. unfold lfirep. rewrite length_map, length_seq. reflexivity. Qed.
189
+
190
+ Lemma lin_S : forall Ls x l, (l < length Ls)%nat -> lin Ls x (S l) = lfire (nth l Ls []) (lin Ls x l).
191
+ Proof. intros Ls x l Hl. unfold lin. rewrite (firstn_snoc _ Ls l []) by exact Hl. apply lmap_app. Qed.
192
+
193
+ Lemma lfirep_ext : forall L e1 e2 y, (forall q y', e1 q y' = e2 q y') -> lfirep L e1 y = lfirep L e2 y.
194
+ Proof. intros L e1 e2 y H. unfold lfirep. apply map_ext. intro q. rewrite H. reflexivity. Qed.
195
+
196
+ (* copy c of row i of a layer of m rows is c m + i *)
197
+ Lemma cp_inj : forall c1 c2 i1 i2 m, (i1 < m)%nat -> (i2 < m)%nat -> (c1 * m + i1 = c2 * m + i2)%nat -> c1 = c2 /\ i1 = i2.
198
+ Proof.
199
+ intros c1 c2 i1 i2 m H1 H2 E.
200
+ assert (Q1 : c1 = ((c1 * m + i1) / m)%nat) by (apply (Nat.div_unique _ _ c1 i1 H1); lia).
201
+ assert (Q2 : c2 = ((c2 * m + i2) / m)%nat) by (apply (Nat.div_unique _ _ c2 i2 H2); lia).
202
+ assert (R1 : i1 = ((c1 * m + i1) mod m)%nat) by (apply (Nat.mod_unique _ _ c1 i1 H1); lia).
203
+ assert (R2 : i2 = ((c2 * m + i2) mod m)%nat) by (apply (Nat.mod_unique _ _ c2 i2 H2); lia).
204
+ rewrite E in Q1, R1. split; congruence.
205
+ Qed.
206
+
207
+ Lemma cp_mod : forall c i m, (i < m)%nat -> ((c * m + i) mod m = i)%nat.
208
+ Proof. intros c i m H. rewrite Nat.add_comm, Nat.Div0.mod_add. apply Nat.mod_small. exact H. Qed.
209
+
210
+ Lemma cp_split : forall q m, (0 < m)%nat -> q = (q / m * m + q mod m)%nat.
211
+ Proof. intros q m H. rewrite Nat.mul_comm. apply Nat.div_mod. lia. Qed.
212
+
213
+ Lemma existsb_seq_false : forall f m, existsb f (seq 0 m) = false -> forall q, (q < m)%nat -> f q = false.
214
+ Proof.
215
+ intros f m H q Hq. destruct (f q) eqn:E; [|reflexivity].
216
+ assert (C : existsb f (seq 0 m) = true) by (apply existsb_exists; exists q; split; [apply in_seq; lia | exact E]).
217
+ congruence.
218
+ Qed.
219
+
220
+ Lemma existsb_seq_true : forall f m, existsb f (seq 0 m) = true -> exists q, (q < m)%nat /\ f q = true.
221
+ Proof. intros f m H. apply existsb_exists in H as (q & Hq & E). apply in_seq in Hq. exists q. split; [lia | exact E]. Qed.
222
+
223
+ Lemma ncnt_ge1 : forall k f c, (c < k)%nat -> f c = true -> (0 < ncnt k f)%nat.
224
+ Proof.
225
+ induction k as [|k IH]; intros f c Hc Hf; [lia|]. cbn [ncnt].
226
+ destruct (Nat.eq_dec c k) as [->|E]; [rewrite Hf; lia|]. specialize (IH f c ltac:(lia) Hf). lia.
227
+ Qed.
228
+
229
+ (* sum over j1 <> j2 of p j1 p j2 is at most the product of the sums *)
230
+ Lemma sum_ne_le : forall m (T1 T2 : nat -> bool) (p : nat -> R), (forall j, 0 <= p j) ->
231
+ rsum m (fun j1 => rsum m (fun j2 => if T1 j1 && T2 j2 && negb (Nat.eqb j1 j2) then p j1 * p j2 else 0))
232
+ <= rsum m (fun j => if T1 j then p j else 0) * rsum m (fun j => if T2 j then p j else 0).
233
+ Proof.
234
+ intros m T1 T2 p Hp. rewrite Rmult_comm, <- rsum_scal. apply rsum_le. intros j1 Hj1.
235
+ rewrite Rmult_comm, <- rsum_scal. apply rsum_le. intros j2 Hj2.
236
+ pose proof (Hp j1). pose proof (Hp j2).
237
+ destruct (T1 j1), (T2 j2), (Nat.eqb j1 j2); cbn [andb negb]; nra.
238
+ Qed.
239
+
240
+ Section Restore.
241
+ (* ---- the run, unrolled layer by layer ------------------------------------------------------------------------------ *)
242
+ Variable Omega : Type.
243
+ Variable X : nat -> Omega -> R.
244
+ (* the layers of the map, its n state bits, the states xs t of the run and the device cells Dv *)
245
+ Variables (Ls : list (list tu)) (n : nat) (xs : nat -> list bool) (Dv : nat -> bool).
246
+ Hypothesis HL : lwf n Ls.
247
+ Hypothesis Hne : Ls <> [].
248
+ Hypothesis Hlast : length (last Ls []) = n.
249
+ Hypothesis Hxs : forall t, length (xs t) = n.
250
+ (* off the device cells the run takes the step of the map *)
251
+ Hypothesis Hstep : forall t j, (j < n)%nat -> Dv j = false -> nth j (xs (S t)) false = nth j (lmap Ls (xs t)) false.
252
+ (* the perturbation of copy q of layer a of the unrolled run is the variable vid a q *)
253
+ Variable vid : nat -> nat -> nat.
254
+
255
+ Lemma NL_pos : (0 < length Ls)%nat.
256
+ Proof. destruct (length Ls) eqn:E; [|lia]. apply length_zero_iff_nil in E. contradiction. Qed.
257
+
258
+ (* layer a of the unrolled run is layer lyr a of step stp a *)
259
+ Definition stp (a : nat) : nat := a / length Ls.
260
+ Definition lyr (a : nat) : nat := a mod length Ls.
261
+
262
+ Lemma lyr_lt : forall a, (lyr a < length Ls)%nat.
263
+ Proof. intro a. apply Nat.mod_upper_bound. pose proof NL_pos. lia. Qed.
264
+
265
+ Lemma a_decomp : forall a, a = (stp a * length Ls + lyr a)%nat.
266
+ Proof. intro a. unfold stp, lyr. pose proof NL_pos. rewrite Nat.mul_comm. apply Nat.div_mod. lia. Qed.
267
+
268
+ Lemma stp_lyr : forall t l, (l < length Ls)%nat -> stp (t * length Ls + l) = t /\ lyr (t * length Ls + l) = l.
269
+ Proof.
270
+ intros t l Hl. unfold stp, lyr. split.
271
+ - symmetry. apply (Nat.div_unique _ _ t l Hl). lia.
272
+ - symmetry. apply (Nat.mod_unique _ _ t l Hl). lia.
273
+ Qed.
274
+
275
+ Lemma lyr_succ : forall a, (lyr (S a) = 0 /\ lyr a = length Ls - 1 /\ stp (S a) = S (stp a))%nat
276
+ \/ (lyr (S a) = S (lyr a) /\ lyr (S a) <> 0 /\ stp (S a) = stp a)%nat.
277
+ Proof.
278
+ intro a. pose proof (lyr_lt a) as H. pose proof (a_decomp a) as Ea. pose proof NL_pos.
279
+ destruct (Nat.eq_dec (S (lyr a)) (length Ls)) as [E|E].
280
+ - left. assert (Es : S a = (S (stp a) * length Ls + 0)%nat) by lia.
281
+ destruct (stp_lyr (S (stp a)) 0 NL_pos) as [E1 E2]. rewrite <- Es in E1, E2. lia.
282
+ - right. assert (Es : S a = (stp a * length Ls + S (lyr a))%nat) by lia.
283
+ destruct (stp_lyr (stp a) (S (lyr a)) ltac:(lia)) as [E1 E2]. rewrite <- Es in E1, E2. lia.
284
+ Qed.
285
+
286
+ Definition lay (a : nat) : list tu := nth (lyr a) Ls [].
287
+ Definition nla (a : nat) : nat := length (lay a).
288
+ Definition wia (a : nat) : nat := win Ls n (lyr a).
289
+ (* the input and the output of layer a on the run, its row i, and the pre-activation of that row *)
290
+ Definition exin (a : nat) : list bool := lin Ls (xs (stp a)) (lyr a).
291
+ Definition exo (a : nat) : list bool := lfire (lay a) (exin a).
292
+ Definition rowa (a i : nat) : tu := nth i (lay a) tu0.
293
+ Definition zv (a i : nat) : Z := pre (rowa a i) (exin a).
294
+ (* T(v): the inputs j of row i whose error moves it toward the comparator *)
295
+ Definition tT (a i j : nat) : bool := tw (zv a i) (wgt (rowa a i) j) (nth j (exin a) false).
296
+
297
+ (* the device writes every copy of a device cell with its value in the run *)
298
+ Definition reset (x o : list bool) : list bool :=
299
+ map (fun k => if Dv (k mod n) then nth (k mod n) x false else nth k o false) (seq 0 (length o)).
300
+ (* the perturbations of step t: copy q of layer l reads the variable vid (t L + l) q *)
301
+ Definition Et (w : Omega) (t : nat) : nat -> nat -> list bool -> R := fun l q _ => X (vid (t * length Ls + l) q) w.
302
+ (* the perturbed run of the threefold amplification, from the replicated initial state *)
303
+ Fixpoint run3 (w : Omega) (t : nat) : list bool :=
304
+ match t with O => rep 3 (xs 0) | S t' => reset (xs (S t')) (lmapp (amap 3 n Ls) 0 (Et w t') (run3 w t')) end.
305
+ Definition pn (w : Omega) (t l : nat) : list bool := lmapp (firstn l (amap 3 n Ls)) 0 (Et w t) (run3 w t).
306
+ Definition inp (w : Omega) (a : nat) : list bool := pn w (stp a) (lyr a).
307
+ Definition out (w : Omega) (a : nat) : list bool := pn w (stp a) (S (lyr a)).
308
+
309
+ (* copy q of layer a is wrong, input copy q of layer a is wrong *)
310
+ Definition wb (w : Omega) (a q : nat) : bool := negb (Bool.eqb (nth q (out w a) false) (nth (q mod nla a) (exo a) false)).
311
+ Definition wib (w : Omega) (a q : nat) : bool := negb (Bool.eqb (nth q (inp w a) false) (nth (q mod wia a) (exin a) false)).
312
+ (* |S_v|: the wrong copies of the inputs of row i that move it toward the comparator *)
313
+ Definition Sc (w : Omega) (a i : nat) : nat := ncnt (3 * wia a) (fun q => wib w a q && tT a i (q mod wia a)).
314
+ (* the wrong copies of row i, and of input j *)
315
+ Definition ncw (w : Omega) (a i : nat) : nat := ncnt 3 (fun c => wb w a (c * nla a + i)).
316
+ Definition nci (w : Omega) (a j : nat) : nat := ncnt 3 (fun c => wib w a (c * wia a + j)).
317
+
318
+ Lemma out_eq : forall w a, out w a = lfirep (alayer 3 (wia a) (lay a)) (fun q _ => X (vid a q) w) (inp w a).
319
+ Proof.
320
+ intros w a. unfold out, inp, pn. pose proof (lyr_lt a) as Hl.
321
+ rewrite (firstn_snoc _ (amap 3 n Ls) (lyr a) []) by (rewrite length_amap; exact Hl).
322
+ rewrite lmapp_app, length_firstn, length_amap, Nat.min_l by lia. rewrite nth_amap by exact Hl.
323
+ unfold Et. cbn [Nat.add]. rewrite <- (a_decomp a). reflexivity.
324
+ Qed.
325
+
326
+ Lemma inp_0 : forall w, inp w 0 = rep 3 (xs 0).
327
+ Proof. intro w. unfold inp, pn, stp, lyr. rewrite Nat.Div0.div_0_l, Nat.Div0.mod_0_l. reflexivity. Qed.
328
+
329
+ Lemma inp_S : forall w a, lyr (S a) <> 0%nat -> inp w (S a) = out w a.
330
+ Proof.
331
+ intros w a H. destruct (lyr_succ a) as [(E & _)|(E1 & _ & E2)]; [contradiction|].
332
+ unfold inp, out. rewrite E1, E2. reflexivity.
333
+ Qed.
334
+
335
+ Lemma inp_B : forall w a, lyr (S a) = 0%nat -> inp w (S a) = reset (xs (S (stp a))) (out w a).
336
+ Proof.
337
+ intros w a H. destruct (lyr_succ a) as [(_ & E1 & E2)|(_ & E & _)]; [|contradiction].
338
+ unfold inp, out. rewrite H, E2, E1. unfold pn. rewrite firstn_0. cbn [lmapp run3].
339
+ replace (S (length Ls - 1)) with (length Ls) by (pose proof NL_pos; lia).
340
+ rewrite firstn_all2 by (rewrite length_amap; lia). reflexivity.
341
+ Qed.
342
+
343
+ Lemma exin_0 : exin 0 = xs 0.
344
+ Proof. unfold exin, stp, lyr. rewrite Nat.Div0.div_0_l, Nat.Div0.mod_0_l. reflexivity. Qed.
345
+
346
+ Lemma exin_S : forall a, lyr (S a) <> 0%nat -> exin (S a) = exo a.
347
+ Proof.
348
+ intros a H. destruct (lyr_succ a) as [(E & _)|(E1 & _ & E2)]; [contradiction|].
349
+ unfold exin, exo, lay. rewrite E1, E2. apply lin_S. apply lyr_lt.
350
+ Qed.
351
+
352
+ Lemma exin_B : forall a, lyr (S a) = 0%nat -> exin (S a) = xs (S (stp a)) /\ exo a = lmap Ls (xs (stp a)).
353
+ Proof.
354
+ intros a H. destruct (lyr_succ a) as [(_ & E1 & E2)|(_ & E & _)]; [|contradiction]. split.
355
+ - unfold exin. rewrite H, E2. reflexivity.
356
+ - unfold exo, lay, exin. rewrite E1. rewrite <- lin_S by (pose proof NL_pos; lia).
357
+ replace (S (length Ls - 1)) with (length Ls) by (pose proof NL_pos; lia). unfold lin. rewrite firstn_all. reflexivity.
358
+ Qed.
359
+
360
+ Lemma wia_0 : wia 0 = n.
361
+ Proof. unfold wia, lyr. rewrite Nat.Div0.mod_0_l. reflexivity. Qed.
362
+
363
+ Lemma wia_S : forall a, lyr (S a) <> 0%nat -> wia (S a) = nla a.
364
+ Proof.
365
+ intros a H. destruct (lyr_succ a) as [(E & _)|(E1 & _ & _)]; [contradiction|]. unfold wia, nla, lay. rewrite E1. reflexivity.
366
+ Qed.
367
+
368
+ Lemma wia_B : forall a, lyr (S a) = 0%nat -> wia (S a) = n /\ nla a = n.
369
+ Proof.
370
+ intros a H. destruct (lyr_succ a) as [(_ & E1 & _)|(_ & E & _)]; [|contradiction]. split.
371
+ - unfold wia. rewrite H. reflexivity.
372
+ - unfold nla, lay. rewrite E1, <- (last_nth' _ Ls [] Hne). exact Hlast.
373
+ Qed.
374
+
375
+ Lemma len_exin : forall a, length (exin a) = wia a.
376
+ Proof. intro a. unfold exin, wia. rewrite lin_len' by (pose proof (lyr_lt a); lia). rewrite Hxs. reflexivity. Qed.
377
+
378
+ Lemma len_exo : forall a, length (exo a) = nla a.
379
+ Proof. intro a. unfold exo, lfire. rewrite length_map. reflexivity. Qed.
380
+
381
+ Lemma len_out : forall w a, length (out w a) = (3 * nla a)%nat.
382
+ Proof. intros w a. rewrite out_eq, length_lfirep, length_alayer. reflexivity. Qed.
383
+
384
+ Lemma len_reset : forall x o, length (reset x o) = length o.
385
+ Proof. intros x o. unfold reset. rewrite length_map, length_seq. reflexivity. Qed.
386
+
387
+ Lemma len_inp : forall w a, length (inp w a) = (3 * wia a)%nat.
388
+ Proof.
389
+ intros w [|a].
390
+ - rewrite inp_0, wia_0, length_rep, Hxs. reflexivity.
391
+ - destruct (Nat.eq_dec (lyr (S a)) 0) as [H|H].
392
+ + rewrite inp_B, len_reset, len_out by exact H. destruct (wia_B a H) as [-> ->]. reflexivity.
393
+ + rewrite inp_S, len_out, wia_S by exact H. reflexivity.
394
+ Qed.
395
+
396
+ Lemma nth_reset : forall x o q, (q < length o)%nat ->
397
+ nth q (reset x o) false = if Dv (q mod n) then nth (q mod n) x false else nth q o false.
398
+ Proof. intros x o q Hq. unfold reset. rewrite nth_map_seq by exact Hq. reflexivity. Qed.
399
+
400
+ (* the inputs of step 0 are exact; inside a step the inputs of a layer are the outputs of the layer before; between
401
+ steps the device cells are exact and the other state bits are the outputs of the last layer *)
402
+ Lemma wib_0 : forall w q, (q < 3 * n)%nat -> wib w 0 q = false.
403
+ Proof.
404
+ intros w q Hq. unfold wib. rewrite inp_0, exin_0, wia_0. rewrite nth_rep_mod by (rewrite Hxs; exact Hq).
405
+ rewrite Hxs, Bool.eqb_reflx. reflexivity.
406
+ Qed.
407
+
408
+ Lemma wib_S : forall w a q, lyr (S a) <> 0%nat -> wib w (S a) q = wb w a q.
409
+ Proof. intros w a q H. unfold wib, wb. rewrite inp_S, exin_S, wia_S by exact H. reflexivity. Qed.
410
+
411
+ Lemma wib_B : forall w a q, lyr (S a) = 0%nat -> (q < 3 * n)%nat ->
412
+ wib w (S a) q = if Dv (q mod n) then false else wb w a q.
413
+ Proof.
414
+ intros w a q H Hq. destruct (exin_B a H) as [E1 E2]. destruct (wia_B a H) as [W1 W2].
415
+ unfold wib, wb. rewrite inp_B by exact H. rewrite E1, W1. rewrite nth_reset by (rewrite len_out, W2; exact Hq).
416
+ assert (Hj : (q mod n < n)%nat) by (apply Nat.mod_upper_bound; lia).
417
+ destruct (Dv (q mod n)) eqn:Ed.
418
+ - rewrite Bool.eqb_reflx. reflexivity.
419
+ - rewrite E2, W2, (Hstep (stp a) (q mod n) Hj Ed). reflexivity.
420
+ Qed.
421
+
422
+ Lemma rowa_ok : forall a i, (i < nla a)%nat -> rowok (wia a) (rowa a i).
423
+ Proof. intros a i Hi. exact (urow_ok Ls n HL (lyr a) i (lyr_lt a) Hi). Qed.
424
+
425
+ Lemma exo_nth : forall a i, (i < nla a)%nat -> nth i (exo a) false = Z.leb 0 (zv a i).
426
+ Proof. intros a i Hi. unfold exo. rewrite lfire_nth by exact Hi. reflexivity. Qed.
427
+
428
+ (* a wrong copy of row i is a perturbation beyond D - |S_v| on the far side *)
429
+ Lemma wrong_far : forall w a q, (q < 3 * nla a)%nat -> wb w a q = true ->
430
+ far (zv a (q mod nla a)) (Sc w a (q mod nla a)) (X (vid a q) w).
431
+ Proof.
432
+ intros w a q Hq Hw. assert (Hn0 : nla a <> 0%nat) by lia.
433
+ set (i := (q mod nla a)%nat). assert (Hi : (i < nla a)%nat) by (apply Nat.mod_upper_bound; exact Hn0).
434
+ pose proof (rowa_ok a i Hi) as Hu. set (u := rowa a i) in *.
435
+ unfold zv. fold u. rewrite <- len_exin in Hu. apply (far_core u (exin a) (inp w a)); [exact Hu | |].
436
+ - rewrite len_exin in Hu |- *. destruct (arow_ok 3 _ _ Hu) as [Hnd Hlt].
437
+ assert (E : forall p, In p (tin (arow 3 (wia a) u)) ->
438
+ (negb (Bool.eqb (nth (fst p) (inp w a) false) (nth (fst p) (rep 3 (exin a)) false))
439
+ && tw (pre u (exin a)) (snd p) (nth (fst p) (rep 3 (exin a)) false))
440
+ = (wib w a (fst p) && tT a i (fst p mod wia a))).
441
+ { intros [q' z] Hin. cbn [fst snd]. destruct (in_arow _ _ _ _ _ Hin) as (c & j & Hc & Hj & ->).
442
+ destruct Hu as [Hnd' Hl']. destruct (Hl' j z Hj) as [Hjw _].
443
+ assert (Hm : ((c * wia a + j) mod wia a = j)%nat)
444
+ by (rewrite Nat.add_comm, Nat.Div0.mod_add; apply Nat.mod_small; exact Hjw).
445
+ assert (Hr : nth (c * wia a + j) (rep 3 (exin a)) false = nth j (exin a) false).
446
+ { rewrite <- len_exin. apply nth_rep; [exact Hc | rewrite len_exin; exact Hjw]. }
447
+ unfold wib, tT. fold u. rewrite Hm, Hr, (wgt_in u j z Hnd' Hj). reflexivity. }
448
+ rewrite (filter_ext_in _ _ _ E). unfold Sc.
449
+ exact (filter_pos_le (tin (arow 3 (wia a) u)) (fun q => wib w a q && tT a i (q mod wia a)) (3 * wia a) Hnd
450
+ (fun j z Hin => proj1 (Hlt j z Hin))).
451
+ - rewrite len_exin. intro E. unfold wb in Hw. rewrite out_eq in Hw.
452
+ rewrite nth_lfirep in Hw by (rewrite length_alayer; exact Hq).
453
+ rewrite nth_alayer in Hw by exact Hq. fold (nla a) in Hw. fold i in Hw. fold (rowa a i) in Hw. fold u in Hw.
454
+ rewrite exo_nth in Hw by exact Hi. fold i u in Hw. unfold zv in Hw. fold u in Hw. rewrite E, Bool.eqb_reflx in Hw.
455
+ discriminate.
456
+ Qed.
457
+
458
+ (* ---- stops ----------------------------------------------------------------------------------------------------------- *)
459
+ (* a layer is a stop when a wrong copy of one of its rows has |S_v| >= 2, or when it is the last layer of a step and one
460
+ of its rows has two wrong copies *)
461
+ Definition stop1 (w : Omega) (a : nat) : bool :=
462
+ existsb (fun q => wb w a q && Nat.leb 2 (Sc w a (q mod nla a))) (seq 0 (3 * nla a)).
463
+ Definition stop2 (w : Omega) (a : nat) : bool :=
464
+ Nat.eqb (lyr a) (length Ls - 1) && existsb (fun i => Nat.leb 2 (ncw w a i)) (seq 0 (nla a)).
465
+ Definition stopb (w : Omega) (a : nat) : bool := stop1 w a || stop2 w a.
466
+
467
+ (* no stop up to layer a, no stop before layer a *)
468
+ Definition Gu (a : nat) (w : Omega) : Prop := forall a', (a' <= a)%nat -> stopb w a' = false.
469
+ Definition Gb (a : nat) (w : Omega) : Prop := forall a', (a' < a)%nat -> stopb w a' = false.
470
+ (* W_v: row i of layer a has a wrong copy and no layer up to a is a stop; the same for input j of layer a *)
471
+ Definition Wv (a i : nat) (w : Omega) : Prop := (0 < ncw w a i)%nat /\ Gu a w.
472
+ Definition Win (a j : nat) (w : Omega) : Prop := (0 < nci w a j)%nat /\ Gb a w.
473
+ (* no layer before a is a stop, |S_v| <= 1, and row i has two wrong copies, or three *)
474
+ Definition E2 (a i : nat) (w : Omega) : Prop := Gb a w /\ (Sc w a i <= 1)%nat /\ (2 <= ncw w a i)%nat.
475
+ Definition E3 (a i : nat) (w : Omega) : Prop := Gb a w /\ (Sc w a i <= 1)%nat /\ ncw w a i = 3%nat.
476
+
477
+ Lemma Gu_Gb : forall a w, Gu a w <-> Gb (S a) w.
478
+ Proof. intros a w. unfold Gu, Gb. split; intros H a' Ha'; apply H; lia. Qed.
479
+
480
+ (* where no stop lies, a wrong copy has |S_v| <= 1, and in the last layer of a step no row has two wrong copies *)
481
+ Lemma nostop_Sc : forall w a q, stopb w a = false -> (q < 3 * nla a)%nat -> wb w a q = true -> (Sc w a (q mod nla a) <= 1)%nat.
482
+ Proof.
483
+ intros w a q H Hq Hw. apply orb_false_iff in H as [H1 _]. pose proof (existsb_seq_false _ _ H1 q Hq) as E.
484
+ cbv beta in E. rewrite Hw in E. cbn [andb] in E. apply Nat.leb_gt in E. lia.
485
+ Qed.
486
+
487
+ Lemma nostop_ncw : forall w a i, stopb w a = false -> lyr a = (length Ls - 1)%nat -> (i < nla a)%nat -> (ncw w a i <= 1)%nat.
488
+ Proof.
489
+ intros w a i H Hl Hi. apply orb_false_iff in H as [_ H2]. unfold stop2 in H2. rewrite Hl, Nat.eqb_refl in H2.
490
+ cbn [andb] in H2. pose proof (existsb_seq_false _ _ H2 i Hi) as E. cbv beta in E. apply Nat.leb_gt in E. lia.
491
+ Qed.
492
+
493
+ Lemma ncw_copy : forall w a i, (0 < ncw w a i)%nat -> exists c, (c < 3)%nat /\ wb w a (c * nla a + i) = true.
494
+ Proof. intros w a i H. apply ncnt_pos in H as (c & Hc & E). exists c. split; assumption. Qed.
495
+
496
+ (* |S_v| >= 1 gives an input j in T(v) with a wrong copy *)
497
+ Lemma Sc_pos : forall w a i, (0 < Sc w a i)%nat -> exists j, (j < wia a)%nat /\ tT a i j = true /\ (0 < nci w a j)%nat.
498
+ Proof.
499
+ intros w a i H. apply ncnt_pos in H as (q & Hq & E). apply andb_prop in E as [E1 E2].
500
+ assert (Hw : (0 < wia a)%nat) by lia. exists (q mod wia a). split; [apply Nat.mod_upper_bound; lia|]. split; [exact E2|].
501
+ apply (ncnt_ge1 3 _ (q / wia a)); [apply Nat.Div0.div_lt_upper_bound; lia|].
502
+ rewrite <- (cp_split q (wia a) Hw). exact E1.
503
+ Qed.
504
+
505
+ (* |S_v| >= 2: two distinct inputs in T(v) with wrong copies, or all of them copies of one input j, |S_v| its wrong
506
+ copies *)
507
+ Lemma Sc_two : forall w a i, (2 <= Sc w a i)%nat ->
508
+ (exists j1 j2, (j1 < j2)%nat /\ (j2 < wia a)%nat /\ tT a i j1 = true /\ tT a i j2 = true /\ (0 < nci w a j1)%nat /\ (0 < nci w a j2)%nat)
509
+ \/ (exists j, (j < wia a)%nat /\ tT a i j = true /\ Sc w a i = nci w a j).
510
+ Proof.
511
+ intros w a i H. assert (Hw : (0 < wia a)%nat) by (unfold Sc in H; destruct (wia a); [cbn in H; lia | lia]).
512
+ destruct (ncnt_pos (3 * wia a) (fun q => wib w a q && tT a i (q mod wia a)) ltac:(unfold Sc in H; lia)) as (q1 & Hq1 & E1).
513
+ set (j := (q1 mod wia a)%nat). apply andb_prop in E1 as [W1 T1].
514
+ assert (Hj : (j < wia a)%nat) by (apply Nat.mod_upper_bound; lia).
515
+ assert (N1 : (0 < nci w a j)%nat).
516
+ { apply (ncnt_ge1 3 _ (q1 / wia a)); [apply Nat.Div0.div_lt_upper_bound; lia|]. cbv beta. unfold j.
517
+ rewrite <- (cp_split q1 (wia a) Hw). exact W1. }
518
+ destruct (search (3 * wia a) (fun q => wib w a q && tT a i (q mod wia a) && negb (Nat.eqb (q mod wia a) j) = true))
519
+ as [(q2 & Hq2 & E2)|Hn].
520
+ - intro q. destruct (wib w a q && tT a i (q mod wia a) && negb (Nat.eqb (q mod wia a) j)); [left | right]; congruence.
521
+ - left. apply andb_prop in E2 as [E2 Ne]. apply andb_prop in E2 as [W2 T2]. apply negb_true_iff, Nat.eqb_neq in Ne.
522
+ assert (Hj2 : (q2 mod wia a < wia a)%nat) by (apply Nat.mod_upper_bound; lia).
523
+ assert (N2 : (0 < nci w a (q2 mod wia a))%nat).
524
+ { apply (ncnt_ge1 3 _ (q2 / wia a)); [apply Nat.Div0.div_lt_upper_bound; lia|]. rewrite <- (cp_split q2 (wia a) Hw). exact W2. }
525
+ destruct (Nat.lt_ge_cases j (q2 mod wia a)) as [L|L].
526
+ + exists j, (q2 mod wia a). repeat split; assumption.
527
+ + exists (q2 mod wia a), j. repeat split; try assumption; lia.
528
+ - right. exists j. split; [exact Hj|]. split; [exact T1|]. unfold Sc, nci.
529
+ rewrite (ncnt_ext (3 * wia a) _ (fun q => wib w a q && Nat.eqb (q mod wia a) j)).
530
+ + apply ncnt_row. exact Hj.
531
+ + intros q Hq. specialize (Hn q Hq). destruct (wib w a q) eqn:Wq; [|reflexivity]. cbn [andb] in Hn |- *.
532
+ destruct (Nat.eqb_spec (q mod wia a) j) as [Eq|Eq].
533
+ * rewrite Eq. exact T1.
534
+ * destruct (tT a i (q mod wia a)); [exfalso; apply Hn; reflexivity | reflexivity].
535
+ Qed.
536
+
537
+ (* ---- the probability space ---------------------------------------------------------------------------------- *)
538
+ Variable P : (Omega -> Prop) -> R.
539
+ Hypothesis P_mono : forall A B : Omega -> Prop, (forall w, A w -> B w) -> P A <= P B.
540
+ Hypothesis P_or : forall A B : Omega -> Prop, P (fun w => A w \/ B w) <= P A + P B.
541
+ Hypothesis P_empty : P (fun _ => False) = 0.
542
+ Hypothesis P_true : P (fun _ => True) = 1.
543
+ Hypothesis P_indep : forall (I J : nat -> Prop) (A B : Omega -> Prop), (forall g, I g -> J g -> False) ->
544
+ dep Omega X I A -> dep Omega X J B -> P (fun w => A w /\ B w) = P A * P B.
545
+ (* P adds on disjoint events built from the threshold events *)
546
+ Hypothesis P_add : forall A B, meas Omega X A -> meas Omega X B -> (forall w, A w -> B w -> False) ->
547
+ P (fun w => A w \/ B w) = P A + P B.
548
+ Variable s : R.
549
+ Hypothesis Hs : 0 < s.
550
+ Hypothesis tail_ge : forall g c, P (fun w => c <= X g w) = Q (c / s).
551
+ Hypothesis tail_le : forall g c, P (fun w => X g w <= c) = Q (- c / s).
552
+ Hypothesis vid_inj : forall a q a' q', vid a q = vid a' q' -> a = a' /\ q = q'.
553
+
554
+ Lemma Pex : forall m (A : nat -> Omega -> Prop), P (fun w => exists k, (k < m)%nat /\ A k w) <= rsum m (fun k => P (A k)).
555
+ Proof. exact (P_exists Omega P P_mono P_or P_empty). Qed.
556
+
557
+ Lemma Pnn : forall A, 0 <= P A.
558
+ Proof. exact (P_nonneg Omega P P_mono P_empty). Qed.
559
+
560
+ Lemma Ple1 : forall A, P A <= 1.
561
+ Proof. exact (P_le1 Omega P P_mono P_true). Qed.
562
+
563
+ Lemma Pnone : forall A : Omega -> Prop, (forall w, ~ A w) -> P A = 0.
564
+ Proof. intros A H. apply Rle_antisym; [rewrite <- P_empty; apply P_mono; intros w Hw; exact (H w Hw) | apply Pnn]. Qed.
565
+
566
+ Lemma P_or3 : forall A B C : Omega -> Prop, P (fun w => A w \/ B w \/ C w) <= P A + P B + P C.
567
+ Proof. intros A B C. eapply Rle_trans; [apply P_or|]. pose proof (P_or B C). lra. Qed.
568
+
569
+ (* the union bound over the j < m that pass a test T *)
570
+ Lemma P_sum : forall m (T : nat -> bool) (A : nat -> Omega -> Prop) (b : nat -> R),
571
+ (forall j, (j < m)%nat -> T j = true -> P (A j) <= b j) ->
572
+ P (fun w => exists j, (j < m)%nat /\ T j = true /\ A j w) <= rsum m (fun j => if T j then b j else 0).
573
+ Proof.
574
+ intros m T A b H. eapply Rle_trans; [apply (Pex m (fun j w => T j = true /\ A j w))|]. apply rsum_le. intros j Hj.
575
+ destruct (T j) eqn:E.
576
+ - eapply Rle_trans; [|apply (H j Hj E)]. apply P_mono. intros w [_ Hw]. exact Hw.
577
+ - right. apply Pnone. intros w [C _]. discriminate.
578
+ Qed.
579
+
580
+ (* events on distinct variables are independent *)
581
+ Lemma P_ind2 : forall g1 g2 (A B : R -> Prop), g1 <> g2 ->
582
+ P (fun w => A (X g1 w) /\ B (X g2 w)) = P (fun w => A (X g1 w)) * P (fun w => B (X g2 w)).
583
+ Proof.
584
+ intros g1 g2 A B Hg. apply (P_indep (fun g => g = g1) (fun g => g = g2)).
585
+ - intros g -> E. exact (Hg E).
586
+ - intros w w' H. rewrite (H g1 eq_refl). reflexivity.
587
+ - intros w w' H. rewrite (H g2 eq_refl). reflexivity.
588
+ Qed.
589
+
590
+ Lemma P_ind3 : forall g1 g2 g3 (A B C : R -> Prop), g1 <> g2 -> g1 <> g3 -> g2 <> g3 ->
591
+ P (fun w => A (X g1 w) /\ B (X g2 w) /\ C (X g3 w))
592
+ = P (fun w => A (X g1 w)) * P (fun w => B (X g2 w)) * P (fun w => C (X g3 w)).
593
+ Proof.
594
+ intros g1 g2 g3 A B C H12 H13 H23.
595
+ rewrite (P_indep (fun g => g = g1) (fun g => g = g2 \/ g = g3) (fun w => A (X g1 w)) (fun w => B (X g2 w) /\ C (X g3 w))).
596
+ - rewrite P_ind2 by exact H23. ring.
597
+ - intros g -> [E|E]; [exact (H12 E) | exact (H13 E)].
598
+ - intros w w' H. rewrite (H g1 eq_refl). reflexivity.
599
+ - intros w w' H. rewrite (H g2 (or_introl eq_refl)), (H g3 (or_intror eq_refl)). reflexivity.
600
+ Qed.
601
+
602
+ (* unions over the three copies of a row, and over pairs of copies *)
603
+ Lemma P_copies : forall (g : nat -> nat) (A : R -> Prop) p, (forall c, (c < 3)%nat -> P (fun w => A (X (g c) w)) <= p) ->
604
+ P (fun w => exists c, (c < 3)%nat /\ A (X (g c) w)) <= 3 * p.
605
+ Proof.
606
+ intros g A p H. eapply Rle_trans; [apply (Pex 3 (fun c w => A (X (g c) w)))|].
607
+ cbn [rsum]. pose proof (H 0%nat ltac:(lia)). pose proof (H 1%nat ltac:(lia)). pose proof (H 2%nat ltac:(lia)). lra.
608
+ Qed.
609
+
610
+ Lemma P_copy_pairs : forall (g1 g2 : nat -> nat) (A B : R -> Prop) pA pB,
611
+ (forall c1 c2, (c1 < 3)%nat -> (c2 < 3)%nat -> g1 c1 <> g2 c2) ->
612
+ (forall c, (c < 3)%nat -> P (fun w => A (X (g1 c) w)) <= pA) -> (forall c, (c < 3)%nat -> P (fun w => B (X (g2 c) w)) <= pB) ->
613
+ P (fun w => exists c1, (c1 < 3)%nat /\ exists c2, (c2 < 3)%nat /\ A (X (g1 c1) w) /\ B (X (g2 c2) w)) <= 9 * pA * pB.
614
+ Proof.
615
+ intros g1 g2 A B pA pB Hg HA HB.
616
+ eapply Rle_trans; [apply (Pex 3 (fun c1 w => exists c2, (c2 < 3)%nat /\ A (X (g1 c1) w) /\ B (X (g2 c2) w)))|].
617
+ assert (Hc : forall c1, (c1 < 3)%nat ->
618
+ P (fun w => exists c2, (c2 < 3)%nat /\ A (X (g1 c1) w) /\ B (X (g2 c2) w)) <= 3 * (pA * pB)).
619
+ { intros c1 Hc1. eapply Rle_trans; [apply (Pex 3 (fun c2 w => A (X (g1 c1) w) /\ B (X (g2 c2) w)))|].
620
+ assert (Hp : forall c2, (c2 < 3)%nat -> P (fun w => A (X (g1 c1) w) /\ B (X (g2 c2) w)) <= pA * pB).
621
+ { intros c2 Hc2. rewrite P_ind2 by (apply Hg; assumption).
622
+ apply Rmult_le_compat; [apply Pnn | apply Pnn | apply HA; exact Hc1 | apply HB; exact Hc2]. }
623
+ cbn [rsum]. pose proof (Hp 0%nat ltac:(lia)). pose proof (Hp 1%nat ltac:(lia)). pose proof (Hp 2%nat ltac:(lia)). lra. }
624
+ cbn [rsum]. pose proof (Hc 0%nat ltac:(lia)). pose proof (Hc 1%nat ltac:(lia)). pose proof (Hc 2%nat ltac:(lia)). lra.
625
+ Qed.
626
+
627
+ Lemma P_copy_lt : forall (g : nat -> nat) (A B : R -> Prop) pA pB, (forall c1 c2, (c1 < 3)%nat -> (c2 < 3)%nat -> c1 <> c2 -> g c1 <> g c2) ->
628
+ (forall c, (c < 3)%nat -> P (fun w => A (X (g c) w)) <= pA) -> (forall c, (c < 3)%nat -> P (fun w => B (X (g c) w)) <= pB) ->
629
+ P (fun w => exists c1 c2, (c1 < c2)%nat /\ (c2 < 3)%nat /\ A (X (g c1) w) /\ B (X (g c2) w)) <= 3 * pA * pB.
630
+ Proof.
631
+ intros g A B pA pB Hg HA HB.
632
+ eapply Rle_trans; [apply (P_mono _ (fun w => (A (X (g 0%nat) w) /\ B (X (g 1%nat) w)) \/ (A (X (g 0%nat) w) /\ B (X (g 2%nat) w))
633
+ \/ (A (X (g 1%nat) w) /\ B (X (g 2%nat) w))))|].
634
+ - intros w (c1 & c2 & H1 & H2 & Ha & Hb).
635
+ destruct c1 as [|[|c1]]; destruct c2 as [|[|[|c2]]]; try lia; auto.
636
+ - eapply Rle_trans; [apply P_or3|].
637
+ assert (Hp : forall c1 c2, (c1 < 3)%nat -> (c2 < 3)%nat -> c1 <> c2 -> P (fun w => A (X (g c1) w) /\ B (X (g c2) w)) <= pA * pB).
638
+ { intros c1 c2 H1 H2 H12. rewrite P_ind2 by (apply Hg; assumption).
639
+ apply Rmult_le_compat; [apply Pnn | apply Pnn | apply HA; exact H1 | apply HB; exact H2]. }
640
+ pose proof (Hp 0%nat 1%nat ltac:(lia) ltac:(lia) ltac:(lia)). pose proof (Hp 0%nat 2%nat ltac:(lia) ltac:(lia) ltac:(lia)).
641
+ pose proof (Hp 1%nat 2%nat ltac:(lia) ltac:(lia) ltac:(lia)). lra.
642
+ Qed.
643
+
644
+ (* ---- the perturbation that fails a copy ------------------------------------------------------------------------ *)
645
+ (* q_k(v) = Q((D_v - k)/s) and Delta_v = q_1(v) - q_0(v) *)
646
+ Definition qk (a i k : nat) : R := Q ((3 * Rabs (IZR (zv a i) + 1/2) - INR k) / s).
647
+ Definition dl (a i : nat) : R := qk a i 1 - qk a i 0.
648
+
649
+ Lemma qk_range : forall a i k, 0 <= qk a i k <= 1.
650
+ Proof. intros. apply Q_range. Qed.
651
+
652
+ Lemma qk_mono : forall a i k k', (k <= k')%nat -> qk a i k <= qk a i k'.
653
+ Proof.
654
+ intros a i k k' H. unfold qk. apply Q_decr. apply le_INR in H. unfold Rdiv.
655
+ apply Rmult_le_compat_r; [apply Rlt_le, Rinv_0_lt_compat; exact Hs | lra].
656
+ Qed.
657
+
658
+ Lemma dl_nn : forall a i, 0 <= dl a i.
659
+ Proof. intros a i. unfold dl. pose proof (qk_mono a i 0 1 ltac:(lia)). lra. Qed.
660
+
661
+ Lemma far_dec : forall z k e, far z k e \/ ~ far z k e.
662
+ Proof.
663
+ intros z k e. unfold far. destruct (Z.leb 0 z).
664
+ - destruct (Rlt_dec e (- (3 * Rabs (IZR z + 1/2) - INR k))); [left | right]; assumption.
665
+ - destruct (Rle_dec (3 * Rabs (IZR z + 1/2) - INR k) e); [left | right]; assumption.
666
+ Qed.
667
+
668
+ Lemma far_mono : forall z k k' e, (k <= k')%nat -> far z k e -> far z k' e.
669
+ Proof. intros z k k' e H. apply le_INR in H. unfold far. destruct (Z.leb 0 z); lra. Qed.
670
+
671
+ Lemma P_far : forall a i k g, P (fun w => far (zv a i) k (X g w)) <= qk a i k.
672
+ Proof.
673
+ intros a i k g. unfold far, qk. set (D := 3 * Rabs (IZR (zv a i) + 1/2)). destruct (Z.leb 0 (zv a i)).
674
+ - eapply Rle_trans; [apply (P_mono _ (fun w => X g w <= - (D - INR k))); intros w H; lra|].
675
+ rewrite tail_le. right. f_equal. field. lra.
676
+ - rewrite tail_ge. right. reflexivity.
677
+ Qed.
678
+
679
+ Lemma P_band : forall g c1 c0, c1 <= c0 -> P (fun w => c1 <= X g w /\ ~ c0 <= X g w) = Q (c1 / s) - Q (c0 / s).
680
+ Proof.
681
+ intros g c1 c0 H.
682
+ assert (E : P (fun w => c1 <= X g w) = P (fun w => c0 <= X g w) + P (fun w => c1 <= X g w /\ ~ c0 <= X g w)).
683
+ { rewrite <- P_add.
684
+ - apply (P_ext Omega P P_mono). intro w. split.
685
+ + intro H1. destruct (Rle_dec c0 (X g w)) as [H0|H0]; [left; exact H0 | right; split; assumption].
686
+ + intros [H0|[H1 _]]; [lra | exact H1].
687
+ - apply meas_ge.
688
+ - apply meas_and; [apply meas_ge | apply meas_not, meas_ge].
689
+ - intros w H0 [_ H1]. exact (H1 H0). }
690
+ rewrite !tail_ge in E. lra.
691
+ Qed.
692
+
693
+ Lemma P_far10 : forall a i g, P (fun w => far (zv a i) 1 (X g w) /\ ~ far (zv a i) 0 (X g w)) <= dl a i.
694
+ Proof.
695
+ intros a i g. unfold far, dl, qk. set (D := 3 * Rabs (IZR (zv a i) + 1/2)). cbn [INR]. destruct (Z.leb 0 (zv a i)).
696
+ - rewrite (P_ext Omega P P_mono _ (fun w => - D <= X g w /\ ~ - (D - 1) <= X g w)).
697
+ + rewrite P_band by lra. replace (- D / s) with (- (D / s)) by (field; lra).
698
+ replace (- (D - 1) / s) with (- ((D - 1) / s)) by (field; lra). rewrite !Q_sym. replace (D - 0) with D by ring. lra.
699
+ + intro w. split; intros [H1 H2]; (split; [lra | intro; lra]).
700
+ - rewrite (P_ext Omega P P_mono _ (fun w => D - 1 <= X g w /\ ~ D <= X g w)).
701
+ + rewrite P_band by lra. replace (D - 0) with D by ring. lra.
702
+ + intro w. split; intros [H1 H2]; (split; [lra | intro; lra]).
703
+ Qed.
704
+
705
+ (* ---- what the events depend on --------------------------------------------------------------------------------- *)
706
+ (* the variables of the layers before a, and of layer a *)
707
+ Definition pastv (a g : nat) : Prop := exists a' q, (a' < a)%nat /\ g = vid a' q.
708
+ Definition nowv (a g : nat) : Prop := exists q, g = vid a q.
709
+
710
+ Lemma past_now : forall a g, pastv a g -> nowv a g -> False.
711
+ Proof. intros a g (a' & q & Ha & ->) (q' & E). apply vid_inj in E as [E _]. lia. Qed.
712
+
713
+ Lemma P_pn : forall a (A B : Omega -> Prop), dep Omega X (pastv a) A -> dep Omega X (nowv a) B ->
714
+ P (fun w => A w /\ B w) = P A * P B.
715
+ Proof. intros a A B HA HB. apply (P_indep (pastv a) (nowv a)); [exact (past_now a) | exact HA | exact HB]. Qed.
716
+
717
+ Lemma dep_now : forall a (F : (nat -> R) -> Prop), dep Omega X (nowv a) (fun w => F (fun q => X (vid a q) w)).
718
+ Proof.
719
+ intros a F w w' H. replace (fun q => X (vid a q) w') with (fun q => X (vid a q) w); [reflexivity|].
720
+ apply functional_extensionality. intro q. apply H. exists q. reflexivity.
721
+ Qed.
722
+
723
+ Lemma dep_and : forall I (A B : Omega -> Prop), dep Omega X I A -> dep Omega X I B -> dep Omega X I (fun w => A w /\ B w).
724
+ Proof. intros I A B HA HB w w' H. rewrite (HA w w' H), (HB w w' H). reflexivity. Qed.
725
+
726
+ Lemma dep_or : forall I (A B : Omega -> Prop), dep Omega X I A -> dep Omega X I B -> dep Omega X I (fun w => A w \/ B w).
727
+ Proof. intros I A B HA HB w w' H. rewrite (HA w w' H), (HB w w' H). reflexivity. Qed.
728
+
729
+ Lemma dep_ex : forall I m (T : nat -> Prop) (A : nat -> Omega -> Prop), (forall j, dep Omega X I (A j)) ->
730
+ dep Omega X I (fun w => exists j, (j < m)%nat /\ T j /\ A j w).
731
+ Proof.
732
+ intros I m T A HA w w' H. split; intros (j & Hj & Tj & Aj); exists j; split; [exact Hj | | exact Hj |];
733
+ (split; [exact Tj|]); [apply (HA j w w' H) | apply (HA j w w' H)]; exact Aj.
734
+ Qed.
735
+
736
+ Lemma dep_mono : forall I J (A : Omega -> Prop), (forall g, I g -> J g) -> dep Omega X I A -> dep Omega X J A.
737
+ Proof. intros I J A HIJ HA w w' H. apply HA. intros g Hg. apply H. apply HIJ. exact Hg. Qed.
738
+
739
+ Lemma pastv_S : forall a g, pastv a g -> pastv (S a) g.
740
+ Proof. intros a g (a' & q & Ha & E). exists a', q. split; [lia | exact E]. Qed.
741
+
742
+ (* the run up to layer a reads only the variables of layers up to a *)
743
+ Lemma inp_ext : forall w w' a, (forall a' q, (a' < a)%nat -> X (vid a' q) w = X (vid a' q) w') -> inp w a = inp w' a.
744
+ Proof.
745
+ intros w w' a. induction a as [|a IH]; intro H; [rewrite !inp_0; reflexivity|].
746
+ assert (Eo : out w a = out w' a).
747
+ { rewrite !out_eq, (IH (fun a' q Ha' => H a' q ltac:(lia))). apply lfirep_ext. intros q _. apply H. lia. }
748
+ destruct (Nat.eq_dec (lyr (S a)) 0) as [B|B]; [rewrite !inp_B by exact B | rewrite !inp_S by exact B]; rewrite Eo; reflexivity.
749
+ Qed.
750
+
751
+ Lemma out_ext : forall w w' a, (forall a' q, (a' <= a)%nat -> X (vid a' q) w = X (vid a' q) w') -> out w a = out w' a.
752
+ Proof.
753
+ intros w w' a H. rewrite !out_eq, (inp_ext w w' a (fun a' q Ha' => H a' q ltac:(lia))). apply lfirep_ext.
754
+ intros q _. apply H. lia.
755
+ Qed.
756
+
757
+ Lemma stop_ext : forall w w' a, (forall a' q, (a' <= a)%nat -> X (vid a' q) w = X (vid a' q) w') -> stopb w a = stopb w' a.
758
+ Proof.
759
+ intros w w' a H. unfold stopb, stop1, stop2, ncw, Sc, wb, wib.
760
+ rewrite (out_ext w w' a H), (inp_ext w w' a (fun a' q Ha' => H a' q ltac:(lia))). reflexivity.
761
+ Qed.
762
+
763
+ Lemma agree : forall a w w', (forall g, pastv a g -> X g w = X g w') -> forall a' q, (a' < a)%nat -> X (vid a' q) w = X (vid a' q) w'.
764
+ Proof. intros a w w' H a' q Ha'. apply H. exists a', q. split; [exact Ha' | reflexivity]. Qed.
765
+
766
+ Lemma dep_Gb : forall a, dep Omega X (pastv a) (Gb a).
767
+ Proof.
768
+ intros a w w' H. pose proof (agree a w w' H) as Ag. unfold Gb.
769
+ assert (E : forall a', (a' < a)%nat -> stopb w a' = stopb w' a')
770
+ by (intros a' Ha'; apply stop_ext; intros a'' q Ha''; apply Ag; lia).
771
+ split; intros HG a' Ha'; [rewrite <- (E a' Ha') | rewrite (E a' Ha')]; apply HG; exact Ha'.
772
+ Qed.
773
+
774
+ Lemma dep_Win : forall a j, dep Omega X (pastv a) (Win a j).
775
+ Proof.
776
+ intros a j w w' H. pose proof (agree a w w' H) as Ag. unfold Win, nci, wib.
777
+ rewrite (inp_ext w w' a Ag). rewrite (dep_Gb a w w' H). reflexivity.
778
+ Qed.
779
+
780
+ Lemma dep_Wv : forall a i, dep Omega X (pastv (S a)) (Wv a i).
781
+ Proof.
782
+ intros a i w w' H. pose proof (agree (S a) w w' H) as Ag. unfold Wv, ncw, wb.
783
+ rewrite (out_ext w w' a (fun a' q Ha' => Ag a' q ltac:(lia))). rewrite !Gu_Gb, (dep_Gb (S a) w w' H). reflexivity.
784
+ Qed.
785
+
786
+ Lemma dep_E2 : forall a i, dep Omega X (pastv (S a)) (E2 a i).
787
+ Proof.
788
+ intros a i w w' H. pose proof (agree (S a) w w' H) as Ag. unfold E2, ncw, Sc, wb, wib.
789
+ rewrite (out_ext w w' a (fun a' q Ha' => Ag a' q ltac:(lia))), (inp_ext w w' a (fun a' q Ha' => Ag a' q ltac:(lia))).
790
+ rewrite (dep_mono _ _ _ (pastv_S a) (dep_Gb a) w w' H). reflexivity.
791
+ Qed.
792
+
793
+ Lemma dep_E3 : forall a i, dep Omega X (pastv (S a)) (E3 a i).
794
+ Proof.
795
+ intros a i w w' H. pose proof (agree (S a) w w' H) as Ag. unfold E3, ncw, Sc, wb, wib.
796
+ rewrite (out_ext w w' a (fun a' q Ha' => Ag a' q ltac:(lia))), (inp_ext w w' a (fun a' q Ha' => Ag a' q ltac:(lia))).
797
+ rewrite (dep_mono _ _ _ (pastv_S a) (dep_Gb a) w w' H). reflexivity.
798
+ Qed.
799
+
800
+ (* ---- the recursion of Proposition 6.14 ------------------------------------------------------------------------- *)
801
+ (* X_v = sum of p over T(v) *)
802
+ Definition Xs (a i : nat) (p : nat -> R) : R := rsum (wia a) (fun j => if tT a i j then p j else 0).
803
+ (* the sum over T(v1) and T(v2) in K_{v1 v2} *)
804
+ Definition Kpair (a i1 i2 : nat) (p : nat -> R) (k : nat -> nat -> R) : R :=
805
+ rsum (wia a) (fun j => if tT a i1 j && tT a i2 j then p j else 0)
806
+ + rsum (wia a) (fun j1 => rsum (wia a) (fun j2 => if tT a i1 j1 && tT a i2 j2 && negb (Nat.eqb j1 j2) then k j1 j2 else 0)).
807
+
808
+ (* P and K of the inputs of layer a: zero on the state of step 0 and on the device cells of every state *)
809
+ Fixpoint PK (a : nat) : (nat -> R) * (nat -> nat -> R) :=
810
+ match a with
811
+ | O => (fun _ => 0, fun _ _ => 0)
812
+ | S a' =>
813
+ let pv := fun i => 3 * qk a' i 0 + 3 * dl a' i * Xs a' i (fst (PK a')) in
814
+ let kv := fun i1 i2 => 9 * dl a' i1 * dl a' i2 * Kpair a' i1 i2 (fst (PK a')) (snd (PK a')) in
815
+ if Nat.eqb (lyr (S a')) 0 then (fun j => if Dv j then 0 else pv j, fun j1 j2 => if Dv j1 || Dv j2 then 0 else kv j1 j2)
816
+ else (pv, kv)
817
+ end.
818
+
819
+ Definition Pin (a : nat) : nat -> R := fst (PK a).
820
+ Definition Kin (a : nat) : nat -> nat -> R := snd (PK a).
821
+ (* P_v, K_{v1 v2}, P^(2)_v and P^(3)_v of the rows of layer a *)
822
+ Definition Pv (a i : nat) : R := 3 * qk a i 0 + 3 * dl a i * Xs a i (Pin a).
823
+ Definition Kv (a i1 i2 : nat) : R := 9 * dl a i1 * dl a i2 * Kpair a i1 i2 (Pin a) (Kin a).
824
+ Definition P2v (a i : nat) : R := 3 * qk a i 0 ^ 2 + 3 * (qk a i 1 ^ 2 - qk a i 0 ^ 2) * Xs a i (Pin a).
825
+ Definition P3v (a i : nat) : R := qk a i 0 ^ 3 + (qk a i 1 ^ 3 - qk a i 0 ^ 3) * Xs a i (Pin a).
826
+ (* P^(2) and P^(3) of the inputs of layer a, zero on every state *)
827
+ Definition P2in (a j : nat) : R := if Nat.eqb (lyr a) 0 then 0 else P2v (a - 1) j.
828
+ Definition P3in (a j : nat) : R := if Nat.eqb (lyr a) 0 then 0 else P3v (a - 1) j.
829
+
830
+ (* the contribution of layer a to b(t) *)
831
+ Definition bl (a : nat) : R :=
832
+ rsum (nla a) (fun i =>
833
+ Rmin 1 (3 * qk a i 2) * Xs a i (P2in a) + Rmin 1 (3 * qk a i 3) * Xs a i (P3in a)
834
+ + rsum (wia a) (fun j1 => rsum (wia a) (fun j2 =>
835
+ if tT a i j1 && tT a i j2 && Nat.ltb j1 j2 then Pin a j1 * Pin a j2 + Kin a j1 j2 else 0)))
836
+ + (if Nat.eqb (lyr a) (length Ls - 1) then rsum (nla a) (fun i => P2v a i) else 0).
837
+
838
+ (* b(t): the sum over the layers of step t *)
839
+ Definition bt (t : nat) : R := rsum (length Ls) (fun l => bl (t * length Ls + l)).
840
+
841
+ Lemma Pin_S : forall a j, Pin (S a) j = if Nat.eqb (lyr (S a)) 0 then (if Dv j then 0 else Pv a j) else Pv a j.
842
+ Proof. intros a j. unfold Pin, Pv. cbn [PK]. destruct (Nat.eqb (lyr (S a)) 0); reflexivity. Qed.
843
+
844
+ Lemma Kin_S : forall a j1 j2,
845
+ Kin (S a) j1 j2 = if Nat.eqb (lyr (S a)) 0 then (if Dv j1 || Dv j2 then 0 else Kv a j1 j2) else Kv a j1 j2.
846
+ Proof. intros a j1 j2. unfold Kin, Kv. cbn [PK]. destruct (Nat.eqb (lyr (S a)) 0); reflexivity. Qed.
847
+
848
+ Lemma Xs_nn : forall a i p, (forall j, 0 <= p j) -> 0 <= Xs a i p.
849
+ Proof. intros a i p H. apply rsum_nonneg. intros j _. destruct (tT a i j); [apply H | lra]. Qed.
850
+
851
+ Lemma PK_nn : forall a, (forall j, 0 <= Pin a j) /\ (forall j1 j2, 0 <= Kin a j1 j2).
852
+ Proof.
853
+ induction a as [|a [IP IK]]; [split; intros; unfold Pin, Kin; cbn; lra|].
854
+ assert (HP : forall i, 0 <= Pv a i).
855
+ { intro i. unfold Pv. pose proof (qk_range a i 0). pose proof (dl_nn a i). pose proof (Xs_nn a i _ IP). nra. }
856
+ assert (HK : forall i1 i2, 0 <= Kv a i1 i2).
857
+ { intros i1 i2. unfold Kv. pose proof (dl_nn a i1). pose proof (dl_nn a i2).
858
+ assert (0 <= Kpair a i1 i2 (Pin a) (Kin a)).
859
+ { unfold Kpair. apply Rplus_le_le_0_compat; apply rsum_nonneg; intros j1 _; [destruct (tT a i1 j1 && tT a i2 j1); [apply IP | lra]|].
860
+ apply rsum_nonneg. intros j2 _. destruct (tT a i1 j1 && tT a i2 j2 && negb (Nat.eqb j1 j2)); [apply IK | lra]. }
861
+ assert (0 <= 9 * dl a i1 * dl a i2) by (apply Rmult_le_pos; [apply Rmult_le_pos; lra | lra]). nra. }
862
+ split; [intro j; rewrite Pin_S | intros j1 j2; rewrite Kin_S];
863
+ destruct (Nat.eqb (lyr (S a)) 0); try destruct (Dv j); try destruct (Dv j1 || Dv j2); (lra || apply HP || apply HK).
864
+ Qed.
865
+
866
+ Lemma rsum_if_scal : forall m (T : nat -> bool) (p : nat -> R) c,
867
+ rsum m (fun j => if T j then p j * c else 0) = c * rsum m (fun j => if T j then p j else 0).
868
+ Proof. intros m T p c. rewrite <- rsum_scal. apply rsum_ext. intros j _. destruct (T j); ring. Qed.
869
+
870
+ (* ---- P(W_v) <= P_v ------------------------------------------------------------------------------------------------- *)
871
+ Lemma claim_P : forall a i, (i < nla a)%nat -> (forall j, (j < wia a)%nat -> P (Win a j) <= Pin a j) -> P (Wv a i) <= Pv a i.
872
+ Proof.
873
+ intros a i Hi HW. set (g := fun c => vid a (c * nla a + i)%nat).
874
+ eapply Rle_trans; [apply (P_mono _ (fun w => (exists c, (c < 3)%nat /\ far (zv a i) 0 (X (g c) w))
875
+ \/ (exists j, (j < wia a)%nat /\ tT a i j = true /\ (Win a j w /\
876
+ (exists c, (c < 3)%nat /\ (far (zv a i) 1 (X (g c) w) /\ ~ far (zv a i) 0 (X (g c) w)))))))|].
877
+ - intros w [Hn HG]. destruct (ncw_copy w a i Hn) as (c & Hc & Hwc).
878
+ assert (Hq : (c * nla a + i < 3 * nla a)%nat) by nia.
879
+ pose proof (wrong_far w a _ Hq Hwc) as Hf. pose proof (nostop_Sc w a _ (HG a (le_n a)) Hq Hwc) as HS.
880
+ rewrite cp_mod in Hf, HS by exact Hi.
881
+ destruct (far_dec (zv a i) 0 (X (g c) w)) as [F0|F0]; [left; exists c; split; assumption|].
882
+ right. assert (S1 : Sc w a i = 1%nat) by (destruct (Sc w a i) as [|[|k]]; [exfalso; apply F0; exact Hf | reflexivity | lia]).
883
+ destruct (Sc_pos w a i ltac:(lia)) as (j & Hj & Tj & Nj). exists j. split; [exact Hj|]. split; [exact Tj|]. split.
884
+ + split; [exact Nj|]. intros a' Ha'. apply HG. lia.
885
+ + exists c. split; [exact Hc|]. split; [rewrite S1 in Hf; exact Hf | exact F0].
886
+ - eapply Rle_trans; [apply P_or|].
887
+ pose proof (P_copies g (far (zv a i) 0) (qk a i 0) (fun c _ => P_far a i 0 (g c))) as B0.
888
+ assert (B1 : P (fun w => exists j, (j < wia a)%nat /\ tT a i j = true /\ (Win a j w /\
889
+ (exists c, (c < 3)%nat /\ (far (zv a i) 1 (X (g c) w) /\ ~ far (zv a i) 0 (X (g c) w)))))
890
+ <= rsum (wia a) (fun j => if tT a i j then Pin a j * (3 * dl a i) else 0)).
891
+ { apply P_sum. intros j Hj Tj. rewrite (P_pn a).
892
+ - apply Rmult_le_compat; [apply Pnn | apply Pnn | apply HW; exact Hj|].
893
+ exact (P_copies g (fun e => far (zv a i) 1 e /\ ~ far (zv a i) 0 e) (dl a i) (fun c _ => P_far10 a i (g c))).
894
+ - apply dep_Win.
895
+ - exact (dep_now a (fun f => exists c, (c < 3)%nat /\
896
+ (far (zv a i) 1 (f (c * nla a + i)%nat) /\ ~ far (zv a i) 0 (f (c * nla a + i)%nat)))). }
897
+ rewrite rsum_if_scal in B1. unfold Pv, Xs. lra.
898
+ Qed.
899
+
900
+ (* ---- two and three wrong copies, and pairs of rows ---------------------------------------------------------------- *)
901
+ Definition cpy (a i c : nat) : nat := (c * nla a + i)%nat.
902
+ Definition F0 (z : Z) (e : R) : Prop := far z 0 e.
903
+ Definition F10 (z : Z) (e : R) : Prop := far z 1 e /\ ~ far z 0 e.
904
+
905
+ Lemma cpy_lt : forall a i c, (i < nla a)%nat -> (c < 3)%nat -> (cpy a i c < 3 * nla a)%nat.
906
+ Proof. intros a i c Hi Hc. unfold cpy. nia. Qed.
907
+
908
+ Lemma cpy_mod : forall a i c, (i < nla a)%nat -> (cpy a i c mod nla a = i)%nat.
909
+ Proof. intros a i c Hi. apply cp_mod. exact Hi. Qed.
910
+
911
+ Lemma vid_cpy : forall a i1 i2 c1 c2, (i1 < nla a)%nat -> (i2 < nla a)%nat -> (c1 <> c2 \/ i1 <> i2) ->
912
+ vid a (cpy a i1 c1) <> vid a (cpy a i2 c2).
913
+ Proof.
914
+ intros a i1 i2 c1 c2 H1 H2 Hd E. apply vid_inj in E as [_ E]. apply cp_inj in E as [E1 E2]; [|exact H1 | exact H2].
915
+ destruct Hd; contradiction.
916
+ Qed.
917
+
918
+ Lemma P_or4 : forall A B C D : Omega -> Prop, P (fun w => A w \/ B w \/ C w \/ D w) <= P A + P B + P C + P D.
919
+ Proof. intros A B C D. eapply Rle_trans; [apply P_or|]. pose proof (P_or3 B C D). lra. Qed.
920
+
921
+ Lemma P_trip : forall g1 g2 g3 (A B C : R -> Prop) pa pb pc, g1 <> g2 -> g1 <> g3 -> g2 <> g3 ->
922
+ P (fun w => A (X g1 w)) <= pa -> P (fun w => B (X g2 w)) <= pb -> P (fun w => C (X g3 w)) <= pc ->
923
+ P (fun w => A (X g1 w) /\ B (X g2 w) /\ C (X g3 w)) <= pa * pb * pc.
924
+ Proof.
925
+ intros g1 g2 g3 A B C pa pb pc H12 H13 H23 Ha Hb Hc. rewrite P_ind3 by assumption.
926
+ apply Rmult_le_compat; [apply Rmult_le_pos; apply Pnn | apply Pnn | | exact Hc].
927
+ apply Rmult_le_compat; [apply Pnn | apply Pnn | exact Ha | exact Hb].
928
+ Qed.
929
+
930
+ Lemma dep_ex0 : forall I m (A : nat -> Omega -> Prop), (forall j, dep Omega X I (A j)) ->
931
+ dep Omega X I (fun w => exists j, (j < m)%nat /\ A j w).
932
+ Proof.
933
+ intros I m A HA w w' H. split; intros (j & Hj & Aj); exists j; split; [exact Hj | | exact Hj |];
934
+ [apply (HA j w w' H) | apply (HA j w w' H)]; exact Aj.
935
+ Qed.
936
+
937
+ (* the copies of the present layer: two of row i, then three, then one of each of two rows *)
938
+ Definition N2 (a i : nat) (f : nat -> R) : Prop :=
939
+ (exists c1 c2, (c1 < c2)%nat /\ (c2 < 3)%nat /\ F10 (zv a i) (f (cpy a i c1)) /\ far (zv a i) 1 (f (cpy a i c2)))
940
+ \/ (exists c1 c2, (c1 < c2)%nat /\ (c2 < 3)%nat /\ F0 (zv a i) (f (cpy a i c1)) /\ F10 (zv a i) (f (cpy a i c2))).
941
+
942
+ Definition N3 (a i : nat) (f : nat -> R) : Prop :=
943
+ (F10 (zv a i) (f (cpy a i 0)) /\ far (zv a i) 1 (f (cpy a i 1)) /\ far (zv a i) 1 (f (cpy a i 2)))
944
+ \/ (F0 (zv a i) (f (cpy a i 0)) /\ F10 (zv a i) (f (cpy a i 1)) /\ far (zv a i) 1 (f (cpy a i 2)))
945
+ \/ (F0 (zv a i) (f (cpy a i 0)) /\ F0 (zv a i) (f (cpy a i 1)) /\ F10 (zv a i) (f (cpy a i 2))).
946
+
947
+ Definition Npr (a i1 i2 : nat) (A B : Z -> R -> Prop) (f : nat -> R) : Prop :=
948
+ exists c1, (c1 < 3)%nat /\ exists c2, (c2 < 3)%nat /\ A (zv a i1) (f (cpy a i1 c1)) /\ B (zv a i2) (f (cpy a i2 c2)).
949
+
950
+ Lemma P_N2 : forall a i, (i < nla a)%nat ->
951
+ P (fun w => N2 a i (fun q => X (vid a q) w)) <= 3 * dl a i * qk a i 1 + 3 * qk a i 0 * dl a i.
952
+ Proof.
953
+ intros a i Hi.
954
+ assert (Hg : forall c1 c2, (c1 < 3)%nat -> (c2 < 3)%nat -> c1 <> c2 -> vid a (cpy a i c1) <> vid a (cpy a i c2))
955
+ by (intros c1 c2 _ _ Hd; apply vid_cpy; [exact Hi | exact Hi | left; exact Hd]).
956
+ unfold N2. eapply Rle_trans; [apply P_or|]. apply Rplus_le_compat.
957
+ - exact (P_copy_lt (fun c => vid a (cpy a i c)) (F10 (zv a i)) (far (zv a i) 1) (dl a i) (qk a i 1) Hg
958
+ (fun c _ => P_far10 a i _) (fun c _ => P_far a i 1 _)).
959
+ - exact (P_copy_lt (fun c => vid a (cpy a i c)) (F0 (zv a i)) (F10 (zv a i)) (qk a i 0) (dl a i) Hg
960
+ (fun c _ => P_far a i 0 _) (fun c _ => P_far10 a i _)).
961
+ Qed.
962
+
963
+ Lemma P_N3 : forall a i, (i < nla a)%nat ->
964
+ P (fun w => N3 a i (fun q => X (vid a q) w))
965
+ <= dl a i * qk a i 1 * qk a i 1 + qk a i 0 * dl a i * qk a i 1 + qk a i 0 * qk a i 0 * dl a i.
966
+ Proof.
967
+ intros a i Hi.
968
+ assert (Hg : forall c1 c2, c1 <> c2 -> vid a (cpy a i c1) <> vid a (cpy a i c2))
969
+ by (intros c1 c2 Hd; apply vid_cpy; [exact Hi | exact Hi | left; exact Hd]).
970
+ unfold N3. eapply Rle_trans; [apply P_or3|]. apply Rplus_le_compat; [apply Rplus_le_compat|].
971
+ - exact (P_trip _ _ _ (F10 (zv a i)) (far (zv a i) 1) (far (zv a i) 1) _ _ _ (Hg 0%nat 1%nat ltac:(lia))
972
+ (Hg 0%nat 2%nat ltac:(lia)) (Hg 1%nat 2%nat ltac:(lia)) (P_far10 a i _) (P_far a i 1 _) (P_far a i 1 _)).
973
+ - exact (P_trip _ _ _ (F0 (zv a i)) (F10 (zv a i)) (far (zv a i) 1) _ _ _ (Hg 0%nat 1%nat ltac:(lia))
974
+ (Hg 0%nat 2%nat ltac:(lia)) (Hg 1%nat 2%nat ltac:(lia)) (P_far a i 0 _) (P_far10 a i _) (P_far a i 1 _)).
975
+ - exact (P_trip _ _ _ (F0 (zv a i)) (F0 (zv a i)) (F10 (zv a i)) _ _ _ (Hg 0%nat 1%nat ltac:(lia))
976
+ (Hg 0%nat 2%nat ltac:(lia)) (Hg 1%nat 2%nat ltac:(lia)) (P_far a i 0 _) (P_far a i 0 _) (P_far10 a i _)).
977
+ Qed.
978
+
979
+ Lemma P_Npr : forall a i1 i2 (A B : Z -> R -> Prop) pA pB, (i1 < nla a)%nat -> (i2 < nla a)%nat -> i1 <> i2 ->
980
+ (forall g, P (fun w => A (zv a i1) (X g w)) <= pA) -> (forall g, P (fun w => B (zv a i2) (X g w)) <= pB) ->
981
+ P (fun w => Npr a i1 i2 A B (fun q => X (vid a q) w)) <= 9 * pA * pB.
982
+ Proof.
983
+ intros a i1 i2 A B pA pB H1 H2 Hd HA HB. unfold Npr.
984
+ exact (P_copy_pairs (fun c => vid a (cpy a i1 c)) (fun c => vid a (cpy a i2 c)) (A (zv a i1)) (B (zv a i2)) pA pB
985
+ (fun c1 c2 _ _ => vid_cpy a i1 i2 c1 c2 H1 H2 (or_intror Hd)) (fun c _ => HA _) (fun c _ => HB _)).
986
+ Qed.
987
+
988
+ (* a wrong copy of row i fails beyond D - |S_v|, and in a layer without a stop |S_v| <= 1 *)
989
+ Lemma wrong_cpy : forall w a i c, (i < nla a)%nat -> (c < 3)%nat -> wb w a (cpy a i c) = true ->
990
+ far (zv a i) (Sc w a i) (X (vid a (cpy a i c)) w).
991
+ Proof.
992
+ intros w a i c Hi Hc Hw. pose proof (wrong_far w a _ (cpy_lt a i c Hi Hc) Hw) as Hf. rewrite cpy_mod in Hf by exact Hi.
993
+ exact Hf.
994
+ Qed.
995
+
996
+ Lemma wrong_Sc : forall w a i c, (i < nla a)%nat -> (c < 3)%nat -> wb w a (cpy a i c) = true -> stopb w a = false ->
997
+ (Sc w a i <= 1)%nat.
998
+ Proof.
999
+ intros w a i c Hi Hc Hw Hst. pose proof (nostop_Sc w a _ Hst (cpy_lt a i c Hi Hc) Hw) as HS. rewrite cpy_mod in HS by exact Hi.
1000
+ exact HS.
1001
+ Qed.
1002
+
1003
+ (* a copy that fails without failing at threshold D has |S_v| = 1 and an input in T(v) with a wrong copy *)
1004
+ Lemma one_input : forall w a i e, (Sc w a i <= 1)%nat -> far (zv a i) (Sc w a i) e -> ~ far (zv a i) 0 e ->
1005
+ Sc w a i = 1%nat /\ exists j, (j < wia a)%nat /\ tT a i j = true /\ (0 < nci w a j)%nat.
1006
+ Proof.
1007
+ intros w a i e HS Hf H0. assert (S1 : Sc w a i = 1%nat) by (destruct (Sc w a i) as [|[|k]]; [contradiction | reflexivity | lia]).
1008
+ split; [exact S1|]. apply Sc_pos. lia.
1009
+ Qed.
1010
+
1011
+ (* ---- P^(2) and P^(3) -------------------------------------------------------------------------------------------- *)
1012
+ Lemma claim_P2 : forall a i, (i < nla a)%nat -> (forall j, (j < wia a)%nat -> P (Win a j) <= Pin a j) -> P (E2 a i) <= P2v a i.
1013
+ Proof.
1014
+ intros a i Hi HW.
1015
+ assert (Hg : forall c1 c2, (c1 < 3)%nat -> (c2 < 3)%nat -> c1 <> c2 -> vid a (cpy a i c1) <> vid a (cpy a i c2))
1016
+ by (intros c1 c2 _ _ Hd; apply vid_cpy; [exact Hi | exact Hi | left; exact Hd]).
1017
+ eapply Rle_trans; [apply (P_mono _ (fun w =>
1018
+ (exists c1 c2, (c1 < c2)%nat /\ (c2 < 3)%nat /\ F0 (zv a i) (X (vid a (cpy a i c1)) w) /\ F0 (zv a i) (X (vid a (cpy a i c2)) w))
1019
+ \/ (exists j, (j < wia a)%nat /\ tT a i j = true /\ (Win a j w /\ N2 a i (fun q => X (vid a q) w)))))|].
1020
+ - intros w (HG & HS & H2). destruct (ncnt_two (fun c => wb w a (cpy a i c)) H2) as (c1 & c2 & H12 & Hc2 & W1 & W2).
1021
+ pose proof (wrong_cpy w a i c1 Hi ltac:(lia) W1) as Hf1. pose proof (wrong_cpy w a i c2 Hi Hc2 W2) as Hf2.
1022
+ destruct (far_dec (zv a i) 0 (X (vid a (cpy a i c1)) w)) as [A1|A1];
1023
+ destruct (far_dec (zv a i) 0 (X (vid a (cpy a i c2)) w)) as [A2|A2].
1024
+ + left. exists c1, c2. repeat split; assumption.
1025
+ + right. destruct (one_input w a i _ HS Hf2 A2) as [S1 (j & Hj & Tj & Nj)]. rewrite S1 in Hf1, Hf2.
1026
+ exists j. split; [exact Hj|]. split; [exact Tj|]. split; [split; assumption|].
1027
+ right. exists c1, c2. repeat split; assumption.
1028
+ + right. destruct (one_input w a i _ HS Hf1 A1) as [S1 (j & Hj & Tj & Nj)]. rewrite S1 in Hf1, Hf2.
1029
+ exists j. split; [exact Hj|]. split; [exact Tj|]. split; [split; assumption|].
1030
+ left. exists c1, c2. repeat split; assumption.
1031
+ + right. destruct (one_input w a i _ HS Hf1 A1) as [S1 (j & Hj & Tj & Nj)]. rewrite S1 in Hf1, Hf2.
1032
+ exists j. split; [exact Hj|]. split; [exact Tj|]. split; [split; assumption|].
1033
+ left. exists c1, c2. repeat split; assumption.
1034
+ - eapply Rle_trans; [apply P_or|].
1035
+ replace (P2v a i) with (3 * qk a i 0 * qk a i 0
1036
+ + rsum (wia a) (fun j => if tT a i j then Pin a j * (3 * dl a i * qk a i 1 + 3 * qk a i 0 * dl a i) else 0))
1037
+ by (rewrite rsum_if_scal; unfold P2v, Xs, dl; ring).
1038
+ apply Rplus_le_compat.
1039
+ + exact (P_copy_lt (fun c => vid a (cpy a i c)) (F0 (zv a i)) (F0 (zv a i)) (qk a i 0) (qk a i 0) Hg
1040
+ (fun c _ => P_far a i 0 _) (fun c _ => P_far a i 0 _)).
1041
+ + apply (P_sum (wia a) (tT a i) (fun j w => Win a j w /\ N2 a i (fun q => X (vid a q) w))).
1042
+ intros j Hj Tj. cbv beta. rewrite (P_pn a).
1043
+ * apply Rmult_le_compat; [apply Pnn | apply Pnn | apply HW; exact Hj | apply P_N2; exact Hi].
1044
+ * apply dep_Win.
1045
+ * apply (dep_now a (N2 a i)).
1046
+ Qed.
1047
+
1048
+ Lemma claim_P3 : forall a i, (i < nla a)%nat -> (forall j, (j < wia a)%nat -> P (Win a j) <= Pin a j) -> P (E3 a i) <= P3v a i.
1049
+ Proof.
1050
+ intros a i Hi HW.
1051
+ assert (Hg : forall c1 c2, c1 <> c2 -> vid a (cpy a i c1) <> vid a (cpy a i c2))
1052
+ by (intros c1 c2 Hd; apply vid_cpy; [exact Hi | exact Hi | left; exact Hd]).
1053
+ eapply Rle_trans; [apply (P_mono _ (fun w =>
1054
+ (F0 (zv a i) (X (vid a (cpy a i 0)) w) /\ F0 (zv a i) (X (vid a (cpy a i 1)) w) /\ F0 (zv a i) (X (vid a (cpy a i 2)) w))
1055
+ \/ (exists j, (j < wia a)%nat /\ tT a i j = true /\ (Win a j w /\ N3 a i (fun q => X (vid a q) w)))))|].
1056
+ - intros w (HG & HS & H3). destruct (ncnt_three (fun c => wb w a (cpy a i c)) H3) as (W0 & W1 & W2).
1057
+ pose proof (wrong_cpy w a i 0 Hi ltac:(lia) W0) as Hf0. pose proof (wrong_cpy w a i 1 Hi ltac:(lia) W1) as Hf1.
1058
+ pose proof (wrong_cpy w a i 2 Hi ltac:(lia) W2) as Hf2.
1059
+ destruct (far_dec (zv a i) 0 (X (vid a (cpy a i 0)) w)) as [A0|A0].
1060
+ + destruct (far_dec (zv a i) 0 (X (vid a (cpy a i 1)) w)) as [A1|A1].
1061
+ * destruct (far_dec (zv a i) 0 (X (vid a (cpy a i 2)) w)) as [A2|A2].
1062
+ -- left. repeat split; assumption.
1063
+ -- right. destruct (one_input w a i _ HS Hf2 A2) as [S1 (j & Hj & Tj & Nj)]. rewrite S1 in Hf0, Hf1, Hf2.
1064
+ exists j. split; [exact Hj|]. split; [exact Tj|]. split; [split; assumption|]. right. right. repeat split; assumption.
1065
+ * right. destruct (one_input w a i _ HS Hf1 A1) as [S1 (j & Hj & Tj & Nj)]. rewrite S1 in Hf0, Hf1, Hf2.
1066
+ exists j. split; [exact Hj|]. split; [exact Tj|]. split; [split; assumption|]. right. left. repeat split; assumption.
1067
+ + right. destruct (one_input w a i _ HS Hf0 A0) as [S1 (j & Hj & Tj & Nj)]. rewrite S1 in Hf0, Hf1, Hf2.
1068
+ exists j. split; [exact Hj|]. split; [exact Tj|]. split; [split; assumption|]. left. repeat split; assumption.
1069
+ - eapply Rle_trans; [apply P_or|].
1070
+ replace (P3v a i) with (qk a i 0 * qk a i 0 * qk a i 0
1071
+ + rsum (wia a) (fun j => if tT a i j then Pin a j * (dl a i * qk a i 1 * qk a i 1
1072
+ + qk a i 0 * dl a i * qk a i 1 + qk a i 0 * qk a i 0 * dl a i) else 0))
1073
+ by (rewrite rsum_if_scal; unfold P3v, Xs, dl; ring).
1074
+ apply Rplus_le_compat.
1075
+ + exact (P_trip _ _ _ (F0 (zv a i)) (F0 (zv a i)) (F0 (zv a i)) _ _ _ (Hg 0%nat 1%nat ltac:(lia))
1076
+ (Hg 0%nat 2%nat ltac:(lia)) (Hg 1%nat 2%nat ltac:(lia)) (P_far a i 0 _) (P_far a i 0 _) (P_far a i 0 _)).
1077
+ + apply (P_sum (wia a) (tT a i) (fun j w => Win a j w /\ N3 a i (fun q => X (vid a q) w))).
1078
+ intros j Hj Tj. cbv beta. rewrite (P_pn a).
1079
+ * apply Rmult_le_compat; [apply Pnn | apply Pnn | apply HW; exact Hj | apply P_N3; exact Hi].
1080
+ * apply dep_Win.
1081
+ * apply (dep_now a (N3 a i)).
1082
+ Qed.
1083
+
1084
+ (* ---- P(W_v1 and W_v2) <= P_v1 P_v2 + K_v1v2 ----------------------------------------------------------------- *)
1085
+ Lemma claim_K : forall a i1 i2, (i1 < nla a)%nat -> (i2 < nla a)%nat -> i1 <> i2 ->
1086
+ (forall j, (j < wia a)%nat -> P (Win a j) <= Pin a j) ->
1087
+ (forall j1 j2, (j1 < wia a)%nat -> (j2 < wia a)%nat -> j1 <> j2 ->
1088
+ P (fun w => Win a j1 w /\ Win a j2 w) <= Pin a j1 * Pin a j2 + Kin a j1 j2) ->
1089
+ P (fun w => Wv a i1 w /\ Wv a i2 w) <= Pv a i1 * Pv a i2 + Kv a i1 i2.
1090
+ Proof.
1091
+ intros a i1 i2 H1 H2 Hd HW HK.
1092
+ eapply Rle_trans; [apply (P_mono _ (fun w =>
1093
+ Npr a i1 i2 F0 F0 (fun q => X (vid a q) w)
1094
+ \/ ((exists j, (j < wia a)%nat /\ tT a i1 j = true /\ Win a j w) /\ Npr a i1 i2 F10 F0 (fun q => X (vid a q) w))
1095
+ \/ ((exists j, (j < wia a)%nat /\ tT a i2 j = true /\ Win a j w) /\ Npr a i1 i2 F0 F10 (fun q => X (vid a q) w))
1096
+ \/ (((exists j, (j < wia a)%nat /\ (tT a i1 j && tT a i2 j) = true /\ Win a j w)
1097
+ \/ (exists j1, (j1 < wia a)%nat /\ exists j2, (j2 < wia a)%nat
1098
+ /\ (tT a i1 j1 && tT a i2 j2 && negb (Nat.eqb j1 j2)) = true /\ (Win a j1 w /\ Win a j2 w)))
1099
+ /\ Npr a i1 i2 F10 F10 (fun q => X (vid a q) w))))|].
1100
+ - intros w [[N1 G1] [N2' G2]].
1101
+ destruct (ncw_copy w a i1 N1) as (c1 & Hc1 & W1). destruct (ncw_copy w a i2 N2') as (c2 & Hc2 & W2).
1102
+ pose proof (wrong_cpy w a i1 c1 H1 Hc1 W1) as Hf1. pose proof (wrong_cpy w a i2 c2 H2 Hc2 W2) as Hf2.
1103
+ pose proof (wrong_Sc w a i1 c1 H1 Hc1 W1 (G1 a (le_n a))) as HS1. pose proof (wrong_Sc w a i2 c2 H2 Hc2 W2 (G2 a (le_n a))) as HS2.
1104
+ assert (HGb : Gb a w) by (intros a' Ha'; apply G1; lia).
1105
+ destruct (far_dec (zv a i1) 0 (X (vid a (cpy a i1 c1)) w)) as [A1|A1];
1106
+ destruct (far_dec (zv a i2) 0 (X (vid a (cpy a i2 c2)) w)) as [A2|A2].
1107
+ + left. exists c1. split; [exact Hc1|]. exists c2. split; [exact Hc2|]. split; assumption.
1108
+ + right; right; left. destruct (one_input w a i2 _ HS2 Hf2 A2) as [S2 (j & Hj & Tj & Nj)]. rewrite S2 in Hf2.
1109
+ split; [exists j; split; [exact Hj|]; split; [exact Tj | split; assumption]|].
1110
+ exists c1. split; [exact Hc1|]. exists c2. split; [exact Hc2|]. repeat split; assumption.
1111
+ + right; left. destruct (one_input w a i1 _ HS1 Hf1 A1) as [S1 (j & Hj & Tj & Nj)]. rewrite S1 in Hf1.
1112
+ split; [exists j; split; [exact Hj|]; split; [exact Tj | split; assumption]|].
1113
+ exists c1. split; [exact Hc1|]. exists c2. split; [exact Hc2|]. repeat split; assumption.
1114
+ + right; right; right. destruct (one_input w a i1 _ HS1 Hf1 A1) as [S1 (j1 & Hj1 & Tj1 & Nj1)].
1115
+ destruct (one_input w a i2 _ HS2 Hf2 A2) as [S2 (j2 & Hj2 & Tj2 & Nj2)]. rewrite S1 in Hf1. rewrite S2 in Hf2. split.
1116
+ * destruct (Nat.eq_dec j1 j2) as [<-|E].
1117
+ -- left. exists j1. split; [exact Hj1|]. split; [rewrite Tj1, Tj2; reflexivity | split; assumption].
1118
+ -- right. exists j1. split; [exact Hj1|]. exists j2. split; [exact Hj2|]. split.
1119
+ ++ rewrite Tj1, Tj2. cbn [andb]. apply negb_true_iff, Nat.eqb_neq. exact E.
1120
+ ++ split; split; assumption.
1121
+ * exists c1. split; [exact Hc1|]. exists c2. split; [exact Hc2|]. repeat split; assumption.
1122
+ - eapply Rle_trans; [apply P_or4|].
1123
+ assert (B0 : P (fun w => Npr a i1 i2 F0 F0 (fun q => X (vid a q) w)) <= 9 * qk a i1 0 * qk a i2 0)
1124
+ by (apply P_Npr; [exact H1 | exact H2 | exact Hd | intro g; exact (P_far a i1 0 g) | intro g; exact (P_far a i2 0 g)]).
1125
+ assert (B1 : P (fun w => (exists j, (j < wia a)%nat /\ tT a i1 j = true /\ Win a j w) /\ Npr a i1 i2 F10 F0 (fun q => X (vid a q) w))
1126
+ <= Xs a i1 (Pin a) * (9 * dl a i1 * qk a i2 0)).
1127
+ { rewrite (P_pn a).
1128
+ - apply Rmult_le_compat; [apply Pnn | apply Pnn | |].
1129
+ + unfold Xs. apply (P_sum (wia a) (tT a i1) (fun j => Win a j)). intros j Hj _. apply HW. exact Hj.
1130
+ + apply P_Npr; [exact H1 | exact H2 | exact Hd | intro g; exact (P_far10 a i1 g) | intro g; exact (P_far a i2 0 g)].
1131
+ - apply dep_ex. intro j. apply dep_Win.
1132
+ - apply (dep_now a (Npr a i1 i2 F10 F0)). }
1133
+ assert (B2 : P (fun w => (exists j, (j < wia a)%nat /\ tT a i2 j = true /\ Win a j w) /\ Npr a i1 i2 F0 F10 (fun q => X (vid a q) w))
1134
+ <= Xs a i2 (Pin a) * (9 * qk a i1 0 * dl a i2)).
1135
+ { rewrite (P_pn a).
1136
+ - apply Rmult_le_compat; [apply Pnn | apply Pnn | |].
1137
+ + unfold Xs. apply (P_sum (wia a) (tT a i2) (fun j => Win a j)). intros j Hj _. apply HW. exact Hj.
1138
+ + apply P_Npr; [exact H1 | exact H2 | exact Hd | intro g; exact (P_far a i1 0 g) | intro g; exact (P_far10 a i2 g)].
1139
+ - apply dep_ex. intro j. apply dep_Win.
1140
+ - apply (dep_now a (Npr a i1 i2 F0 F10)). }
1141
+ set (SN := rsum (wia a) (fun j => if tT a i1 j && tT a i2 j then Pin a j else 0)).
1142
+ set (SP := rsum (wia a) (fun j1 => rsum (wia a) (fun j2 =>
1143
+ if tT a i1 j1 && tT a i2 j2 && negb (Nat.eqb j1 j2) then Pin a j1 * Pin a j2 else 0))).
1144
+ set (SK := rsum (wia a) (fun j1 => rsum (wia a) (fun j2 =>
1145
+ if tT a i1 j1 && tT a i2 j2 && negb (Nat.eqb j1 j2) then Kin a j1 j2 else 0))).
1146
+ assert (B3 : P (fun w => ((exists j, (j < wia a)%nat /\ (tT a i1 j && tT a i2 j) = true /\ Win a j w)
1147
+ \/ (exists j1, (j1 < wia a)%nat /\ exists j2, (j2 < wia a)%nat
1148
+ /\ (tT a i1 j1 && tT a i2 j2 && negb (Nat.eqb j1 j2)) = true /\ (Win a j1 w /\ Win a j2 w)))
1149
+ /\ Npr a i1 i2 F10 F10 (fun q => X (vid a q) w))
1150
+ <= (SN + (SP + SK)) * (9 * dl a i1 * dl a i2)).
1151
+ { rewrite (P_pn a).
1152
+ - apply Rmult_le_compat; [apply Pnn | apply Pnn | |].
1153
+ + eapply Rle_trans; [apply P_or|]. apply Rplus_le_compat.
1154
+ * apply (P_sum (wia a) (fun j => tT a i1 j && tT a i2 j) (fun j => Win a j)). intros j Hj _. apply HW. exact Hj.
1155
+ * replace (SP + SK) with (rsum (wia a) (fun j1 => rsum (wia a) (fun j2 =>
1156
+ if tT a i1 j1 && tT a i2 j2 && negb (Nat.eqb j1 j2) then Pin a j1 * Pin a j2 + Kin a j1 j2 else 0))).
1157
+ -- eapply Rle_trans; [apply (Pex (wia a) (fun j1 w => exists j2, (j2 < wia a)%nat
1158
+ /\ (tT a i1 j1 && tT a i2 j2 && negb (Nat.eqb j1 j2)) = true /\ (Win a j1 w /\ Win a j2 w)))|].
1159
+ apply rsum_le. intros j1 Hj1.
1160
+ apply (P_sum (wia a) (fun j2 => tT a i1 j1 && tT a i2 j2 && negb (Nat.eqb j1 j2)) (fun j2 w => Win a j1 w /\ Win a j2 w)).
1161
+ intros j2 Hj2 T. apply HK; [exact Hj1 | exact Hj2|]. apply andb_prop in T as [_ T].
1162
+ apply negb_true_iff, Nat.eqb_neq in T. exact T.
1163
+ -- unfold SP, SK. rewrite <- rsum_plus. apply rsum_ext. intros j1 _. rewrite <- rsum_plus. apply rsum_ext.
1164
+ intros j2 _. destruct (tT a i1 j1 && tT a i2 j2 && negb (Nat.eqb j1 j2)); ring.
1165
+ + apply P_Npr; [exact H1 | exact H2 | exact Hd | intro g; exact (P_far10 a i1 g) | intro g; exact (P_far10 a i2 g)].
1166
+ - apply dep_or; [apply dep_ex; intro j; apply dep_Win|]. apply dep_ex0. intro j1. apply dep_ex. intro j2.
1167
+ apply dep_and; apply dep_Win.
1168
+ - apply (dep_now a (Npr a i1 i2 F10 F10)). }
1169
+ pose proof (sum_ne_le (wia a) (tT a i1) (tT a i2) (Pin a) (proj1 (PK_nn a))) as HSP. fold SP in HSP.
1170
+ change (rsum (wia a) (fun j => if tT a i1 j then Pin a j else 0)) with (Xs a i1 (Pin a)) in HSP.
1171
+ change (rsum (wia a) (fun j => if tT a i2 j then Pin a j else 0)) with (Xs a i2 (Pin a)) in HSP.
1172
+ pose proof (dl_nn a i1). pose proof (dl_nn a i2).
1173
+ assert (HD : 0 <= 9 * dl a i1 * dl a i2) by (apply Rmult_le_pos; [apply Rmult_le_pos|]; lra).
1174
+ pose proof (Rmult_le_compat_l _ _ _ HD HSP) as HSP'.
1175
+ unfold Pv, Kv, Kpair. fold SN SK. nra.
1176
+ Qed.
1177
+
1178
+ (* ---- the bounds hold layer by layer -------------------------------------------------------------------------------- *)
1179
+ Lemma lyr_0 : lyr 0 = 0%nat.
1180
+ Proof. unfold lyr. apply Nat.Div0.mod_0_l. Qed.
1181
+
1182
+ Lemma nci_0 : forall w j, (j < n)%nat -> nci w 0 j = 0%nat.
1183
+ Proof.
1184
+ intros w j Hj. unfold nci. rewrite wia_0. rewrite (ncnt_ext 3 _ (fun _ => false)); [apply ncnt_false|].
1185
+ intros c Hc. apply wib_0. nia.
1186
+ Qed.
1187
+
1188
+ Lemma nci_S : forall w a j, lyr (S a) <> 0%nat -> nci w (S a) j = ncw w a j.
1189
+ Proof. intros w a j H. unfold nci, ncw. rewrite (wia_S a H). apply ncnt_ext. intros c Hc. apply wib_S. exact H. Qed.
1190
+
1191
+ Lemma nci_B : forall w a j, lyr (S a) = 0%nat -> (j < n)%nat -> nci w (S a) j = if Dv j then 0%nat else ncw w a j.
1192
+ Proof.
1193
+ intros w a j H Hj. destruct (wia_B a H) as [W1 W2]. unfold nci, ncw. rewrite W1, W2. destruct (Dv j) eqn:E.
1194
+ - rewrite (ncnt_ext 3 _ (fun _ => false)); [apply ncnt_false|]. intros c Hc.
1195
+ rewrite wib_B by (exact H || nia). rewrite cp_mod by exact Hj. rewrite E. reflexivity.
1196
+ - apply ncnt_ext. intros c Hc. rewrite wib_B by (exact H || nia). rewrite cp_mod by exact Hj. rewrite E. reflexivity.
1197
+ Qed.
1198
+
1199
+ Lemma Win_S : forall w a j, lyr (S a) <> 0%nat -> (Win (S a) j w <-> Wv a j w).
1200
+ Proof. intros w a j H. unfold Win, Wv. rewrite nci_S by exact H. rewrite Gu_Gb. reflexivity. Qed.
1201
+
1202
+ Lemma Win_B : forall w a j, lyr (S a) = 0%nat -> (j < n)%nat -> Win (S a) j w -> Dv j = false /\ Wv a j w.
1203
+ Proof.
1204
+ intros w a j H Hj [Hn HG]. rewrite nci_B in Hn by assumption. destruct (Dv j); [lia|]. split; [reflexivity|].
1205
+ split; [exact Hn | apply Gu_Gb; exact HG].
1206
+ Qed.
1207
+
1208
+ Lemma Pin_N : forall a j, lyr (S a) <> 0%nat -> Pin (S a) j = Pv a j.
1209
+ Proof. intros a j H. rewrite Pin_S. destruct (Nat.eqb_spec (lyr (S a)) 0); [contradiction | reflexivity]. Qed.
1210
+
1211
+ Lemma Pin_Bd : forall a j, lyr (S a) = 0%nat -> Dv j = true -> Pin (S a) j = 0.
1212
+ Proof. intros a j H E. rewrite Pin_S, H, E. reflexivity. Qed.
1213
+
1214
+ Lemma Pin_Bn : forall a j, lyr (S a) = 0%nat -> Dv j = false -> Pin (S a) j = Pv a j.
1215
+ Proof. intros a j H E. rewrite Pin_S, H, E. reflexivity. Qed.
1216
+
1217
+ Lemma Kin_N : forall a j1 j2, lyr (S a) <> 0%nat -> Kin (S a) j1 j2 = Kv a j1 j2.
1218
+ Proof. intros a j1 j2 H. rewrite Kin_S. destruct (Nat.eqb_spec (lyr (S a)) 0); [contradiction | reflexivity]. Qed.
1219
+
1220
+ Lemma Kin_Bd : forall a j1 j2, lyr (S a) = 0%nat -> Dv j1 = true \/ Dv j2 = true -> Kin (S a) j1 j2 = 0.
1221
+ Proof. intros a j1 j2 H [E|E]; rewrite Kin_S, H, E; [reflexivity | rewrite orb_true_r; reflexivity]. Qed.
1222
+
1223
+ Lemma Kin_Bn : forall a j1 j2, lyr (S a) = 0%nat -> Dv j1 = false -> Dv j2 = false -> Kin (S a) j1 j2 = Kv a j1 j2.
1224
+ Proof. intros a j1 j2 H E1 E2. rewrite Kin_S, H, E1, E2. reflexivity. Qed.
1225
+
1226
+ (* P(W) <= P and P(W and W') <= P P' + K for the inputs of every layer, by induction over the layers *)
1227
+ Lemma claims : forall a, (forall j, (j < wia a)%nat -> P (Win a j) <= Pin a j) /\
1228
+ (forall j1 j2, (j1 < wia a)%nat -> (j2 < wia a)%nat -> j1 <> j2 ->
1229
+ P (fun w => Win a j1 w /\ Win a j2 w) <= Pin a j1 * Pin a j2 + Kin a j1 j2).
1230
+ Proof.
1231
+ induction a as [|a [IW IK]].
1232
+ - rewrite wia_0. assert (E : forall j w, (j < n)%nat -> ~ Win 0 j w) by (intros j w Hj [Hn _]; rewrite nci_0 in Hn by exact Hj; lia).
1233
+ split.
1234
+ + intros j Hj. rewrite (Pnone (Win 0 j)) by (intro w; apply E; exact Hj). unfold Pin. cbn. lra.
1235
+ + intros j1 j2 Hj1 Hj2 _. rewrite Pnone by (intros w [W _]; exact (E j1 w Hj1 W)). unfold Pin, Kin. cbn. lra.
1236
+ - pose proof (fun i Hi => claim_P a i Hi IW) as CP. pose proof (fun i1 i2 H1 H2 Hd => claim_K a i1 i2 H1 H2 Hd IW IK) as CK.
1237
+ destruct (PK_nn (S a)) as [NP NK].
1238
+ destruct (Nat.eq_dec (lyr (S a)) 0) as [B|B].
1239
+ + destruct (wia_B a B) as [W1 W2]. rewrite W1. split.
1240
+ * intros j Hj. destruct (Dv j) eqn:E.
1241
+ -- rewrite (Pin_Bd a j B E). right. apply Pnone. intros w Hw. destruct (Win_B w a j B Hj Hw) as [C _]. congruence.
1242
+ -- rewrite (Pin_Bn a j B E).
1243
+ eapply Rle_trans; [apply P_mono; intros w Hw; exact (proj2 (Win_B w a j B Hj Hw))|]. apply CP. lia.
1244
+ * intros j1 j2 Hj1 Hj2 Hd. pose proof (NP j1). pose proof (NP j2).
1245
+ destruct (Dv j1) eqn:E1; [|destruct (Dv j2) eqn:E2].
1246
+ -- rewrite Pnone by (intros w [Hw _]; destruct (Win_B w a j1 B Hj1 Hw) as [C _]; congruence).
1247
+ rewrite (Kin_Bd a j1 j2 B (or_introl E1)). nra.
1248
+ -- rewrite Pnone by (intros w [_ Hw]; destruct (Win_B w a j2 B Hj2 Hw) as [C _]; congruence).
1249
+ rewrite (Kin_Bd a j1 j2 B (or_intror E2)). nra.
1250
+ -- rewrite (Pin_Bn a j1 B E1), (Pin_Bn a j2 B E2), (Kin_Bn a j1 j2 B E1 E2).
1251
+ eapply Rle_trans; [apply P_mono; intros w [Hw1 Hw2];
1252
+ exact (conj (proj2 (Win_B w a j1 B Hj1 Hw1)) (proj2 (Win_B w a j2 B Hj2 Hw2)))|].
1253
+ apply CK; [lia | lia | exact Hd].
1254
+ + rewrite (wia_S a B). split.
1255
+ * intros j Hj. rewrite (Pin_N a j B).
1256
+ eapply Rle_trans; [apply P_mono; intros w Hw; exact (proj1 (Win_S w a j B) Hw)|]. apply CP. exact Hj.
1257
+ * intros j1 j2 Hj1 Hj2 Hd. rewrite (Pin_N a j1 B), (Pin_N a j2 B), (Kin_N a j1 j2 B).
1258
+ eapply Rle_trans; [apply P_mono; intros w [Hw1 Hw2]; exact (conj (proj1 (Win_S w a j1 B) Hw1) (proj1 (Win_S w a j2 B) Hw2))|].
1259
+ apply CK; assumption.
1260
+ Qed.
1261
+
1262
+ (* ---- the first stop ------------------------------------------------------------------------------------------------ *)
1263
+ (* the input j of layer a has two wrong copies, or three, and no layer before is a stop; empty on the state *)
1264
+ Definition B2 (a j : nat) (w : Omega) : Prop := lyr a <> 0%nat /\ E2 (a - 1) j w.
1265
+ Definition B3 (a j : nat) (w : Omega) : Prop := lyr a <> 0%nat /\ E3 (a - 1) j w.
1266
+ (* some copy of row i fails beyond D - k *)
1267
+ Definition N1 (a i k : nat) (f : nat -> R) : Prop := exists c, (c < 3)%nat /\ far (zv a i) k (f (cpy a i c)).
1268
+
1269
+ Lemma P_B2 : forall a j, (j < wia a)%nat -> P (B2 a j) <= P2in a j.
1270
+ Proof.
1271
+ intros a j Hj. unfold P2in. destruct (Nat.eqb_spec (lyr a) 0) as [B|B].
1272
+ - right. apply Pnone. intros w [C _]. contradiction.
1273
+ - destruct a as [|a]; [rewrite lyr_0 in B; contradiction|]. replace (S a - 1)%nat with a by lia.
1274
+ eapply Rle_trans; [apply P_mono; intros w [_ H]; replace (S a - 1)%nat with a in H by lia; exact H|].
1275
+ apply claim_P2; [rewrite (wia_S a B) in Hj; exact Hj | exact (proj1 (claims a))].
1276
+ Qed.
1277
+
1278
+ Lemma P_B3 : forall a j, (j < wia a)%nat -> P (B3 a j) <= P3in a j.
1279
+ Proof.
1280
+ intros a j Hj. unfold P3in. destruct (Nat.eqb_spec (lyr a) 0) as [B|B].
1281
+ - right. apply Pnone. intros w [C _]. contradiction.
1282
+ - destruct a as [|a]; [rewrite lyr_0 in B; contradiction|]. replace (S a - 1)%nat with a by lia.
1283
+ eapply Rle_trans; [apply P_mono; intros w [_ H]; replace (S a - 1)%nat with a in H by lia; exact H|].
1284
+ apply claim_P3; [rewrite (wia_S a B) in Hj; exact Hj | exact (proj1 (claims a))].
1285
+ Qed.
1286
+
1287
+ Lemma dep_B2 : forall a j, dep Omega X (pastv a) (B2 a j).
1288
+ Proof.
1289
+ intros [|a] j w w' H; unfold B2; [rewrite lyr_0; split; intros [C _]; contradiction|].
1290
+ replace (S a - 1)%nat with a by lia. rewrite (dep_E2 a j w w' H). reflexivity.
1291
+ Qed.
1292
+
1293
+ Lemma dep_B3 : forall a j, dep Omega X (pastv a) (B3 a j).
1294
+ Proof.
1295
+ intros [|a] j w w' H; unfold B3; [rewrite lyr_0; split; intros [C _]; contradiction|].
1296
+ replace (S a - 1)%nat with a by lia. rewrite (dep_E3 a j w w' H). reflexivity.
1297
+ Qed.
1298
+
1299
+ Lemma P_N1 : forall a i k, P (fun w => N1 a i k (fun q => X (vid a q) w)) <= Rmin 1 (3 * qk a i k).
1300
+ Proof.
1301
+ intros a i k. apply Rmin_glb; [apply Ple1|]. unfold N1.
1302
+ exact (P_copies (fun c => vid a (cpy a i c)) (far (zv a i) k) (qk a i k) (fun c _ => P_far a i k _)).
1303
+ Qed.
1304
+
1305
+ Lemma Rmin_nn : forall a i k, 0 <= Rmin 1 (3 * qk a i k).
1306
+ Proof. intros a i k. apply Rmin_glb; [lra|]. pose proof (qk_range a i k). lra. Qed.
1307
+
1308
+ (* the first stop at layer a: P <= the contribution of a to b(t) *)
1309
+ Lemma claim_stop : forall a, P (fun w => stopb w a = true /\ Gb a w) <= bl a.
1310
+ Proof.
1311
+ intro a. destruct (claims a) as [HW HK].
1312
+ eapply Rle_trans; [apply (P_mono _ (fun w =>
1313
+ (exists i, (i < nla a)%nat /\ exists j1, (j1 < wia a)%nat /\ exists j2, (j2 < wia a)%nat
1314
+ /\ (tT a i j1 && tT a i j2 && Nat.ltb j1 j2) = true /\ (Win a j1 w /\ Win a j2 w))
1315
+ \/ (exists i, (i < nla a)%nat /\ exists j, (j < wia a)%nat /\ tT a i j = true /\ (B2 a j w /\ N1 a i 2 (fun q => X (vid a q) w)))
1316
+ \/ (exists i, (i < nla a)%nat /\ exists j, (j < wia a)%nat /\ tT a i j = true /\ (B3 a j w /\ N1 a i 3 (fun q => X (vid a q) w)))
1317
+ \/ (lyr a = (length Ls - 1)%nat /\ exists i, (i < nla a)%nat /\ E2 a i w)))|].
1318
+ - intros w [Hst HG]. unfold stopb in Hst. destruct (stop1 w a) eqn:S1.
1319
+ + apply existsb_seq_true in S1 as (q & Hq & E). apply andb_prop in E as [Wq Sq]. apply Nat.leb_le in Sq.
1320
+ assert (HN : (0 < nla a)%nat) by lia.
1321
+ assert (Hdec : exists i c, (i < nla a)%nat /\ (c < 3)%nat /\ q = cpy a i c).
1322
+ { exists (q mod nla a)%nat, (q / nla a)%nat. split; [apply Nat.mod_upper_bound; lia|].
1323
+ split; [apply Nat.Div0.div_lt_upper_bound; lia|]. unfold cpy. apply cp_split. exact HN. }
1324
+ destruct Hdec as (i & c & Hi & Hc & ->). rewrite cpy_mod in Sq by exact Hi.
1325
+ pose proof (wrong_cpy w a i c Hi Hc Wq) as Hf.
1326
+ destruct (Sc_two w a i Sq) as [(j1 & j2 & H12 & Hj2 & T1 & T2 & N1' & N2') | (j & Hj & Tj & ES)].
1327
+ * left. exists i. split; [exact Hi|]. exists j1. split; [lia|]. exists j2. split; [exact Hj2|]. split.
1328
+ -- rewrite T1, T2. cbn [andb]. apply Nat.ltb_lt. exact H12.
1329
+ -- split; split; assumption.
1330
+ * assert (Hj3 : (nci w a j <= 3)%nat) by apply ncnt_le.
1331
+ destruct a as [|a].
1332
+ -- exfalso. rewrite wia_0 in Hj. rewrite nci_0 in ES by exact Hj. lia.
1333
+ -- destruct (Nat.eq_dec (lyr (S a)) 0) as [B|B].
1334
+ ++ exfalso. destruct (wia_B a B) as [W1 W2]. rewrite W1 in Hj. rewrite (nci_B w a j B Hj) in ES.
1335
+ destruct (Dv j) eqn:Ed; [lia|].
1336
+ assert (Hs2 : stopb w a = true).
1337
+ { unfold stopb. apply orb_true_iff. right. unfold stop2. apply andb_true_iff. split.
1338
+ - apply Nat.eqb_eq. destruct (lyr_succ a) as [(_ & L & _)|(_ & L & _)]; [exact L | contradiction].
1339
+ - apply existsb_exists. exists j. split; [apply in_seq; lia|]. apply Nat.leb_le. lia. }
1340
+ rewrite (HG a (Nat.lt_succ_diag_r a)) in Hs2. discriminate.
1341
+ ++ rewrite (nci_S w a j B) in ES, Hj3. rewrite (wia_S a B) in Hj.
1342
+ assert (HGa : stopb w a = false) by (apply HG; lia).
1343
+ assert (HSj : (Sc w a j <= 1)%nat).
1344
+ { destruct (ncw_copy w a j ltac:(lia)) as (c' & Hc' & W'). exact (wrong_Sc w a j c' Hj Hc' W' HGa). }
1345
+ assert (HGb' : Gb a w) by (intros a'' Ha''; apply HG; lia).
1346
+ assert (Ea : (S a - 1)%nat = a) by lia.
1347
+ destruct (Nat.eq_dec (ncw w a j) 3) as [E3'|E3'].
1348
+ ** right; right; left. exists i. split; [exact Hi|]. exists j. split; [rewrite (wia_S a B); exact Hj|].
1349
+ split; [exact Tj|]. split.
1350
+ --- split; [exact B|]. rewrite Ea. split; [exact HGb'|]. split; [exact HSj | exact E3'].
1351
+ --- exists c. split; [exact Hc|]. rewrite ES, E3' in Hf. exact Hf.
1352
+ ** right; left. exists i. split; [exact Hi|]. exists j. split; [rewrite (wia_S a B); exact Hj|].
1353
+ split; [exact Tj|]. split.
1354
+ --- split; [exact B|]. rewrite Ea. split; [exact HGb'|]. split; [exact HSj | lia].
1355
+ --- exists c. split; [exact Hc|]. replace (Sc w (S a) i) with 2%nat in Hf by lia. exact Hf.
1356
+ + cbn [orb] in Hst. unfold stop2 in Hst. apply andb_prop in Hst as [L Ex]. apply Nat.eqb_eq in L.
1357
+ apply existsb_seq_true in Ex as (i & Hi & E). apply Nat.leb_le in E.
1358
+ right; right; right. split; [exact L|]. exists i. split; [exact Hi|]. split; [exact HG|]. split; [|exact E].
1359
+ destruct (ncw_copy w a i ltac:(lia)) as (c & Hc & W).
1360
+ pose proof (existsb_seq_false _ _ S1 (cpy a i c) (cpy_lt a i c Hi Hc)) as F. cbv beta in F.
1361
+ assert (W' : wb w a (cpy a i c) = true) by exact W. rewrite W' in F. cbn [andb] in F. apply Nat.leb_gt in F.
1362
+ rewrite cpy_mod in F by exact Hi. lia.
1363
+ - eapply Rle_trans; [apply P_or4|]. unfold bl.
1364
+ rewrite rsum_plus, rsum_plus.
1365
+ assert (Bp : P (fun w => exists i, (i < nla a)%nat /\ exists j1, (j1 < wia a)%nat /\ exists j2, (j2 < wia a)%nat
1366
+ /\ (tT a i j1 && tT a i j2 && Nat.ltb j1 j2) = true /\ (Win a j1 w /\ Win a j2 w))
1367
+ <= rsum (nla a) (fun i => rsum (wia a) (fun j1 => rsum (wia a) (fun j2 =>
1368
+ if tT a i j1 && tT a i j2 && Nat.ltb j1 j2 then Pin a j1 * Pin a j2 + Kin a j1 j2 else 0)))).
1369
+ { eapply Rle_trans; [apply Pex|]. apply rsum_le. intros i Hi.
1370
+ eapply Rle_trans; [apply Pex|]. apply rsum_le. intros j1 Hj1.
1371
+ apply (P_sum (wia a) (fun j2 => tT a i j1 && tT a i j2 && Nat.ltb j1 j2) (fun j2 w => Win a j1 w /\ Win a j2 w)).
1372
+ intros j2 Hj2 T. apply HK; [exact Hj1 | exact Hj2|]. apply andb_prop in T as [_ T]. apply Nat.ltb_lt in T. lia. }
1373
+ assert (Bk : forall k (Bk : nat -> Omega -> Prop) (pk : nat -> R),
1374
+ (forall j, (j < wia a)%nat -> P (Bk j) <= pk j) -> (forall j, dep Omega X (pastv a) (Bk j)) ->
1375
+ P (fun w => exists i, (i < nla a)%nat /\ exists j, (j < wia a)%nat /\ tT a i j = true
1376
+ /\ (Bk j w /\ N1 a i k (fun q => X (vid a q) w)))
1377
+ <= rsum (nla a) (fun i => Rmin 1 (3 * qk a i k) * Xs a i pk)).
1378
+ { intros k Bk pk HB HD. eapply Rle_trans; [apply Pex|]. apply rsum_le. intros i Hi.
1379
+ unfold Xs. rewrite <- rsum_if_scal.
1380
+ apply (P_sum (wia a) (tT a i) (fun j w => Bk j w /\ N1 a i k (fun q => X (vid a q) w))).
1381
+ intros j Hj _. cbv beta. rewrite (P_pn a).
1382
+ - apply Rmult_le_compat; [apply Pnn | apply Pnn | apply HB; exact Hj | apply P_N1].
1383
+ - apply HD.
1384
+ - apply (dep_now a (N1 a i k)). }
1385
+ pose proof (Bk 2%nat (B2 a) (P2in a) (P_B2 a) (dep_B2 a)) as B2'.
1386
+ pose proof (Bk 3%nat (B3 a) (P3in a) (P_B3 a) (dep_B3 a)) as B3'.
1387
+ assert (B4 : P (fun w => lyr a = (length Ls - 1)%nat /\ exists i, (i < nla a)%nat /\ E2 a i w)
1388
+ <= (if Nat.eqb (lyr a) (length Ls - 1) then rsum (nla a) (fun i => P2v a i) else 0)).
1389
+ { destruct (Nat.eqb_spec (lyr a) (length Ls - 1)) as [L|L].
1390
+ - eapply Rle_trans; [apply P_mono; intros w [_ H]; exact H|]. eapply Rle_trans; [apply Pex|].
1391
+ apply rsum_le. intros i Hi. apply claim_P2; [exact Hi | exact HW].
1392
+ - right. apply Pnone. intros w [C _]. contradiction. }
1393
+ lra.
1394
+ Qed.
1395
+
1396
+ (* ---- Proposition 6.14 ------------------------------------------------------------------------------------------- *)
1397
+ Lemma out_last : forall w t, out w (t * length Ls + (length Ls - 1)) = lmapp (amap 3 n Ls) 0 (Et w t) (run3 w t).
1398
+ Proof.
1399
+ intros w t. pose proof NL_pos. destruct (stp_lyr t (length Ls - 1) ltac:(lia)) as [E1 E2].
1400
+ unfold out, pn. rewrite E1, E2. replace (S (length Ls - 1)) with (length Ls) by lia.
1401
+ rewrite firstn_all2 by (rewrite length_amap; lia). reflexivity.
1402
+ Qed.
1403
+
1404
+ Lemma exo_last : forall a, lyr a = (length Ls - 1)%nat -> exo a = lmap Ls (xs (stp a)) /\ nla a = n.
1405
+ Proof.
1406
+ intros a L. pose proof NL_pos. split.
1407
+ - unfold exo, lay, exin. rewrite L. rewrite <- lin_S by lia. replace (S (length Ls - 1)) with (length Ls) by lia.
1408
+ unfold lin. rewrite firstn_all. reflexivity.
1409
+ - unfold nla, lay. rewrite L, <- (last_nth' _ Ls [] Hne). exact Hlast.
1410
+ Qed.
1411
+
1412
+ (* every copy is its value in the run, flipped where it is wrong *)
1413
+ Lemma out_xorv : forall w a, out w a = xorv (rep 3 (exo a)) (wb w a).
1414
+ Proof.
1415
+ intros w a. apply nth_ext with (d := false) (d' := false).
1416
+ - rewrite len_out, length_xorv, length_rep, len_exo. reflexivity.
1417
+ - intros k Hk. rewrite len_out in Hk. rewrite nth_xorv by (rewrite length_rep, len_exo; exact Hk).
1418
+ rewrite nth_rep_mod by (rewrite len_exo; exact Hk). rewrite len_exo. unfold wb.
1419
+ destruct (nth k (out w a) false), (nth (k mod nla a) (exo a) false); reflexivity.
1420
+ Qed.
1421
+
1422
+ (* without a stop at the last layer of a step the state read by majority is the state of the run *)
1423
+ Lemma maj_out : forall w a, lyr a = (length Ls - 1)%nat -> stopb w a = false -> maj 3 n (out w a) = lmap Ls (xs (stp a)).
1424
+ Proof.
1425
+ intros w a L Hst. destruct (exo_last a L) as [E1 E2]. rewrite out_xorv, <- E1.
1426
+ apply maj_ok; [reflexivity | rewrite len_exo; exact E2 |].
1427
+ intros j Hj. pose proof (nostop_ncw w a j Hst L ltac:(lia)) as H. unfold ncw in H. rewrite E2 in H.
1428
+ change (3 / 2)%nat with 1%nat. exact H.
1429
+ Qed.
1430
+
1431
+ (* Proposition 6.14: the state of the threefold amplification read by majority leaves the run within T steps with
1432
+ probability at most sum_{t < T} b(t) *)
1433
+ Theorem restoration : forall T,
1434
+ P (fun w => exists t, (t < T)%nat /\ maj 3 n (lmapp (amap 3 n Ls) 0 (Et w t) (run3 w t)) <> lmap Ls (xs t))
1435
+ <= rsum T bt.
1436
+ Proof.
1437
+ intro T. pose proof NL_pos.
1438
+ eapply Rle_trans; [apply (P_mono _ (fun w => exists a, (a < T * length Ls)%nat /\ (stopb w a = true /\ Gb a w)))|].
1439
+ - intros w (t & Ht & Hm). set (a := (t * length Ls + (length Ls - 1))%nat).
1440
+ destruct (stp_lyr t (length Ls - 1) ltac:(lia)) as [E1 E2]. fold a in E1, E2.
1441
+ assert (Hst : stopb w a = true).
1442
+ { destruct (stopb w a) eqn:Es; [reflexivity|]. exfalso. apply Hm. rewrite <- out_last. fold a.
1443
+ rewrite <- E1. apply maj_out; assumption. }
1444
+ destruct (first_true (stopb w) a Hst) as (a0 & Ha0 & H0 & Hb). exists a0. split; [unfold a in Ha0; nia|].
1445
+ split; [exact H0 | exact Hb].
1446
+ - eapply Rle_trans; [apply Pex|]. unfold bt. rewrite <- rsum_blocks. apply rsum_le. intros a _. apply claim_stop.
1447
+ Qed.
1448
+
1449
+ End Restore.
rocq/StoredCount.v ADDED
@@ -0,0 +1,462 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* Theorem 8.8: the records of the stored host S_{A,w}, G_A = 35A 2^(A-1) - 2^(A+1) + (A^3 - A)/6 + A^2 + 29A + 14w + 91
2
+ + pi_A with pi_A <= 7 empty records, its window of 2^alpha_A cells with alpha_A = A + Theta(log A), and generations of
3
+ Theta(A^3 4^A) steps. *)
4
+ From Stdlib Require Import List Bool Arith ZArith Lia.
5
+ Import ListNotations.
6
+ From TH Require Import TwoHead Net Gates Host HostWF Stored StoredWbr StoredWidth StoredStep StoredPass Lev BlockLev HostLev
7
+ HostCount.
8
+ From TH Require StoredImage Recipe.
9
+
10
+ Local Notation image_bytes := StoredImage.image_bytes.
11
+ Local Notation describe := Recipe.describe.
12
+ Local Notation psteps := Recipe.psteps.
13
+
14
+ (* ---- the records of a unit ------------------------------------------------------------------------------- *)
15
+ (* a chain of k literals, and a unit of threshold t on k literals *)
16
+ Definition chlen (k : nat) : nat := match k with 0 => 0 | 1 => 1 | _ => k - 1 end.
17
+
18
+ Fixpoint rcount (t : Z) (k : nat) : nat :=
19
+ if Z.leb t 0 then 1
20
+ else if Z.ltb (Z.of_nat k) t then 1
21
+ else if Z.eqb t 1 then chlen k
22
+ else if Z.eqb t (Z.of_nat k) then chlen k
23
+ else match k with O => 0 | S k' => rcount t k' + rcount (t - 1) k' + 2 end.
24
+
25
+ Lemma length_chain_eq : forall g ls d acc, length (chain g ls d acc) = chlen (length ls).
26
+ Proof.
27
+ intros g [|l0 [|l1 [|l2 t]]] d acc; cbn [chain length chlen]; try reflexivity.
28
+ rewrite length_chain_tail. lia.
29
+ Qed.
30
+
31
+ Lemma rcount_eq : forall t k, rcount t k =
32
+ if Z.leb t 0 then 1
33
+ else if Z.ltb (Z.of_nat k) t then 1
34
+ else if Z.eqb t 1 then chlen k
35
+ else if Z.eqb t (Z.of_nat k) then chlen k
36
+ else match k with O => 0 | S k' => rcount t k' + rcount (t - 1) k' + 2 end.
37
+ Proof. intros t [|k]; reflexivity. Qed.
38
+
39
+ Lemma length_ucomp_eq : forall xc ls t d acc lev, length (ucomp xc t ls d acc lev) = rcount t (length ls).
40
+ Proof.
41
+ intros xc. induction ls as [|l0 rest IH]; intros t d acc lev; rewrite ucomp_eq, rcount_eq.
42
+ - destruct (Z.leb t 0); [reflexivity|]. destruct (Z.ltb _ t); [reflexivity|].
43
+ destruct (Z.eqb t 1); [apply length_chain_eq|]. destruct (Z.eqb t _); [apply length_chain_eq | reflexivity].
44
+ - destruct (Z.leb t 0); [reflexivity|]. destruct (Z.ltb _ t); [reflexivity|].
45
+ destruct (Z.eqb t 1); [apply length_chain_eq|]. destruct (Z.eqb t _); [apply length_chain_eq|].
46
+ cbn [length]. rewrite !length_app, IH, IH. cbn [length]. lia.
47
+ Qed.
48
+
49
+ Lemma length_next_tbl : forall n nu nx, length (next_tbl n nu nx) = nu.
50
+ Proof.
51
+ intros n nu nx. unfold next_tbl.
52
+ assert (G : forall l tbl, length (fold_left (fun tbl p => setopt tbl (snd p - n) (fst p)) l tbl) = length tbl).
53
+ { induction l as [|p l IH]; intro tbl; cbn [fold_left]; [reflexivity|]. rewrite IH, length_setopt. reflexivity. }
54
+ rewrite G, repeat_length. reflexivity.
55
+ Qed.
56
+
57
+ (* the records of the step: rcount of each unit *)
58
+ Definition srec (us : list tu) : nat := fold_right (fun U acc => rcount (tval U) (length (tin U)) + acc) 0 us.
59
+
60
+ Lemma length_step_go_eq : forall A w nu us nt u, length us <= length nt ->
61
+ length (step_go A w nu u us nt) = srec us.
62
+ Proof.
63
+ intros A w nu us. induction us as [|U us IH]; intros nt u Hl; [reflexivity|].
64
+ destruct nt as [|o nt]; [cbn in Hl; lia|]. cbn [step_go srec fold_right]. rewrite length_app, length_ucomp_eq, length_map.
65
+ rewrite IH by (cbn in Hl; lia). reflexivity.
66
+ Qed.
67
+
68
+ (* ---- the records of the units of H_A -------------------------------------------------------------------- *)
69
+ Definition stval (u : su) : Z := (Z.of_nat (length (filter (fun p => Z.ltb (snd p) 0) (sin u))) - sb u)%Z.
70
+ Definition rcs (u : su) : nat := rcount (stval u) (length (sin u)).
71
+
72
+ Lemma tval_flat : forall n bs u, tval (flat_unit n bs u) = stval u.
73
+ Proof.
74
+ intros n bs u. unfold tval, stval, flat_unit. cbn [tin Net.tb]. f_equal. f_equal.
75
+ rewrite length_filter_map. reflexivity.
76
+ Qed.
77
+
78
+ Lemma neg_lw : forall ls : list lit, length (filter (fun p => Z.ltb (snd p) 0) (map lw ls)) = nneg ls.
79
+ Proof.
80
+ intro ls. unfold nneg. induction ls as [|[x p] t IH]; [reflexivity|]. cbn [map filter lw fst snd negb].
81
+ destruct p; cbn [Z.ltb Z.compare length]; [exact IH | rewrite IH; reflexivity].
82
+ Qed.
83
+
84
+ Lemma rcs_and : forall ls, 1 <= length ls -> rcs (sAND ls) = chlen (length ls).
85
+ Proof.
86
+ intros ls H. unfold rcs, stval. cbn [sin sb sAND]. rewrite neg_lw, length_map, rcount_eq.
87
+ pose proof (npos_nneg ls). replace (Z.of_nat (nneg ls) - - Z.of_nat (npos ls))%Z with (Z.of_nat (length ls)) by lia.
88
+ destruct (Z.leb_spec (Z.of_nat (length ls)) 0); [lia|]. rewrite Z.ltb_irrefl.
89
+ destruct (Z.eqb_spec (Z.of_nat (length ls)) 1); [reflexivity|]. rewrite Z.eqb_refl. reflexivity.
90
+ Qed.
91
+
92
+ Lemma rcs_or : forall ls, 1 <= length ls -> rcs (sOR ls) = chlen (length ls).
93
+ Proof.
94
+ intros ls H. unfold rcs, stval. cbn [sin sb sOR]. rewrite neg_lw, length_map, rcount_eq.
95
+ replace (Z.of_nat (nneg ls) - (Z.of_nat (nneg ls) - 1))%Z with 1%Z by lia. cbn [Z.leb Z.compare].
96
+ destruct (Z.ltb_spec (Z.of_nat (length ls)) 1); [lia|]. reflexivity.
97
+ Qed.
98
+
99
+ Lemma fold_nsum : forall (X : Type) (f : X -> nat) (l : list X) d,
100
+ fold_right (fun x acc => f x + acc) 0 l = nsum (length l) (fun k => f (nth k l d)).
101
+ Proof.
102
+ intros X f l d.
103
+ assert (G : forall l' c, fold_right (fun y acc => f y + acc) c l' = fold_right (fun y acc => f y + acc) 0 l' + c)
104
+ by (induction l' as [|y l' IHl]; intro c; cbn [fold_right]; [reflexivity | rewrite IHl; lia]).
105
+ induction l as [|x t IH] using rev_ind; [reflexivity|].
106
+ rewrite fold_right_app. cbn [fold_right]. rewrite G, Nat.add_0_r.
107
+ rewrite length_app, Nat.add_1_r. cbn [nsum length]. rewrite app_nth2 by lia. rewrite Nat.sub_diag. cbn [nth].
108
+ rewrite IH. f_equal. apply nsum_ext. intros k Hk. rewrite app_nth1 by lia. reflexivity.
109
+ Qed.
110
+
111
+ Lemma bsum_add : forall bs g h, bsum bs (fun x => g x + h x) = bsum bs g + bsum bs h.
112
+ Proof.
113
+ intros bs g h. unfold bsum. rewrite <- nsum_add. apply nsum_ext. intros b _. rewrite <- nsum_add.
114
+ apply nsum_ext. intros j _. apply nsum_add.
115
+ Qed.
116
+
117
+ Lemma chlen_ge2 : forall k, 2 <= k -> chlen k + 1 = k.
118
+ Proof. intros [|[|k]] H; cbn [chlen]; lia. Qed.
119
+
120
+ Lemma and_rcs : forall ls, 2 <= length ls -> rcs (sAND ls) + 1 = length (sin (sAND ls)).
121
+ Proof. intros ls H. rewrite rcs_and by lia. cbn [sin sAND]. rewrite length_map. apply chlen_ge2. exact H. Qed.
122
+
123
+ Lemma or_rcs : forall ls, 2 <= length ls -> rcs (sOR ls) + 1 = length (sin (sOR ls)).
124
+ Proof. intros ls H. rewrite rcs_or by lia. cbn [sin sOR]. rewrite length_map. apply chlen_ge2. exact H. Qed.
125
+
126
+ Section SC.
127
+ Variable A : nat.
128
+ Hypothesis HA : 3 <= A.
129
+
130
+ (* the threshold units take more records than literals: the copy of the carry term T_{1,*}, and the units of threshold 2
131
+ on three and four literals *)
132
+ Definition dlt (b r : nat) : nat :=
133
+ if Nat.eqb b 17 then (if Nat.eqb r 0 then 1 else 0)
134
+ else if Nat.eqb b (tb A + 6) then (if Nat.eqb r 1 then 2 else 0)
135
+ else if Nat.eqb b (tb A + 7) then 2
136
+ else if Nat.eqb b (tb A + 8) then 5 else 0.
137
+
138
+ Lemma dlt_pre : forall b r, b < 17 -> dlt b r = 0.
139
+ Proof.
140
+ intros b r H. unfold dlt, tb. destruct (Nat.eqb_spec b 17); [lia|]. destruct (Nat.eqb_spec b (16 + A + 6)); [lia|].
141
+ destruct (Nat.eqb_spec b (16 + A + 7)); [lia|]. destruct (Nat.eqb_spec b (16 + A + 8)); [lia | reflexivity].
142
+ Qed.
143
+
144
+ Lemma dlt_T : forall k r, 1 <= k -> k < A -> dlt (16 + k) r = if Nat.eqb k 1 then (if Nat.eqb r 0 then 1 else 0) else 0.
145
+ Proof.
146
+ intros k r H1 H2. unfold dlt, tb. destruct (Nat.eqb_spec k 1) as [->|E]; [reflexivity|].
147
+ destruct (Nat.eqb_spec (16 + k) 17); [lia|].
148
+ destruct (Nat.eqb_spec (16 + k) (16 + A + 6)); [lia|]. destruct (Nat.eqb_spec (16 + k) (16 + A + 7)); [lia|].
149
+ destruct (Nat.eqb_spec (16 + k) (16 + A + 8)); [lia | reflexivity].
150
+ Qed.
151
+
152
+ Lemma dlt_post : forall i r, dlt (tb A + i) r = if Nat.eqb i 6 then (if Nat.eqb r 1 then 2 else 0)
153
+ else if Nat.eqb i 7 then 2 else if Nat.eqb i 8 then 5 else 0.
154
+ Proof.
155
+ intros i r. unfold dlt, tb. destruct (Nat.eqb_spec (16 + A + i) 17); [lia|].
156
+ destruct (Nat.eqb_spec i 6) as [->|E6]; [rewrite Nat.eqb_refl; reflexivity|].
157
+ destruct (Nat.eqb_spec (16 + A + i) (16 + A + 6)); [lia|].
158
+ destruct (Nat.eqb_spec i 7) as [->|E7]; [rewrite Nat.eqb_refl; reflexivity|].
159
+ destruct (Nat.eqb_spec (16 + A + i) (16 + A + 7)); [lia|].
160
+ destruct (Nat.eqb_spec i 8) as [->|E8]; [rewrite Nat.eqb_refl; reflexivity|].
161
+ destruct (Nat.eqb_spec (16 + A + i) (16 + A + 8)); [lia | reflexivity].
162
+ Qed.
163
+
164
+ Ltac len2 := cbn [length]; unfold lits; rewrite ?length_map, ?length_seq, ?length_app; cbn [length]; lia.
165
+
166
+ Theorem host_rcs : forall b j r, valid (hblocks A) (nH A) (SRef b j r) ->
167
+ rcs (sunit (hblocks A) b j r) + 1 = length (sin (sunit (hblocks A) b j r)) + dlt b r.
168
+ Proof.
169
+ intros b j r (Hb & Hj & Hr). rewrite length_hblocks in Hb by lia. unfold sunit. pose proof (SW_ge A HA) as HS.
170
+ destruct (Nat.lt_ge_cases b 17) as [Hp|Hp].
171
+ { rewrite dlt_pre, Nat.add_0_r by exact Hp. rewrite nth_hb_pre in Hj, Hr |- * by exact Hp.
172
+ assert (Hc : b = 0 \/ b = 1 \/ b = 2 \/ b = 3 \/ b = 4 \/ b = 5 \/ b = 6 \/ b = 7 \/ b = 8 \/ b = 9
173
+ \/ b = 10 \/ b = 11 \/ b = 12 \/ b = 13 \/ b = 14 \/ b = 15 \/ b = 16) by lia.
174
+ destruct Hc as [->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->| ->]]]]]]]]]]]]]]]];
175
+ cbn [nth hpre bcount bsize bshape blk_P blk_HP blk_FA blk_Q blk_F blk_PA blk_PB blk_AC blk_W
176
+ blk_RX blk_RY blk_KP blk_X blk_Y blk_PR] in Hj, Hr |- *;
177
+ (destruct r as [|r]; [|lia]); cbn [nth].
178
+ - apply and_rcs. len2.
179
+ - apply and_rcs. len2.
180
+ - apply and_rcs. len2.
181
+ - apply and_rcs. len2.
182
+ - apply and_rcs. len2.
183
+ - apply or_rcs. rewrite length_map, (Q_count A HA j Hj).
184
+ replace A with (S (A - 1)) in HS at 1 by lia. unfold SW in HS. rewrite Nat.pow_succ_r' in HS. lia.
185
+ - apply or_rcs. len2.
186
+ - apply and_rcs. len2.
187
+ - apply and_rcs. len2.
188
+ - apply and_rcs. len2.
189
+ - apply and_rcs. len2.
190
+ - apply and_rcs. len2.
191
+ - apply and_rcs. len2.
192
+ - apply and_rcs. len2.
193
+ - apply or_rcs. len2.
194
+ - apply or_rcs. len2.
195
+ - apply or_rcs. len2. }
196
+ destruct (Nat.lt_ge_cases b (tb A)) as [HT|HT].
197
+ { unfold tb in HT. replace b with (16 + (b - 16)) in Hj, Hr |- * by lia.
198
+ rewrite dlt_T by lia. rewrite nth_hb_T in Hj, Hr |- * by lia. cbn [bcount bsize bshape blk_T] in Hj, Hr |- *.
199
+ remember (b - 16) as k eqn:Ek. assert (Hk : 1 <= k < A) by lia.
200
+ destruct r as [|r]; cbn [nth].
201
+ - destruct (Nat.eqb_spec k 1) as [->|E].
202
+ + cbn. reflexivity.
203
+ + rewrite Nat.add_0_r. apply and_rcs. rewrite length_map, length_seq. lia.
204
+ - rewrite nth_map_d with (d' := 0) by (rewrite length_seq; lia). rewrite seq_nth by lia.
205
+ assert (Hz : (if Nat.eqb k 1 then (if Nat.eqb (S r) 0 then 1 else 0) else 0) = 0)
206
+ by (destruct (Nat.eqb k 1); reflexivity).
207
+ rewrite Hz, Nat.add_0_r. apply and_rcs. rewrite length_app, length_map, length_seq. cbn [length]. lia. }
208
+ replace b with (tb A + (b - tb A)) in Hj, Hr |- * by lia. rewrite dlt_post.
209
+ rewrite nth_hb_post in Hj, Hr |- * by lia.
210
+ assert (Hi : b - tb A < 15) by (unfold tb in *; lia).
211
+ remember (b - tb A) as i eqn:Ei. clear Ei Hb Hp HT.
212
+ assert (Hc : i = 0 \/ i = 1 \/ i = 2 \/ i = 3 \/ i = 4 \/ i = 5 \/ i = 6 \/ i = 7 \/ i = 8 \/ i = 9
213
+ \/ i = 10 \/ i = 11 \/ i = 12 \/ i = 13 \/ i = 14) by lia.
214
+ destruct Hc as [->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->| ->]]]]]]]]]]]]]];
215
+ cbn [nth hpost bcount bsize bshape blk_C blk_AX blk_NX blk_XN blk_EQ blk_R0 blk_H blk_R blk_LEQ
216
+ blk_TA blk_TB blk_NP blk_HAB blk_WR blk_NM Nat.eqb] in Hj, Hr |- *.
217
+ - destruct r as [|r]; [|lia]. cbn [nth]. rewrite Nat.add_0_r. apply or_rcs. len2.
218
+ - destruct r as [|r]; [|lia]. cbn [nth]. rewrite Nat.add_0_r. apply and_rcs. len2.
219
+ - destruct r as [|r]; [|lia]. cbn [nth]. rewrite Nat.add_0_r. apply and_rcs. len2.
220
+ - destruct r as [|r]; [|lia]. cbn [nth]. rewrite Nat.add_0_r. apply or_rcs. len2.
221
+ - destruct r as [|r]; [|lia]. cbn [nth]. rewrite Nat.add_0_r. apply and_rcs. len2.
222
+ - rewrite Nat.add_0_r. assert (Hr3 : r = 0 \/ r = 1 \/ r = 2) by lia.
223
+ destruct Hr3 as [->|[->| ->]]; cbn [nth]; first [apply and_rcs | apply or_rcs]; len2.
224
+ - assert (Hr3 : r = 0 \/ r = 1 \/ r = 2) by lia. destruct Hr3 as [->|[->| ->]]; reflexivity.
225
+ - destruct r as [|r]; [|lia]. reflexivity.
226
+ - destruct r as [|r]; [|lia]. reflexivity.
227
+ - destruct r as [|r]; [|lia]. cbn [nth]. rewrite Nat.add_0_r. apply and_rcs. len2.
228
+ - destruct r as [|r]; [|lia]. cbn [nth]. rewrite Nat.add_0_r. apply and_rcs. len2.
229
+ - destruct r as [|r]; [|lia]. cbn [nth]. rewrite Nat.add_0_r. apply or_rcs. len2.
230
+ - rewrite Nat.add_0_r. assert (Hr3 : r = 0 \/ r = 1 \/ r = 2) by lia.
231
+ destruct Hr3 as [->|[->| ->]]; cbn [nth]; first [apply and_rcs | apply or_rcs]; len2.
232
+ - destruct r as [|r]; [|lia]. cbn [nth]. rewrite Nat.add_0_r. apply and_rcs. len2.
233
+ - destruct r as [|r]; [|lia]. cbn [nth]. rewrite Nat.add_0_r. apply or_rcs. len2.
234
+ Qed.
235
+
236
+ (* the records of the step of H_A: one fewer than the literals of each unit, and 4A + 2 more for the copy and the units of
237
+ threshold 2 *)
238
+ Theorem host_step_records : srec (host_units A) + length (host_units A)
239
+ = nsum (length (host_units A)) (fun k => length (tin (nth k (host_units A) tu0))) + 4 * A + 2.
240
+ Proof.
241
+ pose proof (host_wf' A HA) as Hwf. pose proof (hout_valid A HA) as Hov.
242
+ unfold srec. rewrite (fold_nsum _ (fun U => rcount (tval U) (length (tin U))) _ tu0).
243
+ change (host_units A) with (fus (hblocks A) (nH A)).
244
+ rewrite (edges_bsum _ _ _ Hwf Hov), (fus_len _ _ Hwf), (nsum_units _ _ _ Hwf Hov).
245
+ rewrite <- (fus_len _ _ Hwf), (units_bsum _ _ _ Hwf Hov).
246
+ rewrite (bsum_ext (hblocks A) (nH A) _ (fun x => rcs (usu (hblocks A) x)))
247
+ by (intros b j r Hv; rewrite (fus_nth _ _ Hwf b j r Hv), tval_flat; unfold flat_unit; cbn [tin usu];
248
+ rewrite length_map; reflexivity).
249
+ rewrite <- bsum_add.
250
+ rewrite (bsum_ext (hblocks A) (nH A) _ (fun x => length (sin (usu (hblocks A) x))
251
+ + match x with SRef b _ r => dlt b r | SIn _ => 0 end))
252
+ by (intros b j r Hv; cbn [usu]; apply host_rcs; exact Hv).
253
+ rewrite bsum_add. enough (bsum (hblocks A) (fun x => match x with SRef b _ r => dlt b r | SIn _ => 0 end) = 4 * A + 2) by lia.
254
+ rewrite (bsum_host A HA).
255
+ rewrite (nsum_ext 17 _ (fun _ => 0)).
256
+ 2: { intros b Hb. apply nsum_zero. intros j _. apply nsum_zero. intros r _. apply dlt_pre. exact Hb. }
257
+ rewrite (nsum_ext (A - 1) _ (fun i => if Nat.eqb i 0 then 1 else 0)).
258
+ 2: { intros i Hi. replace (17 + i) with (16 + S i) by lia.
259
+ rewrite (nsum_ext (S (S i)) _ (fun r => if Nat.eqb (S i) 1 then (if Nat.eqb r 0 then 1 else 0) else 0))
260
+ by (intros r _; apply dlt_T; lia).
261
+ destruct (Nat.eqb_spec i 0) as [->|E].
262
+ - cbn. reflexivity.
263
+ - apply nsum_zero. intros r _. destruct (Nat.eqb_spec (S i) 1); [lia | reflexivity]. }
264
+ rewrite (nsum_ext 15 _ (fun i => if Nat.eqb i 6 then 2 * (A - 1) else if Nat.eqb i 7 then 2 * (A - 1)
265
+ else if Nat.eqb i 8 then 5 else 0)).
266
+ 2: { intros i Hi.
267
+ assert (Hc : i = 0 \/ i = 1 \/ i = 2 \/ i = 3 \/ i = 4 \/ i = 5 \/ i = 6 \/ i = 7 \/ i = 8 \/ i = 9
268
+ \/ i = 10 \/ i = 11 \/ i = 12 \/ i = 13 \/ i = 14) by lia.
269
+ destruct Hc as [->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->| ->]]]]]]]]]]]]]];
270
+ cbn [nth hpost bcount bsize blk_C blk_AX blk_NX blk_XN blk_EQ blk_R0 blk_H blk_R blk_LEQ
271
+ blk_TA blk_TB blk_NP blk_HAB blk_WR blk_NM nsum]; rewrite ?dlt_post; cbn [Nat.eqb];
272
+ rewrite ?nsum_const; try lia. }
273
+ rewrite (nsum_one (A - 1) (fun i => if Nat.eqb i 0 then 1 else 0) 0);
274
+ [| lia | intros k _ Hk; destruct (Nat.eqb_spec k 0); [lia | reflexivity]].
275
+ rewrite nsum_zero by reflexivity. cbn [nsum Nat.eqb]. lia.
276
+ Qed.
277
+
278
+ End SC.
279
+
280
+ (* ---- the device and the whole image ---------------------------------------------------------------------- *)
281
+ Lemma length_device_eq : forall A w nu lv, 8 <= A -> 2 <= w -> length (Stored.device A w nu lv) = 11 * A + 12 * w + 75.
282
+ Proof.
283
+ intros A w nu lv HA Hw. unfold Stored.device, word1. rewrite !length_app.
284
+ rewrite !length_chain_eq. cbn [length]. rewrite !length_map, !length_seq.
285
+ rewrite (length_cmk _ _ _ _ 3) by (intro; reflexivity).
286
+ rewrite (length_cmk _ _ _ _ 8) by (intro; reflexivity).
287
+ rewrite (length_cmk _ _ _ _ 4) by (intro; reflexivity).
288
+ rewrite (length_cmk _ _ _ _ 3) by (intro; reflexivity).
289
+ rewrite (length_cmk _ _ _ _ 3) by (intro; reflexivity).
290
+ rewrite (length_cmk _ _ _ _ 4) by (intro; reflexivity).
291
+ rewrite (length_cmk _ _ _ _ A) by (intro; rewrite length_map, length_seq; reflexivity).
292
+ rewrite ?length_map, ?length_seq. unfold gMUX. cbn [length].
293
+ assert (C1 : chlen (S (A - 1)) = A - 1) by (destruct (A - 1) as [|a] eqn:E; [lia | reflexivity]).
294
+ pose proof (chlen_ge2 w Hw). rewrite C1. lia.
295
+ Qed.
296
+
297
+ (* G_A = 35A 2^(A-1) - 2^(A+1) + (A^3 - A)/6 + A^2 + 29A + 14w + 91 + pi_A, with pi_A < 8 empty records *)
298
+ Theorem stored_records : forall A w, 8 <= A -> 2 <= w -> exists p, p < 8 /\
299
+ 6 * length (stored A w) + 12 * SW A = 105 * A * SW A + A * A * A + 6 * (A * A) + 173 * A + 84 * w + 546 + 6 * p.
300
+ Proof.
301
+ intros A w HA Hw. rewrite (stored_split A w), !length_app, repeat_length. unfold handover. cbn [length].
302
+ rewrite (length_startup A w _ (length_image A)), length_device_eq by assumption.
303
+ rewrite length_step_go_eq by (rewrite length_next_tbl; lia).
304
+ match goal with |- context [padn ?a ?b] => exists (padn a b); split; [apply padn_lt|] end.
305
+ pose proof (host_step_records A ltac:(lia)) as R. pose proof (host_edges A ltac:(lia)) as E.
306
+ pose proof (host_units_count A ltac:(lia)) as U. nia.
307
+ Qed.
308
+
309
+ (* ---- growth ---------------------------------------------------------------------------------------------- *)
310
+ Lemma sq_le : forall A, 8 <= A -> 4 * (A * A) <= SW A.
311
+ Proof.
312
+ intros A HA. replace A with (8 + (A - 8)) by lia. generalize (A - 8) as k. clear.
313
+ induction k as [|k IH]; [cbn; lia|]. unfold SW in *. replace (8 + S k) with (S (8 + k)) by lia.
314
+ rewrite Nat.pow_succ_r'. nia.
315
+ Qed.
316
+
317
+ Lemma cube_le : forall A, 8 <= A -> A * A * A <= 4 * SW A.
318
+ Proof.
319
+ intros A HA. replace A with (8 + (A - 8)) by lia. generalize (A - 8) as k. clear.
320
+ induction k as [|k IH]; [cbn; lia|]. unfold SW in *. replace (8 + S k) with (S (8 + k)) by lia.
321
+ rewrite Nat.pow_succ_r'. nia.
322
+ Qed.
323
+
324
+ Lemma units_le : forall A, 8 <= A -> length (host_units A) <= 9 * A * SW A.
325
+ Proof. intros A HA. pose proof (host_units_count A ltac:(lia)). pose proof (sq_le A HA). nia. Qed.
326
+
327
+ Lemma edges_le : forall A, 8 <= A -> nsum (length (host_units A)) (fun k => length (tin (nth k (host_units A) tu0))) <= 26 * A * SW A.
328
+ Proof. intros A HA. pose proof (host_edges A ltac:(lia)). pose proof (sq_le A HA). pose proof (cube_le A HA). nia. Qed.
329
+
330
+ Lemma levels_le : forall us, levels us <= fold_right (fun u acc => length (tin u) + acc) 0 us.
331
+ Proof.
332
+ intro us. unfold levels.
333
+ assert (G : forall c, fold_left Nat.max (map (fun u => if thr_unit u then length (tin u) - 2 else 0) us) c
334
+ <= c + fold_right (fun u acc => length (tin u) + acc) 0 us).
335
+ { induction us as [|u t IH]; intro c; cbn [map fold_left fold_right]; [lia|].
336
+ specialize (IH (Nat.max c (if thr_unit u then length (tin u) - 2 else 0))). destruct (thr_unit u); lia. }
337
+ specialize (G 0). lia.
338
+ Qed.
339
+
340
+ (* the cells of the window *)
341
+ Lemma alS_eq : forall A w, alS A w = Nat.log2_up (ncells A w (length (host_units A)) (levels (host_units A))).
342
+ Proof. intros A w. reflexivity. Qed.
343
+
344
+ Lemma ncells_eq : forall A w nu lv, ncells A w nu lv = 24 + 4 * w + nH A + nu + 3 * lv.
345
+ Proof. intros A w nu lv. unfold ncells, DB, nh. lia. Qed.
346
+
347
+ (* alpha_A = A + Theta(log A) *)
348
+ Theorem alpha_bounds : forall A w, 8 <= A -> w <= SW A -> A + Nat.log2 A + 3 <= alS A w <= A + Nat.log2 A + 8.
349
+ Proof.
350
+ intros A w HA Hw. rewrite alS_eq, ncells_eq.
351
+ pose proof (units_le A HA) as U. pose proof (edges_le A HA) as E. pose proof (levels_le (host_units A)) as L.
352
+ rewrite (fold_nsum _ (fun u => length (tin u)) _ tu0) in L. cbv beta in L.
353
+ pose proof (host_units_count A ltac:(lia)) as U2.
354
+ pose proof (Nat.log2_spec A ltac:(lia)) as [Hl1 Hl2]. set (k := Nat.log2 A) in *.
355
+ assert (HS : 256 <= SW A) by (pose proof (sq_le A HA); nia).
356
+ set (c := 24 + 4 * w + nH A + length (host_units A) + 3 * levels (host_units A)).
357
+ assert (Hc0 : 0 < c) by (unfold c; lia).
358
+ split.
359
+ - replace (A + k + 3) with (S (A + k + 2)) by lia. apply Nat.le_succ_l.
360
+ apply (proj1 (Nat.log2_up_lt_pow2 c (A + k + 2) Hc0)).
361
+ replace (A + k + 2) with (k + 2 + A) by lia. rewrite !Nat.pow_add_r. unfold c, SW in *. change (2 ^ 2) with 4. nia.
362
+ - apply Nat.log2_up_le_pow2; [exact Hc0|].
363
+ replace (A + k + 8) with ((k + 1) + 7 + A) by lia.
364
+ rewrite (Nat.pow_add_r 2 (k + 1 + 7) A), (Nat.pow_add_r 2 (k + 1) 7). change (2 ^ 7) with 128.
365
+ fold (SW A). set (S := SW A) in *.
366
+ assert (HP : 8 * S <= A * S) by nia.
367
+ assert (HA2 : A <= S) by (pose proof (sq_le A HA) as Q; fold S in Q; nia).
368
+ assert (Hn : nH A = A + 1 + A * S) by (unfold nH, S, SW; lia).
369
+ assert (Hc : c <= 90 * (A * S)) by (unfold c; rewrite Hn; lia).
370
+ assert (Hk : (A + 1) * (128 * S) <= 2 ^ (k + 1) * (128 * S))
371
+ by (apply Nat.mul_le_mono_r; replace (k + 1) with (Datatypes.S k) by lia; lia).
372
+ lia.
373
+ Qed.
374
+
375
+ (* the image as bytes: (8 + 3 alpha) G / 8 *)
376
+ Lemma image_bytes_len : forall A w, 8 * length (image_bytes A w) = recw (alS A w) * length (stored A w).
377
+ Proof.
378
+ intros A w. unfold StoredImage.image_bytes. rewrite StoredImage.length_bytes. pose proof (StoredImage.image_whole A w) as H.
379
+ pose proof (Nat.div_mod_eq (recw (alS A w) * length (stored A w)) 8). lia.
380
+ Qed.
381
+
382
+ Lemma stored_le : forall A w, 8 <= A -> 2 <= w <= 2 * A + 10 -> length (stored A w) <= 18 * A * SW A.
383
+ Proof.
384
+ intros A w HA Hw. destruct (stored_records A w HA ltac:(lia)) as (p & Hp & H).
385
+ pose proof (sq_le A HA). pose proof (cube_le A HA). nia.
386
+ Qed.
387
+
388
+ Lemma stored_ge : forall A w, 8 <= A -> 2 <= w -> 17 * A * SW A <= length (stored A w).
389
+ Proof.
390
+ intros A w HA Hw. destruct (stored_records A w HA Hw) as (p & Hp & H).
391
+ pose proof (sq_le A HA). nia.
392
+ Qed.
393
+
394
+ Lemma bytes_le : forall A w, 8 <= A -> 2 <= w <= 2 * A + 10 -> 8 * length (image_bytes A w) <= 180 * (A * A) * SW A.
395
+ Proof.
396
+ intros A w HA Hw. rewrite image_bytes_len. pose proof (stored_le A w HA Hw) as G.
397
+ pose proof (alpha_bounds A w HA ltac:(pose proof (sq_le A HA); nia)) as [_ Ha].
398
+ pose proof (Nat.log2_le_lin A ltac:(lia)). unfold recw. nia.
399
+ Qed.
400
+
401
+ (* a counter of 2A + 10 bits holds every recipe of at most 2B + 1 bytes, and there is a least such width from 20 on *)
402
+ Lemma width_2A : forall A, 8 <= A -> 2 * length (image_bytes A (2 * A + 10)) + 1 < 2 ^ (2 * A + 10).
403
+ Proof.
404
+ intros A HA. pose proof (bytes_le A (2 * A + 10) HA ltac:(lia)) as B. pose proof (sq_le A HA) as Q.
405
+ replace (2 * A + 10) with (A + A + 10) at 2 by lia. rewrite !Nat.pow_add_r. change (2 ^ 10) with 1024.
406
+ unfold SW in *. nia.
407
+ Qed.
408
+
409
+ Lemma least_from : forall (P : nat -> Prop), (forall n, {P n} + {~ P n}) ->
410
+ forall d a, P (a + d) -> exists m, a <= m <= a + d /\ P m /\ forall k, a <= k < m -> ~ P k.
411
+ Proof.
412
+ intros P Pdec d. induction d as [|d IH]; intros a H.
413
+ - exists a. split; [lia|]. split; [rewrite Nat.add_0_r in H; exact H|]. intros k Hk. lia.
414
+ - destruct (Pdec a) as [Ha|Ha].
415
+ + exists a. split; [lia|]. split; [exact Ha|]. intros k Hk. lia.
416
+ + destruct (IH (S a)) as (m & Hm & Pm & Hl); [replace (S a + d) with (a + S d) by lia; exact H|].
417
+ exists m. split; [lia|]. split; [exact Pm|]. intros k Hk. destruct (Nat.eq_dec k a) as [->|E]; [exact Ha|].
418
+ apply Hl. lia.
419
+ Qed.
420
+
421
+ Theorem width_least : forall A, 8 <= A -> exists w, 20 <= w <= 2 * A + 10
422
+ /\ 2 * length (image_bytes A w) + 1 < 2 ^ w
423
+ /\ forall w', 20 <= w' < w -> 2 ^ w' <= 2 * length (image_bytes A w') + 1.
424
+ Proof.
425
+ intros A HA.
426
+ destruct (least_from (fun w => 2 * length (image_bytes A w) + 1 < 2 ^ w)
427
+ (fun w => lt_dec _ _) (2 * A + 10 - 20) 20) as (m & Hm & Pm & Hl).
428
+ - replace (20 + (2 * A + 10 - 20)) with (2 * A + 10) by lia. apply width_2A. exact HA.
429
+ - exists m. split; [lia|]. split; [exact Pm|]. intros w' Hw'. specialize (Hl w' Hw'). lia.
430
+ Qed.
431
+
432
+ (* with banks of G_A slots a generation is P G_A steps, Theta(A^3 4^A) *)
433
+ Theorem generation_bounds : forall A w, 8 <= A -> 20 <= w <= 2 * A + 10 ->
434
+ 256 * (A * A * A) * (SW A * SW A) <= psteps (describe (image_bytes A w)) * length (stored A w)
435
+ <= 32 * 256 * (A * A * A) * (SW A * SW A).
436
+ Proof.
437
+ intros A w HA Hw. pose proof (sq_le A HA) as Q.
438
+ destruct (Recipe.describe_spec (image_bytes A w) (StoredImage.image_bytes_lt A w)) as (D & T & _).
439
+ pose proof (Recipe.psteps_lower _ T) as P1. rewrite D in P1.
440
+ destruct (Recipe.describe_steps (image_bytes A w) (StoredImage.image_bytes_lt A w)) as [P2 _].
441
+ pose proof (image_bytes_len A w) as B.
442
+ pose proof (stored_le A w HA ltac:(lia)) as G1. pose proof (stored_ge A w HA ltac:(lia)) as G2.
443
+ pose proof (alpha_bounds A w HA ltac:(nia)) as [Ha1 Ha2]. pose proof (Nat.log2_le_lin A ltac:(lia)) as Hlog.
444
+ unfold recw in B.
445
+ set (P := psteps (describe (image_bytes A w))) in *. set (G := length (stored A w)) in *.
446
+ set (Bn := length (image_bytes A w)) in *. set (al := alS A w) in *. set (S := SW A) in *.
447
+ assert (HS : 256 <= S) by nia.
448
+ assert (HAS : 8 * 256 <= A * S) by (apply Nat.mul_le_mono; lia).
449
+ split.
450
+ - assert (L0 : 3 * A * G <= 3 * al * G) by (apply Nat.mul_le_mono_r, Nat.mul_le_mono_l; lia).
451
+ assert (L1 : 3 * A * G <= 8 * Bn) by lia.
452
+ assert (L2 : 3 * A * G * G <= 2 * P * G) by (apply Nat.mul_le_mono_r; lia).
453
+ assert (L3 : A * (17 * A * S * (17 * A * S)) <= A * (G * G)) by (apply Nat.mul_le_mono_l, Nat.mul_le_mono; exact G2).
454
+ lia.
455
+ - assert (U0 : (8 + 3 * al) * G <= 10 * A * G) by (apply Nat.mul_le_mono_r; lia).
456
+ assert (HG0 : 464 <= G) by lia.
457
+ assert (HG : 464 <= A * G) by (pose proof (Nat.mul_le_mono 1 A 464 G ltac:(lia) HG0); lia).
458
+ assert (U2 : 16 * P <= 251 * A * G) by lia.
459
+ assert (U3 : 16 * P * G <= 251 * A * G * G) by (apply Nat.mul_le_mono_r; exact U2).
460
+ assert (U4 : A * (G * G) <= A * (18 * A * S * (18 * A * S))) by (apply Nat.mul_le_mono_l, Nat.mul_le_mono; exact G1).
461
+ lia.
462
+ Qed.
rocq/StoredFast.v ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* The table of next values in one pass over the units, equal to next_tbl for the host since the units of
2
+ the next values come in increasing order, and the image of the stored host computed with it: the
3
+ definition that the extraction runs. *)
4
+ From Stdlib Require Import List Bool Arith ZArith Lia Sorting.Sorted.
5
+ Import ListNotations.
6
+ From TH Require Import TwoHead Net Host HostWF HostIP Device Stored StoredStep.
7
+
8
+ (* cnt entries from position u, the pairs (value, position) in increasing order of position *)
9
+ Fixpoint tbl_merge (u cnt : nat) (ps : list (nat * nat)) : list (option nat) :=
10
+ match cnt with
11
+ | O => []
12
+ | S c =>
13
+ match ps with
14
+ | (i, k) :: ps' => if Nat.eqb k u then Some i :: tbl_merge (S u) c ps' else None :: tbl_merge (S u) c ps
15
+ | [] => None :: tbl_merge (S u) c []
16
+ end
17
+ end.
18
+
19
+ Definition next_tbl_lin (n nu : nat) (nx : list nat) : list (option nat) := tbl_merge n nu (combine (seq 0 n) nx).
20
+
21
+ Lemma length_tbl_merge : forall cnt u ps, length (tbl_merge u cnt ps) = cnt.
22
+ Proof.
23
+ induction cnt as [|c IH]; intros u ps; [reflexivity|].
24
+ destruct ps as [|[i k] ps]; cbn [tbl_merge]; [cbn [length]; rewrite IH; reflexivity|].
25
+ destruct (Nat.eqb k u); cbn [length]; rewrite IH; reflexivity.
26
+ Qed.
27
+
28
+ Lemma nth_tbl_merge : forall cnt u ps j, StronglySorted (fun p q => snd p < snd q) ps ->
29
+ Forall (fun p => u <= snd p) ps -> j < cnt ->
30
+ nth j (tbl_merge u cnt ps) None = match find (fun p => Nat.eqb (snd p) (u + j)) ps with
31
+ | Some p => Some (fst p) | None => None end.
32
+ Proof.
33
+ induction cnt as [|c IH]; intros u ps j Hs Hf Hj; [lia|].
34
+ destruct ps as [|[i k] ps'].
35
+ - cbn [tbl_merge]. destruct j as [|j]; [reflexivity|]. cbn [nth].
36
+ rewrite IH; [reflexivity | constructor | constructor | lia].
37
+ - apply StronglySorted_inv in Hs as [Hs Hall]. apply Forall_cons_iff in Hf as [Hk Hf]. cbn [snd] in Hk.
38
+ assert (Hgt : Forall (fun p => k < snd p) ps') by exact Hall.
39
+ cbn [tbl_merge]. destruct (Nat.eqb_spec k u) as [->|Ne].
40
+ + destruct j as [|j].
41
+ * cbn [nth find fst snd]. rewrite Nat.add_0_r, Nat.eqb_refl. reflexivity.
42
+ * cbn [nth find fst snd]. replace (Nat.eqb u (u + S j)) with false by (symmetry; apply Nat.eqb_neq; lia).
43
+ rewrite IH; [| exact Hs | | lia].
44
+ -- replace (S u + j) with (u + S j) by lia. reflexivity.
45
+ -- eapply Forall_impl; [|exact Hgt]. intros p Hp. cbn beta in Hp. lia.
46
+ + destruct j as [|j].
47
+ * cbn [nth find fst snd]. rewrite Nat.add_0_r. replace (Nat.eqb k u) with false by (symmetry; apply Nat.eqb_neq; exact Ne).
48
+ rewrite find_none_of; [reflexivity|]. intros p Hp. rewrite Forall_forall in Hgt. specialize (Hgt p Hp).
49
+ apply Nat.eqb_neq. lia.
50
+ * cbn [nth]. rewrite IH; [| constructor; [exact Hs | exact Hall] | | lia].
51
+ -- replace (S u + j) with (u + S j) by lia. reflexivity.
52
+ -- constructor; [cbn [snd]; lia|]. eapply Forall_impl; [|exact Hgt]. intros p Hp. cbn beta in Hp. lia.
53
+ Qed.
54
+
55
+ Lemma sorted_combine : forall (a l : list nat), length a = length l -> StronglySorted lt l ->
56
+ StronglySorted (fun p q => snd p < snd q) (combine a l).
57
+ Proof.
58
+ induction a as [|x a IH]; intros [|y l] Hl Hs; cbn [combine]; try constructor;
59
+ apply StronglySorted_inv in Hs as [Hs Hall].
60
+ - apply IH; [cbn in Hl; lia | exact Hs].
61
+ - apply Forall_forall. intros [i k] Hp. cbn [snd]. apply in_combine_r in Hp. rewrite Forall_forall in Hall.
62
+ apply Hall. exact Hp.
63
+ Qed.
64
+
65
+ Lemma sorted_map_seq : forall (f : nat -> nat) m len, (forall i j, m <= i -> i < j -> j < m + len -> f i < f j) ->
66
+ StronglySorted lt (map f (seq m len)).
67
+ Proof.
68
+ intros f m len. revert m. induction len as [|len IH]; intros m H; cbn [seq map]; constructor.
69
+ - apply IH. intros i j Hi Hij Hj. apply H; lia.
70
+ - apply Forall_map, Forall_forall. intros j Hj. apply in_seq in Hj. apply H; lia.
71
+ Qed.
72
+
73
+ Section Host.
74
+ Variable A : nat.
75
+ Hypothesis HA : 3 <= A.
76
+
77
+ Local Notation n := (nH A).
78
+ Local Notation us := (host_units A).
79
+
80
+ (* the units of the next values come in the order of the state bits *)
81
+ Lemma hout_mono : forall i j, i < j -> j < n -> idx n (hblocks A) (hout A i) < idx n (hblocks A) (hout A j).
82
+ Proof.
83
+ intros i j Hij Hj.
84
+ pose proof (boff_mono (hblocks A) (tb A + 12) (tb A + 11) ltac:(lia) ltac:(rewrite len_hb; lia)) as B1.
85
+ pose proof (boff_mono (hblocks A) (tb A + 14) (tb A + 12) ltac:(lia) ltac:(rewrite len_hb; lia)) as B2.
86
+ rewrite (bcount_post A HA 11), (bsize_post A HA 11) in B1 by lia.
87
+ rewrite (bcount_post A HA 12), (bsize_post A HA 12) in B2 by lia.
88
+ cbn [nth hpost bcount bsize blk_NP blk_HAB] in B1, B2.
89
+ unfold hout.
90
+ destruct (Nat.ltb_spec i A), (Nat.ltb_spec j A); try destruct (Nat.eqb_spec i A); try destruct (Nat.eqb_spec j A);
91
+ cbn [idx]; rewrite ?(bsize_post A HA 11), ?(bsize_post A HA 12), ?(bsize_post A HA 14) by lia;
92
+ cbn [nth hpost bsize blk_NP blk_HAB blk_NM]; lia.
93
+ Qed.
94
+
95
+ Lemma host_next_sorted : StronglySorted lt (host_next A).
96
+ Proof.
97
+ unfold host_next. apply sorted_map_seq. intros i j _ Hij Hj. apply hout_mono; lia.
98
+ Qed.
99
+
100
+ Theorem next_tbl_lin_eq : next_tbl_lin n (length us) (host_next A) = next_tbl n (length us) (host_next A).
101
+ Proof.
102
+ apply (nth_ext _ _ None None).
103
+ - unfold next_tbl_lin. rewrite length_tbl_merge, (proj1 (nt_spec A HA)). reflexivity.
104
+ - intros u Hu. unfold next_tbl_lin in *. rewrite length_tbl_merge in Hu.
105
+ rewrite (proj2 (nt_spec A HA) u Hu). rewrite nth_tbl_merge; [reflexivity | | | exact Hu].
106
+ + apply sorted_combine; [rewrite length_seq, length_host_next; reflexivity | exact host_next_sorted].
107
+ + apply Forall_forall. intros p Hp. rewrite <- length_host_next in Hp.
108
+ destruct (in_combine_seq (host_next A) p Hp) as [H1 H2]. rewrite H2. rewrite length_host_next in H1.
109
+ exact (proj1 (host_next_range A HA (fst p) H1)).
110
+ Qed.
111
+
112
+ End Host.
113
+
114
+ (* ---- the image of the stored host with the table in one pass ------------------------------------------ *)
115
+ Definition stored_of_lin (A w : nat) (us : list tu) (nx m : list nat) : list rec * nat :=
116
+ let nu := length us in
117
+ let lv := levels us in
118
+ let al := Nat.log2_up (ncells A w nu lv) in
119
+ let body := startup A w m ++ step_go A w nu 0 us (next_tbl_lin (nH A) nu nx) ++ device A w nu lv in
120
+ (body ++ repeat EMPTY (padn al (length body)) ++ handover A w, al).
121
+
122
+ Definition stored_bits_lin (A w : nat) : list bool :=
123
+ let sa := stored_of_lin A w (host_units A) (host_next A) (image A (progPstar A)) in
124
+ concat (map (enc_recA (snd sa)) (fst sa)).
125
+
126
+ Theorem stored_bits_lin_eq : forall A w, 3 <= A -> stored_bits_lin A w = stored_bits A w.
127
+ Proof.
128
+ intros A w HA. unfold stored_bits_lin, stored_bits, stored_of_lin, stored_of. cbv zeta.
129
+ rewrite (next_tbl_lin_eq A HA). reflexivity.
130
+ Qed.
rocq/StoredImage.v CHANGED
@@ -1,8 +1,8 @@
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.
@@ -84,7 +84,7 @@ Proof. intros A w. apply bytes_lt. Qed.
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 => []
@@ -116,15 +116,6 @@ 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 _].
 
1
+ (* The image of the stored host as a byte string, and recipes of byte strings by literal tokens (Lemma 4.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 Recipe.
6
 
7
  (* ---- bits and bytes --------------------------------------------------------------------------------------- *)
8
  Lemma nat2bits_bits2nat : forall l, nat2bits (length l) (bits2nat l) = l.
 
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 4.2 ------------------------------------------------------------------- *)
88
  Fixpoint chunks (fuel : nat) (f : list nat) : list (list nat) :=
89
  match fuel with
90
  | O => []
 
116
 
117
  Definition lits (f : list nat) : list token := map (fun c => Lit (map nu c)) (chunks (length f) f).
118
 
 
 
 
 
 
 
 
 
 
119
  Lemma lits_ok : forall f, Forall tok_ok (lits f).
120
  Proof.
121
  intro f. unfold lits. apply Forall_map, Forall_forall. intros c Hc. destruct (chunks_ok _ _ _ Hc) as [Hl _].
rocq/StoredProp.v ADDED
@@ -0,0 +1,332 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (* Proposition 8.5 in one statement: from every state of the ring machine whose window holds a state of H_A,
2
+ its registers and clear requests, whatever the other cells hold, a pass of S_{A,w} loads x_0(m*_A), clears
3
+ the registers, the idle bank and the copy tape and returns the heads if booted is 0, carries out one step
4
+ of H_A and the device of Definition 8.4, and sets booted to the negation of the halt bit; at the halt it
5
+ returns the arm and the copy head and hands over at its G-th step, and otherwise its S steps bring the slot
6
+ head back to slot 0. *)
7
+ From Stdlib Require Import List Bool Arith ZArith Lia.
8
+ Import ListNotations.
9
+ From TH Require Import TwoHead Net Abstract Indep Run PhysSem PhysMain View Stored WinRun WinPar ViewOps Host HostWF
10
+ HostSem HostIP Device Pstar StoredStep StoredBoot StoredDev StoredPass StoredOk StoredRun.
11
+
12
+ (* ---- the device of Definition 8.4 on the host's state, its registers and the three heads ------------------ *)
13
+ Record sdst := mkSD { sy : hst; scnt : nat; slim : nat; sdest : bool; srd : tape; sarm : tape; scpy : tape }.
14
+
15
+ Section Dev84.
16
+ Variables (A w Lb L : nat).
17
+
18
+ (* the byte under the read head, most significant bit first *)
19
+ Definition rbyte (R : tape) : nat := bits2nat (map (fun k => nth (adv L k (th R)) (td R) false) (seq 0 8)).
20
+
21
+ Definition sdevice (x : sdst) : sdst :=
22
+ let y := sy x in
23
+ let wr := Nat.eqb (memv y (cwr A)) 1 in
24
+ let rd := Nat.eqb (memv y (crd A)) 1 in
25
+ let rw := Nat.eqb (memv y (crw A)) 1 in
26
+ let eot := sdest x && Nat.eqb (scnt x) (slim x) in
27
+ let g := rd && negb eot in
28
+ let c1 := if g then S (scnt x) mod 2 ^ w else scnt x in
29
+ let ob := nat2bits 8 (memv y (rout A)) in
30
+ let y1 := if wr then setm A y (rout A) 0 else y in
31
+ let y2 := if rd then (if eot then setm A y1 (ceot A) 1
32
+ else setm A (setm A y1 (rin A) (sext A (rbyte (srd x)))) (ceot A) 0) else y1 in
33
+ mkSD (setm A (setm A (setm A y2 (cwr A) 0) (crd A) 0) (crw A) 0)
34
+ (if rw then 0 else c1) (if rw then c1 else slim x) (sdest x || rw)
35
+ (mkT (td (srd x)) (if rw then 0 else if g then adv L 8 (th (srd x)) else th (srd x)))
36
+ (if wr && negb (sdest x) then wseq Lb ob (sarm x) else sarm x)
37
+ (if wr && sdest x then wseq L ob (scpy x) else scpy x).
38
+
39
+ (* the cells of the window that hold the state of the host and its registers *)
40
+ Definition srel (ww : list bool) (x : sdst) : Prop :=
41
+ holds A w ww (sy x) /\ hvalid A (sy x) /\ scnt x < 2 ^ w /\ slim x < 2 ^ w
42
+ /\ (forall i, i < w -> wget ww (CNT i) = Nat.testbit (scnt x) i)
43
+ /\ (forall i, i < w -> wget ww (LIM w i) = Nat.testbit (slim x) i)
44
+ /\ wget ww (DEST w) = sdest x.
45
+
46
+ (* the startup, the step of H_A and the device *)
47
+ Definition sboot (b : bool) (x : sdst) : sdst :=
48
+ if b then x
49
+ else mkSD (x0m (image A (progPstar A))) 0 0 false (mkT (td (srd x)) 0) (mkT (repeat false Lb) 0) (mkT (repeat false L) 0).
50
+
51
+ Definition sstep (x : sdst) : sdst := mkSD (subleq A (sy x)) (scnt x) (slim x) (sdest x) (srd x) (sarm x) (scpy x).
52
+
53
+ Definition spass (b : bool) (x : sdst) : sdst := sdevice (sstep (sboot b x)).
54
+
55
+ End Dev84.
56
+
57
+ (* ---- a pass of the records on a view ----------------------------------------------------------------------- *)
58
+ Section ViewPass.
59
+ Variables (A w Lb L : nat).
60
+ Hypotheses (HA : 8 <= A) (Hw : 1 <= w) (HL : 1 <= L).
61
+
62
+ Local Notation W := (2 ^ alS A w).
63
+ Local Notation m := (image A (progPstar A)).
64
+ Local Notation nu := (length (host_units A)).
65
+ Local Notation lvs := (levels (host_units A)).
66
+
67
+ Lemma rbyte_lt : forall R, rbyte L R < 256.
68
+ Proof.
69
+ intro R. unfold rbyte. pose proof (bits2nat_lt (map (fun k => nth (adv L k (th R)) (td R) false) (seq 0 8))) as H.
70
+ rewrite length_map, length_seq in H. exact H.
71
+ Qed.
72
+
73
+ Lemma testbit_rbyte : forall R t, t < 8 -> Nat.testbit (rbyte L R) t = nth (adv L (7 - t) (th R)) (td R) false.
74
+ Proof.
75
+ intros R t Ht. unfold rbyte.
76
+ set (l := map (fun k => nth (adv L k (th R)) (td R) false) (seq 0 8)).
77
+ assert (Hl : length l = 8) by (unfold l; rewrite length_map, length_seq; reflexivity).
78
+ pose proof (testbit_bits2nat l (7 - t) ltac:(lia)) as E. rewrite Hl in E.
79
+ replace (8 - 1 - (7 - t)) with t in E by lia. rewrite E. unfold l.
80
+ rewrite (nth_map_seq _ (fun k => nth (adv L k (th R)) (td R) false) 8 (7 - t) false) by lia. reflexivity.
81
+ Qed.
82
+
83
+ Lemma memv_sdevice : forall x j, j < SW A ->
84
+ let y := sy x in
85
+ let rd := Nat.eqb (memv y (crd A)) 1 in
86
+ let eot := sdest x && Nat.eqb (scnt x) (slim x) in
87
+ memv (sy (sdevice A w Lb L x)) j =
88
+ if Nat.eqb j (cwr A) || Nat.eqb j (crd A) || Nat.eqb j (crw A) then 0
89
+ else if Nat.eqb j (rout A) then (if Nat.eqb (memv y (cwr A)) 1 then 0 else memv y j)
90
+ else if Nat.eqb j (rin A) then (if rd && negb eot then sext A (rbyte L (srd x)) else memv y j)
91
+ else if Nat.eqb j (ceot A) then (if rd then (if eot then 1 else 0) else memv y j)
92
+ else memv y j.
93
+ Proof.
94
+ intros x j Hj y rd eot. pose proof (SW256 A HA) as HS. unfold sdevice. fold y rd eot. cbv zeta. cbn [sy].
95
+ rewrite !setm_mem by exact Hj.
96
+ destruct rd, eot, (Nat.eqb (memv y (cwr A)) 1); cbn [andb negb]; rewrite ?setm_mem by exact Hj;
97
+ unfold cwr, crd, crw, rout, rin, ceot in *;
98
+ repeat match goal with |- context [Nat.eqb ?a ?b] => destruct (Nat.eqb_spec a b) end;
99
+ cbn [orb]; try lia; reflexivity.
100
+ Qed.
101
+
102
+ Lemma sdevice_pc : forall x, hpc (sy (sdevice A w Lb L x)) = hpc (sy x) /\ hhalt (sy (sdevice A w Lb L x)) = hhalt (sy x)
103
+ /\ length (hmem (sy (sdevice A w Lb L x))) = SW A.
104
+ Proof.
105
+ intro x. unfold sdevice. cbv zeta. cbn [sy]. split; [|split; [|apply setm_len]]; unfold setm; cbn [hpc hhalt];
106
+ destruct (Nat.eqb (memv (sy x) (crd A)) 1), (sdest x && Nat.eqb (scnt x) (slim x)), (Nat.eqb (memv (sy x) (cwr A)) 1);
107
+ reflexivity.
108
+ Qed.
109
+
110
+ Lemma sdevice_valid : forall x, hvalid A (sy x) -> hvalid A (sy (sdevice A w Lb L x)).
111
+ Proof.
112
+ intros x Hv. pose proof (SW256 A HA) as HS.
113
+ assert (H1 : hvalid A (if Nat.eqb (memv (sy x) (cwr A)) 1 then setm A (sy x) (rout A) 0 else sy x))
114
+ by (destruct (Nat.eqb _ 1); [apply (setm_valid A HA); [exact Hv | lia] | exact Hv]).
115
+ unfold sdevice. cbv zeta. cbn [sy].
116
+ apply (setm_valid A HA); [|lia]. apply (setm_valid A HA); [|lia]. apply (setm_valid A HA); [|lia].
117
+ destruct (Nat.eqb (memv (sy x) (crd A)) 1); [|exact H1].
118
+ destruct (sdest x && Nat.eqb (scnt x) (slim x)); [apply (setm_valid A HA); [exact H1 | lia]|].
119
+ apply (setm_valid A HA); [|lia]. apply (setm_valid A HA); [exact H1|]. apply sext_lt; [exact HA | apply rbyte_lt].
120
+ Qed.
121
+
122
+ (* the startup *)
123
+ Lemma startup_rel : forall v x, reqclear (vw v) -> length (vw v) = W -> srel A w (vw v) x ->
124
+ srd x = vr v -> sarm x = va v -> scpy x = vc v ->
125
+ let b := wget (vw v) BOOT in
126
+ let u := vrun Lb L (startup A w m) v in
127
+ reqclear (vw u) /\ length (vw u) = W /\ wget (vw u) BOOT = true /\ srel A w (vw u) (sboot A Lb L b x)
128
+ /\ vr u = srd (sboot A Lb L b x) /\ va u = sarm (sboot A Lb L b x) /\ vc u = scpy (sboot A Lb L b x)
129
+ /\ vho u = vho v.
130
+ Proof.
131
+ intros v x Hq Hl Hr ER EA EC. cbv zeta. destruct (wget (vw v) BOOT) eqn:Eb.
132
+ - rewrite (startup_booted A w Lb L HA Hw v Hq Hl Eb). cbn [sboot].
133
+ exact (conj Hq (conj Hl (conj Eb (conj Hr (conj (eq_sym ER) (conj (eq_sym EA) (conj (eq_sym EC) eq_refl))))))).
134
+ - pose proof (startup_run A w W Lb L m ltac:(lia) (length_image A) (HWs A w HA Hw) v Hq Hl) as U. cbv zeta in U.
135
+ destruct U as (Q & L1 & B1 & S1 & R1 & D1 & _ & VR & VA & VC & VH). rewrite Eb in S1, R1, D1, VR, VA, VC.
136
+ cbn [sboot sy scnt slim sdest srd sarm scpy].
137
+ refine (conj Q (conj L1 (conj B1 (conj _ (conj _ (conj VA (conj VC VH))))))).
138
+ + unfold srel. cbn [sy scnt slim sdest].
139
+ refine (conj _ (conj (init_valid A HA) (conj _ (conj _ (conj _ (conj _ _)))))).
140
+ * intros i Hi. rewrite S1 by exact Hi. reflexivity.
141
+ * pose proof (Nat.pow_nonzero 2 w ltac:(lia)). lia.
142
+ * pose proof (Nat.pow_nonzero 2 w ltac:(lia)). lia.
143
+ * intros i Hi. rewrite (proj1 (R1 i Hi)), andb_false_r, Nat.bits_0. reflexivity.
144
+ * intros i Hi. rewrite (proj2 (R1 i Hi)), andb_false_r, Nat.bits_0. reflexivity.
145
+ * rewrite D1, andb_false_r. reflexivity.
146
+ + rewrite VR, ER. reflexivity.
147
+ Qed.
148
+
149
+ (* a pass of the records: the startup, the step of H_A, the device, the padding and the hand-over *)
150
+ Theorem view_pass : forall v x, reqclear (vw v) -> length (vw v) = W -> srel A w (vw v) x ->
151
+ srd x = vr v -> sarm x = va v -> scpy x = vc v ->
152
+ let x' := spass A w Lb L (wget (vw v) BOOT) x in
153
+ let h := hhalt (sy x') in
154
+ let v' := vrun Lb L (stored A w) v in
155
+ reqclear (vw v') /\ length (vw v') = W /\ srel A w (vw v') x' /\ wget (vw v') BOOT = negb h
156
+ /\ vr v' = srd x' /\ va v' = (if h then mkT (td (sarm x')) 0 else sarm x')
157
+ /\ vc v' = (if h then mkT (td (scpy x')) 0 else scpy x') /\ vho v' = vho v || h.
158
+ Proof.
159
+ intros v x Hq Hl Hr ER EA EC. cbv zeta.
160
+ pose proof (startup_rel v x Hq Hl Hr ER EA EC) as SU. cbv zeta in SU.
161
+ destruct SU as (Q1 & L1 & B1 & R1 & VR1 & VA1 & VC1 & VH1).
162
+ set (x1 := sboot A Lb L (wget (vw v) BOOT) x) in *.
163
+ set (u1 := vrun Lb L (startup A w m) v) in *.
164
+ unfold spass. fold x1.
165
+ rewrite (stored_split A w), !vrun_app. fold u1.
166
+ destruct R1 as (Hs1 & Hv1 & Hc1 & Hm1 & C1 & M1 & D1).
167
+ pose proof (SW256 A HA) as HS. pose proof (io_lt A w W HA Hw (HW A w HA Hw)) as (I1 & I2 & I3 & I4 & I5 & I6).
168
+ (* the step of H_A *)
169
+ pose proof (step_view A w Lb L HA Hw u1 (sy x1) Q1 L1 Hs1 Hv1) as SV. cbv zeta in SV.
170
+ destruct SV as (Q2 & L2 & S2 & U2 & VR2 & VA2 & VC2 & VH2).
171
+ set (u2 := vrun Lb L (step_go A w nu 0 (host_units A) (next_tbl (nH A) nu (host_next A))) u1) in *.
172
+ set (y := subleq A (sy x1)) in *.
173
+ assert (Hvy : hvalid A y) by (apply subleq_valid; assumption).
174
+ pose proof Hvy as (_ & Hly & _).
175
+ assert (C2 : forall i, i < w -> wget (vw u2) (CNT i) = Nat.testbit (scnt x1) i)
176
+ by (intros i Hi; rewrite U2 by (left; unfold CNT, ST; lia); apply C1, Hi).
177
+ assert (M2 : forall i, i < w -> wget (vw u2) (LIM w i) = Nat.testbit (slim x1) i)
178
+ by (intros i Hi; rewrite U2 by (left; unfold LIM, ST; lia); apply M1, Hi).
179
+ assert (D2 : wget (vw u2) (DEST w) = sdest x1) by (rewrite U2 by (left; unfold DEST, ST; lia); exact D1).
180
+ assert (B2 : wget (vw u2) BOOT = true) by (rewrite U2 by (left; unfold BOOT, ST; lia); exact B1).
181
+ (* what the device reads *)
182
+ set (wrb := Nat.eqb (memv y (cwr A)) 1). set (rdb := Nat.eqb (memv y (crd A)) 1).
183
+ set (rwb := Nat.eqb (memv y (crw A)) 1). set (eot := sdest x1 && Nat.eqb (scnt x1) (slim x1)).
184
+ assert (WR : wrv A w (vw u2) = wrb) by (apply word1v_holds; assumption).
185
+ assert (RD : rdv A w (vw u2) = rdb) by (apply word1v_holds; assumption).
186
+ assert (RW : rwv A w (vw u2) = rwb) by (apply word1v_holds; assumption).
187
+ assert (EQ : eqv w (vw u2) = Nat.eqb (scnt x1) (slim x1)) by (apply (regs_eq A w HA Hw); assumption).
188
+ assert (EO : eotv w (vw u2) = eot) by (unfold eotv, destv, eot; rewrite EQ, D2; apply andb_comm).
189
+ assert (G : gv A w (vw u2) = rdb && negb eot) by (unfold gv; rewrite RD, EO; reflexivity).
190
+ assert (CA : cav A w (vw u2) = wrb && negb (sdest x1)) by (unfold cav, destv; rewrite WR, D2; reflexivity).
191
+ assert (CC : ccv A w (vw u2) = wrb && sdest x1) by (unfold ccv, destv; rewrite WR, D2; reflexivity).
192
+ assert (CN : forall i, i < w -> cntv A w (vw u2) i = Nat.testbit (if rdb && negb eot then S (scnt x1) else scnt x1) i)
193
+ by (intros i Hi; rewrite (cntv_eq A w HA Hw (vw u2) (scnt x1) C2 i Hi), G; reflexivity).
194
+ assert (OB : outbits A w (vw u2) = nat2bits 8 (memv y (rout A))) by (apply outbits_eq; assumption).
195
+ (* the device *)
196
+ pose proof (device_run A w W Lb L HA Hw (HW A w HA Hw) u2 Q2 L2) as DV. cbv zeta in DV.
197
+ destruct DV as (Q3 & L3 & H3 & A3 & C3 & R3 & RO3 & RI3 & CE03 & CE3 & RQ3 & CL3 & D3 & U3).
198
+ set (u3 := vrun Lb L (Stored.device A w nu lvs) u2) in *.
199
+ rewrite (pad_run Lb L _ u3 Q3).
200
+ (* the hand-over *)
201
+ assert (HWh : 15 + 2 * w + A < W) by (pose proof (HWs A w HA Hw); unfold nH in *; nia).
202
+ pose proof (handover_run A w W Lb L HWh u3 Q3 L3) as HO3. cbv zeta in HO3.
203
+ destruct HO3 as (Q4 & L4 & U4 & R4 & A4 & C4 & H4).
204
+ set (u4 := vrun Lb L (handover A w) u3) in *.
205
+ assert (Hh3 : wget (vw u3) (ST w A) = hhalt y).
206
+ { rewrite U3 by (apply ST_ndevw; lia). rewrite S2 by (unfold nH; lia). apply nth_encodeH_halt. }
207
+ rewrite Hh3 in U4, A4, C4, H4.
208
+ assert (W4 : forall c, c <> BOOT -> wget (vw u4) c = wget (vw u3) c)
209
+ by (intros c Hc; rewrite U4, (proj2 (Nat.eqb_neq _ _) Hc); reflexivity).
210
+ (* the state the device leaves *)
211
+ pose proof (sdevice_pc (sstep A x1)) as (Dp & Dh & Dl).
212
+ pose proof (sdevice_valid (sstep A x1) Hvy) as Dv.
213
+ pose proof (fun j Hj => memv_sdevice (sstep A x1) j Hj) as Dm. cbv zeta in Dm.
214
+ remember (sdevice A w Lb L (sstep A x1)) as x3 eqn:Ex3.
215
+ assert (Fc : scnt x3 = if rwb then 0 else if rdb && negb eot then S (scnt x1) mod 2 ^ w else scnt x1)
216
+ by (rewrite Ex3; reflexivity).
217
+ assert (Fl : slim x3 = if rwb then (if rdb && negb eot then S (scnt x1) mod 2 ^ w else scnt x1) else slim x1)
218
+ by (rewrite Ex3; reflexivity).
219
+ assert (Fd : sdest x3 = sdest x1 || rwb) by (rewrite Ex3; reflexivity).
220
+ assert (FR : srd x3 = mkT (td (srd x1)) (if rwb then 0 else if rdb && negb eot then adv L 8 (th (srd x1)) else th (srd x1)))
221
+ by (rewrite Ex3; reflexivity).
222
+ assert (FI : sarm x3 = if wrb && negb (sdest x1) then wseq Lb (nat2bits 8 (memv y (rout A))) (sarm x1) else sarm x1)
223
+ by (rewrite Ex3; reflexivity).
224
+ assert (FC : scpy x3 = if wrb && sdest x1 then wseq L (nat2bits 8 (memv y (rout A))) (scpy x1) else scpy x1)
225
+ by (rewrite Ex3; reflexivity).
226
+ change (hhalt (sy (sstep A x1))) with (hhalt y) in Dh. change (hpc (sy (sstep A x1))) with (hpc y) in Dp.
227
+ rewrite Dh.
228
+ refine (conj Q4 (conj L4 (conj _ (conj _ (conj _ (conj _ (conj _ _))))))).
229
+ - (* the state of the host and the registers *)
230
+ refine (conj _ (conj Dv (conj _ (conj _ (conj _ (conj _ _)))))).
231
+ + apply (holds_of A w HA Hw); [exact Dl | | |].
232
+ * intros i Hi. rewrite W4 by (unfold ST, BOOT; lia). rewrite U3 by (apply ST_ndevw; lia).
233
+ rewrite S2 by (unfold nH; lia). rewrite nth_encodeH_pc by exact Hi. rewrite Dp. reflexivity.
234
+ * rewrite W4 by (unfold ST, BOOT; lia). rewrite Hh3. symmetry. exact Dh.
235
+ * intros j t Hj Ht. rewrite W4 by (pose proof (MB_range A w W HA Hw (HW A w HA Hw) j t Hj Ht); unfold BOOT; lia).
236
+ rewrite (Dm j Hj). cbn [sstep sy scnt slim sdest srd]. fold y wrb rdb eot.
237
+ destruct (Nat.eqb_spec j (cwr A)) as [->|N1].
238
+ { cbn [orb]. rewrite RQ3 by (auto; lia). rewrite Nat.bits_0. reflexivity. }
239
+ destruct (Nat.eqb_spec j (crd A)) as [->|N2].
240
+ { cbn [orb]. rewrite RQ3 by (auto; lia). rewrite Nat.bits_0. reflexivity. }
241
+ destruct (Nat.eqb_spec j (crw A)) as [->|N3].
242
+ { cbn [orb]. rewrite RQ3 by (auto; lia). rewrite Nat.bits_0. reflexivity. }
243
+ cbn [orb].
244
+ destruct (Nat.eqb_spec j (rout A)) as [->|N4].
245
+ { rewrite RO3 by exact Ht. rewrite (holds_MB A w HA Hw (vw u2) y (rout A) t S2 Hly I6 Ht), WR.
246
+ destruct wrb; cbn [negb]; [rewrite andb_false_r, Nat.bits_0 | rewrite andb_true_r]; reflexivity. }
247
+ destruct (Nat.eqb_spec j (rin A)) as [->|N5].
248
+ { rewrite RI3 by exact Ht. rewrite G, VR2, VR1.
249
+ destruct (rdb && negb eot) eqn:Eg.
250
+ - rewrite testbit_sext by (try assumption; apply rbyte_lt).
251
+ destruct (Nat.lt_ge_cases t 8) as [T8|T8].
252
+ + rewrite testbit_rbyte by lia. f_equal. f_equal. lia.
253
+ + rewrite testbit_rbyte by lia. replace (7 - t) with 0 by lia. reflexivity.
254
+ - apply (holds_MB A w HA Hw (vw u2) y (rin A) t S2 Hly I5 Ht). }
255
+ destruct (Nat.eqb_spec j (ceot A)) as [->|N6].
256
+ { destruct (Nat.eq_dec t 0) as [->|Ht0].
257
+ - rewrite CE03, RD, EO. destruct rdb; [destruct eot; reflexivity|].
258
+ apply (holds_MB A w HA Hw (vw u2) y (ceot A) 0 S2 Hly I2 Ht).
259
+ - rewrite CE3 by lia. rewrite RD, (holds_MB A w HA Hw (vw u2) y (ceot A) t S2 Hly I2 Ht).
260
+ destruct rdb; cbn [negb]; [rewrite andb_false_r | rewrite andb_true_r; reflexivity].
261
+ destruct eot; [|rewrite Nat.bits_0; reflexivity]. symmetry. apply testbit_lt_false.
262
+ apply (Nat.lt_le_trans _ (2 ^ 1)); [cbn; lia | apply Nat.pow_le_mono_r; lia]. }
263
+ rewrite U3 by (apply MB_ndevw; assumption). apply (holds_MB A w HA Hw); assumption.
264
+ + rewrite Fc. destruct rwb; [pose proof (Nat.pow_nonzero 2 w ltac:(lia)); lia|].
265
+ destruct (rdb && negb eot); [apply Nat.mod_upper_bound, Nat.pow_nonzero; lia | exact Hc1].
266
+ + rewrite Fl. destruct rwb; [|exact Hm1].
267
+ destruct (rdb && negb eot); [apply Nat.mod_upper_bound, Nat.pow_nonzero; lia | exact Hc1].
268
+ + intros i Hi. rewrite W4 by (unfold CNT, BOOT; lia). rewrite (proj1 (CL3 i Hi)), CN, RW, Fc by exact Hi.
269
+ destruct rwb; cbn [negb]; [rewrite andb_false_r, Nat.bits_0; reflexivity | rewrite andb_true_r].
270
+ destruct (rdb && negb eot); [|reflexivity]. symmetry. apply Nat.mod_pow2_bits_low. exact Hi.
271
+ + intros i Hi. rewrite W4 by (unfold LIM, BOOT; lia). rewrite (proj2 (CL3 i Hi)), RW, Fl.
272
+ destruct rwb; [|apply M2; exact Hi]. rewrite CN by exact Hi.
273
+ destruct (rdb && negb eot); [|reflexivity]. symmetry. apply Nat.mod_pow2_bits_low. exact Hi.
274
+ + rewrite W4 by (unfold DEST, BOOT; lia). rewrite D3, Fd. unfold destv. rewrite D2, RW. reflexivity.
275
+ - (* booted *)
276
+ rewrite U4, Nat.eqb_refl. rewrite U3.
277
+ + rewrite B2. reflexivity.
278
+ + unfold devw. intro H. unfold BOOT, DB, CNT, LIM, DEST, MB, ST in *.
279
+ destruct H as [H|[(j & Hj & [E|E])|[E|(c0 & t & _ & Ht & E)]]]; lia.
280
+ - (* the read tape *)
281
+ rewrite R4, R3, VR2, VR1, RW, G, FR. reflexivity.
282
+ - (* the arm *)
283
+ rewrite A4, A3, VA2, VA1, CA, OB, FI. reflexivity.
284
+ - (* the copy tape *)
285
+ rewrite C4, C3, VC2, VC1, CC, OB, FC. reflexivity.
286
+ - (* the hand-over *)
287
+ rewrite H4, H3, VH2, VH1. reflexivity.
288
+ Qed.
289
+
290
+ End ViewPass.
291
+
292
+ (* ---- Proposition 8.5: the pass on the machine --------------------------------------------------------------- *)
293
+ Section MachPass.
294
+ Variables (A w K S0 L : nat).
295
+ Hypotheses (HA : 8 <= A) (Hw : 1 <= w) (HK : 2 <= K) (HS : length (stored A w) <= S0) (HL : 1 <= L).
296
+
297
+ Local Notation al := (alS A w).
298
+ Local Notation G := (length (stored A w)).
299
+ Local Notation Lb := (S0 * recw (alS A w)).
300
+
301
+ Theorem stored_pass : forall s0 x, fits al K S0 L s0 ->
302
+ bq (nth (kap s0) (banks s0) bank0) = img A w S0 -> bs (nth (kap s0) (banks s0) bank0) = 0 ->
303
+ reqclear (win s0) -> srel A w (win s0) x -> srd x = nth (kap s0) (tapes s0) tape0 ->
304
+ sarm x = lin al (nth (succ_mod K (kap s0)) (banks s0) bank0) -> scpy x = nth (succ_mod K (kap s0)) (tapes s0) tape0 ->
305
+ let x' := spass A w Lb L (wget (win s0) BOOT) x in
306
+ let h := hhalt (sy x') in
307
+ let s := itern al K S0 L (if h then G else S0) s0 in
308
+ fits al K S0 L s /\ reqclear (win s) /\ srel A w (win s) x' /\ wget (win s) BOOT = negb h
309
+ /\ kap s = (if h then succ_mod K (kap s0) else kap s0)
310
+ /\ nth (kap s0) (banks s) bank0 = mkB (img A w S0) (if h then G mod S0 else 0) (bj (nth (kap s0) (banks s0) bank0))
311
+ /\ nth (kap s0) (tapes s) tape0 = srd x'
312
+ /\ lin al (nth (succ_mod K (kap s0)) (banks s) bank0) = (if h then mkT (td (sarm x')) 0 else sarm x')
313
+ /\ nth (succ_mod K (kap s0)) (tapes s) tape0 = (if h then mkT (td (scpy x')) 0 else scpy x')
314
+ /\ (forall y, y < K -> y <> kap s0 -> y <> succ_mod K (kap s0) ->
315
+ nth y (banks s) bank0 = nth y (banks s0) bank0 /\ nth y (tapes s) tape0 = nth y (tapes s0) tape0).
316
+ Proof.
317
+ intros s0 x Hf Hb Hs Hq Hr ER EA EC x' h s.
318
+ assert (Hl0 : length (vw (view0 al K s0)) = 2 ^ al) by (destruct Hf as (Hl & _); exact Hl).
319
+ pose proof (view_pass A w Lb L HA Hw HL (view0 al K s0) x Hq Hl0 Hr ER EA EC) as VP. cbv zeta in VP.
320
+ fold x' h in VP. destruct VP as (Q & Ll & Rr & Bt & VR & VA & VC & VH).
321
+ assert (VH' : vho (vrun Lb L (stored A w) (view0 al K s0)) = h) by (rewrite VH; reflexivity).
322
+ pose proof (machine_pass_gen A w K S0 L HA Hw HK HS HL s0 h Hf Hb Hs Hq Q VH') as M. fold s in M.
323
+ destruct M as (Hfs & Hws & Hks & Has & His & Hrs & Hcs & Hos). rewrite VH' in Hks.
324
+ rewrite <- Hws in Q, Rr, Bt.
325
+ refine (conj Hfs (conj Q (conj Rr (conj Bt (conj Hks (conj _ (conj _ (conj _ (conj _ Hos))))))))).
326
+ - rewrite Has, Hb, Hs, Nat.add_0_l. destruct h; [reflexivity|]. rewrite Nat.Div0.mod_same. reflexivity.
327
+ - rewrite Hrs. exact VR.
328
+ - rewrite His. exact VA.
329
+ - rewrite Hcs. exact VC.
330
+ Qed.
331
+
332
+ End MachPass.
rocq/StoredRun.v CHANGED
@@ -373,12 +373,12 @@ Proof.
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.
@@ -404,6 +404,14 @@ Proof.
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.
 
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_gen : forall s0 h,
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) -> reqclear (vw (vrun Lb L rs (view0 al K s0))) -> vho (vrun Lb L rs (view0 al K s0)) = h ->
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 Hf Hb Hs Hq 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.
 
404
  rewrite firstn_all2 in M by (rewrite length_app, repeat_length; lia). rewrite Hfull in M. exact M.
405
  Qed.
406
 
407
+ Lemma machine_pass : forall s0 h c o1 o2,
408
+ fits al K S0 L s0 -> bq (nth (kap s0) (banks s0) bank0) = img -> bs (nth (kap s0) (banks s0) bank0) = 0 ->
409
+ reqclear (win s0) -> Rv A w Lb L h c o1 o2 (vrun Lb L rs (view0 al K s0)) ->
410
+ 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)).
411
+ Proof.
412
+ intros s0 h c o1 o2 Hf Hb Hs Hq (Q & _ & Hh & _). exact (machine_pass_gen s0 h Hf Hb Hs Hq Q Hh).
413
+ Qed.
414
+
415
  (* a pass that does not hand over leaves the state it started from but for the window, the idle bank and the
416
  copy tape, and the view it ends in is the view of the next pass *)
417
  Lemma bank_eta0 : forall q, bs q = 0 -> mkB (bq q) 0 (bj q) = q.
rocq/_CoqProject CHANGED
@@ -25,6 +25,21 @@ Adder.v
25
  HostSem.v
26
  Device.v
27
  Pstar.v
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  ExtractHost.v
29
  HostIP.v
30
  View.v
@@ -38,8 +53,12 @@ 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
 
25
  HostSem.v
26
  Device.v
27
  Pstar.v
28
+ Recipe.v
29
+ Lower.v
30
+ Lev.v
31
+ BlockLev.v
32
+ HostLev.v
33
+ HostCount.v
34
+ PhysLev.v
35
+ Margin.v
36
+ Erfc.v
37
+ Choose.v
38
+ Noise.v
39
+ NoiseNum.v
40
+ Restore.v
41
+ FlipLower.v
42
+ AmpHost.v
43
  ExtractHost.v
44
  HostIP.v
45
  View.v
 
53
  StoredPass.v
54
  StoredOk.v
55
  StoredRun.v
56
+ StoredProp.v
57
  StoredWbr.v
58
  StoredMain.v
59
  StoredImage.v
60
  StoredWidth.v
61
+ StoredCount.v
62
+ StoredFast.v
63
+ ExtrNat.v
64
  ExtractStored.v
rocq/extract/dumpstored.ml CHANGED
@@ -1,8 +1,8 @@
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))
 
1
+ (* writes the image of the stored host, stored_bits_lin of StoredFast.v, equal to stored_bits of Stored.v,
2
+ extracted by ExtractStored.v, as bytes, most 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_lin 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))
src/independent.py CHANGED
@@ -47,7 +47,7 @@ def build(A, fold=False):
47
  N = Net(n)
48
 
49
  def sel(bits, j, extra=()):
50
- # the decode line [bits == j] as one conjunction of literals, Lemma 3.6
51
  lits = [(bits[i], bool((j >> i) & 1)) for i in range(A)] + list(extra)
52
  return N.AND(*lits)
53
 
 
47
  N = Net(n)
48
 
49
  def sel(bits, j, extra=()):
50
+ # the decode line [bits == j] as one conjunction of literals, Lemma 3.5
51
  lits = [(bits[i], bool((j >> i) & 1)) for i in range(A)] + list(extra)
52
  return N.AND(*lits)
53
 
src/netlist_eval.c CHANGED
@@ -22,7 +22,7 @@
22
  * indices, all little-endian int32. For the host family the state is the A
23
  * counter bits, the halt bit and 2^A words of A bits, most significant bit
24
  * first, and A is recovered from n = A + 1 + A 2^A. For the amplified host of
25
- * Section 6.3 the state is R copies of that, copy c occupying the block
26
  * c n0 .. (c+1) n0 - 1, and (R, A) is recovered from n = R (A + 1 + A 2^A) with
27
  * the smallest R; the device reads each bit of a cell as the majority of its
28
  * copies and writes every copy, and rand replicates each random state and
 
22
  * indices, all little-endian int32. For the host family the state is the A
23
  * counter bits, the halt bit and 2^A words of A bits, most significant bit
24
  * first, and A is recovered from n = A + 1 + A 2^A. For the amplified host of
25
+ * Section 6.2 the state is R copies of that, copy c occupying the block
26
  * c n0 .. (c+1) n0 - 1, and (R, A) is recovered from n = R (A + 1 + A 2^A) with
27
  * the smallest R; the device reads each bit of a cell as the majority of its
28
  * copies and writes every copy, and rand replicates each random state and
src/noise.py CHANGED
@@ -226,7 +226,7 @@ def run_leak(args) -> int:
226
  kmax = max(int((W != 0).sum(dim=1).max()) for W in L.W)
227
  r_H = describe(sigma)
228
  print(f"[leak] M = {M:,}, widest layer {nmax}, largest fan-in {kmax}; "
229
- f"Corollary 6.3 permits eps*k + gamma*(n-k) < 1/2", flush=True)
230
 
231
  def worst_bound(eps, gam):
232
  w = 0.0
@@ -519,7 +519,7 @@ def run_certify(args) -> int:
519
  out["leak_rows"] = rows
520
  n_cert = sum(r["certified_by_orbit"] for r in rows)
521
  n_exact = sum(r["first_deviation"] is None for r in rows)
522
- print(f" of the {len(rows)} rows of the leak table, Corollary 6.3 certifies "
523
  f"{sum(r['worst_bound'] < 0.5 for r in rows)}, the orbit certificate {n_cert}, "
524
  f"and {n_exact} were exact")
525
  if not args.short:
 
226
  kmax = max(int((W != 0).sum(dim=1).max()) for W in L.W)
227
  r_H = describe(sigma)
228
  print(f"[leak] M = {M:,}, widest layer {nmax}, largest fan-in {kmax}; "
229
+ f"Proposition 6.3 permits eps*k + gamma*(n-k) < 1/2", flush=True)
230
 
231
  def worst_bound(eps, gam):
232
  w = 0.0
 
519
  out["leak_rows"] = rows
520
  n_cert = sum(r["certified_by_orbit"] for r in rows)
521
  n_exact = sum(r["first_deviation"] is None for r in rows)
522
+ print(f" of the {len(rows)} rows of the leak table, Proposition 6.3 certifies "
523
  f"{sum(r['worst_bound'] < 0.5 for r in rows)}, the orbit certificate {n_cert}, "
524
  f"and {n_exact} were exact")
525
  if not args.short:
src/paper.py CHANGED
@@ -1077,7 +1077,7 @@ def host_extraction(widths=(8, 9, 10)):
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')
@@ -1153,10 +1153,35 @@ def main_rocq():
1153
  print(out.stdout, out.stderr)
1154
  return 1
1155
  names = re.findall(r'^Print Assumptions (\S+)\.$', open(os.path.join(ROCQ, 'Assumptions.v')).read(), re.M)
1156
- lines = [l.strip() for l in out.stdout.splitlines() if l.strip()]
1157
- if len(lines) != len(names) or any(l != 'Closed under the global context' for l in lines):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1158
  print(out.stdout)
1159
  return 1
 
 
 
 
 
 
 
 
 
 
1160
  host = host_extraction()
1161
  stored = stored_extraction()
1162
  images = pstar_images()
@@ -1167,7 +1192,7 @@ def main_rocq():
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 {}
 
1077
  return dict(members=members, identical=all(m['identical'] for m in members))
1078
 
1079
 
1080
+ def stored_extraction(widths=(8, 9, 10)):
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')
 
1153
  print(out.stdout, out.stderr)
1154
  return 1
1155
  names = re.findall(r'^Print Assumptions (\S+)\.$', open(os.path.join(ROCQ, 'Assumptions.v')).read(), re.M)
1156
+ # one block per theorem: closed, or the axioms it depends on, each named at the start of a line
1157
+ blocks = []
1158
+ for line in out.stdout.splitlines():
1159
+ if line.startswith('Closed under the global context'):
1160
+ blocks.append(None)
1161
+ elif line.startswith('Axioms:'):
1162
+ blocks.append([])
1163
+ elif blocks and blocks[-1] is not None and re.match(r"^[A-Za-z_][\w.']* :", line):
1164
+ blocks[-1].append(line.split(' :')[0])
1165
+ # the theorems on real numbers use the axioms of the standard library's reals; the values evaluated by the interval
1166
+ # tactic also the specifications of the primitive integers and floating-point numbers; all others none
1167
+ reals = {'ClassicalDedekindReals.sig_forall_dec', 'ClassicalDedekindReals.sig_not_dec',
1168
+ 'FunctionalExtensionality.functional_extensionality_dep', 'Classical_Prop.classic'}
1169
+ prim = ('Uint63Axioms.', 'Sint63Axioms.', 'FloatAxioms.', 'PrimInt63.', 'PrimFloat.', 'PrimArray.')
1170
+ real_modules = ('Lower.', 'Margin.', 'Erfc.', 'Choose.', 'Noise.', 'Restore.', 'FlipLower.')
1171
+ theorems = {}
1172
+ if len(blocks) != len(names):
1173
  print(out.stdout)
1174
  return 1
1175
+ for n, ax in zip(names, blocks):
1176
+ if ax is None:
1177
+ theorems[n] = 'closed'
1178
+ elif n.startswith(real_modules) and set(ax) <= reals:
1179
+ theorems[n] = 'reals'
1180
+ elif n.startswith('NoiseNum.') and all(a in reals or a.startswith(prim) for a in ax):
1181
+ theorems[n] = 'reals, primitive numbers'
1182
+ else:
1183
+ print(n, ax)
1184
+ return 1
1185
  host = host_extraction()
1186
  stored = stored_extraction()
1187
  images = pstar_images()
 
1192
  files = [l for l in open(os.path.join(ROCQ, '_CoqProject')).read().split() if l.endswith('.v')]
1193
  lines = sum(len(open(os.path.join(ROCQ, f)).read().splitlines()) for f in files)
1194
  res = dict(rocq=version.splitlines()[0], files=len(files), lines=lines,
1195
+ build_seconds=round(build, 1), theorems=theorems,
1196
  host_extraction=host, stored_extraction=stored, pstar_images=images,
1197
  extraction_identical=identical)
1198
  rec = json.load(open(RECORD)) if os.path.exists(RECORD) else {}
src/twohead.py CHANGED
@@ -891,7 +891,7 @@ def main_net():
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
@@ -1750,7 +1750,7 @@ def census(tau):
1750
 
1751
 
1752
  def passes(tau):
1753
- """The steps of P* on a recipe, Proposition 5.4."""
1754
  lit, rep, flit, frep = census(tau)
1755
  return 5 * flit + 4 * frep + 7 * lit + 9 * rep + 7 + 1 + 6 * len(tau) + 2
1756
 
 
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 6.4 and Theorem 6.8(ii)
895
  t0 = time.time()
896
  run = json.load(open(STORED_RECORD))['run']
897
  alpha = (run['record_bits'] - 8) // 3
 
1750
 
1751
 
1752
  def passes(tau):
1753
+ """The steps of P* on a recipe, Proposition 5.3."""
1754
  lit, rep, flit, frep = census(tau)
1755
  return 5 * flit + 4 * frep + 7 * lit + 9 * rep + 7 + 1 + 6 * len(tau) + 2
1756