Commit ·
8cfe9fa
1
Parent(s): 9dc9d2f
Prove in Rocq that the host family computes SUBLEQ at every word width, check the stored host's startup and step records on decision diagrams, state the stored-host theorems for every stored host with their overhead, bound self-reproduction under noise, remove the neuromorphic mappings, and cut the paper to 30 pages
Browse files- .gitignore +3 -0
- README.md +9 -7
- paper/README.md +4 -6
- paper/runs/independent_neuromorphic.json +0 -34
- paper/runs/paper_neuromorphic.json +0 -29
- paper/runs/paper_rocq.json +13 -4
- paper/runs/paper_stored_host.json +9 -0
- paper/universal_construction_ternary.pdf +2 -2
- paper/universal_construction_ternary.tex +0 -0
- rocq/Adder.v +128 -0
- rocq/Assumptions.v +3 -2
- rocq/ExtractHost.v +5 -0
- rocq/Host.v +137 -0
- rocq/HostSem.v +555 -0
- rocq/HostWF.v +251 -0
- rocq/PhysSem.v +15 -15
- rocq/_CoqProject +5 -0
- rocq/extract/dumphost.ml +13 -0
- src/independent.py +2 -184
- src/noise.py +3 -228
- src/paper.py +29 -3
- src/twohead.py +121 -2
.gitignore
CHANGED
|
@@ -17,6 +17,9 @@ rocq/.*.aux
|
|
| 17 |
rocq/.lia.cache
|
| 18 |
rocq/extract/physnet.ml
|
| 19 |
rocq/extract/physnet.mli
|
|
|
|
|
|
|
|
|
|
| 20 |
rocq/.nia.cache
|
| 21 |
rocq/extract/dump
|
| 22 |
rocq/extract/*.cm*
|
|
|
|
| 17 |
rocq/.lia.cache
|
| 18 |
rocq/extract/physnet.ml
|
| 19 |
rocq/extract/physnet.mli
|
| 20 |
+
rocq/extract/hostnet.ml
|
| 21 |
+
rocq/extract/hostnet.mli
|
| 22 |
+
rocq/extract/dumphost
|
| 23 |
rocq/.nia.cache
|
| 24 |
rocq/extract/dump
|
| 25 |
rocq/extract/*.cm*
|
README.md
CHANGED
|
@@ -596,7 +596,9 @@ that netlist. It also shows where the restriction to {-1, 0, 1} is paid for,
|
|
| 596 |
and that a fixed ternary network, the two-head machine of
|
| 597 |
`src/twohead.py`, holds a stored network in its state and evaluates one
|
| 598 |
record per step, which `rocq/` proves for every window of 2^α cells, bank and
|
| 599 |
-
tape
|
|
|
|
|
|
|
| 600 |
two inputs with records that load its memory, its tape device and a hand-over,
|
| 601 |
and stored in the member with 4096 cells, runs the 27-instruction program on a
|
| 602 |
recipe for its own records: it writes them into the idle bank, copies the recipe
|
|
@@ -997,8 +999,8 @@ src/ the library; `python src/<file>.py <command>
|
|
| 997 |
│ and `constructor8`, the neural_subleq8io suite
|
| 998 |
├── twohead.py the two-head machine: the organism (`organism`), the netlist
|
| 999 |
│ N_{G,L} (`net`), and the host stored in it (`stored`)
|
| 1000 |
-
├── noise.py read noise and weight error on the host (`host`),
|
| 1001 |
-
│ host (`amplified`)
|
| 1002 |
├── paper.py the paper's checks and runs, one command each
|
| 1003 |
├── independent.py code written from the paper's text alone
|
| 1004 |
├── netlist_eval.c an evaluator of the host family and the amplified host in C
|
|
@@ -1007,10 +1009,10 @@ src/ the library; `python src/<file>.py <command>
|
|
| 1007 |
├── restore_bound.c the restoration bound of the amplified host along the orbit
|
| 1008 |
└── nsim.c the noise simulator of independent.py
|
| 1009 |
paper/ the manuscript, and the record of every run it reports
|
| 1010 |
-
rocq/ Rocq proofs: the
|
| 1011 |
-
|
| 1012 |
-
|
| 1013 |
-
generation
|
| 1014 |
tools/play.py the playground, and a demonstration on each machine
|
| 1015 |
llm_integration/
|
| 1016 |
├── llm.py SmolLM2 with the frozen circuits: the circuit wrapper, the
|
|
|
|
| 596 |
and that a fixed ternary network, the two-head machine of
|
| 597 |
`src/twohead.py`, holds a stored network in its state and evaluates one
|
| 598 |
record per step, which `rocq/` proves for every window of 2^α cells, bank and
|
| 599 |
+
tape; `rocq/` also proves that the host family computes SUBLEQ at every word
|
| 600 |
+
width, and the H_8 it defines is the netlist of the published serialization. The
|
| 601 |
+
host itself, compiled by `src/twohead.py` into 36,074 records of
|
| 602 |
two inputs with records that load its memory, its tape device and a hand-over,
|
| 603 |
and stored in the member with 4096 cells, runs the 27-instruction program on a
|
| 604 |
recipe for its own records: it writes them into the idle bank, copies the recipe
|
|
|
|
| 999 |
│ and `constructor8`, the neural_subleq8io suite
|
| 1000 |
├── twohead.py the two-head machine: the organism (`organism`), the netlist
|
| 1001 |
│ N_{G,L} (`net`), and the host stored in it (`stored`)
|
| 1002 |
+
├── noise.py read noise and weight error on the host (`host`), and the
|
| 1003 |
+
│ amplified host (`amplified`)
|
| 1004 |
├── paper.py the paper's checks and runs, one command each
|
| 1005 |
├── independent.py code written from the paper's text alone
|
| 1006 |
├── netlist_eval.c an evaluator of the host family and the amplified host in C
|
|
|
|
| 1009 |
├── restore_bound.c the restoration bound of the amplified host along the orbit
|
| 1010 |
└── nsim.c the noise simulator of independent.py
|
| 1011 |
paper/ the manuscript, and the record of every run it reports
|
| 1012 |
+
rocq/ Rocq proofs: the host family H_A computes SUBLEQ for every word
|
| 1013 |
+
width, the netlist of the two-head machine computes its step
|
| 1014 |
+
for every window of 2^α cells, the organism builds every image
|
| 1015 |
+
from any description of it and reproduces in every generation
|
| 1016 |
tools/play.py the playground, and a demonstration on each machine
|
| 1017 |
llm_integration/
|
| 1018 |
├── llm.py SmolLM2 with the frozen circuits: the circuit wrapper, the
|
paper/README.md
CHANGED
|
@@ -12,8 +12,7 @@ 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 |
-
needs Lava, which requires Python 3.10.
|
| 17 |
|
| 18 |
| Command | Record | Establishes |
|
| 19 |
|---|---|---|
|
|
@@ -37,14 +36,13 @@ needs Lava, which requires Python 3.10.
|
|
| 37 |
| `paper.py family-gate` | `paper_runs_family_gate.json` | four of them on the netlist of sigma |
|
| 38 |
| `paper.py c` | `paper_c_evaluator.json` | the host on the evaluator in C, `src/netlist_eval.c` |
|
| 39 |
| `paper.py throughput` | `paper_throughput.json` | the rate of each evaluator |
|
| 40 |
-
| `paper.py rocq` | `paper_rocq.json` | the Rocq development of `rocq/`, its assumptions and the
|
| 41 |
| `twohead.py organism` | `paper_twohead.json` | the translating organism on the two-head machine, three generations |
|
| 42 |
| `twohead.py net` | `paper_twohead_net.json` | the netlist N_{G,L} against the machine for windows of 64 and 4096 cells, its file, the organism on it in C, and the netlist extracted from Rocq |
|
| 43 |
-
| `twohead.py stored` | `paper_stored_host.json` | the host compiled into records of the two-head machine: one pass against the host's step and its device, and three generations in C |
|
| 44 |
| `noise.py host` | `paper_noise_*.json` | the margin, the profile bound, read noise, the deviation curve, 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 |
-
| `
|
| 47 |
-
| `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, Tables 3 to 6 with the noise simulator `src/nsim.c`, and the datapath on Loihi and Akida |
|
| 48 |
|
| 49 |
Rebuild the typeset paper with any TeX installation:
|
| 50 |
|
|
|
|
| 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 |
|---|---|---|
|
|
|
|
| 36 |
| `paper.py family-gate` | `paper_runs_family_gate.json` | four of them on the netlist of sigma |
|
| 37 |
| `paper.py c` | `paper_c_evaluator.json` | the host on the evaluator in C, `src/netlist_eval.c` |
|
| 38 |
| `paper.py throughput` | `paper_throughput.json` | the rate of each evaluator |
|
| 39 |
+
| `paper.py rocq` | `paper_rocq.json` | the Rocq development of `rocq/`, its assumptions, and the host H_8 extracted from it against the netlist sigma(N_host) denotes |
|
| 40 |
| `twohead.py organism` | `paper_twohead.json` | the translating organism on the two-head machine, three generations |
|
| 41 |
| `twohead.py net` | `paper_twohead_net.json` | the netlist N_{G,L} against the machine for windows of 64 and 4096 cells, its file, the organism on it in C, and the netlist extracted from Rocq |
|
| 42 |
+
| `twohead.py stored` | `paper_stored_host.json` | the host compiled into records of the two-head machine: one pass against the host's step and its device, the startup and step records on decision diagrams over the signals of N_host (`stored symbolic`), and three generations in C |
|
| 43 |
| `noise.py host` | `paper_noise_*.json` | the margin, the profile bound, read noise, the deviation curve, 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 |
|
paper/runs/independent_neuromorphic.json
DELETED
|
@@ -1,34 +0,0 @@
|
|
| 1 |
-
{
|
| 2 |
-
"datapath": {
|
| 3 |
-
"units": 106,
|
| 4 |
-
"depth": 5,
|
| 5 |
-
"widths": [
|
| 6 |
-
48,
|
| 7 |
-
58,
|
| 8 |
-
23,
|
| 9 |
-
23,
|
| 10 |
-
9
|
| 11 |
-
]
|
| 12 |
-
},
|
| 13 |
-
"akida": {
|
| 14 |
-
"backend": "akida 2.19.3",
|
| 15 |
-
"patterns": 65536,
|
| 16 |
-
"failures": 0
|
| 17 |
-
},
|
| 18 |
-
"lava_vth_16": {
|
| 19 |
-
"backend": "lava fixed_pt",
|
| 20 |
-
"vth": 16,
|
| 21 |
-
"patterns": 4096,
|
| 22 |
-
"failures": 0,
|
| 23 |
-
"margin_firing_side": 128,
|
| 24 |
-
"margin_quiet_side": 0
|
| 25 |
-
},
|
| 26 |
-
"lava_vth_17": {
|
| 27 |
-
"backend": "lava fixed_pt",
|
| 28 |
-
"vth": 17,
|
| 29 |
-
"patterns": 4096,
|
| 30 |
-
"failures": 0,
|
| 31 |
-
"margin_firing_side": 64,
|
| 32 |
-
"margin_quiet_side": 64
|
| 33 |
-
}
|
| 34 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
paper/runs/paper_neuromorphic.json
DELETED
|
@@ -1,29 +0,0 @@
|
|
| 1 |
-
{
|
| 2 |
-
"backend": "Lava 0.10.0, fixed_pt tag (Loihi neuron model)",
|
| 3 |
-
"units": 106,
|
| 4 |
-
"layers": 5,
|
| 5 |
-
"widths": [
|
| 6 |
-
48,
|
| 7 |
-
58,
|
| 8 |
-
23,
|
| 9 |
-
23,
|
| 10 |
-
9
|
| 11 |
-
],
|
| 12 |
-
"worst_accumulation": 16,
|
| 13 |
-
"patterns": 4096,
|
| 14 |
-
"failures": 0,
|
| 15 |
-
"margin_membrane_units": 64,
|
| 16 |
-
"weight_scale": 2,
|
| 17 |
-
"synapse_granularity": 2,
|
| 18 |
-
"bias_offset": 9,
|
| 19 |
-
"ok": true,
|
| 20 |
-
"akida": {
|
| 21 |
-
"backend": "akida 2.19.3, software backend",
|
| 22 |
-
"layers": 5,
|
| 23 |
-
"patterns": 65536,
|
| 24 |
-
"failures": 0,
|
| 25 |
-
"weights_bits": 2,
|
| 26 |
-
"act_bits": 1,
|
| 27 |
-
"ok": true
|
| 28 |
-
}
|
| 29 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
paper/runs/paper_rocq.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
{
|
| 2 |
"rocq": "The Rocq Prover, version 9.1.1",
|
| 3 |
-
"files":
|
| 4 |
-
"build_seconds":
|
| 5 |
"theorems": {
|
| 6 |
"PhysMain.netlist_step": "closed",
|
| 7 |
"PhysMain.netlist_step64": "closed",
|
|
@@ -18,7 +18,16 @@
|
|
| 18 |
"Main.every_generation": "closed",
|
| 19 |
"SelfRep.self_reproduction": "closed",
|
| 20 |
"SelfRep.second_generation": "closed",
|
| 21 |
-
"SelfRep.periodic": "closed"
|
|
|
|
| 22 |
},
|
| 23 |
-
"extraction_identical": true
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
}
|
|
|
|
| 1 |
{
|
| 2 |
"rocq": "The Rocq Prover, version 9.1.1",
|
| 3 |
+
"files": 30,
|
| 4 |
+
"build_seconds": 303.5,
|
| 5 |
"theorems": {
|
| 6 |
"PhysMain.netlist_step": "closed",
|
| 7 |
"PhysMain.netlist_step64": "closed",
|
|
|
|
| 18 |
"Main.every_generation": "closed",
|
| 19 |
"SelfRep.self_reproduction": "closed",
|
| 20 |
"SelfRep.second_generation": "closed",
|
| 21 |
+
"SelfRep.periodic": "closed",
|
| 22 |
+
"HostSem.host_step": "closed"
|
| 23 |
},
|
| 24 |
+
"extraction_identical": true,
|
| 25 |
+
"lines": 5093,
|
| 26 |
+
"host_extraction": {
|
| 27 |
+
"A": 8,
|
| 28 |
+
"units": 17598,
|
| 29 |
+
"identical": true,
|
| 30 |
+
"sha256_sigma": "2263144948d68cafbf1616a6c0bd74e98cb597c1a6d5b1512d65d3aff574f17a",
|
| 31 |
+
"sha256_rocq": "2263144948d68cafbf1616a6c0bd74e98cb597c1a6d5b1512d65d3aff574f17a"
|
| 32 |
+
}
|
| 33 |
}
|
paper/runs/paper_stored_host.json
CHANGED
|
@@ -66,5 +66,14 @@
|
|
| 66 |
"records": 36074,
|
| 67 |
"window_cells": 2896,
|
| 68 |
"seconds": 131.8
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
}
|
| 70 |
}
|
|
|
|
| 66 |
"records": 36074,
|
| 67 |
"window_cells": 2896,
|
| 68 |
"seconds": 131.8
|
| 69 |
+
},
|
| 70 |
+
"symbolic": {
|
| 71 |
+
"startup_records": 2099,
|
| 72 |
+
"step_records": 33568,
|
| 73 |
+
"startup_exact": true,
|
| 74 |
+
"step_exact": true,
|
| 75 |
+
"sha256_image": "7a769aa264a89860149962d7e98f8b2a5cb34ceb7778e88bcbffdccdc0996154",
|
| 76 |
+
"nodes": 1435999,
|
| 77 |
+
"seconds": 3.6
|
| 78 |
}
|
| 79 |
}
|
paper/universal_construction_ternary.pdf
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:c973871985a763cf000c4cfa9e8126aa37eb0efb94c99261d4289b10a39e1b10
|
| 3 |
+
size 327298
|
paper/universal_construction_ternary.tex
CHANGED
|
The diff for this file is too large to render.
See raw diff
|
|
|
rocq/Adder.v
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
(* The subtractor of Lemma 3.2: the carry-lookahead terms are the ripple carries of y + not x + 1,
|
| 2 |
+
and the sum bits spell (y - x) mod 2^A. *)
|
| 3 |
+
From Stdlib Require Import List Bool Arith Lia.
|
| 4 |
+
Import ListNotations.
|
| 5 |
+
From TH Require Import TwoHead Net PhysSem.
|
| 6 |
+
|
| 7 |
+
(* the value of the bits f 0 .. f (n - 1), least significant first *)
|
| 8 |
+
Definition bv (f : nat -> bool) (n : nat) : nat := bits2nat (rev (map f (seq 0 n))).
|
| 9 |
+
|
| 10 |
+
Lemma bv_S : forall f n, bv f (S n) = (if f n then 2 ^ n else 0) + bv f n.
|
| 11 |
+
Proof.
|
| 12 |
+
intros f n. unfold bv. rewrite seq_S, map_app, rev_app_distr. cbn [map rev app].
|
| 13 |
+
rewrite bits2nat_cons, length_rev, length_map, length_seq. reflexivity.
|
| 14 |
+
Qed.
|
| 15 |
+
|
| 16 |
+
Lemma bv_lt : forall f n, bv f n < 2 ^ n.
|
| 17 |
+
Proof.
|
| 18 |
+
intros f n. unfold bv. pose proof (bits2nat_lt (rev (map f (seq 0 n)))) as H.
|
| 19 |
+
rewrite length_rev, length_map, length_seq in H. exact H.
|
| 20 |
+
Qed.
|
| 21 |
+
|
| 22 |
+
Lemma testbit_bv : forall f n k, k < n -> Nat.testbit (bv f n) k = f k.
|
| 23 |
+
Proof.
|
| 24 |
+
intros f n k Hk. unfold bv.
|
| 25 |
+
pose proof (testbit_bits2nat (rev (map f (seq 0 n))) (n - 1 - k)) as T.
|
| 26 |
+
rewrite length_rev, length_map, length_seq in T. replace (n - 1 - (n - 1 - k)) with k in T by lia.
|
| 27 |
+
rewrite T by lia. rewrite rev_nth by (rewrite length_map, length_seq; lia).
|
| 28 |
+
rewrite length_map, length_seq. replace (n - S (n - 1 - k)) with k by lia.
|
| 29 |
+
rewrite nth_map_d with (d' := 0) by (rewrite length_seq; lia). rewrite seq_nth by lia. reflexivity.
|
| 30 |
+
Qed.
|
| 31 |
+
|
| 32 |
+
Lemma bv_testbit : forall z n, z < 2 ^ n -> bv (Nat.testbit z) n = z.
|
| 33 |
+
Proof.
|
| 34 |
+
intros z n Hz. apply (bits_eq_nat _ _ n); [apply bv_lt | exact Hz |].
|
| 35 |
+
intros i Hi. apply testbit_bv. exact Hi.
|
| 36 |
+
Qed.
|
| 37 |
+
|
| 38 |
+
Lemma bv_compl : forall f n, bv f n + bv (fun i => negb (f i)) n + 1 = 2 ^ n.
|
| 39 |
+
Proof.
|
| 40 |
+
intros f n. induction n as [|n IH]; [reflexivity|].
|
| 41 |
+
rewrite !bv_S. cbn [Nat.pow]. destruct (f n); cbn [negb]; lia.
|
| 42 |
+
Qed.
|
| 43 |
+
|
| 44 |
+
Section Sub.
|
| 45 |
+
Variables x y : nat.
|
| 46 |
+
|
| 47 |
+
Definition xb (i : nat) : bool := Nat.testbit x i.
|
| 48 |
+
Definition yb (i : nat) : bool := Nat.testbit y i.
|
| 49 |
+
Definition gb (i : nat) : bool := yb i && negb (xb i).
|
| 50 |
+
Definition pg (i : nat) : bool := negb (xb i) || yb i.
|
| 51 |
+
|
| 52 |
+
Fixpoint carry (k : nat) : bool := match k with O => true | S m => gb m || (pg m && carry m) end.
|
| 53 |
+
|
| 54 |
+
Definition sumbit (k : nat) : bool := xorb (xorb (yb k) (negb (xb k))) (carry k).
|
| 55 |
+
|
| 56 |
+
Lemma adder : forall n,
|
| 57 |
+
bv yb n + bv (fun i => negb (xb i)) n + 1 = bv sumbit n + (if carry n then 2 ^ n else 0).
|
| 58 |
+
Proof.
|
| 59 |
+
induction n as [|n IH]; [reflexivity|].
|
| 60 |
+
rewrite !bv_S. cbn [carry Nat.pow]. unfold sumbit, gb, pg in *.
|
| 61 |
+
destruct (yb n), (xb n), (carry n); cbn [negb xorb andb orb] in *; lia.
|
| 62 |
+
Qed.
|
| 63 |
+
|
| 64 |
+
Lemma sub_value : forall A, x < 2 ^ A -> y < 2 ^ A -> bv sumbit A = (y + 2 ^ A - x) mod 2 ^ A.
|
| 65 |
+
Proof.
|
| 66 |
+
intros A Hx Hy. pose proof (adder A) as H. pose proof (bv_compl xb A) as C.
|
| 67 |
+
change (bv yb A) with (bv (Nat.testbit y) A) in H. rewrite (bv_testbit y A Hy) in H.
|
| 68 |
+
change (bv xb A) with (bv (Nat.testbit x) A) in C. rewrite (bv_testbit x A Hx) in C.
|
| 69 |
+
pose proof (bv_lt sumbit A) as L.
|
| 70 |
+
assert (E : y + 2 ^ A - x = bv sumbit A + (if carry A then 1 else 0) * 2 ^ A)
|
| 71 |
+
by (destruct (carry A); lia).
|
| 72 |
+
rewrite E, Nat.Div0.mod_add, Nat.mod_small by exact L. reflexivity.
|
| 73 |
+
Qed.
|
| 74 |
+
|
| 75 |
+
Lemma sub_bits : forall A k, x < 2 ^ A -> y < 2 ^ A -> k < A ->
|
| 76 |
+
Nat.testbit ((y + 2 ^ A - x) mod 2 ^ A) k = sumbit k.
|
| 77 |
+
Proof. intros A k Hx Hy Hk. rewrite <- sub_value by assumption. apply testbit_bv. exact Hk. Qed.
|
| 78 |
+
|
| 79 |
+
Lemma existsb_and_r : forall (T : Type) (g : T -> bool) c l, existsb (fun a => g a && c) l = existsb g l && c.
|
| 80 |
+
Proof.
|
| 81 |
+
intros T g c l. induction l as [|a l IH]; [reflexivity|]. cbn [existsb]. rewrite IH.
|
| 82 |
+
destruct (g a), c, (existsb g l); reflexivity.
|
| 83 |
+
Qed.
|
| 84 |
+
|
| 85 |
+
Lemma forallb_seq_S : forall (f : nat -> bool) m n, forallb f (seq m (S n)) = forallb f (seq m n) && f (m + n).
|
| 86 |
+
Proof. intros f m n. rewrite seq_S, forallb_app. cbn [forallb]. rewrite andb_true_r. reflexivity. Qed.
|
| 87 |
+
|
| 88 |
+
(* the carry into bit k: all of 0 .. k-1 propagate, or some j generates and j+1 .. k-1 propagate *)
|
| 89 |
+
Lemma carry_closed : forall k,
|
| 90 |
+
carry k = forallb pg (seq 0 k) || existsb (fun j => gb j && forallb pg (seq (S j) (k - S j))) (seq 0 k).
|
| 91 |
+
Proof.
|
| 92 |
+
induction k as [|k IH]; [reflexivity|].
|
| 93 |
+
cbn [carry]. rewrite IH, forallb_seq_S, seq_S, existsb_app. cbn [existsb]. rewrite Nat.add_0_l.
|
| 94 |
+
replace (S k - S k) with 0 by lia. cbn [seq forallb]. rewrite andb_true_r, orb_false_r.
|
| 95 |
+
assert (E : existsb (fun j => gb j && forallb pg (seq (S j) (S k - S j))) (seq 0 k)
|
| 96 |
+
= existsb (fun j => gb j && forallb pg (seq (S j) (k - S j))) (seq 0 k) && pg k).
|
| 97 |
+
{ rewrite (existsb_ext_in _ _ (fun j => (gb j && forallb pg (seq (S j) (k - S j))) && pg k)).
|
| 98 |
+
- apply (existsb_and_r _ (fun j => gb j && forallb pg (seq (S j) (k - S j)))).
|
| 99 |
+
- intros j Hj. apply in_seq in Hj. replace (S k - S j) with (S (k - S j)) by lia. rewrite forallb_seq_S.
|
| 100 |
+
replace (S j + (k - S j)) with k by lia. rewrite andb_assoc. reflexivity. }
|
| 101 |
+
rewrite E. destruct (pg k), (gb k); cbn [andb orb]; rewrite ?andb_true_r, ?andb_false_r, ?orb_false_r,
|
| 102 |
+
?orb_true_r; reflexivity.
|
| 103 |
+
Qed.
|
| 104 |
+
|
| 105 |
+
End Sub.
|
| 106 |
+
|
| 107 |
+
Lemma testbit_top : forall r n, 1 <= n -> r < 2 ^ n -> Nat.testbit r (n - 1) = (2 ^ (n - 1) <=? r).
|
| 108 |
+
Proof.
|
| 109 |
+
intros r n Hn Hr. replace n with (S (n - 1)) in Hr by lia. rewrite Nat.pow_succ_r' in Hr.
|
| 110 |
+
apply Nat.b2n_inj. rewrite Nat.testbit_spec'.
|
| 111 |
+
destruct (Nat.leb_spec (2 ^ (n - 1)) r) as [H|H].
|
| 112 |
+
- assert (D : r / 2 ^ (n - 1) = 1).
|
| 113 |
+
{ symmetry. apply Nat.div_unique with (r - 2 ^ (n - 1)); lia. }
|
| 114 |
+
rewrite D. reflexivity.
|
| 115 |
+
- rewrite Nat.div_small by exact H. reflexivity.
|
| 116 |
+
Qed.
|
| 117 |
+
|
| 118 |
+
Lemma sub_zero : forall A x y, x < 2 ^ A -> y < 2 ^ A -> Nat.eqb ((y + 2 ^ A - x) mod 2 ^ A) 0 = Nat.eqb x y.
|
| 119 |
+
Proof.
|
| 120 |
+
intros A x y Hx Hy. pose proof (Nat.pow_nonzero 2 A ltac:(lia)) as Hn.
|
| 121 |
+
destruct (Nat.eqb_spec x y) as [->|E].
|
| 122 |
+
- replace (y + 2 ^ A - y) with (1 * 2 ^ A) by lia. rewrite Nat.Div0.mod_mul. reflexivity.
|
| 123 |
+
- apply Nat.eqb_neq. intro Z.
|
| 124 |
+
destruct (Nat.le_gt_cases x y) as [L|L].
|
| 125 |
+
+ replace (y + 2 ^ A - x) with ((y - x) + 1 * 2 ^ A) in Z by lia.
|
| 126 |
+
rewrite Nat.Div0.mod_add, Nat.mod_small in Z by lia. lia.
|
| 127 |
+
+ rewrite Nat.mod_small in Z by lia. lia.
|
| 128 |
+
Qed.
|
rocq/Assumptions.v
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
-
(* The assumptions of the main theorems, printed by src/
|
| 2 |
-
From TH Require Import PhysMain PhysFacts NetMain Complete Run PassLemma Main SelfRep.
|
| 3 |
|
| 4 |
Print Assumptions PhysMain.netlist_step.
|
| 5 |
Print Assumptions PhysMain.netlist_step64.
|
|
@@ -17,3 +17,4 @@ Print Assumptions Main.every_generation.
|
|
| 17 |
Print Assumptions SelfRep.self_reproduction.
|
| 18 |
Print Assumptions SelfRep.second_generation.
|
| 19 |
Print Assumptions SelfRep.periodic.
|
|
|
|
|
|
| 1 |
+
(* The assumptions of the main theorems, printed by src/paper.py rocq after the build. *)
|
| 2 |
+
From TH Require Import PhysMain PhysFacts NetMain Complete Run PassLemma Main SelfRep HostSem.
|
| 3 |
|
| 4 |
Print Assumptions PhysMain.netlist_step.
|
| 5 |
Print Assumptions PhysMain.netlist_step64.
|
|
|
|
| 17 |
Print Assumptions SelfRep.self_reproduction.
|
| 18 |
Print Assumptions SelfRep.second_generation.
|
| 19 |
Print Assumptions SelfRep.periodic.
|
| 20 |
+
Print Assumptions HostSem.host_step.
|
rocq/ExtractHost.v
ADDED
|
@@ -0,0 +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.
|
rocq/Host.v
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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.
|
| 6 |
+
|
| 7 |
+
Section Host.
|
| 8 |
+
Variable A : nat.
|
| 9 |
+
|
| 10 |
+
(* the words of memory, and the state bits: the counter, the halt bit, the memory *)
|
| 11 |
+
Definition SW : nat := 2 ^ A.
|
| 12 |
+
Definition nH : nat := A + 1 + SW * A.
|
| 13 |
+
|
| 14 |
+
(* bit t of an A-bit value, most significant first *)
|
| 15 |
+
Definition bitof (v t : nat) : bool := Nat.testbit v (A - 1 - t).
|
| 16 |
+
|
| 17 |
+
Definition pcb (i : nat) : sref := SIn i.
|
| 18 |
+
Definition haltb : sref := SIn A.
|
| 19 |
+
Definition mu (j t : nat) : sref := SIn (A + 1 + j * A + t).
|
| 20 |
+
|
| 21 |
+
(* the literals asserting that the bits f 0 .. f (A - 1), most significant first, spell v *)
|
| 22 |
+
Definition lits (f : nat -> sref) (v : nat) : list lit := map (fun t => (f t, bitof v t)) (seq 0 A).
|
| 23 |
+
|
| 24 |
+
Definition opb (o t : nat) : sref := SRef 6 (o * A + t) 0.
|
| 25 |
+
Definition xv (i : nat) : sref := SRef 14 (A - 1 - i) 0.
|
| 26 |
+
Definition yv (i : nat) : sref := SRef 15 (A - 1 - i) 0.
|
| 27 |
+
Definition prr (i : nat) : sref := SRef 16 i 0.
|
| 28 |
+
Definition tb : nat := 16 + A.
|
| 29 |
+
|
| 30 |
+
(* 0 to 16: decode, fetch, operands, reads, propagate signals *)
|
| 31 |
+
Definition blk_P : block := Blk SW 1 (fun j => [sAND (lits pcb j)]).
|
| 32 |
+
Definition blk_HP : block := Blk A 1 (fun i => [sAND [(pcb i, true); (haltb, true)]]).
|
| 33 |
+
Definition blk_FA (o : nat) : block :=
|
| 34 |
+
Blk (A * SW) 1 (fun m => [sAND [(mu ((m mod SW + o) mod SW) (m / SW), true); (SRef 0 (m mod SW) 0, true)]]).
|
| 35 |
+
Definition blk_Q : block :=
|
| 36 |
+
Blk A 1 (fun i => [sOR (map (fun j => (SRef 0 j 0, true))
|
| 37 |
+
(filter (fun j => bitof ((j + 3) mod SW) i) (seq 0 SW)))]).
|
| 38 |
+
Definition blk_F : block :=
|
| 39 |
+
Blk (3 * A) 1 (fun m => [sOR (map (fun j => (SRef (2 + m / A) ((m mod A) * SW + j) 0, true)) (seq 0 SW))]).
|
| 40 |
+
Definition blk_PA : block := Blk SW 1 (fun j => [sAND (lits (opb 0) j)]).
|
| 41 |
+
Definition blk_PB : block := Blk SW 1 (fun j => [sAND (lits (opb 1) j)]).
|
| 42 |
+
Definition blk_AC : block := Blk 1 1 (fun _ => [sAND (map (fun t => (opb 2 t, true)) (seq 0 A))]).
|
| 43 |
+
Definition blk_W : block := Blk SW 1 (fun j => [sAND [(haltb, false); (SRef 8 j 0, true)]]).
|
| 44 |
+
Definition blk_RX : block :=
|
| 45 |
+
Blk (A * SW) 1 (fun m => [sAND [(mu (m mod SW) (m / SW), true); (SRef 7 (m mod SW) 0, true)]]).
|
| 46 |
+
Definition blk_RY : block :=
|
| 47 |
+
Blk (A * SW) 1 (fun m => [sAND [(mu (m mod SW) (m / SW), true); (SRef 8 (m mod SW) 0, true)]]).
|
| 48 |
+
Definition blk_KP : block :=
|
| 49 |
+
Blk (SW * A) 1 (fun m => [sAND [(mu (m / A) (m mod A), true); (SRef 10 (m / A) 0, false)]]).
|
| 50 |
+
Definition blk_X : block := Blk A 1 (fun t => [sOR (map (fun j => (SRef 11 (t * SW + j) 0, true)) (seq 0 SW))]).
|
| 51 |
+
Definition blk_Y : block := Blk A 1 (fun t => [sOR (map (fun j => (SRef 12 (t * SW + j) 0, true)) (seq 0 SW))]).
|
| 52 |
+
Definition blk_PR : block := Blk (A - 1) 1 (fun i => [sOR [(xv i, false); (yv i, true)]]).
|
| 53 |
+
|
| 54 |
+
(* 17 to 15 + A: the carry terms into bit k, for k = 1 .. A - 1 *)
|
| 55 |
+
Definition blk_T (k : nat) : block :=
|
| 56 |
+
Blk 1 (S k) (fun _ => sAND (map (fun i => (prr i, true)) (seq 0 k))
|
| 57 |
+
:: map (fun j => sAND ([(yv j, true); (xv j, false)]
|
| 58 |
+
++ map (fun i => (prr i, true)) (seq (S j) (k - S j))))
|
| 59 |
+
(seq 0 k)).
|
| 60 |
+
|
| 61 |
+
(* tb to tb + 14: carries, equality, sum bits, branch, next counter, halt latch, next memory *)
|
| 62 |
+
Definition blk_C : block :=
|
| 63 |
+
Blk (A - 1) 1 (fun m => [sOR ((SRef (16 + S m) 0 0, true)
|
| 64 |
+
:: map (fun j => (SRef (16 + S m) 0 (S j), true)) (seq 0 (S m)))]).
|
| 65 |
+
Definition blk_AX : block := Blk A 1 (fun i => [sAND [(xv i, true); (yv i, true)]]).
|
| 66 |
+
Definition blk_NX : block := Blk A 1 (fun i => [sAND [(xv i, false); (yv i, false)]]).
|
| 67 |
+
Definition blk_XN : block := Blk A 1 (fun i => [sOR [(SRef (tb + 1) i 0, true); (SRef (tb + 2) i 0, true)]]).
|
| 68 |
+
Definition blk_EQ : block := Blk 1 1 (fun _ => [sAND (map (fun i => (SRef (tb + 3) i 0, true)) (seq 0 A))]).
|
| 69 |
+
Definition blk_R0 : block :=
|
| 70 |
+
Blk 1 3 (fun _ => [sOR [(yv 0, true); (xv 0, true)]; sOR [(yv 0, false); (xv 0, false)];
|
| 71 |
+
sAND [(SRef (tb + 5) 0 0, true); (SRef (tb + 5) 0 1, true)]]).
|
| 72 |
+
Definition blk_H : block :=
|
| 73 |
+
Blk (A - 1) 3 (fun m => map (fun b => SU b [(yv (S m), 1%Z); (xv (S m), (-1)%Z); (SRef tb m 0, 1%Z)])
|
| 74 |
+
[0%Z; (-1)%Z; (-2)%Z]).
|
| 75 |
+
Definition blk_R : block :=
|
| 76 |
+
Blk (A - 1) 1 (fun m => [SU (-1) [(SRef (tb + 6) m 0, 1%Z); (SRef (tb + 6) m 1, (-1)%Z);
|
| 77 |
+
(SRef (tb + 6) m 2, 1%Z)]]).
|
| 78 |
+
Definition blk_LEQ : block :=
|
| 79 |
+
Blk 1 1 (fun _ => [SU (-1) [(SRef (tb + 6) (A - 2) 0, 1%Z); (SRef (tb + 6) (A - 2) 1, (-1)%Z);
|
| 80 |
+
(SRef (tb + 6) (A - 2) 2, 1%Z); (SRef (tb + 4) 0 0, 1%Z)]]).
|
| 81 |
+
Definition rbit (k : nat) : sref := if Nat.eqb k 0 then SRef (tb + 5) 0 2 else SRef (tb + 7) (k - 1) 0.
|
| 82 |
+
Definition blk_TA : block :=
|
| 83 |
+
Blk A 1 (fun i => [sAND [(haltb, false); (SRef (tb + 8) 0 0, true); (opb 2 i, true)]]).
|
| 84 |
+
Definition blk_TB : block :=
|
| 85 |
+
Blk A 1 (fun i => [sAND [(haltb, false); (SRef (tb + 8) 0 0, false); (SRef 5 i 0, true)]]).
|
| 86 |
+
Definition blk_NP : block :=
|
| 87 |
+
Blk A 1 (fun i => [sOR [(SRef 1 i 0, true); (SRef (tb + 9) i 0, true); (SRef (tb + 10) i 0, true)]]).
|
| 88 |
+
Definition blk_HAB : block :=
|
| 89 |
+
Blk 1 3 (fun _ => [sAND [(haltb, false); (SRef (tb + 8) 0 0, true); (SRef 9 0 0, true)];
|
| 90 |
+
sAND [(haltb, false); (SRef (tb + 8) 0 0, false); (SRef 0 (SW - 4) 0, true)];
|
| 91 |
+
sOR [(haltb, true); (SRef (tb + 12) 0 0, true); (SRef (tb + 12) 0 1, true)]]).
|
| 92 |
+
Definition blk_WR : block :=
|
| 93 |
+
Blk (SW * A) 1 (fun m => [sAND [(rbit (A - 1 - m mod A), true); (SRef 10 (m / A) 0, true)]]).
|
| 94 |
+
Definition blk_NM : block := Blk (SW * A) 1 (fun m => [sOR [(SRef 13 m 0, true); (SRef (tb + 13) m 0, true)]]).
|
| 95 |
+
|
| 96 |
+
Definition hpre : list block :=
|
| 97 |
+
[blk_P; blk_HP; blk_FA 0; blk_FA 1; blk_FA 2; blk_Q; blk_F; blk_PA; blk_PB; blk_AC; blk_W; blk_RX; blk_RY;
|
| 98 |
+
blk_KP; blk_X; blk_Y; blk_PR].
|
| 99 |
+
Definition hpost : list block :=
|
| 100 |
+
[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;
|
| 101 |
+
blk_WR; blk_NM].
|
| 102 |
+
Definition hblocks : list block := hpre ++ map blk_T (seq 1 (A - 1)) ++ hpost.
|
| 103 |
+
|
| 104 |
+
(* the unit computing the next value of each state bit *)
|
| 105 |
+
Definition hout (i : nat) : sref :=
|
| 106 |
+
if i <? A then SRef (tb + 11) i 0
|
| 107 |
+
else if Nat.eqb i A then SRef (tb + 12) 0 2
|
| 108 |
+
else SRef (tb + 14) (i - A - 1) 0.
|
| 109 |
+
|
| 110 |
+
Definition host_units : list tu := compile nH hblocks.
|
| 111 |
+
Definition host_next : list nat := map (fun i => idx nH hblocks (hout i)) (seq 0 nH).
|
| 112 |
+
|
| 113 |
+
(* ---- the machine: SUBLEQ on 2^A words of A bits, Definition 3.1 ------------------------ *)
|
| 114 |
+
Record hst := mkH { hpc : nat; hhalt : bool; hmem : list nat }.
|
| 115 |
+
|
| 116 |
+
Definition memv (s : hst) (j : nat) : nat := nth j (hmem s) 0.
|
| 117 |
+
|
| 118 |
+
Definition subleq (s : hst) : hst :=
|
| 119 |
+
if hhalt s then s
|
| 120 |
+
else
|
| 121 |
+
let p := hpc s in
|
| 122 |
+
let a := memv s p in
|
| 123 |
+
let b := memv s ((p + 1) mod SW) in
|
| 124 |
+
let c := memv s ((p + 2) mod SW) in
|
| 125 |
+
let r := (memv s b + SW - memv s a) mod SW in
|
| 126 |
+
let leq := Nat.eqb r 0 || Nat.leb (2 ^ (A - 1)) r in
|
| 127 |
+
let p' := if leq then c else (p + 3) mod SW in
|
| 128 |
+
mkH p' (Nat.eqb p' (SW - 1)) (map (fun j => if Nat.eqb j b then r else memv s j) (seq 0 SW)).
|
| 129 |
+
|
| 130 |
+
(* the state bits: the counter and each word most significant bit first *)
|
| 131 |
+
Definition wbits (v : nat) : list bool := map (bitof v) (seq 0 A).
|
| 132 |
+
Definition encodeH (s : hst) : list bool := wbits (hpc s) ++ [hhalt s] ++ concat (map wbits (hmem s)).
|
| 133 |
+
|
| 134 |
+
Definition hvalid (s : hst) : Prop :=
|
| 135 |
+
hpc s < SW /\ length (hmem s) = SW /\ Forall (fun v => v < SW) (hmem s).
|
| 136 |
+
|
| 137 |
+
End Host.
|
rocq/HostSem.v
ADDED
|
@@ -0,0 +1,555 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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.
|
| 6 |
+
|
| 7 |
+
(* ---- the state bits ----------------------------------------------------------------- *)
|
| 8 |
+
Lemma length_wbits : forall A v, length (wbits A v) = A.
|
| 9 |
+
Proof. intros A v. unfold wbits. rewrite length_map, length_seq. reflexivity. Qed.
|
| 10 |
+
|
| 11 |
+
Lemma nth_wbits : forall A v t, t < A -> nth t (wbits A v) false = bitof A v t.
|
| 12 |
+
Proof.
|
| 13 |
+
intros A v t Ht. unfold wbits. rewrite nth_map_d with (d' := 0) by (rewrite length_seq; lia).
|
| 14 |
+
rewrite seq_nth by lia. reflexivity.
|
| 15 |
+
Qed.
|
| 16 |
+
|
| 17 |
+
Lemma length_encodeH : forall A s, length (hmem s) = SW A -> length (encodeH A s) = nH A.
|
| 18 |
+
Proof.
|
| 19 |
+
intros A s H. unfold encodeH, nH. rewrite !length_app, length_wbits. cbn [length].
|
| 20 |
+
rewrite (length_concat_const _ _ A).
|
| 21 |
+
- rewrite length_map, H. lia.
|
| 22 |
+
- apply Forall_forall. intros l Hl. apply in_map_iff in Hl as (v & <- & _). apply length_wbits.
|
| 23 |
+
Qed.
|
| 24 |
+
|
| 25 |
+
Lemma nth_encodeH_pc : forall A s i, i < A -> nth i (encodeH A s) false = bitof A (hpc s) i.
|
| 26 |
+
Proof. intros A s i Hi. unfold encodeH. rewrite app_nth1 by (rewrite length_wbits; lia). apply nth_wbits. exact Hi. Qed.
|
| 27 |
+
|
| 28 |
+
Lemma nth_encodeH_halt : forall A s, nth A (encodeH A s) false = hhalt s.
|
| 29 |
+
Proof.
|
| 30 |
+
intros A s. unfold encodeH. rewrite app_nth2 by (rewrite length_wbits; lia).
|
| 31 |
+
rewrite length_wbits, Nat.sub_diag. reflexivity.
|
| 32 |
+
Qed.
|
| 33 |
+
|
| 34 |
+
Lemma nth_encodeH_mem : forall A s j t, length (hmem s) = SW A -> j < SW A -> t < A ->
|
| 35 |
+
nth (A + 1 + j * A + t) (encodeH A s) false = bitof A (memv s j) t.
|
| 36 |
+
Proof.
|
| 37 |
+
intros A s j t Hl Hj Ht. unfold encodeH. rewrite app_nth2 by (rewrite length_wbits; lia). rewrite length_wbits.
|
| 38 |
+
replace (A + 1 + j * A + t - A) with (S (A * j + t)) by lia. cbn [app nth].
|
| 39 |
+
rewrite (nth_concat_const _ false (map (wbits A) (hmem s)) A j t).
|
| 40 |
+
- rewrite nth_map_d with (d' := 0) by lia. apply nth_wbits. exact Ht.
|
| 41 |
+
- apply Forall_forall. intros l Hl'. apply in_map_iff in Hl' as (v & <- & _). apply length_wbits.
|
| 42 |
+
- rewrite length_map. lia.
|
| 43 |
+
- exact Ht.
|
| 44 |
+
Qed.
|
| 45 |
+
|
| 46 |
+
(* ---- addresses ---------------------------------------------------------------------- *)
|
| 47 |
+
Lemma bits_eqb : forall A p j, p < 2 ^ A -> j < 2 ^ A ->
|
| 48 |
+
forallb (fun t => Bool.eqb (bitof A p t) (bitof A j t)) (seq 0 A) = Nat.eqb p j.
|
| 49 |
+
Proof.
|
| 50 |
+
intros A p j Hp Hj. destruct (Nat.eqb_spec p j) as [->|E].
|
| 51 |
+
- apply forallb_forall. intros t _. apply eqb_reflx.
|
| 52 |
+
- apply Bool.not_true_is_false. intro F. apply E. apply (bits_eq_nat _ _ A Hp Hj).
|
| 53 |
+
intros i Hi. rewrite forallb_forall in F. specialize (F (A - 1 - i) ltac:(apply in_seq; lia)).
|
| 54 |
+
apply Bool.eqb_prop in F. unfold bitof in F. replace (A - 1 - (A - 1 - i)) with i in F by lia. exact F.
|
| 55 |
+
Qed.
|
| 56 |
+
|
| 57 |
+
Lemma testbits_eqb : forall A x y, x < 2 ^ A -> y < 2 ^ A ->
|
| 58 |
+
forallb (fun i => Bool.eqb (Nat.testbit x i) (Nat.testbit y i)) (seq 0 A) = Nat.eqb x y.
|
| 59 |
+
Proof.
|
| 60 |
+
intros A x y Hx Hy. destruct (Nat.eqb_spec x y) as [->|E].
|
| 61 |
+
- apply forallb_forall. intros t _. apply eqb_reflx.
|
| 62 |
+
- apply Bool.not_true_is_false. intro F. apply E. apply (bits_eq_nat _ _ A Hx Hy).
|
| 63 |
+
intros i Hi. rewrite forallb_forall in F. specialize (F i ltac:(apply in_seq; lia)).
|
| 64 |
+
apply Bool.eqb_prop in F. exact F.
|
| 65 |
+
Qed.
|
| 66 |
+
|
| 67 |
+
Lemma lits_fire : forall A (V : sref -> bool) f v w, v < 2 ^ A -> w < 2 ^ A ->
|
| 68 |
+
(forall t, t < A -> V (f t) = bitof A w t) -> forallb (litv V) (lits A f v) = Nat.eqb w v.
|
| 69 |
+
Proof.
|
| 70 |
+
intros A V f v w Hv Hw H. unfold lits. rewrite forallb_map', <- (bits_eqb A w v Hw Hv).
|
| 71 |
+
apply forallb_ext_in. intros t Ht. apply in_seq in Ht. unfold litv. cbn [fst snd]. rewrite H by lia. reflexivity.
|
| 72 |
+
Qed.
|
| 73 |
+
|
| 74 |
+
Lemma all_ones : forall A w, w < 2 ^ A -> forallb (bitof A w) (seq 0 A) = Nat.eqb w (2 ^ A - 1).
|
| 75 |
+
Proof.
|
| 76 |
+
intros A w Hw. rewrite <- (bits_eqb A w (2 ^ A - 1) Hw) by lia.
|
| 77 |
+
apply forallb_ext_in. intros t Ht. apply in_seq in Ht.
|
| 78 |
+
assert (B : bitof A (2 ^ A - 1) t = true).
|
| 79 |
+
{ unfold bitof. replace (2 ^ A - 1) with (Nat.ones A) by (rewrite Nat.ones_equiv; lia).
|
| 80 |
+
apply Nat.ones_spec_low. lia. }
|
| 81 |
+
rewrite B. destruct (bitof A w t); reflexivity.
|
| 82 |
+
Qed.
|
| 83 |
+
|
| 84 |
+
Lemma existsb_filter_eq : forall (f : nat -> bool) p n, p < n ->
|
| 85 |
+
existsb (fun j => Nat.eqb p j) (filter f (seq 0 n)) = f p.
|
| 86 |
+
Proof.
|
| 87 |
+
intros f p n Hp. assert (E : forall l, existsb (fun j => Nat.eqb p j) (filter f l) = existsb (fun j => Nat.eqb p j && f j) l).
|
| 88 |
+
{ induction l as [|a l IH]; [reflexivity|]. cbn [filter existsb]. destruct (f a) eqn:Fa; cbn [existsb];
|
| 89 |
+
rewrite IH; destruct (Nat.eqb p a); reflexivity. }
|
| 90 |
+
rewrite E, existsb_pick. replace ((0 <=? p) && (p <? 0 + n)) with true by (symmetry; apply andb_true_iff; split;
|
| 91 |
+
[apply Nat.leb_le | apply Nat.ltb_lt]; lia). reflexivity.
|
| 92 |
+
Qed.
|
| 93 |
+
|
| 94 |
+
Lemma existsb_pick_r : forall (g : nat -> bool) c n, c < n ->
|
| 95 |
+
existsb (fun a => g a && Nat.eqb c a) (seq 0 n) = g c.
|
| 96 |
+
Proof.
|
| 97 |
+
intros g c n Hc. rewrite (existsb_ext_in _ _ (fun a => Nat.eqb c a && g a)) by (intros a _; apply andb_comm).
|
| 98 |
+
rewrite existsb_pick. replace ((0 <=? c) && (c <? 0 + n)) with true by (symmetry; apply andb_true_iff; split;
|
| 99 |
+
[apply Nat.leb_le | apply Nat.ltb_lt]; lia). reflexivity.
|
| 100 |
+
Qed.
|
| 101 |
+
|
| 102 |
+
(* ---- the step, block by block --------------------------------------------------------- *)
|
| 103 |
+
Section HSem.
|
| 104 |
+
Variables (A : nat) (s : hst).
|
| 105 |
+
Hypotheses (HA : 3 <= A) (Hv : hvalid A s).
|
| 106 |
+
|
| 107 |
+
Let HS : 8 <= SW A := SW_ge A HA.
|
| 108 |
+
|
| 109 |
+
Definition hp : nat := hpc s.
|
| 110 |
+
Definition hh : bool := hhalt s.
|
| 111 |
+
Definition mv (j : nat) : nat := memv s j.
|
| 112 |
+
|
| 113 |
+
Lemma hp_lt : hp < SW A.
|
| 114 |
+
Proof. destruct Hv as (H & _ & _). exact H. Qed.
|
| 115 |
+
|
| 116 |
+
Lemma mv_lt : forall j, j < SW A -> mv j < SW A.
|
| 117 |
+
Proof.
|
| 118 |
+
destruct Hv as (_ & Hl & Hf). intros j Hj. unfold mv, memv. rewrite Forall_forall in Hf.
|
| 119 |
+
apply Hf. apply nth_In. lia.
|
| 120 |
+
Qed.
|
| 121 |
+
|
| 122 |
+
Definition HX (i : nat) : bool := nth i (encodeH A s) false.
|
| 123 |
+
Definition HF (x : sref) : bool := run (host_units A) (nH A) HX (idx (nH A) (hblocks A) x).
|
| 124 |
+
|
| 125 |
+
Lemma HX_pc : forall i, i < A -> HX i = bitof A hp i.
|
| 126 |
+
Proof. intros i Hi. apply nth_encodeH_pc. exact Hi. Qed.
|
| 127 |
+
|
| 128 |
+
Lemma HX_mu : forall j t, j < SW A -> t < A -> HX (A + 1 + j * A + t) = bitof A (mv j) t.
|
| 129 |
+
Proof. destruct Hv as (_ & Hl & _). intros j t Hj Ht. apply nth_encodeH_mem; assumption. Qed.
|
| 130 |
+
|
| 131 |
+
Lemma HF_in : forall i, i < nH A -> HF (SIn i) = HX i.
|
| 132 |
+
Proof. intros i H. unfold HF, host_units. apply net_in. exact H. Qed.
|
| 133 |
+
|
| 134 |
+
Lemma HF_pc : forall i, i < A -> HF (pcb i) = bitof A hp i.
|
| 135 |
+
Proof. intros i Hi. unfold pcb. rewrite HF_in by (unfold nH; lia). apply HX_pc. exact Hi. Qed.
|
| 136 |
+
|
| 137 |
+
Lemma HF_halt : HF (haltb A) = hh.
|
| 138 |
+
Proof. unfold haltb. rewrite HF_in by (unfold nH; lia). apply nth_encodeH_halt. Qed.
|
| 139 |
+
|
| 140 |
+
Lemma HF_mu : forall j t, j < SW A -> t < A -> HF (mu A j t) = bitof A (mv j) t.
|
| 141 |
+
Proof. intros j t Hj Ht. unfold mu. rewrite HF_in by (unfold nH; nia). apply HX_mu; assumption. Qed.
|
| 142 |
+
|
| 143 |
+
Lemma HF_unit : forall b j r, b < length (hblocks A) ->
|
| 144 |
+
j < bcount (nth b (hblocks A) blk0) -> r < bsize (nth b (hblocks A) blk0) ->
|
| 145 |
+
HF (SRef b j r) = sfire' (sunit (hblocks A) b j r) HF.
|
| 146 |
+
Proof.
|
| 147 |
+
intros b j r Hb Hj Hr. unfold HF, host_units.
|
| 148 |
+
apply net_unit; [apply host_wf; exact HA | exact Hb | exact Hj | exact Hr].
|
| 149 |
+
Qed.
|
| 150 |
+
|
| 151 |
+
(* the units of the blocks before the carry terms, after them, and the carry terms *)
|
| 152 |
+
Lemma HF_pre : forall b j r, b < 17 -> j < bcount (nth b (hpre A) blk0) -> r < bsize (nth b (hpre A) blk0) ->
|
| 153 |
+
HF (SRef b j r) = sfire' (nth r (bshape (nth b (hpre A) blk0) j) su0) HF.
|
| 154 |
+
Proof.
|
| 155 |
+
intros b j r Hb Hj Hr. rewrite HF_unit; unfold sunit; rewrite ?nth_hb_pre by exact Hb; try reflexivity; try assumption.
|
| 156 |
+
rewrite length_hblocks by lia. unfold tb. lia.
|
| 157 |
+
Qed.
|
| 158 |
+
|
| 159 |
+
Lemma HF_post : forall i j r, i < 15 -> j < bcount (nth i (hpost A) blk0) -> r < bsize (nth i (hpost A) blk0) ->
|
| 160 |
+
HF (SRef (tb A + i) j r) = sfire' (nth r (bshape (nth i (hpost A) blk0) j) su0) HF.
|
| 161 |
+
Proof.
|
| 162 |
+
intros i j r Hi Hj Hr. rewrite HF_unit; unfold sunit; rewrite ?nth_hb_post by lia; try reflexivity; try assumption.
|
| 163 |
+
rewrite length_hblocks by lia. lia.
|
| 164 |
+
Qed.
|
| 165 |
+
|
| 166 |
+
Lemma HF_Tu : forall k r, 1 <= k -> k < A -> r < S k ->
|
| 167 |
+
HF (SRef (16 + k) 0 r) = sfire' (nth r (bshape (blk_T A k) 0) su0) HF.
|
| 168 |
+
Proof.
|
| 169 |
+
intros k r H1 H2 H3. rewrite HF_unit; unfold sunit; rewrite ?nth_hb_T by assumption; try reflexivity.
|
| 170 |
+
- rewrite length_hblocks by lia. unfold tb. lia.
|
| 171 |
+
- cbn [bcount blk_T]. lia.
|
| 172 |
+
- cbn [bsize blk_T]. exact H3.
|
| 173 |
+
Qed.
|
| 174 |
+
|
| 175 |
+
Ltac pre_fire b := rewrite (HF_pre b) by (cbn [nth hpre bcount bsize blk_P blk_HP blk_FA blk_Q blk_F blk_PA blk_PB
|
| 176 |
+
blk_AC blk_W blk_RX blk_RY blk_KP blk_X blk_Y blk_PR]; nia);
|
| 177 |
+
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
|
| 178 |
+
blk_PR].
|
| 179 |
+
|
| 180 |
+
Ltac post_fire i := rewrite (HF_post i) by (cbn [nth hpost bcount bsize blk_C blk_AX blk_NX blk_XN blk_EQ blk_R0
|
| 181 |
+
blk_H blk_R blk_LEQ blk_TA blk_TB blk_NP blk_HAB blk_WR blk_NM]; nia);
|
| 182 |
+
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
|
| 183 |
+
blk_WR blk_NM].
|
| 184 |
+
|
| 185 |
+
(* 0: decode lines of the counter *)
|
| 186 |
+
Lemma HF_P : forall j, j < SW A -> HF (SRef 0 j 0) = Nat.eqb hp j.
|
| 187 |
+
Proof.
|
| 188 |
+
intros j Hj. pre_fire 0. rewrite sAND_fire. apply (lits_fire A HF (pcb) j hp Hj hp_lt).
|
| 189 |
+
intros t Ht. apply HF_pc. exact Ht.
|
| 190 |
+
Qed.
|
| 191 |
+
|
| 192 |
+
(* 1 *)
|
| 193 |
+
Lemma HF_HP : forall i, i < A -> HF (SRef 1 i 0) = bitof A hp i && hh.
|
| 194 |
+
Proof.
|
| 195 |
+
intros i Hi. pre_fire 1. rewrite sAND_fire. cbn [forallb]. rewrite !litv_pos, HF_pc, HF_halt by exact Hi.
|
| 196 |
+
rewrite andb_true_r. reflexivity.
|
| 197 |
+
Qed.
|
| 198 |
+
|
| 199 |
+
(* 2, 3, 4: the fetch conjunctions *)
|
| 200 |
+
Lemma HF_FA : forall o m, o < 3 -> m < A * SW A ->
|
| 201 |
+
HF (SRef (2 + o) m 0) = bitof A (mv ((m mod SW A + o) mod SW A)) (m / SW A) && Nat.eqb hp (m mod SW A).
|
| 202 |
+
Proof.
|
| 203 |
+
intros o m Ho Hm. pose proof (Nat.mod_upper_bound m (SW A) ltac:(lia)).
|
| 204 |
+
pose proof (Nat.Div0.div_lt_upper_bound m (SW A) A ltac:(lia)).
|
| 205 |
+
assert (E : HF (SRef (2 + o) m 0)
|
| 206 |
+
= forallb (litv HF) [(mu A ((m mod SW A + o) mod SW A) (m / SW A), true); (SRef 0 (m mod SW A) 0, true)]).
|
| 207 |
+
{ destruct o as [|[|[|o]]]; [pre_fire 2 | pre_fire 3 | pre_fire 4 | lia]; apply sAND_fire. }
|
| 208 |
+
rewrite E. cbn [forallb]. rewrite !litv_pos, andb_true_r.
|
| 209 |
+
rewrite HF_mu by (try apply Nat.mod_upper_bound; lia). rewrite HF_P by lia. reflexivity.
|
| 210 |
+
Qed.
|
| 211 |
+
|
| 212 |
+
(* 5: the bits of p + 3 *)
|
| 213 |
+
Lemma HF_Q : forall i, i < A -> HF (SRef 5 i 0) = bitof A ((hp + 3) mod SW A) i.
|
| 214 |
+
Proof.
|
| 215 |
+
intros i Hi. pre_fire 5. rewrite sOR_fire, existsb_map'.
|
| 216 |
+
rewrite (existsb_ext_in _ _ (fun j => Nat.eqb hp j)).
|
| 217 |
+
- apply (existsb_filter_eq (fun j => bitof A ((j + 3) mod SW A) i) hp (SW A) hp_lt).
|
| 218 |
+
- intros j Hj. apply filter_In in Hj as [Hj _]. apply in_seq in Hj. rewrite litv_pos. apply HF_P. lia.
|
| 219 |
+
Qed.
|
| 220 |
+
|
| 221 |
+
(* 6: the operands *)
|
| 222 |
+
Lemma HF_F : forall m, m < 3 * A -> HF (SRef 6 m 0) = bitof A (mv ((hp + m / A) mod SW A)) (m mod A).
|
| 223 |
+
Proof.
|
| 224 |
+
intros m Hm. pose proof (Nat.Div0.div_lt_upper_bound m A 3 ltac:(lia)). pose proof (Nat.mod_upper_bound m A ltac:(lia)).
|
| 225 |
+
pre_fire 6. rewrite sOR_fire, existsb_map'.
|
| 226 |
+
rewrite (existsb_ext_in _ _ (fun j => bitof A (mv ((j + m / A) mod SW A)) (m mod A) && Nat.eqb hp j)).
|
| 227 |
+
- apply (existsb_pick_r (fun j => bitof A (mv ((j + m / A) mod SW A)) (m mod A))). exact hp_lt.
|
| 228 |
+
- intros j Hj. apply in_seq in Hj. rewrite litv_pos. rewrite HF_FA by (try lia; nia).
|
| 229 |
+
replace ((m mod A * SW A + j) mod SW A) with j
|
| 230 |
+
by (rewrite (Nat.add_comm (m mod A * SW A) j), Nat.Div0.mod_add, Nat.mod_small by lia; reflexivity).
|
| 231 |
+
replace ((m mod A * SW A + j) / SW A) with (m mod A)
|
| 232 |
+
by (rewrite (Nat.add_comm (m mod A * SW A) j), Nat.div_add, Nat.div_small by lia; lia).
|
| 233 |
+
reflexivity.
|
| 234 |
+
Qed.
|
| 235 |
+
|
| 236 |
+
Definition ha : nat := mv hp.
|
| 237 |
+
Definition hb : nat := mv ((hp + 1) mod SW A).
|
| 238 |
+
Definition hc : nat := mv ((hp + 2) mod SW A).
|
| 239 |
+
|
| 240 |
+
Lemma ha_lt : ha < SW A.
|
| 241 |
+
Proof. apply mv_lt. exact hp_lt. Qed.
|
| 242 |
+
Lemma hb_lt : hb < SW A.
|
| 243 |
+
Proof. apply mv_lt. apply Nat.mod_upper_bound. lia. Qed.
|
| 244 |
+
Lemma hc_lt : hc < SW A.
|
| 245 |
+
Proof. apply mv_lt. apply Nat.mod_upper_bound. lia. Qed.
|
| 246 |
+
|
| 247 |
+
Lemma HF_opb : forall o t, o < 3 -> t < A -> HF (opb A o t) = bitof A (mv ((hp + o) mod SW A)) t.
|
| 248 |
+
Proof.
|
| 249 |
+
intros o t Ho Ht. unfold opb. rewrite HF_F by nia.
|
| 250 |
+
replace ((o * A + t) / A) with o by (rewrite Nat.add_comm, Nat.div_add, Nat.div_small by lia; lia).
|
| 251 |
+
replace ((o * A + t) mod A) with t by (rewrite Nat.add_comm, Nat.Div0.mod_add, Nat.mod_small by lia; reflexivity).
|
| 252 |
+
reflexivity.
|
| 253 |
+
Qed.
|
| 254 |
+
|
| 255 |
+
Lemma HF_opa : forall t, t < A -> HF (opb A 0 t) = bitof A ha t.
|
| 256 |
+
Proof. intros t Ht. rewrite HF_opb by lia. rewrite Nat.add_0_r, Nat.mod_small by exact hp_lt. reflexivity. Qed.
|
| 257 |
+
|
| 258 |
+
(* 7, 8: decode lines of A and B *)
|
| 259 |
+
Lemma HF_PA : forall j, j < SW A -> HF (SRef 7 j 0) = Nat.eqb ha j.
|
| 260 |
+
Proof.
|
| 261 |
+
intros j Hj. pre_fire 7. rewrite sAND_fire. apply (lits_fire A HF (opb A 0) j ha Hj ha_lt).
|
| 262 |
+
intros t Ht. apply HF_opa. exact Ht.
|
| 263 |
+
Qed.
|
| 264 |
+
|
| 265 |
+
Lemma HF_PB : forall j, j < SW A -> HF (SRef 8 j 0) = Nat.eqb hb j.
|
| 266 |
+
Proof.
|
| 267 |
+
intros j Hj. pre_fire 8. rewrite sAND_fire. apply (lits_fire A HF (opb A 1) j hb Hj hb_lt).
|
| 268 |
+
intros t Ht. rewrite HF_opb by lia. reflexivity.
|
| 269 |
+
Qed.
|
| 270 |
+
|
| 271 |
+
(* 9: C is the halt address *)
|
| 272 |
+
Lemma HF_AC : HF (SRef 9 0 0) = Nat.eqb hc (SW A - 1).
|
| 273 |
+
Proof.
|
| 274 |
+
pre_fire 9. rewrite sAND_fire, forallb_map'. unfold SW. rewrite <- all_ones by exact hc_lt.
|
| 275 |
+
apply forallb_ext_in. intros t Ht. apply in_seq in Ht. rewrite litv_pos, HF_opb by lia. reflexivity.
|
| 276 |
+
Qed.
|
| 277 |
+
|
| 278 |
+
(* 10: write enables *)
|
| 279 |
+
Lemma HF_W : forall j, j < SW A -> HF (SRef 10 j 0) = negb hh && Nat.eqb hb j.
|
| 280 |
+
Proof.
|
| 281 |
+
intros j Hj. pre_fire 10. rewrite sAND_fire. cbn [forallb]. rewrite litv_neg, litv_pos, HF_halt, HF_PB by exact Hj.
|
| 282 |
+
rewrite andb_true_r. reflexivity.
|
| 283 |
+
Qed.
|
| 284 |
+
|
| 285 |
+
(* 11, 12: read conjunctions *)
|
| 286 |
+
Lemma HF_RX : forall m, m < A * SW A ->
|
| 287 |
+
HF (SRef 11 m 0) = bitof A (mv (m mod SW A)) (m / SW A) && Nat.eqb ha (m mod SW A).
|
| 288 |
+
Proof.
|
| 289 |
+
intros m Hm. pose proof (Nat.mod_upper_bound m (SW A) ltac:(lia)).
|
| 290 |
+
pose proof (Nat.Div0.div_lt_upper_bound m (SW A) A ltac:(lia)).
|
| 291 |
+
pre_fire 11. rewrite sAND_fire. cbn [forallb]. rewrite !litv_pos, HF_mu, HF_PA by lia. rewrite andb_true_r. reflexivity.
|
| 292 |
+
Qed.
|
| 293 |
+
|
| 294 |
+
Lemma HF_RY : forall m, m < A * SW A ->
|
| 295 |
+
HF (SRef 12 m 0) = bitof A (mv (m mod SW A)) (m / SW A) && Nat.eqb hb (m mod SW A).
|
| 296 |
+
Proof.
|
| 297 |
+
intros m Hm. pose proof (Nat.mod_upper_bound m (SW A) ltac:(lia)).
|
| 298 |
+
pose proof (Nat.Div0.div_lt_upper_bound m (SW A) A ltac:(lia)).
|
| 299 |
+
pre_fire 12. rewrite sAND_fire. cbn [forallb]. rewrite !litv_pos, HF_mu, HF_PB by lia. rewrite andb_true_r. reflexivity.
|
| 300 |
+
Qed.
|
| 301 |
+
|
| 302 |
+
(* 13: the cells kept *)
|
| 303 |
+
Lemma HF_KP : forall m, m < SW A * A ->
|
| 304 |
+
HF (SRef 13 m 0) = bitof A (mv (m / A)) (m mod A) && negb (negb hh && Nat.eqb hb (m / A)).
|
| 305 |
+
Proof.
|
| 306 |
+
intros m Hm. pose proof (Nat.mod_upper_bound m A ltac:(lia)).
|
| 307 |
+
pose proof (Nat.Div0.div_lt_upper_bound m A (SW A) ltac:(lia)).
|
| 308 |
+
pre_fire 13. rewrite sAND_fire. cbn [forallb]. rewrite litv_pos, litv_neg, HF_mu, HF_W by lia.
|
| 309 |
+
rewrite andb_true_r. reflexivity.
|
| 310 |
+
Qed.
|
| 311 |
+
|
| 312 |
+
(* 14, 15: x = M[A], y = M[B] *)
|
| 313 |
+
Definition hx : nat := mv ha.
|
| 314 |
+
Definition hy : nat := mv hb.
|
| 315 |
+
|
| 316 |
+
Lemma HF_X : forall t, t < A -> HF (SRef 14 t 0) = bitof A hx t.
|
| 317 |
+
Proof.
|
| 318 |
+
intros t Ht. pre_fire 14. rewrite sOR_fire, existsb_map'.
|
| 319 |
+
rewrite (existsb_ext_in _ _ (fun j => bitof A (mv j) t && Nat.eqb ha j)).
|
| 320 |
+
- apply (existsb_pick_r (fun j => bitof A (mv j) t)). exact ha_lt.
|
| 321 |
+
- intros j Hj. apply in_seq in Hj. rewrite litv_pos, HF_RX by nia.
|
| 322 |
+
rewrite (Nat.add_comm (t * SW A) j), Nat.Div0.mod_add, Nat.mod_small by lia.
|
| 323 |
+
replace ((j + t * SW A) / SW A) with t by (rewrite Nat.div_add, Nat.div_small by lia; lia).
|
| 324 |
+
reflexivity.
|
| 325 |
+
Qed.
|
| 326 |
+
|
| 327 |
+
Lemma HF_Y : forall t, t < A -> HF (SRef 15 t 0) = bitof A hy t.
|
| 328 |
+
Proof.
|
| 329 |
+
intros t Ht. pre_fire 15. rewrite sOR_fire, existsb_map'.
|
| 330 |
+
rewrite (existsb_ext_in _ _ (fun j => bitof A (mv j) t && Nat.eqb hb j)).
|
| 331 |
+
- apply (existsb_pick_r (fun j => bitof A (mv j) t)). exact hb_lt.
|
| 332 |
+
- intros j Hj. apply in_seq in Hj. rewrite litv_pos, HF_RY by nia.
|
| 333 |
+
rewrite (Nat.add_comm (t * SW A) j), Nat.Div0.mod_add, Nat.mod_small by lia.
|
| 334 |
+
replace ((j + t * SW A) / SW A) with t by (rewrite Nat.div_add, Nat.div_small by lia; lia).
|
| 335 |
+
reflexivity.
|
| 336 |
+
Qed.
|
| 337 |
+
|
| 338 |
+
Lemma HF_xv : forall i, i < A -> HF (xv A i) = Nat.testbit hx i.
|
| 339 |
+
Proof. intros i Hi. unfold xv. rewrite HF_X by lia. unfold bitof. f_equal. lia. Qed.
|
| 340 |
+
|
| 341 |
+
Lemma HF_yv : forall i, i < A -> HF (yv A i) = Nat.testbit hy i.
|
| 342 |
+
Proof. intros i Hi. unfold yv. rewrite HF_Y by lia. unfold bitof. f_equal. lia. Qed.
|
| 343 |
+
|
| 344 |
+
(* 16: propagate signals *)
|
| 345 |
+
Lemma HF_PR : forall i, i < A - 1 -> HF (prr i) = pg hx hy i.
|
| 346 |
+
Proof.
|
| 347 |
+
intros i Hi. unfold prr. pre_fire 16. rewrite sOR_fire. cbn [existsb]. rewrite litv_neg, litv_pos, HF_xv, HF_yv by lia.
|
| 348 |
+
rewrite orb_false_r. reflexivity.
|
| 349 |
+
Qed.
|
| 350 |
+
|
| 351 |
+
(* 17 to 15 + A: the carry terms *)
|
| 352 |
+
Lemma HF_Tn : forall k, 1 <= k -> k < A -> HF (SRef (16 + k) 0 0) = forallb (pg hx hy) (seq 0 k).
|
| 353 |
+
Proof.
|
| 354 |
+
intros k H1 H2. rewrite HF_Tu by lia. cbn [bshape blk_T nth]. rewrite sAND_fire, forallb_map'.
|
| 355 |
+
apply forallb_ext_in. intros i Hi. apply in_seq in Hi. rewrite litv_pos. apply HF_PR. lia.
|
| 356 |
+
Qed.
|
| 357 |
+
|
| 358 |
+
Lemma HF_Tj : forall k j, 1 <= k -> k < A -> j < k ->
|
| 359 |
+
HF (SRef (16 + k) 0 (S j)) = gb hx hy j && forallb (pg hx hy) (seq (S j) (k - S j)).
|
| 360 |
+
Proof.
|
| 361 |
+
intros k j H1 H2 H3. rewrite HF_Tu by lia. cbn [bshape blk_T nth].
|
| 362 |
+
rewrite nth_map_d with (d' := 0) by (rewrite length_seq; lia). rewrite seq_nth by lia.
|
| 363 |
+
rewrite sAND_fire. cbn [Nat.add forallb]. rewrite forallb_app. cbn [forallb].
|
| 364 |
+
rewrite litv_pos, litv_neg, HF_xv, HF_yv by lia. rewrite andb_true_r, forallb_map'.
|
| 365 |
+
rewrite (forallb_ext_in _ _ (pg hx hy)).
|
| 366 |
+
- unfold gb, xb, yb. reflexivity.
|
| 367 |
+
- intros i Hi. apply in_seq in Hi. rewrite litv_pos. apply HF_PR. lia.
|
| 368 |
+
Qed.
|
| 369 |
+
|
| 370 |
+
(* tb: carries *)
|
| 371 |
+
Lemma HF_C : forall m, m < A - 1 -> HF (SRef (tb A) m 0) = carry hx hy (S m).
|
| 372 |
+
Proof.
|
| 373 |
+
intros m Hm. rewrite <- (Nat.add_0_r (tb A)). post_fire 0. rewrite sOR_fire. cbn [existsb]. rewrite litv_pos.
|
| 374 |
+
rewrite HF_Tn by lia. rewrite existsb_map'.
|
| 375 |
+
rewrite (existsb_ext_in _ _ (fun j => gb hx hy j && forallb (pg hx hy) (seq (S j) (S m - S j)))).
|
| 376 |
+
- rewrite carry_closed. reflexivity.
|
| 377 |
+
- intros j Hj. apply in_seq in Hj. rewrite litv_pos. apply HF_Tj; lia.
|
| 378 |
+
Qed.
|
| 379 |
+
|
| 380 |
+
(* tb + 1 to tb + 4: equality *)
|
| 381 |
+
Lemma HF_XN : forall i, i < A -> HF (SRef (tb A + 3) i 0) = Bool.eqb (Nat.testbit hx i) (Nat.testbit hy i).
|
| 382 |
+
Proof.
|
| 383 |
+
intros i Hi. post_fire 3. rewrite sOR_fire. cbn [existsb]. rewrite !litv_pos, orb_false_r.
|
| 384 |
+
post_fire 1. post_fire 2. rewrite !sAND_fire. cbn [forallb]. rewrite !litv_pos, !litv_neg, HF_xv, HF_yv by lia.
|
| 385 |
+
destruct (Nat.testbit hx i), (Nat.testbit hy i); reflexivity.
|
| 386 |
+
Qed.
|
| 387 |
+
|
| 388 |
+
Lemma HF_EQ : HF (SRef (tb A + 4) 0 0) = Nat.eqb hx hy.
|
| 389 |
+
Proof.
|
| 390 |
+
post_fire 4. rewrite sAND_fire, forallb_map'. unfold SW in *.
|
| 391 |
+
rewrite <- (testbits_eqb A hx hy) by (apply mv_lt; first [exact ha_lt | exact hb_lt]).
|
| 392 |
+
apply forallb_ext_in. intros i Hi. apply in_seq in Hi. rewrite litv_pos. apply HF_XN. lia.
|
| 393 |
+
Qed.
|
| 394 |
+
|
| 395 |
+
(* tb + 5 to tb + 7: the sum bits *)
|
| 396 |
+
Lemma HF_R0 : HF (SRef (tb A + 5) 0 2) = sumbit hx hy 0.
|
| 397 |
+
Proof.
|
| 398 |
+
post_fire 5. rewrite sAND_fire. cbn [forallb]. rewrite !litv_pos, andb_true_r.
|
| 399 |
+
post_fire 5. post_fire 5. rewrite !sOR_fire. cbn [existsb]. rewrite !litv_pos, !litv_neg, HF_xv, HF_yv by lia.
|
| 400 |
+
unfold sumbit, xb, yb. cbn [carry]. destruct (Nat.testbit hx 0), (Nat.testbit hy 0); reflexivity.
|
| 401 |
+
Qed.
|
| 402 |
+
|
| 403 |
+
Definition cnt (k : nat) : nat :=
|
| 404 |
+
(if yb hy k then 1 else 0) + (if xb hx k then 0 else 1) + (if carry hx hy k then 1 else 0).
|
| 405 |
+
|
| 406 |
+
Lemma HF_H : forall m u, m < A - 1 -> u < 3 -> HF (SRef (tb A + 6) m u) = Nat.leb (S u) (cnt (S m)).
|
| 407 |
+
Proof.
|
| 408 |
+
intros m u Hm Hu. post_fire 6. rewrite nth_map_d with (d' := 0%Z) by (cbn [length]; lia).
|
| 409 |
+
unfold sfire'. cbn [sb sin swsum]. rewrite HF_xv, HF_yv by lia. rewrite HF_C by lia.
|
| 410 |
+
unfold cnt, xb, yb. destruct u as [|[|[|u]]]; [| | | lia]; cbn [nth];
|
| 411 |
+
destruct (Nat.testbit hy (S m)), (Nat.testbit hx (S m)), (carry hx hy (S m)); reflexivity.
|
| 412 |
+
Qed.
|
| 413 |
+
|
| 414 |
+
Lemma HF_R : forall m, m < A - 1 -> HF (SRef (tb A + 7) m 0) = sumbit hx hy (S m).
|
| 415 |
+
Proof.
|
| 416 |
+
intros m Hm. post_fire 7. unfold sfire'. cbn [sb sin swsum]. rewrite !HF_H by lia.
|
| 417 |
+
unfold sumbit, cnt, xb, yb. destruct (Nat.testbit hy (S m)), (Nat.testbit hx (S m)), (carry hx hy (S m)); reflexivity.
|
| 418 |
+
Qed.
|
| 419 |
+
|
| 420 |
+
Lemma HF_rbit : forall k, k < A -> HF (rbit A k) = sumbit hx hy k.
|
| 421 |
+
Proof.
|
| 422 |
+
intros k Hk. unfold rbit. destruct (Nat.eqb_spec k 0) as [->|E]; [apply HF_R0|].
|
| 423 |
+
rewrite HF_R by lia. f_equal. lia.
|
| 424 |
+
Qed.
|
| 425 |
+
|
| 426 |
+
(* the difference and the branch *)
|
| 427 |
+
Definition hr : nat := (hy + SW A - hx) mod SW A.
|
| 428 |
+
Definition hleq : bool := Nat.eqb hr 0 || Nat.leb (2 ^ (A - 1)) hr.
|
| 429 |
+
|
| 430 |
+
Lemma hx_lt : hx < 2 ^ A.
|
| 431 |
+
Proof. apply mv_lt. exact ha_lt. Qed.
|
| 432 |
+
Lemma hy_lt : hy < 2 ^ A.
|
| 433 |
+
Proof. apply mv_lt. exact hb_lt. Qed.
|
| 434 |
+
|
| 435 |
+
Lemma hr_bits : forall k, k < A -> Nat.testbit hr k = sumbit hx hy k.
|
| 436 |
+
Proof. intros k Hk. unfold hr, SW. apply sub_bits; [exact hx_lt | exact hy_lt | exact Hk]. Qed.
|
| 437 |
+
|
| 438 |
+
(* tb + 8: the branch *)
|
| 439 |
+
Lemma HF_LEQ : HF (SRef (tb A + 8) 0 0) = hleq.
|
| 440 |
+
Proof.
|
| 441 |
+
post_fire 8. unfold sfire'. cbn [sb sin swsum]. rewrite !HF_H by lia. rewrite HF_EQ.
|
| 442 |
+
replace (S (A - 2)) with (A - 1) by lia.
|
| 443 |
+
assert (T : sumbit hx hy (A - 1) = Nat.leb (2 ^ (A - 1)) hr).
|
| 444 |
+
{ rewrite <- hr_bits by lia. apply testbit_top; [lia|]. unfold hr, SW. apply Nat.mod_upper_bound, Nat.pow_nonzero.
|
| 445 |
+
lia. }
|
| 446 |
+
assert (Z : Nat.eqb hx hy = Nat.eqb hr 0).
|
| 447 |
+
{ unfold hr, SW. rewrite sub_zero; [reflexivity | exact hx_lt | exact hy_lt]. }
|
| 448 |
+
unfold hleq. rewrite <- T, <- Z. unfold sumbit, cnt, xb, yb.
|
| 449 |
+
destruct (Nat.testbit hy (A - 1)), (Nat.testbit hx (A - 1)), (carry hx hy (A - 1)), (Nat.eqb hx hy); reflexivity.
|
| 450 |
+
Qed.
|
| 451 |
+
|
| 452 |
+
(* tb + 9 to tb + 11: the next counter *)
|
| 453 |
+
Lemma HF_NP : forall i, i < A ->
|
| 454 |
+
HF (SRef (tb A + 11) i 0) = (bitof A hp i && hh) || (negb hh && hleq && bitof A hc i)
|
| 455 |
+
|| (negb hh && negb hleq && bitof A ((hp + 3) mod SW A) i).
|
| 456 |
+
Proof.
|
| 457 |
+
intros i Hi. post_fire 11. rewrite sOR_fire. cbn [existsb]. rewrite !litv_pos, orb_false_r.
|
| 458 |
+
rewrite HF_HP by exact Hi. post_fire 9. post_fire 10. rewrite !sAND_fire. cbn [forallb].
|
| 459 |
+
rewrite !litv_pos, !litv_neg, HF_halt, HF_LEQ, HF_Q by exact Hi. rewrite HF_opb by lia.
|
| 460 |
+
rewrite !andb_true_r, !andb_assoc, orb_assoc. reflexivity.
|
| 461 |
+
Qed.
|
| 462 |
+
|
| 463 |
+
(* tb + 12: the halt latch *)
|
| 464 |
+
Lemma HF_NH : HF (SRef (tb A + 12) 0 2) =
|
| 465 |
+
hh || (negb hh && hleq && Nat.eqb hc (SW A - 1)) || (negb hh && negb hleq && Nat.eqb hp (SW A - 4)).
|
| 466 |
+
Proof.
|
| 467 |
+
post_fire 12. rewrite sOR_fire. cbn [existsb]. rewrite !litv_pos, orb_false_r, HF_halt.
|
| 468 |
+
post_fire 12. post_fire 12. rewrite !sAND_fire. cbn [forallb].
|
| 469 |
+
rewrite !litv_pos, !litv_neg, HF_halt, HF_LEQ, HF_AC, HF_P by lia.
|
| 470 |
+
rewrite !andb_true_r, !andb_assoc, orb_assoc. reflexivity.
|
| 471 |
+
Qed.
|
| 472 |
+
|
| 473 |
+
(* tb + 13, tb + 14: the next memory *)
|
| 474 |
+
Lemma HF_NM : forall m, m < SW A * A ->
|
| 475 |
+
HF (SRef (tb A + 14) m 0) =
|
| 476 |
+
(bitof A (mv (m / A)) (m mod A) && negb (negb hh && Nat.eqb hb (m / A)))
|
| 477 |
+
|| (bitof A hr (m mod A) && (negb hh && Nat.eqb hb (m / A))).
|
| 478 |
+
Proof.
|
| 479 |
+
intros m Hm. pose proof (Nat.mod_upper_bound m A ltac:(lia)).
|
| 480 |
+
pose proof (Nat.Div0.div_lt_upper_bound m A (SW A) ltac:(lia)).
|
| 481 |
+
post_fire 14. rewrite sOR_fire. cbn [existsb]. rewrite !litv_pos, orb_false_r. rewrite HF_KP by exact Hm.
|
| 482 |
+
post_fire 13. rewrite sAND_fire. cbn [forallb]. rewrite !litv_pos, andb_true_r, HF_rbit, HF_W by lia.
|
| 483 |
+
rewrite <- hr_bits by lia. unfold bitof. reflexivity.
|
| 484 |
+
Qed.
|
| 485 |
+
|
| 486 |
+
End HSem.
|
| 487 |
+
|
| 488 |
+
(* ---- the step ------------------------------------------------------------------------ *)
|
| 489 |
+
Lemma p3_halt : forall A p, 3 <= A -> p < SW A -> Nat.eqb ((p + 3) mod SW A) (SW A - 1) = Nat.eqb p (SW A - 4).
|
| 490 |
+
Proof.
|
| 491 |
+
intros A p HA Hp. pose proof (SW_ge A HA).
|
| 492 |
+
destruct (Nat.lt_ge_cases (p + 3) (SW A)) as [L|L].
|
| 493 |
+
- rewrite Nat.mod_small by exact L. destruct (Nat.eqb_spec (p + 3) (SW A - 1)), (Nat.eqb_spec p (SW A - 4)); lia.
|
| 494 |
+
- replace (p + 3) with ((p + 3 - SW A) + 1 * SW A) by lia. rewrite Nat.Div0.mod_add, Nat.mod_small by lia.
|
| 495 |
+
destruct (Nat.eqb_spec (p + 3 - SW A) (SW A - 1)), (Nat.eqb_spec p (SW A - 4)); lia.
|
| 496 |
+
Qed.
|
| 497 |
+
|
| 498 |
+
(* the step of the machine in the names of the section *)
|
| 499 |
+
Lemma subleq_halted : forall A s, hhalt s = true -> subleq A s = s.
|
| 500 |
+
Proof. intros A s H. unfold subleq. rewrite H. reflexivity. Qed.
|
| 501 |
+
|
| 502 |
+
Lemma subleq_run : forall A s, hhalt s = false ->
|
| 503 |
+
subleq A s = mkH (if hleq A s then hc A s else (hp s + 3) mod SW A)
|
| 504 |
+
(Nat.eqb (if hleq A s then hc A s else (hp s + 3) mod SW A) (SW A - 1))
|
| 505 |
+
(map (fun j => if Nat.eqb j (hb A s) then hr A s else memv s j) (seq 0 (SW A))).
|
| 506 |
+
Proof. intros A s H. unfold subleq. rewrite H. reflexivity. Qed.
|
| 507 |
+
|
| 508 |
+
Lemma memv_run : forall A s j, hhalt s = false -> j < SW A ->
|
| 509 |
+
memv (subleq A s) j = if Nat.eqb j (hb A s) then hr A s else memv s j.
|
| 510 |
+
Proof.
|
| 511 |
+
intros A s j H Hj. rewrite subleq_run by exact H. unfold memv at 1. cbn [hmem].
|
| 512 |
+
rewrite nth_map_seq by exact Hj. reflexivity.
|
| 513 |
+
Qed.
|
| 514 |
+
|
| 515 |
+
Theorem host_step : forall A s, 3 <= A -> hvalid A s ->
|
| 516 |
+
netstep (nH A) (host_units A) (host_next A) (encodeH A s) = encodeH A (subleq A s).
|
| 517 |
+
Proof.
|
| 518 |
+
intros A s HA Hv. pose proof (SW_ge A HA) as HS. pose proof Hv as (Hp & Hl & Hf).
|
| 519 |
+
assert (Hl' : length (hmem (subleq A s)) = SW A).
|
| 520 |
+
{ unfold subleq. destruct (hhalt s); [exact Hl|]. cbn [hmem]. rewrite length_map, length_seq. reflexivity. }
|
| 521 |
+
unfold netstep, host_next. rewrite map_map.
|
| 522 |
+
apply nth_ext with (d := false) (d' := false).
|
| 523 |
+
{ rewrite length_map, length_seq, length_encodeH by exact Hl'. reflexivity. }
|
| 524 |
+
intros i Hi. rewrite length_map, length_seq in Hi.
|
| 525 |
+
rewrite (nth_map_seq _ (fun i => run (host_units A) (nH A) (fun i0 => nth i0 (encodeH A s) false)
|
| 526 |
+
(idx (nH A) (hblocks A) (hout A i))) (nH A) i false Hi).
|
| 527 |
+
change (run (host_units A) (nH A) (fun i0 => nth i0 (encodeH A s) false) (idx (nH A) (hblocks A) (hout A i)))
|
| 528 |
+
with (HF A s (hout A i)).
|
| 529 |
+
unfold hout. destruct (Nat.ltb_spec i A) as [Hi1|Hi1].
|
| 530 |
+
- (* the counter *)
|
| 531 |
+
rewrite HF_NP by assumption. rewrite nth_encodeH_pc by exact Hi1. unfold hh.
|
| 532 |
+
destruct (hhalt s) eqn:Eh.
|
| 533 |
+
+ rewrite subleq_halted by exact Eh. cbn [negb andb orb]. rewrite andb_true_r, !orb_false_r. reflexivity.
|
| 534 |
+
+ rewrite subleq_run by exact Eh. cbn [hpc negb andb orb]. rewrite andb_false_r, orb_false_l.
|
| 535 |
+
destruct (hleq A s); cbn [negb andb orb]; rewrite ?orb_false_r; reflexivity.
|
| 536 |
+
- destruct (Nat.eqb_spec i A) as [->|Hi2].
|
| 537 |
+
+ (* the halt bit *)
|
| 538 |
+
rewrite HF_NH by assumption. rewrite nth_encodeH_halt. unfold hh.
|
| 539 |
+
destruct (hhalt s) eqn:Eh.
|
| 540 |
+
* rewrite subleq_halted by exact Eh. rewrite Eh. reflexivity.
|
| 541 |
+
* rewrite subleq_run by exact Eh. cbn [hhalt negb andb orb].
|
| 542 |
+
destruct (hleq A s); cbn [negb andb orb]; [rewrite orb_false_r; reflexivity|].
|
| 543 |
+
rewrite p3_halt by (unfold hp; assumption). reflexivity.
|
| 544 |
+
+ (* the memory *)
|
| 545 |
+
remember (i - A - 1) as m eqn:Em. assert (Hm : m < SW A * A) by (unfold nH in Hi; lia).
|
| 546 |
+
pose proof (Nat.mod_upper_bound m A ltac:(lia)). pose proof (Nat.Div0.div_lt_upper_bound m A (SW A) ltac:(lia)).
|
| 547 |
+
replace i with (A + 1 + (m / A) * A + m mod A) by (pose proof (Nat.div_mod_eq m A); lia).
|
| 548 |
+
rewrite HF_NM by assumption. rewrite nth_encodeH_mem by assumption. unfold hh.
|
| 549 |
+
destruct (hhalt s) eqn:Eh.
|
| 550 |
+
* rewrite subleq_halted by exact Eh. cbn [negb andb orb]. rewrite andb_true_r, andb_false_r, orb_false_r.
|
| 551 |
+
reflexivity.
|
| 552 |
+
* rewrite memv_run by assumption. rewrite (Nat.eqb_sym (m / A) (hb A s)).
|
| 553 |
+
destruct (Nat.eqb (hb A s) (m / A)); cbn [negb andb orb];
|
| 554 |
+
rewrite ?andb_true_r, ?andb_false_r, ?orb_false_r, ?orb_false_l; reflexivity.
|
| 555 |
+
Qed.
|
rocq/HostWF.v
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
(* The host netlist reads, at every unit, only state bits and earlier units, for every A >= 3. *)
|
| 2 |
+
From Stdlib Require Import List Bool Arith ZArith Lia.
|
| 3 |
+
Import ListNotations.
|
| 4 |
+
From TH Require Import TwoHead Net Gates Host.
|
| 5 |
+
|
| 6 |
+
Lemma SW_ge : forall A, 3 <= A -> 8 <= SW A.
|
| 7 |
+
Proof.
|
| 8 |
+
intros A H. unfold SW. replace A with (3 + (A - 3)) by lia. rewrite Nat.pow_add_r.
|
| 9 |
+
pose proof (Nat.pow_nonzero 2 (A - 3) ltac:(lia)). cbn [Nat.pow]. lia.
|
| 10 |
+
Qed.
|
| 11 |
+
|
| 12 |
+
Lemma length_hpre : forall A, length (hpre A) = 17.
|
| 13 |
+
Proof. reflexivity. Qed.
|
| 14 |
+
|
| 15 |
+
Lemma length_hpost : forall A, length (hpost A) = 15.
|
| 16 |
+
Proof. reflexivity. Qed.
|
| 17 |
+
|
| 18 |
+
Lemma length_hblocks : forall A, 1 <= A -> length (hblocks A) = tb A + 15.
|
| 19 |
+
Proof.
|
| 20 |
+
intros A H. unfold hblocks, tb. rewrite !length_app, length_map, length_seq, length_hpre, length_hpost. lia.
|
| 21 |
+
Qed.
|
| 22 |
+
|
| 23 |
+
Lemma nth_hb_pre : forall A b, b < 17 -> nth b (hblocks A) blk0 = nth b (hpre A) blk0.
|
| 24 |
+
Proof. intros A b H. unfold hblocks. rewrite app_nth1 by (rewrite length_hpre; exact H). reflexivity. Qed.
|
| 25 |
+
|
| 26 |
+
Lemma nth_hb_T : forall A k, 1 <= k -> k < A -> nth (16 + k) (hblocks A) blk0 = blk_T A k.
|
| 27 |
+
Proof.
|
| 28 |
+
intros A k H1 H2. unfold hblocks. rewrite app_nth2 by (rewrite length_hpre; lia). rewrite length_hpre.
|
| 29 |
+
rewrite app_nth1 by (rewrite length_map, length_seq; lia).
|
| 30 |
+
rewrite nth_map_d with (d' := 0) by (rewrite length_seq; lia). rewrite seq_nth by lia. f_equal. lia.
|
| 31 |
+
Qed.
|
| 32 |
+
|
| 33 |
+
Lemma nth_hb_post : forall A i, 1 <= A -> nth (tb A + i) (hblocks A) blk0 = nth i (hpost A) blk0.
|
| 34 |
+
Proof.
|
| 35 |
+
intros A i H. unfold hblocks, tb. rewrite app_nth2 by (rewrite length_hpre; lia). rewrite length_hpre.
|
| 36 |
+
rewrite app_nth2 by (rewrite length_map, length_seq; lia). rewrite length_map, length_seq. f_equal. lia.
|
| 37 |
+
Qed.
|
| 38 |
+
|
| 39 |
+
(* what a conjunction or a disjunction of literals reads *)
|
| 40 |
+
Lemma in_sin_lits : forall ls x w,
|
| 41 |
+
In (x, w) (sin (sAND ls)) \/ In (x, w) (sin (sOR ls)) -> In x (map fst ls).
|
| 42 |
+
Proof.
|
| 43 |
+
intros ls x w H. cbn [sin sAND sOR] in H.
|
| 44 |
+
assert (K : In (x, w) (map lw ls) -> In x (map fst ls)).
|
| 45 |
+
{ intro H'. apply in_map_iff in H' as ([y p] & E & Hl). unfold lw in E. cbn [fst snd] in E.
|
| 46 |
+
injection E as Ey _. subst y. apply in_map_iff. exists (x, p). split; [reflexivity | exact Hl]. }
|
| 47 |
+
destruct H as [H|H]; apply K; exact H.
|
| 48 |
+
Qed.
|
| 49 |
+
|
| 50 |
+
Section Reads.
|
| 51 |
+
Variable A : nat.
|
| 52 |
+
|
| 53 |
+
Let rb := reads_back (hblocks A) (nH A).
|
| 54 |
+
|
| 55 |
+
Lemma rb_in : forall b j r i, i < nH A -> rb b j r (SIn i).
|
| 56 |
+
Proof. intros b j r i H. exact H. Qed.
|
| 57 |
+
|
| 58 |
+
Lemma rb_mu : forall b j r j' t, j' < SW A -> t < A -> rb b j r (mu A j' t).
|
| 59 |
+
Proof. intros b j r j' t H1 H2. unfold mu. apply rb_in. unfold nH. nia. Qed.
|
| 60 |
+
|
| 61 |
+
Lemma rb_pre : forall b j r b' j' r', b' < 17 -> b' < b ->
|
| 62 |
+
j' < bcount (nth b' (hpre A) blk0) -> r' < bsize (nth b' (hpre A) blk0) -> rb b j r (SRef b' j' r').
|
| 63 |
+
Proof. intros b j r b' j' r' H1 H2 H3 H4. left. rewrite nth_hb_pre by exact H1. auto. Qed.
|
| 64 |
+
|
| 65 |
+
Lemma rb_T : forall b j r k r', 1 <= k -> k < A -> 16 + k < b -> r' < S k -> rb b j r (SRef (16 + k) 0 r').
|
| 66 |
+
Proof. intros b j r k r' H1 H2 H3 H4. left. rewrite nth_hb_T by assumption. cbn [bcount bsize blk_T]. lia. Qed.
|
| 67 |
+
|
| 68 |
+
Lemma rb_post : forall b j r i j' r', 1 <= A -> tb A + i < b ->
|
| 69 |
+
j' < bcount (nth i (hpost A) blk0) -> r' < bsize (nth i (hpost A) blk0) -> rb b j r (SRef (tb A + i) j' r').
|
| 70 |
+
Proof. intros b j r i j' r' H0 H1 H2 H3. left. rewrite nth_hb_post by lia. auto. Qed.
|
| 71 |
+
|
| 72 |
+
Lemma rb_post0 : forall b j r j' r', 1 <= A -> tb A < b ->
|
| 73 |
+
j' < bcount (nth 0 (hpost A) blk0) -> r' < bsize (nth 0 (hpost A) blk0) -> rb b j r (SRef (tb A) j' r').
|
| 74 |
+
Proof.
|
| 75 |
+
intros b j r j' r' H0 H1 H2 H3. left. pose proof (nth_hb_post A 0 H0) as E. rewrite Nat.add_0_r in E.
|
| 76 |
+
rewrite E. auto.
|
| 77 |
+
Qed.
|
| 78 |
+
|
| 79 |
+
Lemma rb_self : forall b j r r', r' < r -> rb b j r (SRef b j r').
|
| 80 |
+
Proof. intros b j r r' H. right. auto. Qed.
|
| 81 |
+
|
| 82 |
+
Lemma rb_xv : forall b j r i, 1 <= A -> 15 < b -> rb b j r (xv A i).
|
| 83 |
+
Proof. intros b j r i H0 H. unfold xv. apply rb_pre; cbn [nth hpre bcount bsize blk_X]; lia. Qed.
|
| 84 |
+
|
| 85 |
+
Lemma rb_yv : forall b j r i, 1 <= A -> 15 < b -> rb b j r (yv A i).
|
| 86 |
+
Proof. intros b j r i H0 H. unfold yv. apply rb_pre; cbn [nth hpre bcount bsize blk_Y]; lia. Qed.
|
| 87 |
+
|
| 88 |
+
Lemma rb_opb : forall b j r o t, 6 < b -> o < 3 -> t < A -> rb b j r (opb A o t).
|
| 89 |
+
Proof. intros b j r o t H1 H2 H3. unfold opb. apply rb_pre; cbn [nth hpre bcount bsize blk_F]; nia. Qed.
|
| 90 |
+
|
| 91 |
+
Lemma rb_prr : forall b j r i, 16 < b -> i < A - 1 -> rb b j r (prr i).
|
| 92 |
+
Proof. intros b j r i H1 H2. unfold prr. apply rb_pre; cbn [nth hpre bcount bsize blk_PR]; lia. Qed.
|
| 93 |
+
|
| 94 |
+
Lemma rb_rbit : forall b j r k, tb A + 7 < b -> k < A -> rb b j r (rbit A k).
|
| 95 |
+
Proof.
|
| 96 |
+
intros b j r k H1 H2. unfold rbit. destruct (Nat.eqb_spec k 0).
|
| 97 |
+
- apply rb_post; cbn [nth hpost bcount bsize blk_R0]; lia.
|
| 98 |
+
- apply rb_post; cbn [nth hpost bcount bsize blk_R]; lia.
|
| 99 |
+
Qed.
|
| 100 |
+
|
| 101 |
+
End Reads.
|
| 102 |
+
|
| 103 |
+
Lemma mod_lt : forall a n, 0 < n -> a mod n < n.
|
| 104 |
+
Proof. intros a n H. apply Nat.mod_upper_bound. lia. Qed.
|
| 105 |
+
|
| 106 |
+
Lemma div_lt : forall a b n, a < b * n -> 0 < n -> a / n < b.
|
| 107 |
+
Proof. intros a b n H1 H2. apply Nat.Div0.div_lt_upper_bound. lia. Qed.
|
| 108 |
+
|
| 109 |
+
Ltac lits_in Hin :=
|
| 110 |
+
let H := fresh in
|
| 111 |
+
pose proof (in_sin_lits _ _ _ (or_introl Hin)) as H || pose proof (in_sin_lits _ _ _ (or_intror Hin)) as H;
|
| 112 |
+
clear Hin; unfold lits in H; rewrite ?map_map in H; cbn [map fst] in H.
|
| 113 |
+
|
| 114 |
+
Theorem host_wf : forall A, 3 <= A -> wf (hblocks A) (nH A).
|
| 115 |
+
Proof.
|
| 116 |
+
intros A HA. pose proof (SW_ge A HA) as HS.
|
| 117 |
+
split.
|
| 118 |
+
{ unfold hblocks. apply Forall_app; split; [|apply Forall_app; split].
|
| 119 |
+
- unfold hpre. repeat apply Forall_cons; try apply Forall_nil; intros j Hj; reflexivity.
|
| 120 |
+
- apply Forall_forall. intros blk Hin. apply in_map_iff in Hin as (k & <- & _).
|
| 121 |
+
intros j Hj. cbn [bshape bsize blk_T length]. rewrite length_map, length_seq. reflexivity.
|
| 122 |
+
- unfold hpost. repeat apply Forall_cons; try apply Forall_nil; intros j Hj; reflexivity. }
|
| 123 |
+
intros b j r x w Hb Hj Hr Hin. rewrite length_hblocks in Hb by lia. unfold sunit in Hin.
|
| 124 |
+
destruct (Nat.lt_ge_cases b 17) as [Hp|Hp].
|
| 125 |
+
{ rewrite nth_hb_pre in Hj, Hr, Hin by exact Hp.
|
| 126 |
+
assert (Hc : b = 0 \/ b = 1 \/ b = 2 \/ b = 3 \/ b = 4 \/ b = 5 \/ b = 6 \/ b = 7 \/ b = 8 \/ b = 9
|
| 127 |
+
\/ b = 10 \/ b = 11 \/ b = 12 \/ b = 13 \/ b = 14 \/ b = 15 \/ b = 16) by lia.
|
| 128 |
+
destruct Hc as [->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->| ->]]]]]]]]]]]]]]]];
|
| 129 |
+
cbn [nth hpre bcount bsize bshape blk_P blk_HP blk_FA blk_Q blk_F blk_PA blk_PB blk_AC blk_W
|
| 130 |
+
blk_RX blk_RY blk_KP blk_X blk_Y blk_PR] in Hj, Hr, Hin;
|
| 131 |
+
(destruct r as [|r]; [|lia]); cbn [nth] in Hin.
|
| 132 |
+
- (* P *) lits_in Hin. apply in_map_iff in H as (t & <- & Ht). apply in_seq in Ht. apply rb_in. unfold nH. nia.
|
| 133 |
+
- (* HP *) lits_in Hin. destruct H as [<-|[<-|[]]]; apply rb_in; unfold nH; nia.
|
| 134 |
+
- (* FA 0 *) lits_in Hin. pose proof (mod_lt j (SW A) ltac:(lia)). pose proof (div_lt j A (SW A) ltac:(lia) ltac:(lia)).
|
| 135 |
+
destruct H as [<-|[<-|[]]]; [apply rb_mu; [apply mod_lt|]; lia|].
|
| 136 |
+
apply rb_pre; cbn [nth hpre bcount bsize blk_P]; lia.
|
| 137 |
+
- (* FA 1 *) lits_in Hin. pose proof (mod_lt j (SW A) ltac:(lia)). pose proof (div_lt j A (SW A) ltac:(lia) ltac:(lia)).
|
| 138 |
+
destruct H as [<-|[<-|[]]]; [apply rb_mu; [apply mod_lt|]; lia|].
|
| 139 |
+
apply rb_pre; cbn [nth hpre bcount bsize blk_P]; lia.
|
| 140 |
+
- (* FA 2 *) lits_in Hin. pose proof (mod_lt j (SW A) ltac:(lia)). pose proof (div_lt j A (SW A) ltac:(lia) ltac:(lia)).
|
| 141 |
+
destruct H as [<-|[<-|[]]]; [apply rb_mu; [apply mod_lt|]; lia|].
|
| 142 |
+
apply rb_pre; cbn [nth hpre bcount bsize blk_P]; lia.
|
| 143 |
+
- (* Q *) lits_in Hin. rewrite ?map_map in H. apply in_map_iff in H as (j' & <- & Hj').
|
| 144 |
+
apply filter_In in Hj' as [Hj' _]. apply in_seq in Hj'.
|
| 145 |
+
apply rb_pre; cbn [nth hpre bcount bsize blk_P]; lia.
|
| 146 |
+
- (* F *) lits_in Hin. rewrite ?map_map in H. apply in_map_iff in H as (j' & <- & Hj'). apply in_seq in Hj'.
|
| 147 |
+
cbn [fst]. pose proof (div_lt j 3 A ltac:(lia) ltac:(lia)). pose proof (mod_lt j A ltac:(lia)).
|
| 148 |
+
apply rb_pre; [lia | lia | |].
|
| 149 |
+
+ assert (Ho : j / A = 0 \/ j / A = 1 \/ j / A = 2) by lia.
|
| 150 |
+
destruct Ho as [-> | [-> | ->]]; cbn [Nat.add nth hpre bcount blk_FA]; nia.
|
| 151 |
+
+ assert (Ho : j / A = 0 \/ j / A = 1 \/ j / A = 2) by lia.
|
| 152 |
+
destruct Ho as [-> | [-> | ->]]; cbn [Nat.add nth hpre bsize blk_FA]; lia.
|
| 153 |
+
- (* PA *) lits_in Hin. apply in_map_iff in H as (t & <- & Ht). apply in_seq in Ht. apply rb_opb; lia.
|
| 154 |
+
- (* PB *) lits_in Hin. apply in_map_iff in H as (t & <- & Ht). apply in_seq in Ht. apply rb_opb; lia.
|
| 155 |
+
- (* AC *) lits_in Hin. rewrite ?map_map in H. apply in_map_iff in H as (t & <- & Ht). apply in_seq in Ht.
|
| 156 |
+
apply rb_opb; lia.
|
| 157 |
+
- (* W *) lits_in Hin. destruct H as [<-|[<-|[]]]; [apply rb_in; unfold nH; nia|].
|
| 158 |
+
apply rb_pre; cbn [nth hpre bcount bsize blk_PB]; lia.
|
| 159 |
+
- (* RX *) lits_in Hin. pose proof (mod_lt j (SW A) ltac:(lia)). pose proof (div_lt j A (SW A) ltac:(lia) ltac:(lia)).
|
| 160 |
+
destruct H as [<-|[<-|[]]]; [apply rb_mu; lia|]. apply rb_pre; cbn [nth hpre bcount bsize blk_PA]; lia.
|
| 161 |
+
- (* RY *) lits_in Hin. pose proof (mod_lt j (SW A) ltac:(lia)). pose proof (div_lt j A (SW A) ltac:(lia) ltac:(lia)).
|
| 162 |
+
destruct H as [<-|[<-|[]]]; [apply rb_mu; lia|]. apply rb_pre; cbn [nth hpre bcount bsize blk_PB]; lia.
|
| 163 |
+
- (* KP *) lits_in Hin. pose proof (mod_lt j A ltac:(lia)). pose proof (div_lt j (SW A) A ltac:(lia) ltac:(lia)).
|
| 164 |
+
destruct H as [<-|[<-|[]]]; [apply rb_mu; lia|]. apply rb_pre; cbn [nth hpre bcount bsize blk_W]; lia.
|
| 165 |
+
- (* X *) lits_in Hin. rewrite ?map_map in H. apply in_map_iff in H as (j' & <- & Hj'). apply in_seq in Hj'.
|
| 166 |
+
apply rb_pre; cbn [nth hpre bcount bsize blk_RX]; nia.
|
| 167 |
+
- (* Y *) lits_in Hin. rewrite ?map_map in H. apply in_map_iff in H as (j' & <- & Hj'). apply in_seq in Hj'.
|
| 168 |
+
apply rb_pre; cbn [nth hpre bcount bsize blk_RY]; nia.
|
| 169 |
+
- (* PR *) lits_in Hin. destruct H as [<-|[<-|[]]]; [apply rb_xv | apply rb_yv]; lia. }
|
| 170 |
+
destruct (Nat.lt_ge_cases b (tb A)) as [HT|HT].
|
| 171 |
+
{ (* the carry terms into bit k = b - 16 *)
|
| 172 |
+
unfold tb in HT. replace b with (16 + (b - 16)) in Hj, Hr, Hin |- * by lia.
|
| 173 |
+
rewrite nth_hb_T in Hj, Hr, Hin by lia. cbn [bcount bsize bshape blk_T] in Hj, Hr, Hin.
|
| 174 |
+
destruct r as [|r].
|
| 175 |
+
- cbn [nth] in Hin. lits_in Hin. rewrite ?map_map in H. apply in_map_iff in H as (i & <- & Hi). apply in_seq in Hi.
|
| 176 |
+
apply rb_prr; lia.
|
| 177 |
+
- cbn [nth] in Hin. rewrite nth_map_d with (d' := 0) in Hin by (rewrite length_seq; lia).
|
| 178 |
+
rewrite seq_nth in Hin by lia. lits_in Hin. rewrite ?map_app, ?map_map in H. cbn [map fst] in H.
|
| 179 |
+
destruct H as [<-|[<-|H]]; [apply rb_yv; lia | apply rb_xv; lia|].
|
| 180 |
+
apply in_map_iff in H as (i & <- & Hi). apply in_seq in Hi. apply rb_prr; lia. }
|
| 181 |
+
replace b with (tb A + (b - tb A)) in Hj, Hr, Hin |- * by lia.
|
| 182 |
+
rewrite nth_hb_post in Hj, Hr, Hin by lia.
|
| 183 |
+
assert (Hi : b - tb A < 15) by (unfold tb in *; lia).
|
| 184 |
+
remember (b - tb A) as i eqn:Ei. clear Ei Hb Hp HT.
|
| 185 |
+
assert (Hc : i = 0 \/ i = 1 \/ i = 2 \/ i = 3 \/ i = 4 \/ i = 5 \/ i = 6 \/ i = 7 \/ i = 8 \/ i = 9
|
| 186 |
+
\/ i = 10 \/ i = 11 \/ i = 12 \/ i = 13 \/ i = 14) by lia.
|
| 187 |
+
destruct Hc as [->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->|[->| ->]]]]]]]]]]]]]];
|
| 188 |
+
cbn [nth hpost bcount bsize bshape blk_C blk_AX blk_NX blk_XN blk_EQ blk_R0 blk_H blk_R blk_LEQ
|
| 189 |
+
blk_TA blk_TB blk_NP blk_HAB blk_WR blk_NM] in Hj, Hr, Hin.
|
| 190 |
+
- (* C *) destruct r as [|r]; [|lia]. cbn [nth] in Hin. lits_in Hin. destruct H as [<-|H].
|
| 191 |
+
+ apply rb_T; unfold tb; lia.
|
| 192 |
+
+ rewrite ?map_map in H. apply in_map_iff in H as (j' & <- & Hj'). apply in_seq in Hj'. apply rb_T; unfold tb; lia.
|
| 193 |
+
- (* AX *) destruct r as [|r]; [|lia]. cbn [nth] in Hin. lits_in Hin.
|
| 194 |
+
destruct H as [<-|[<-|[]]]; [apply rb_xv | apply rb_yv]; unfold tb; lia.
|
| 195 |
+
- (* NX *) destruct r as [|r]; [|lia]. cbn [nth] in Hin. lits_in Hin.
|
| 196 |
+
destruct H as [<-|[<-|[]]]; [apply rb_xv | apply rb_yv]; unfold tb; lia.
|
| 197 |
+
- (* XN *) destruct r as [|r]; [|lia]. cbn [nth] in Hin. lits_in Hin.
|
| 198 |
+
destruct H as [<-|[<-|[]]]; apply rb_post; cbn [nth hpost bcount bsize blk_AX blk_NX]; lia.
|
| 199 |
+
- (* EQ *) destruct r as [|r]; [|lia]. cbn [nth] in Hin. lits_in Hin. rewrite ?map_map in H.
|
| 200 |
+
apply in_map_iff in H as (i' & <- & Hi'). apply in_seq in Hi'.
|
| 201 |
+
apply rb_post; cbn [nth hpost bcount bsize blk_XN]; lia.
|
| 202 |
+
- (* R0 *) assert (Hj0 : j = 0) by lia. subst j. assert (Hr3 : r = 0 \/ r = 1 \/ r = 2) by lia.
|
| 203 |
+
destruct Hr3 as [->|[->| ->]]; cbn [nth] in Hin; lits_in Hin.
|
| 204 |
+
+ destruct H as [<-|[<-|[]]]; [apply rb_yv | apply rb_xv]; unfold tb; lia.
|
| 205 |
+
+ destruct H as [<-|[<-|[]]]; [apply rb_yv | apply rb_xv]; unfold tb; lia.
|
| 206 |
+
+ destruct H as [<-|[<-|[]]]; apply rb_self; lia.
|
| 207 |
+
- (* H *) assert (Hr3 : r = 0 \/ r = 1 \/ r = 2) by lia.
|
| 208 |
+
destruct Hr3 as [->|[->| ->]];
|
| 209 |
+
cbn [nth map sin] in Hin; repeat (destruct Hin as [Hin|Hin]; [injection Hin as <- <-|]); try destruct Hin;
|
| 210 |
+
first [apply rb_yv; unfold tb; lia | apply rb_xv; unfold tb; lia
|
| 211 |
+
| apply rb_post0; cbn [nth hpost bcount bsize blk_C]; lia].
|
| 212 |
+
- (* R *) destruct r as [|r]; [|lia]. cbn [nth sin] in Hin.
|
| 213 |
+
repeat (destruct Hin as [Hin|Hin]; [injection Hin as <- <-|]); try destruct Hin;
|
| 214 |
+
apply rb_post; cbn [nth hpost bcount bsize blk_H]; lia.
|
| 215 |
+
- (* LEQ *) destruct r as [|r]; [|lia]. cbn [nth sin] in Hin.
|
| 216 |
+
repeat (destruct Hin as [Hin|Hin]; [injection Hin as <- <-|]); try destruct Hin;
|
| 217 |
+
apply rb_post; cbn [nth hpost bcount bsize blk_H blk_EQ]; lia.
|
| 218 |
+
- (* TA *) destruct r as [|r]; [|lia]. cbn [nth] in Hin. lits_in Hin.
|
| 219 |
+
destruct H as [<-|[<-|[<-|[]]]]; [apply rb_in; unfold nH; lia
|
| 220 |
+
| apply rb_post; cbn [nth hpost bcount bsize blk_LEQ]; lia
|
| 221 |
+
| apply rb_opb; unfold tb; lia].
|
| 222 |
+
- (* TB *) destruct r as [|r]; [|lia]. cbn [nth] in Hin. lits_in Hin.
|
| 223 |
+
destruct H as [<-|[<-|[<-|[]]]]; [apply rb_in; unfold nH; lia
|
| 224 |
+
| apply rb_post; cbn [nth hpost bcount bsize blk_LEQ]; lia
|
| 225 |
+
| apply rb_pre; [lia | unfold tb; lia | cbn [nth hpre bcount blk_Q]; lia
|
| 226 |
+
| cbn [nth hpre bsize blk_Q]; lia]].
|
| 227 |
+
- (* NP *) destruct r as [|r]; [|lia]. cbn [nth] in Hin. lits_in Hin.
|
| 228 |
+
destruct H as [<-|[<-|[<-|[]]]];
|
| 229 |
+
[ apply rb_pre; [lia | unfold tb; lia | cbn [nth hpre bcount blk_HP]; lia | cbn [nth hpre bsize blk_HP]; lia]
|
| 230 |
+
| apply rb_post; cbn [nth hpost bcount bsize blk_TA]; lia
|
| 231 |
+
| apply rb_post; cbn [nth hpost bcount bsize blk_TB]; lia ].
|
| 232 |
+
- (* HA, HB, NH *) assert (Hj0 : j = 0) by lia. subst j. assert (Hr3 : r = 0 \/ r = 1 \/ r = 2) by lia.
|
| 233 |
+
destruct Hr3 as [->|[->| ->]]; cbn [nth] in Hin; lits_in Hin.
|
| 234 |
+
+ destruct H as [<-|[<-|[<-|[]]]];
|
| 235 |
+
[ apply rb_in; unfold nH; lia
|
| 236 |
+
| apply rb_post; cbn [nth hpost bcount bsize blk_LEQ]; lia
|
| 237 |
+
| apply rb_pre; [lia | unfold tb; lia | cbn [nth hpre bcount blk_AC]; lia | cbn [nth hpre bsize blk_AC]; lia] ].
|
| 238 |
+
+ destruct H as [<-|[<-|[<-|[]]]];
|
| 239 |
+
[ apply rb_in; unfold nH; lia
|
| 240 |
+
| apply rb_post; cbn [nth hpost bcount bsize blk_LEQ]; lia
|
| 241 |
+
| apply rb_pre; [lia | unfold tb; lia | cbn [nth hpre bcount blk_P]; lia | cbn [nth hpre bsize blk_P]; lia] ].
|
| 242 |
+
+ destruct H as [<-|[<-|[<-|[]]]]; [apply rb_in; unfold nH; lia | apply rb_self; lia | apply rb_self; lia].
|
| 243 |
+
- (* WR *) destruct r as [|r]; [|lia]. cbn [nth] in Hin. lits_in Hin.
|
| 244 |
+
pose proof (div_lt j (SW A) A ltac:(lia) ltac:(lia)).
|
| 245 |
+
destruct H as [<-|[<-|[]]]; [apply rb_rbit; lia|].
|
| 246 |
+
apply rb_pre; [lia | unfold tb; lia | cbn [nth hpre bcount blk_W]; lia | cbn [nth hpre bsize blk_W]; lia].
|
| 247 |
+
- (* NM *) destruct r as [|r]; [|lia]. cbn [nth] in Hin. lits_in Hin.
|
| 248 |
+
destruct H as [<-|[<-|[]]];
|
| 249 |
+
[ apply rb_pre; [lia | unfold tb; lia | cbn [nth hpre bcount blk_KP]; lia | cbn [nth hpre bsize blk_KP]; lia]
|
| 250 |
+
| apply rb_post; cbn [nth hpost bcount bsize blk_WR]; lia ].
|
| 251 |
+
Qed.
|
rocq/PhysSem.v
CHANGED
|
@@ -98,6 +98,21 @@ Proof.
|
|
| 98 |
unfold stepA, stepres, cellof, wnext, clearq. cbv zeta. rewrite Hk, Hp, Hd. subst v. reflexivity.
|
| 99 |
Qed.
|
| 100 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
Section Sem.
|
| 102 |
Variables (al N L : nat) (s : st).
|
| 103 |
Hypotheses (Hal : 3 <= al) (HN : recw al <= N) (HL : 1 <= L)
|
|
@@ -258,21 +273,6 @@ Proof.
|
|
| 258 |
destruct (Nat.eqb_spec (a - 3) 0); [lia|]. f_equal. lia.
|
| 259 |
Qed.
|
| 260 |
|
| 261 |
-
Lemma existsb_pick : forall (g : nat -> bool) c n m,
|
| 262 |
-
existsb (fun a => Nat.eqb c a && g a) (seq m n) = if (m <=? c) && (c <? m + n) then g c else false.
|
| 263 |
-
Proof.
|
| 264 |
-
intros g c n. induction n as [|n IH]; intro m; cbn [seq existsb].
|
| 265 |
-
- destruct (Nat.leb_spec m c), (Nat.ltb_spec c (m + 0)); cbn [andb]; try reflexivity; lia.
|
| 266 |
-
- rewrite IH. destruct (Nat.eqb_spec c m) as [E|E].
|
| 267 |
-
+ subst c. rewrite Nat.leb_refl.
|
| 268 |
-
replace (m <? m + S n) with true by (symmetry; apply Nat.ltb_lt; lia).
|
| 269 |
-
replace (S m <=? m) with false by (symmetry; apply Nat.leb_gt; lia).
|
| 270 |
-
cbn [andb orb]. destruct (g m); reflexivity.
|
| 271 |
-
+ cbn [andb orb].
|
| 272 |
-
destruct (Nat.leb_spec m c), (Nat.leb_spec (S m) c), (Nat.ltb_spec c (S m + n)), (Nat.ltb_spec c (m + S n));
|
| 273 |
-
cbn [andb]; try reflexivity; lia.
|
| 274 |
-
Qed.
|
| 275 |
-
|
| 276 |
Definition fa (o : nat) : nat := bits2nat (field o).
|
| 277 |
|
| 278 |
Lemma fa_lt : forall o, o + al <= recw al -> fa o < W al.
|
|
|
|
| 98 |
unfold stepA, stepres, cellof, wnext, clearq. cbv zeta. rewrite Hk, Hp, Hd. subst v. reflexivity.
|
| 99 |
Qed.
|
| 100 |
|
| 101 |
+
Lemma existsb_pick : forall (g : nat -> bool) c n m,
|
| 102 |
+
existsb (fun a => Nat.eqb c a && g a) (seq m n) = if (m <=? c) && (c <? m + n) then g c else false.
|
| 103 |
+
Proof.
|
| 104 |
+
intros g c n. induction n as [|n IH]; intro m; cbn [seq existsb].
|
| 105 |
+
- destruct (Nat.leb_spec m c), (Nat.ltb_spec c (m + 0)); cbn [andb]; try reflexivity; lia.
|
| 106 |
+
- rewrite IH. destruct (Nat.eqb_spec c m) as [E|E].
|
| 107 |
+
+ subst c. rewrite Nat.leb_refl.
|
| 108 |
+
replace (m <? m + S n) with true by (symmetry; apply Nat.ltb_lt; lia).
|
| 109 |
+
replace (S m <=? m) with false by (symmetry; apply Nat.leb_gt; lia).
|
| 110 |
+
cbn [andb orb]. destruct (g m); reflexivity.
|
| 111 |
+
+ cbn [andb orb].
|
| 112 |
+
destruct (Nat.leb_spec m c), (Nat.leb_spec (S m) c), (Nat.ltb_spec c (S m + n)), (Nat.ltb_spec c (m + S n));
|
| 113 |
+
cbn [andb]; try reflexivity; lia.
|
| 114 |
+
Qed.
|
| 115 |
+
|
| 116 |
Section Sem.
|
| 117 |
Variables (al N L : nat) (s : st).
|
| 118 |
Hypotheses (Hal : 3 <= al) (HN : recw al <= N) (HL : 1 <= L)
|
|
|
|
| 273 |
destruct (Nat.eqb_spec (a - 3) 0); [lia|]. f_equal. lia.
|
| 274 |
Qed.
|
| 275 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 276 |
Definition fa (o : nat) : nat := bits2nat (field o).
|
| 277 |
|
| 278 |
Lemma fa_lt : forall o, o + al <= recw al -> fa o < W al.
|
rocq/_CoqProject
CHANGED
|
@@ -24,3 +24,8 @@ PhysMain.v
|
|
| 24 |
PhysFacts.v
|
| 25 |
NetMain.v
|
| 26 |
Extract.v
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
PhysFacts.v
|
| 25 |
NetMain.v
|
| 26 |
Extract.v
|
| 27 |
+
Host.v
|
| 28 |
+
HostWF.v
|
| 29 |
+
Adder.v
|
| 30 |
+
HostSem.v
|
| 31 |
+
ExtractHost.v
|
rocq/extract/dumphost.ml
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
(* writes the host netlist defined in Host.v, extracted by ExtractHost.v: dumphost A PATH *)
|
| 2 |
+
let () =
|
| 3 |
+
let a = int_of_string Sys.argv.(1) in
|
| 4 |
+
let us = Hostnet.host_units a and nx = Hostnet.host_next a in
|
| 5 |
+
let oc = open_out_bin Sys.argv.(2) in
|
| 6 |
+
let put x = let b = Bytes.create 4 in Bytes.set_int32_le b 0 (Int32.of_int x); output_bytes oc b in
|
| 7 |
+
let edges = List.fold_left (fun acc (u : Hostnet.tu) -> acc + List.length u.tin) 0 us in
|
| 8 |
+
put (Hostnet.nH a); put (List.length us); put edges;
|
| 9 |
+
List.iter (fun (u : Hostnet.tu) -> put u.tb) us;
|
| 10 |
+
List.iter (fun (u : Hostnet.tu) -> put (List.length u.tin)) us;
|
| 11 |
+
List.iter (fun (u : Hostnet.tu) -> List.iter (fun (s, wt) -> put (wt * (s + 1))) u.tin) us;
|
| 12 |
+
List.iter put nx;
|
| 13 |
+
close_out oc
|
src/independent.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
"""Code written from the paper's text alone: H_A, the levelization, noise
|
| 2 |
import hashlib
|
| 3 |
import json
|
| 4 |
import math
|
|
@@ -393,177 +393,6 @@ def main_levelize():
|
|
| 393 |
w(len(blob))
|
| 394 |
f.write(blob)
|
| 395 |
|
| 396 |
-
NPZ = os.path.join(WORK, 'datapath.npz')
|
| 397 |
-
|
| 398 |
-
RECORD = os.path.join(REPO, 'paper', 'runs', 'independent_neuromorphic.json')
|
| 399 |
-
|
| 400 |
-
K = 9
|
| 401 |
-
|
| 402 |
-
|
| 403 |
-
def record(key, value):
|
| 404 |
-
rec = json.load(open(RECORD)) if os.path.exists(RECORD) else {}
|
| 405 |
-
rec[key] = value
|
| 406 |
-
json.dump(rec, open(RECORD, 'w'), indent=1)
|
| 407 |
-
|
| 408 |
-
|
| 409 |
-
def export():
|
| 410 |
-
N, nxt = build(8)
|
| 411 |
-
blocks = N.block
|
| 412 |
-
nst = N.n
|
| 413 |
-
keep = [k for k, b in enumerate(blocks) if b in ('sub', 'eq', 'LEQ')]
|
| 414 |
-
keepset = set(N.n + k for k in keep)
|
| 415 |
-
# inputs: the units X_t, Y_t of block XY; outputs: r_0..r_7 and LEQ
|
| 416 |
-
xy = [N.n + k for k, b in enumerate(blocks) if b == 'XY']
|
| 417 |
-
X, Y = xy[:8], xy[8:]
|
| 418 |
-
units = {N.n + k: (N.bias[k], N.ins[k]) for k in keep}
|
| 419 |
-
# the outputs: the sum bits are the last 8 units feeding WR, recovered as the inputs of NM's AND units
|
| 420 |
-
sub = [N.n + k for k, b in enumerate(blocks) if b == 'sub']
|
| 421 |
-
r = [sub[-8]] + sub[-7:] # r_0 is the AND of the XOR cell, then r_1..r_7
|
| 422 |
-
leq = [N.n + k for k, b in enumerate(blocks) if b == 'LEQ'][0]
|
| 423 |
-
inputs = X + Y
|
| 424 |
-
outputs = r + [leq]
|
| 425 |
-
# check the choice of outputs by evaluating the cut-out circuit on all pairs
|
| 426 |
-
def ev(xa, xb):
|
| 427 |
-
v = {}
|
| 428 |
-
for t in range(8):
|
| 429 |
-
v[X[t]] = (xa >> t) & 1
|
| 430 |
-
v[Y[t]] = (xb >> t) & 1
|
| 431 |
-
for u in sorted(units):
|
| 432 |
-
b, ins = units[u]
|
| 433 |
-
v[u] = 1 if b + sum(w * v[s] for s, w in ins) >= 0 else 0
|
| 434 |
-
return sum(v[r[k]] << k for k in range(8)), v[leq]
|
| 435 |
-
for xa in range(256):
|
| 436 |
-
for xb in (0, 1, 127, 128, 255, xa, (xa + 1) % 256):
|
| 437 |
-
res = (xb - xa) % 256
|
| 438 |
-
assert ev(xa, xb) == (res, int(res == 0 or res >= 128)), (xa, xb)
|
| 439 |
-
# levelize (Lemma 2.6) with the inputs at layer 0
|
| 440 |
-
depth = {s: 0 for s in inputs}
|
| 441 |
-
for u in sorted(units):
|
| 442 |
-
depth[u] = 1 + max(depth[s] for s, _ in units[u][1])
|
| 443 |
-
d = max(depth[o] for o in outputs)
|
| 444 |
-
lam = {}
|
| 445 |
-
for u in units:
|
| 446 |
-
for s, _ in units[u][1]:
|
| 447 |
-
lam[s] = max(lam.get(s, 0), depth[u])
|
| 448 |
-
for o in outputs:
|
| 449 |
-
lam[o] = d + 1
|
| 450 |
-
layers, prev = [], {s: i for i, s in enumerate(inputs)}
|
| 451 |
-
for l in range(1, d + 1):
|
| 452 |
-
rows = []
|
| 453 |
-
if l < d:
|
| 454 |
-
for s in list(inputs) + sorted(units):
|
| 455 |
-
if s in units and depth[s] == l:
|
| 456 |
-
rows.append((s, units[s][0], units[s][1]))
|
| 457 |
-
elif depth[s] < l < lam.get(s, -1):
|
| 458 |
-
rows.append((s, -1, [(s, 1)]))
|
| 459 |
-
else:
|
| 460 |
-
for o in outputs:
|
| 461 |
-
rows.append((o, units[o][0], units[o][1]) if depth[o] == d else (o, -1, [(o, 1)]))
|
| 462 |
-
W = np.zeros((len(rows), len(prev)), dtype=np.int32)
|
| 463 |
-
b = np.zeros(len(rows), dtype=np.int32)
|
| 464 |
-
for i, (_, bb, ins) in enumerate(rows):
|
| 465 |
-
b[i] = bb
|
| 466 |
-
for s, w in ins:
|
| 467 |
-
W[i, prev[s]] = w
|
| 468 |
-
layers.append((W, b))
|
| 469 |
-
prev = {s: i for i, (s, _, _) in enumerate(rows)}
|
| 470 |
-
out = dict(n_layers=np.array([d]), n_units=np.array([len(units)]))
|
| 471 |
-
for i, (W, b) in enumerate(layers):
|
| 472 |
-
out[f'W{i}'], out[f'b{i}'] = W, b
|
| 473 |
-
os.makedirs(WORK, exist_ok=True)
|
| 474 |
-
np.savez(NPZ, **out)
|
| 475 |
-
res = dict(units=len(units), depth=d, widths=[int(W.shape[0]) for W, _ in layers])
|
| 476 |
-
record('datapath', res)
|
| 477 |
-
print(json.dumps(res))
|
| 478 |
-
|
| 479 |
-
|
| 480 |
-
def reference(xa, xb):
|
| 481 |
-
res = (xb - xa) % 256
|
| 482 |
-
return res, int(res == 0 or res >= 128)
|
| 483 |
-
|
| 484 |
-
|
| 485 |
-
def operands(n, seed):
|
| 486 |
-
rng = np.random.default_rng(seed)
|
| 487 |
-
xa = rng.integers(0, 256, n)
|
| 488 |
-
xb = rng.integers(0, 256, n)
|
| 489 |
-
xa[:256], xb[:256] = np.arange(256), 0
|
| 490 |
-
xa[256:512], xb[256:512] = 0, np.arange(256)
|
| 491 |
-
xa[512:768], xb[512:768] = np.arange(256), np.arange(256)
|
| 492 |
-
return xa, xb
|
| 493 |
-
|
| 494 |
-
|
| 495 |
-
def lava(off):
|
| 496 |
-
from lava.magma.core.run_conditions import RunSteps
|
| 497 |
-
from lava.magma.core.run_configs import Loihi2SimCfg
|
| 498 |
-
from lava.proc.dense.process import Dense
|
| 499 |
-
from lava.proc.io.sink import RingBuffer as Sink
|
| 500 |
-
from lava.proc.io.source import RingBuffer as Source
|
| 501 |
-
from lava.proc.lif.process import LIF
|
| 502 |
-
z = np.load(NPZ)
|
| 503 |
-
L = int(z['n_layers'][0])
|
| 504 |
-
layers = [(z[f'W{i}'], z[f'b{i}']) for i in range(L)]
|
| 505 |
-
N = 4096
|
| 506 |
-
xa, xb = operands(N, 77)
|
| 507 |
-
spikes = np.zeros((16, N))
|
| 508 |
-
for k in range(8):
|
| 509 |
-
spikes[k] = (xa >> k) & 1
|
| 510 |
-
spikes[8 + k] = (xb >> k) & 1
|
| 511 |
-
T = N + L + 2
|
| 512 |
-
src = Source(data=np.pad(spikes, ((0, 0), (0, T - N))))
|
| 513 |
-
prev, first = src.s_out, None
|
| 514 |
-
vth = 2 * K - 2 + off
|
| 515 |
-
for W, b in layers:
|
| 516 |
-
dn = Dense(weights=(2 * W).astype(np.int32))
|
| 517 |
-
lif = LIF(shape=(W.shape[0],), du=4095, dv=4095, bias_mant=(b + K).astype(np.int32), bias_exp=7, vth=vth)
|
| 518 |
-
prev.connect(dn.s_in)
|
| 519 |
-
dn.a_out.connect(lif.a_in)
|
| 520 |
-
prev, first = lif.s_out, first or lif
|
| 521 |
-
snk = Sink(shape=(9,), buffer=T)
|
| 522 |
-
prev.connect(snk.a_in)
|
| 523 |
-
first.run(condition=RunSteps(num_steps=T), run_cfg=Loihi2SimCfg(select_tag='fixed_pt'))
|
| 524 |
-
out = snk.data.get()
|
| 525 |
-
first.stop()
|
| 526 |
-
bad = 0
|
| 527 |
-
for t in range(N):
|
| 528 |
-
col = out[:, t + L]
|
| 529 |
-
bad += (sum(int(col[k]) << k for k in range(8)), int(col[8])) != reference(int(xa[t]), int(xb[t]))
|
| 530 |
-
# the membrane potential of a unit at pre-activation z is 128 (z + K); the threshold is 64 vth
|
| 531 |
-
margin_fire = 128 * K - 64 * vth
|
| 532 |
-
margin_quiet = 64 * vth - 128 * (K - 1)
|
| 533 |
-
res = dict(backend='lava fixed_pt', vth=vth, patterns=N, failures=bad,
|
| 534 |
-
margin_firing_side=margin_fire, margin_quiet_side=margin_quiet)
|
| 535 |
-
record(f'lava_vth_{vth}', res)
|
| 536 |
-
print(json.dumps(res))
|
| 537 |
-
|
| 538 |
-
|
| 539 |
-
def akida():
|
| 540 |
-
import akida as ak
|
| 541 |
-
from akida import FullyConnected, InputData, Model
|
| 542 |
-
z = np.load(NPZ)
|
| 543 |
-
L = int(z['n_layers'][0])
|
| 544 |
-
layers = [(z[f'W{i}'], z[f'b{i}']) for i in range(L)]
|
| 545 |
-
m = Model()
|
| 546 |
-
m.add(InputData(input_shape=(1, 1, 16), input_bits=1))
|
| 547 |
-
for i, (W, b) in enumerate(layers):
|
| 548 |
-
m.add(FullyConnected(units=int(W.shape[0]), weights_bits=2, activation=True, act_bits=1, name=f'l{i}'))
|
| 549 |
-
lay = m.get_layer(i + 1)
|
| 550 |
-
wv = np.zeros(lay.variables['weights'].shape, dtype=np.int8)
|
| 551 |
-
wv[0, 0, :, :] = W.T.astype(np.int8)
|
| 552 |
-
lay.variables['weights'] = wv
|
| 553 |
-
lay.variables['threshold'] = (-b - 1).astype(np.int32)
|
| 554 |
-
N = 65536
|
| 555 |
-
xa, xb = np.arange(N) % 256, np.arange(N) // 256
|
| 556 |
-
Xin = np.zeros((N, 1, 1, 16), dtype=np.uint8)
|
| 557 |
-
for k in range(8):
|
| 558 |
-
Xin[:, 0, 0, k] = (xa >> k) & 1
|
| 559 |
-
Xin[:, 0, 0, 8 + k] = (xb >> k) & 1
|
| 560 |
-
out = np.concatenate([m.forward(Xin[i:i + 8192]).reshape(-1, 9) for i in range(0, N, 8192)])
|
| 561 |
-
bad = sum((sum(int(out[t, k]) << k for k in range(8)), int(out[t, 8])) != reference(int(xa[t]), int(xb[t]))
|
| 562 |
-
for t in range(N))
|
| 563 |
-
res = dict(backend=f'akida {ak.__version__}', patterns=N, failures=int(bad))
|
| 564 |
-
record('akida', res)
|
| 565 |
-
print(json.dumps(res))
|
| 566 |
-
|
| 567 |
NSIM, BIN, HIST = os.path.join(WORK, 'nsim'), os.path.join(WORK, 'host_lev.bin'), os.path.join(WORK, 'hist_sd.bin')
|
| 568 |
|
| 569 |
M = 41967
|
|
@@ -624,7 +453,6 @@ def main_noise():
|
|
| 624 |
print(json.dumps({k: v for k, v in out.items() if k in ('exact_self_reproducing', 'profile', 'seconds')}))
|
| 625 |
|
| 626 |
|
| 627 |
-
|
| 628 |
def load():
|
| 629 |
b = open(BIN, 'rb').read()
|
| 630 |
pos = 0
|
|
@@ -748,17 +576,7 @@ def cmd_host_family():
|
|
| 748 |
json.dump(out, open(os.path.join(RUNS, 'independent_host_family.json'), 'w'), indent=1)
|
| 749 |
|
| 750 |
|
| 751 |
-
|
| 752 |
-
cmd = sys.argv[1]
|
| 753 |
-
if cmd == 'export':
|
| 754 |
-
export()
|
| 755 |
-
elif cmd == 'lava':
|
| 756 |
-
lava(int(sys.argv[2]))
|
| 757 |
-
else:
|
| 758 |
-
akida()
|
| 759 |
-
|
| 760 |
-
|
| 761 |
-
COMMANDS = {'host-family': cmd_host_family, 'levelize': main_levelize, 'neuromorphic': cmd_neuromorphic, 'noise': main_noise, 'weight-error': main_weight_error}
|
| 762 |
|
| 763 |
|
| 764 |
if __name__ == "__main__":
|
|
|
|
| 1 |
+
"""Code written from the paper's text alone: H_A, the levelization, noise and weight error."""
|
| 2 |
import hashlib
|
| 3 |
import json
|
| 4 |
import math
|
|
|
|
| 393 |
w(len(blob))
|
| 394 |
f.write(blob)
|
| 395 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 396 |
NSIM, BIN, HIST = os.path.join(WORK, 'nsim'), os.path.join(WORK, 'host_lev.bin'), os.path.join(WORK, 'hist_sd.bin')
|
| 397 |
|
| 398 |
M = 41967
|
|
|
|
| 453 |
print(json.dumps({k: v for k, v in out.items() if k in ('exact_self_reproducing', 'profile', 'seconds')}))
|
| 454 |
|
| 455 |
|
|
|
|
| 456 |
def load():
|
| 457 |
b = open(BIN, 'rb').read()
|
| 458 |
pos = 0
|
|
|
|
| 576 |
json.dump(out, open(os.path.join(RUNS, 'independent_host_family.json'), 'w'), indent=1)
|
| 577 |
|
| 578 |
|
| 579 |
+
COMMANDS = {'host-family': cmd_host_family, 'levelize': main_levelize, 'noise': main_noise, 'weight-error': main_weight_error}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 580 |
|
| 581 |
|
| 582 |
if __name__ == "__main__":
|
src/noise.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
"""Perturbation experiments on the levelized host
|
| 2 |
from __future__ import annotations
|
| 3 |
|
| 4 |
import argparse
|
|
@@ -12,8 +12,6 @@ import tempfile
|
|
| 12 |
import time
|
| 13 |
from typing import Dict, List, Tuple
|
| 14 |
|
| 15 |
-
import numpy as np
|
| 16 |
-
|
| 17 |
from host import (
|
| 18 |
encode,
|
| 19 |
M_P,
|
|
@@ -21,17 +19,14 @@ from host import (
|
|
| 21 |
HALT_PC,
|
| 22 |
Tape,
|
| 23 |
describe,
|
| 24 |
-
field,
|
| 25 |
inst,
|
| 26 |
read_host,
|
| 27 |
ser,
|
| 28 |
tau_star,
|
| 29 |
-
run_reference,
|
| 30 |
STATE_LAYOUT,
|
| 31 |
IO_CELLS,
|
| 32 |
-
STATE_BITS,
|
| 33 |
)
|
| 34 |
-
from paper import levelize, parse_sigma, write_flat
|
| 35 |
|
| 36 |
|
| 37 |
REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
@@ -1301,227 +1296,7 @@ def main_amplified() -> int:
|
|
| 1301 |
"curve": cmd_curve, "restore": cmd_restore, "layers": cmd_layers,
|
| 1302 |
"bound": cmd_bound}[args.mode](args)
|
| 1303 |
|
| 1304 |
-
|
| 1305 |
-
|
| 1306 |
-
NPZ = os.path.join(REPO, "paper", "runs", "datapath_layers.npz")
|
| 1307 |
-
|
| 1308 |
-
|
| 1309 |
-
def datapath_net():
|
| 1310 |
-
"""The subtractor, equality test and branch of H_8, cut out of the host netlist."""
|
| 1311 |
-
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
| 1312 |
-
from host import build
|
| 1313 |
-
from machines import Net
|
| 1314 |
-
full, _, _ = build(8)
|
| 1315 |
-
A = 8
|
| 1316 |
-
xv = [f"X{A - 1 - i}" for i in range(A)]
|
| 1317 |
-
yv = [f"Y{A - 1 - i}" for i in range(A)]
|
| 1318 |
-
keep = set()
|
| 1319 |
-
stack = [f"R{k}" for k in range(A)] + ["LEQ"]
|
| 1320 |
-
while stack:
|
| 1321 |
-
g = stack.pop()
|
| 1322 |
-
if g in keep or g in xv or g in yv:
|
| 1323 |
-
continue
|
| 1324 |
-
keep.add(g)
|
| 1325 |
-
stack.extend(s for s, _ in full.gates[g][0])
|
| 1326 |
-
net = Net()
|
| 1327 |
-
for gname, (ins, bias) in full.gates.items():
|
| 1328 |
-
if gname in keep:
|
| 1329 |
-
net.g(gname, list(ins), bias)
|
| 1330 |
-
return net, xv, yv, [f"R{k}" for k in range(A)], "LEQ"
|
| 1331 |
-
|
| 1332 |
-
|
| 1333 |
-
def export() -> int:
|
| 1334 |
-
"""Levelize the datapath and write its integer weights and biases."""
|
| 1335 |
-
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
| 1336 |
-
from machines import compile_net
|
| 1337 |
-
net, xv, yv, r, leq = datapath_net()
|
| 1338 |
-
inputs = xv + yv
|
| 1339 |
-
outputs = r + [leq]
|
| 1340 |
-
layers, info = compile_net(net, inputs, outputs, final_ordered=True)
|
| 1341 |
-
d = {"n_layers": np.array([len(layers)]),
|
| 1342 |
-
"n_units": np.array([len(net.gates)]),
|
| 1343 |
-
"n_inputs": np.array([len(inputs)]),
|
| 1344 |
-
"n_outputs": np.array([len(outputs)])}
|
| 1345 |
-
for i, (W, bb) in enumerate(layers):
|
| 1346 |
-
d[f"W{i}"] = W.numpy().astype(np.int32)
|
| 1347 |
-
d[f"b{i}"] = bb.numpy().astype(np.int32)
|
| 1348 |
-
os.makedirs(os.path.dirname(NPZ), exist_ok=True)
|
| 1349 |
-
np.savez(NPZ, **d)
|
| 1350 |
-
print(f" datapath: {len(net.gates)} units on {len(inputs)} inputs, "
|
| 1351 |
-
f"{len(layers)} layers of widths "
|
| 1352 |
-
f"{[int(W.shape[0]) for W, _ in layers]}")
|
| 1353 |
-
print(f" wrote {NPZ}")
|
| 1354 |
-
return 0
|
| 1355 |
-
|
| 1356 |
-
|
| 1357 |
-
def reference(xa, xb):
|
| 1358 |
-
"""The subtraction and the branch predicate of Definition 3.1, as integers."""
|
| 1359 |
-
res = (xb - xa) & 0xFF
|
| 1360 |
-
leq = 1 if (res == 0 or res >= 128) else 0
|
| 1361 |
-
return res, leq
|
| 1362 |
-
|
| 1363 |
-
|
| 1364 |
-
def run() -> int:
|
| 1365 |
-
from lava.magma.core.run_conditions import RunSteps
|
| 1366 |
-
from lava.magma.core.run_configs import Loihi2SimCfg
|
| 1367 |
-
from lava.proc.dense.process import Dense
|
| 1368 |
-
from lava.proc.io.sink import RingBuffer as Sink
|
| 1369 |
-
from lava.proc.io.source import RingBuffer as Source
|
| 1370 |
-
from lava.proc.lif.process import LIF
|
| 1371 |
-
|
| 1372 |
-
z = np.load(NPZ)
|
| 1373 |
-
L = int(z["n_layers"][0])
|
| 1374 |
-
n_in = int(z["n_inputs"][0])
|
| 1375 |
-
n_out = int(z["n_outputs"][0])
|
| 1376 |
-
layers = [(z[f"W{i}"], z[f"b{i}"]) for i in range(L)]
|
| 1377 |
-
print(f" datapath: {int(z['n_units'][0])} units on {n_in} inputs, "
|
| 1378 |
-
f"{L} layers of widths {[int(W.shape[0]) for W, _ in layers]}",
|
| 1379 |
-
flush=True)
|
| 1380 |
-
|
| 1381 |
-
worst = 0
|
| 1382 |
-
for W, b in layers:
|
| 1383 |
-
hi = np.maximum(W, 0).sum(axis=1) + b + K
|
| 1384 |
-
lo = np.minimum(W, 0).sum(axis=1) + b + K
|
| 1385 |
-
worst = max(worst, int(np.abs(np.concatenate([hi, lo])).max()))
|
| 1386 |
-
print(f" worst |<w,x> + b + K| over all units and all inputs: {worst}, "
|
| 1387 |
-
f"so the membrane potential stays below {128 * worst} < 4096: "
|
| 1388 |
-
f"{'yes' if 128 * worst < 4096 else 'NO'}", flush=True)
|
| 1389 |
-
assert 128 * worst < 4096
|
| 1390 |
-
|
| 1391 |
-
rng = np.random.default_rng(20260910)
|
| 1392 |
-
N = 4096
|
| 1393 |
-
xa = rng.integers(0, 256, N)
|
| 1394 |
-
xb = rng.integers(0, 256, N)
|
| 1395 |
-
xa[:256] = np.arange(256); xb[:256] = 0 # every difference through zero
|
| 1396 |
-
xa[256:512] = 0; xb[256:512] = np.arange(256)
|
| 1397 |
-
xa[512:768] = np.arange(256); xb[512:768] = np.arange(256) # x = y
|
| 1398 |
-
|
| 1399 |
-
spikes = np.zeros((n_in, N))
|
| 1400 |
-
for t in range(N):
|
| 1401 |
-
for k in range(8):
|
| 1402 |
-
spikes[k, t] = (xa[t] >> k) & 1 # x, value bits
|
| 1403 |
-
spikes[8 + k, t] = (xb[t] >> k) & 1 # y
|
| 1404 |
-
|
| 1405 |
-
T = N + L + 2
|
| 1406 |
-
src = Source(data=np.pad(spikes, ((0, 0), (0, T - N))))
|
| 1407 |
-
prev = src.s_out
|
| 1408 |
-
first_lif = None
|
| 1409 |
-
for W, b in layers:
|
| 1410 |
-
dn = Dense(weights=(2 * W).astype(np.int32))
|
| 1411 |
-
lif = LIF(shape=(W.shape[0],), du=4095, dv=4095,
|
| 1412 |
-
bias_mant=(b + K).astype(np.int32), bias_exp=7, vth=2 * K - 1)
|
| 1413 |
-
prev.connect(dn.s_in)
|
| 1414 |
-
dn.a_out.connect(lif.a_in)
|
| 1415 |
-
prev = lif.s_out
|
| 1416 |
-
first_lif = first_lif or lif
|
| 1417 |
-
snk = Sink(shape=(n_out,), buffer=T)
|
| 1418 |
-
prev.connect(snk.a_in)
|
| 1419 |
-
|
| 1420 |
-
print(f" running {T} time steps of the {L}-layer chain on the "
|
| 1421 |
-
f"bit-accurate fixed-point model", flush=True)
|
| 1422 |
-
first_lif.run(condition=RunSteps(num_steps=T),
|
| 1423 |
-
run_cfg=Loihi2SimCfg(select_tag="fixed_pt"))
|
| 1424 |
-
out = snk.data.get()
|
| 1425 |
-
first_lif.stop()
|
| 1426 |
-
|
| 1427 |
-
bad = []
|
| 1428 |
-
for t in range(N):
|
| 1429 |
-
col = out[:, t + L]
|
| 1430 |
-
res = sum(int(col[k]) << k for k in range(8))
|
| 1431 |
-
leq = int(col[8])
|
| 1432 |
-
want = reference(int(xa[t]), int(xb[t]))
|
| 1433 |
-
if (res, leq) != want:
|
| 1434 |
-
bad.append((t, (res, leq), want))
|
| 1435 |
-
print(f" {N} operand pairs, pipelined one per time step: "
|
| 1436 |
-
f"{'all exact' if not bad else f'{len(bad)} FAILED {bad[:3]}'}",
|
| 1437 |
-
flush=True)
|
| 1438 |
-
|
| 1439 |
-
print(f" one unit weight moves the membrane potential by 128 units and "
|
| 1440 |
-
f"the comparator sits midway between the firing and non-firing "
|
| 1441 |
-
f"values, so the margin of Theorem 6.2 is 64 units of membrane "
|
| 1442 |
-
f"potential on this model")
|
| 1443 |
-
|
| 1444 |
-
ok = not bad
|
| 1445 |
-
json.dump({"backend": "Lava 0.10.0, fixed_pt tag (Loihi neuron model)",
|
| 1446 |
-
"units": int(z["n_units"][0]), "layers": L,
|
| 1447 |
-
"widths": [int(W.shape[0]) for W, _ in layers],
|
| 1448 |
-
"worst_accumulation": worst, "patterns": N,
|
| 1449 |
-
"failures": len(bad), "margin_membrane_units": 64,
|
| 1450 |
-
"weight_scale": 2, "synapse_granularity": 2,
|
| 1451 |
-
"bias_offset": K, "ok": ok},
|
| 1452 |
-
open(runs_path("paper_neuromorphic.json"), "w"), indent=1)
|
| 1453 |
-
print("NEUROMORPHIC:", "PASS" if ok else "FAIL")
|
| 1454 |
-
return 0 if ok else 1
|
| 1455 |
-
|
| 1456 |
-
|
| 1457 |
-
def akida() -> int:
|
| 1458 |
-
"""The same datapath on the Akida layer model."""
|
| 1459 |
-
import numpy as np
|
| 1460 |
-
import akida as ak
|
| 1461 |
-
from akida import FullyConnected, InputData, Model
|
| 1462 |
-
|
| 1463 |
-
z = np.load(NPZ)
|
| 1464 |
-
L = int(z["n_layers"][0])
|
| 1465 |
-
n_in = int(z["n_inputs"][0])
|
| 1466 |
-
layers = [(z[f"W{i}"], z[f"b{i}"]) for i in range(L)]
|
| 1467 |
-
print(f" Akida {ak.__version__}; devices attached: {len(ak.devices())}; "
|
| 1468 |
-
f"{L} layers of widths {[int(W.shape[0]) for W, _ in layers]}",
|
| 1469 |
-
flush=True)
|
| 1470 |
-
|
| 1471 |
-
m = Model()
|
| 1472 |
-
m.add(InputData(input_shape=(1, 1, n_in), input_bits=1))
|
| 1473 |
-
for i, (W, b) in enumerate(layers):
|
| 1474 |
-
m.add(FullyConnected(units=int(W.shape[0]), weights_bits=2,
|
| 1475 |
-
activation=True, act_bits=1, name=f"layer{i}"))
|
| 1476 |
-
lay = m.get_layer(i + 1)
|
| 1477 |
-
wv = np.zeros(lay.variables["weights"].shape, dtype=np.int8)
|
| 1478 |
-
wv[0, 0, :, :] = W.T.astype(np.int8)
|
| 1479 |
-
lay.variables["weights"] = wv
|
| 1480 |
-
lay.variables["threshold"] = (-b - 1).astype(np.int32)
|
| 1481 |
-
|
| 1482 |
-
N = 65536 # every operand pair
|
| 1483 |
-
xa = np.arange(N) % 256
|
| 1484 |
-
xb = np.arange(N) // 256
|
| 1485 |
-
X = np.zeros((N, 1, 1, n_in), dtype=np.uint8)
|
| 1486 |
-
for k in range(8):
|
| 1487 |
-
X[:, 0, 0, k] = (xa >> k) & 1
|
| 1488 |
-
X[:, 0, 0, 8 + k] = (xb >> k) & 1
|
| 1489 |
-
out = np.concatenate([m.forward(X[i:i + 8192]).reshape(-1, out_w)
|
| 1490 |
-
for i in range(0, N, 8192)
|
| 1491 |
-
for out_w in [int(layers[-1][0].shape[0])]])
|
| 1492 |
-
|
| 1493 |
-
bad = []
|
| 1494 |
-
for t in range(N):
|
| 1495 |
-
res = sum(int(out[t, k]) << k for k in range(8))
|
| 1496 |
-
leq = int(out[t, 8])
|
| 1497 |
-
want = reference(int(xa[t]), int(xb[t]))
|
| 1498 |
-
if (res, leq) != want:
|
| 1499 |
-
bad.append((t, (res, leq), want))
|
| 1500 |
-
print(f" all {N} operand pairs forwarded through the layer stack: "
|
| 1501 |
-
f"{'all exact' if not bad else f'{len(bad)} FAILED {bad[:3]}'}",
|
| 1502 |
-
flush=True)
|
| 1503 |
-
print(f" weights are stored at two bits and thresholds as integers, so "
|
| 1504 |
-
f"the circuit is represented without rounding")
|
| 1505 |
-
|
| 1506 |
-
ok = not bad
|
| 1507 |
-
old = {}
|
| 1508 |
-
p = runs_path("paper_neuromorphic.json")
|
| 1509 |
-
if os.path.exists(p):
|
| 1510 |
-
old = json.load(open(p))
|
| 1511 |
-
old["akida"] = {"backend": f"akida {ak.__version__}, software backend",
|
| 1512 |
-
"layers": L, "patterns": N, "failures": len(bad),
|
| 1513 |
-
"weights_bits": 2, "act_bits": 1, "ok": ok}
|
| 1514 |
-
json.dump(old, open(p, "w"), indent=1)
|
| 1515 |
-
print("AKIDA:", "PASS" if ok else "FAIL")
|
| 1516 |
-
return 0 if ok else 1
|
| 1517 |
-
|
| 1518 |
-
|
| 1519 |
-
def cmd_neuromorphic():
|
| 1520 |
-
mode = sys.argv[1] if len(sys.argv) > 1 else "run"
|
| 1521 |
-
sys.exit({"export": export, "run": run, "akida": akida}[mode]())
|
| 1522 |
-
|
| 1523 |
-
|
| 1524 |
-
COMMANDS = {'host': main_host, 'amplified': main_amplified, 'neuromorphic': cmd_neuromorphic}
|
| 1525 |
|
| 1526 |
|
| 1527 |
if __name__ == "__main__":
|
|
|
|
| 1 |
+
"""Perturbation experiments on the levelized host and on the amplified host."""
|
| 2 |
from __future__ import annotations
|
| 3 |
|
| 4 |
import argparse
|
|
|
|
| 12 |
import time
|
| 13 |
from typing import Dict, List, Tuple
|
| 14 |
|
|
|
|
|
|
|
| 15 |
from host import (
|
| 16 |
encode,
|
| 17 |
M_P,
|
|
|
|
| 19 |
HALT_PC,
|
| 20 |
Tape,
|
| 21 |
describe,
|
|
|
|
| 22 |
inst,
|
| 23 |
read_host,
|
| 24 |
ser,
|
| 25 |
tau_star,
|
|
|
|
| 26 |
STATE_LAYOUT,
|
| 27 |
IO_CELLS,
|
|
|
|
| 28 |
)
|
| 29 |
+
from paper import levelize, parse_sigma, write_flat
|
| 30 |
|
| 31 |
|
| 32 |
REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
| 1296 |
"curve": cmd_curve, "restore": cmd_restore, "layers": cmd_layers,
|
| 1297 |
"bound": cmd_bound}[args.mode](args)
|
| 1298 |
|
| 1299 |
+
COMMANDS = {'host': main_host, 'amplified': main_amplified}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1300 |
|
| 1301 |
|
| 1302 |
if __name__ == "__main__":
|
src/paper.py
CHANGED
|
@@ -1048,6 +1048,30 @@ ROCQ = os.path.join(REPO, 'rocq')
|
|
| 1048 |
RECORD = os.path.join(REPO, 'paper', 'runs', 'paper_rocq.json')
|
| 1049 |
|
| 1050 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1051 |
def main_rocq():
|
| 1052 |
for tool in ('rocq', 'make', 'ocamlfind'):
|
| 1053 |
if shutil.which(tool) is None:
|
|
@@ -1075,13 +1099,15 @@ def main_rocq():
|
|
| 1075 |
if len(lines) != len(names) or any(l != 'Closed under the global context' for l in lines):
|
| 1076 |
print(out.stdout)
|
| 1077 |
return 1
|
|
|
|
| 1078 |
ext = subprocess.run([sys.executable, os.path.join(REPO, 'src', 'twohead.py'), 'net', 'extract'],
|
| 1079 |
capture_output=True, text=True)
|
| 1080 |
-
identical = ext.returncode == 0 and '"identical": true' in ext.stdout
|
| 1081 |
files = [l for l in open(os.path.join(ROCQ, '_CoqProject')).read().split() if l.endswith('.v')]
|
| 1082 |
-
|
|
|
|
| 1083 |
build_seconds=round(build, 1), theorems={n: 'closed' for n in names},
|
| 1084 |
-
extraction_identical=identical)
|
| 1085 |
rec = json.load(open(RECORD)) if os.path.exists(RECORD) else {}
|
| 1086 |
rec.update(res)
|
| 1087 |
json.dump(rec, open(RECORD, 'w'), indent=1)
|
|
|
|
| 1048 |
RECORD = os.path.join(REPO, 'paper', 'runs', 'paper_rocq.json')
|
| 1049 |
|
| 1050 |
|
| 1051 |
+
def host_extraction():
|
| 1052 |
+
"""The host netlist of rocq/Host.v for A = 8, extracted to OCaml, against the netlist sigma(N_host) denotes."""
|
| 1053 |
+
ex = os.path.join(ROCQ, 'extract')
|
| 1054 |
+
subprocess.run(['ocamlfind', 'ocamlopt', '-package', 'stdlib', 'hostnet.mli', 'hostnet.ml', 'dumphost.ml',
|
| 1055 |
+
'-o', 'dumphost'], cwd=ex, check=True)
|
| 1056 |
+
out = os.path.join(ex, 'host_rocq.bin')
|
| 1057 |
+
subprocess.run([os.path.join(ex, 'dumphost'), '8', out], check=True)
|
| 1058 |
+
theirs = open(out, 'rb').read()
|
| 1059 |
+
n, units, nxt = parse_sigma(read_host())
|
| 1060 |
+
words = array('i', [n, len(units), sum(len(ins) for _, ins in units)])
|
| 1061 |
+
words.extend(b for b, _ in units)
|
| 1062 |
+
words.extend(len(ins) for _, ins in units)
|
| 1063 |
+
words.extend(w * (k + 1) for _, ins in units for k, w in ins)
|
| 1064 |
+
words.extend(nxt)
|
| 1065 |
+
if sys.byteorder != 'little':
|
| 1066 |
+
words.byteswap()
|
| 1067 |
+
ours = words.tobytes()
|
| 1068 |
+
for f in os.listdir(ex):
|
| 1069 |
+
if not f.endswith(('.ml', '.mli')):
|
| 1070 |
+
os.remove(os.path.join(ex, f))
|
| 1071 |
+
return dict(A=8, units=len(units), identical=ours == theirs,
|
| 1072 |
+
sha256_sigma=hashlib.sha256(ours).hexdigest(), sha256_rocq=hashlib.sha256(theirs).hexdigest())
|
| 1073 |
+
|
| 1074 |
+
|
| 1075 |
def main_rocq():
|
| 1076 |
for tool in ('rocq', 'make', 'ocamlfind'):
|
| 1077 |
if shutil.which(tool) is None:
|
|
|
|
| 1099 |
if len(lines) != len(names) or any(l != 'Closed under the global context' for l in lines):
|
| 1100 |
print(out.stdout)
|
| 1101 |
return 1
|
| 1102 |
+
host = host_extraction()
|
| 1103 |
ext = subprocess.run([sys.executable, os.path.join(REPO, 'src', 'twohead.py'), 'net', 'extract'],
|
| 1104 |
capture_output=True, text=True)
|
| 1105 |
+
identical = ext.returncode == 0 and '"identical": true' in ext.stdout and host['identical']
|
| 1106 |
files = [l for l in open(os.path.join(ROCQ, '_CoqProject')).read().split() if l.endswith('.v')]
|
| 1107 |
+
lines = sum(len(open(os.path.join(ROCQ, f)).read().splitlines()) for f in files)
|
| 1108 |
+
res = dict(rocq=version.splitlines()[0], files=len(files), lines=lines,
|
| 1109 |
build_seconds=round(build, 1), theorems={n: 'closed' for n in names},
|
| 1110 |
+
host_extraction=host, extraction_identical=identical)
|
| 1111 |
rec = json.load(open(RECORD)) if os.path.exists(RECORD) else {}
|
| 1112 |
rec.update(res)
|
| 1113 |
json.dump(rec, open(RECORD, 'w'), indent=1)
|
src/twohead.py
CHANGED
|
@@ -653,7 +653,7 @@ def main_net():
|
|
| 653 |
sha256_generator=hashlib.sha256(ours).hexdigest(),
|
| 654 |
sha256_rocq=hashlib.sha256(theirs).hexdigest()))
|
| 655 |
for f in os.listdir(ex):
|
| 656 |
-
if
|
| 657 |
os.remove(os.path.join(ex, f))
|
| 658 |
res = dict(members=members, identical=all(m['identical'] for m in members))
|
| 659 |
net_update_record('extraction', res)
|
|
@@ -714,6 +714,7 @@ HALT = 8
|
|
| 714 |
class Prog:
|
| 715 |
def __init__(self):
|
| 716 |
self.recs = [] # (a0, w0, a1, w1, beta, ao), cells by name
|
|
|
|
| 717 |
self.uid = 0
|
| 718 |
|
| 719 |
def tmp(self):
|
|
@@ -853,6 +854,7 @@ def compile_host(P):
|
|
| 853 |
P.threshold(t, lits, dst)
|
| 854 |
else:
|
| 855 |
_chain_lazy(P, 'and' if t == k else 'or', lits, dst, before)
|
|
|
|
| 856 |
|
| 857 |
order_next = [nxt[PC_BIT(t)] - n for t in range(8)] + [nxt[HALT] - n] + \
|
| 858 |
[nxt[mem_bit(j, t)] - n for j in range(256) for t in range(8)]
|
|
@@ -1082,7 +1084,7 @@ def build_stored():
|
|
| 1082 |
tau = SR.describe(image)
|
| 1083 |
assert SR.decode(tau) == image
|
| 1084 |
return dict(recs=recs, addr=addr, top=top, image=image, image_bits=image_bits, tau=tau,
|
| 1085 |
-
n_host_records=n_host, host=(n, units, nxt))
|
| 1086 |
|
| 1087 |
|
| 1088 |
# ---------------------------------------------------------------------------
|
|
@@ -1233,6 +1235,118 @@ def check_stored(trials=40, seed=3, verbose=False):
|
|
| 1233 |
return dict(trials=trials, disagreements=bad, records=G, window_cells=S['top'])
|
| 1234 |
|
| 1235 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1236 |
def stored_update_record(key, value):
|
| 1237 |
rec = json.load(open(STORED_RECORD)) if os.path.exists(STORED_RECORD) else {}
|
| 1238 |
rec[key] = value
|
|
@@ -1281,6 +1395,11 @@ def cmd_stored():
|
|
| 1281 |
stored_update_record('pass_check', res)
|
| 1282 |
print(json.dumps(res))
|
| 1283 |
sys.exit(0 if res['disagreements'] == 0 else 1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1284 |
elif cmd == 'run':
|
| 1285 |
gens = int(sys.argv[2]) if len(sys.argv) > 2 else 3
|
| 1286 |
res = run_stored(gens)
|
|
|
|
| 653 |
sha256_generator=hashlib.sha256(ours).hexdigest(),
|
| 654 |
sha256_rocq=hashlib.sha256(theirs).hexdigest()))
|
| 655 |
for f in os.listdir(ex):
|
| 656 |
+
if not f.endswith(('.ml', '.mli')):
|
| 657 |
os.remove(os.path.join(ex, f))
|
| 658 |
res = dict(members=members, identical=all(m['identical'] for m in members))
|
| 659 |
net_update_record('extraction', res)
|
|
|
|
| 714 |
class Prog:
|
| 715 |
def __init__(self):
|
| 716 |
self.recs = [] # (a0, w0, a1, w1, beta, ao), cells by name
|
| 717 |
+
self.ends = {} # record -> the unit of the host whose value it writes
|
| 718 |
self.uid = 0
|
| 719 |
|
| 720 |
def tmp(self):
|
|
|
|
| 854 |
P.threshold(t, lits, dst)
|
| 855 |
else:
|
| 856 |
_chain_lazy(P, 'and' if t == k else 'or', lits, dst, before)
|
| 857 |
+
P.ends[len(P.recs) - 1] = u
|
| 858 |
|
| 859 |
order_next = [nxt[PC_BIT(t)] - n for t in range(8)] + [nxt[HALT] - n] + \
|
| 860 |
[nxt[mem_bit(j, t)] - n for j in range(256) for t in range(8)]
|
|
|
|
| 1084 |
tau = SR.describe(image)
|
| 1085 |
assert SR.decode(tau) == image
|
| 1086 |
return dict(recs=recs, addr=addr, top=top, image=image, image_bits=image_bits, tau=tau,
|
| 1087 |
+
n_host_records=n_host, host=(n, units, nxt), ends=P.ends)
|
| 1088 |
|
| 1089 |
|
| 1090 |
# ---------------------------------------------------------------------------
|
|
|
|
| 1235 |
return dict(trials=trials, disagreements=bad, records=G, window_cells=S['top'])
|
| 1236 |
|
| 1237 |
|
| 1238 |
+
class BDD:
|
| 1239 |
+
"""Reduced ordered decision diagrams; a node is an integer, 0 and 1 the leaves."""
|
| 1240 |
+
def __init__(self):
|
| 1241 |
+
self.node = [None, None]
|
| 1242 |
+
self.uniq, self.memo = {}, {}
|
| 1243 |
+
|
| 1244 |
+
def mk(self, v, lo, hi):
|
| 1245 |
+
if lo == hi:
|
| 1246 |
+
return lo
|
| 1247 |
+
r = self.uniq.get((v, lo, hi))
|
| 1248 |
+
if r is None:
|
| 1249 |
+
r = self.uniq[(v, lo, hi)] = len(self.node)
|
| 1250 |
+
self.node.append((v, lo, hi))
|
| 1251 |
+
return r
|
| 1252 |
+
|
| 1253 |
+
def var(self, v):
|
| 1254 |
+
return self.mk(v, 0, 1)
|
| 1255 |
+
|
| 1256 |
+
def ite(self, f, g, h):
|
| 1257 |
+
if f < 2:
|
| 1258 |
+
return g if f else h
|
| 1259 |
+
if g == h:
|
| 1260 |
+
return g
|
| 1261 |
+
if g == 1 and h == 0:
|
| 1262 |
+
return f
|
| 1263 |
+
key = (f, g, h)
|
| 1264 |
+
r = self.memo.get(key)
|
| 1265 |
+
if r is None:
|
| 1266 |
+
v = min(self.node[x][0] for x in key if x > 1)
|
| 1267 |
+
lo = [x if x < 2 or self.node[x][0] != v else self.node[x][1] for x in key]
|
| 1268 |
+
hi = [x if x < 2 or self.node[x][0] != v else self.node[x][2] for x in key]
|
| 1269 |
+
r = self.memo[key] = self.mk(v, self.ite(*lo), self.ite(*hi))
|
| 1270 |
+
return r
|
| 1271 |
+
|
| 1272 |
+
def record(self, w0, x, w1, y, beta):
|
| 1273 |
+
"""H(w0 x + w1 y + beta) of the bits x and y."""
|
| 1274 |
+
val = lambda a, b: 1 if w0 * a + w1 * b + beta >= 0 else 0
|
| 1275 |
+
return self.ite(x, self.ite(y, val(1, 1), val(1, 0)), self.ite(y, val(0, 1), val(0, 0)))
|
| 1276 |
+
|
| 1277 |
+
def atleast(self, t, lits):
|
| 1278 |
+
"""At least t of the literals (x, positive) are true."""
|
| 1279 |
+
if t <= 0:
|
| 1280 |
+
return 1
|
| 1281 |
+
row = [1] + [0] * t
|
| 1282 |
+
for x, pos in reversed(lits):
|
| 1283 |
+
row = [1] + [self.ite(x, row[j - 1], row[j]) if pos else self.ite(x, row[j], row[j - 1])
|
| 1284 |
+
for j in range(1, t + 1)]
|
| 1285 |
+
return row[t]
|
| 1286 |
+
|
| 1287 |
+
|
| 1288 |
+
def symbolic_check():
|
| 1289 |
+
"""The startup and step records of the image of S on decision diagrams over the signals of N_host."""
|
| 1290 |
+
sys.setrecursionlimit(100000)
|
| 1291 |
+
t0 = time.time()
|
| 1292 |
+
S = build_stored()
|
| 1293 |
+
n, units, nxt = host_units()
|
| 1294 |
+
bits = bytes_to_bits(S['image'])
|
| 1295 |
+
recs = [decode_record(bits[k * SH_B:(k + 1) * SH_B], SH_ALPHA) for k in range(len(bits) // SH_B)]
|
| 1296 |
+
lo, hi = 2099, 2099 + S['n_host_records']
|
| 1297 |
+
addr = S['addr']
|
| 1298 |
+
D = BDD()
|
| 1299 |
+
# the value of every signal on the current state: a unit that is a constant or a literal is that,
|
| 1300 |
+
# and the units of one function share the variable of the first; fn[u] is the function of unit u
|
| 1301 |
+
# of the values of its predecessors
|
| 1302 |
+
val, first, fn = [D.var(s) for s in range(n)], {}, []
|
| 1303 |
+
for u, (b, ins) in enumerate(units):
|
| 1304 |
+
f = D.atleast(sum(1 for _, w in ins if w < 0) - b, [(val[s], w > 0) for s, w in ins])
|
| 1305 |
+
fn.append(f)
|
| 1306 |
+
val.append(D.var(first.setdefault(f, n + u)) if f > 1 and D.node[f][1:] not in ((0, 1), (1, 0)) else f)
|
| 1307 |
+
unknown = lambda c: D.var(1 << 30 | c)
|
| 1308 |
+
state = [addr[('s', i)] for i in range(n)]
|
| 1309 |
+
ends = S['ends']
|
| 1310 |
+
agree = [True]
|
| 1311 |
+
|
| 1312 |
+
def run(window, a, b):
|
| 1313 |
+
# at the record that the compiler names as writing the value of unit u, the cell must hold
|
| 1314 |
+
# the function of u, and from then on it holds the value of u
|
| 1315 |
+
for k in range(a, b):
|
| 1316 |
+
a0, w0, a1, w1, beta, ao = recs[k]
|
| 1317 |
+
assert ao >= 7, ('a record writes a head or a request', k)
|
| 1318 |
+
g = D.record(w0, window[a0], w1, window[a1], beta)
|
| 1319 |
+
if k in ends:
|
| 1320 |
+
u = ends[k]
|
| 1321 |
+
agree[0] &= g == fn[u]
|
| 1322 |
+
g = val[n + u]
|
| 1323 |
+
window[ao] = g
|
| 1324 |
+
|
| 1325 |
+
# the startup: x_0(m*) when booted is 0, the window unchanged when it is 1
|
| 1326 |
+
boot = addr[('d', 'booted')]
|
| 1327 |
+
window = [unknown(c) for c in range(SH_W)]
|
| 1328 |
+
regs = [addr[('d', 'cnt', i)] for i in range(CW)] + [addr[('d', 'lim', i)] for i in range(CW)] + \
|
| 1329 |
+
[addr[('d', 'dest')]]
|
| 1330 |
+
before = list(window)
|
| 1331 |
+
run(window, 0, lo)
|
| 1332 |
+
B0 = before[boot]
|
| 1333 |
+
x0 = [0] * n
|
| 1334 |
+
for j in range(256):
|
| 1335 |
+
for t in range(8):
|
| 1336 |
+
x0[mem_bit(j, t)] = (SR.M_STAR[j] >> t) & 1
|
| 1337 |
+
startup = window[boot] == 1 and all(window[c] == D.ite(B0, before[c], 0) for c in regs) and \
|
| 1338 |
+
all(window[state[i]] == D.ite(B0, before[state[i]], x0[i]) for i in range(n))
|
| 1339 |
+
# the step: from every window, the state bits end holding the next state of N_host
|
| 1340 |
+
window = [unknown(c) for c in range(SH_W)]
|
| 1341 |
+
for i in range(n):
|
| 1342 |
+
window[state[i]] = val[i]
|
| 1343 |
+
run(window, lo, hi)
|
| 1344 |
+
step = agree[0] and len(ends) == len(units) and all(window[state[i]] == val[nxt[i]] for i in range(n))
|
| 1345 |
+
return dict(startup_records=lo, step_records=hi - lo, startup_exact=startup, step_exact=step,
|
| 1346 |
+
sha256_image=hashlib.sha256(S['image']).hexdigest(), nodes=len(D.node),
|
| 1347 |
+
seconds=round(time.time() - t0, 1))
|
| 1348 |
+
|
| 1349 |
+
|
| 1350 |
def stored_update_record(key, value):
|
| 1351 |
rec = json.load(open(STORED_RECORD)) if os.path.exists(STORED_RECORD) else {}
|
| 1352 |
rec[key] = value
|
|
|
|
| 1395 |
stored_update_record('pass_check', res)
|
| 1396 |
print(json.dumps(res))
|
| 1397 |
sys.exit(0 if res['disagreements'] == 0 else 1)
|
| 1398 |
+
elif cmd == 'symbolic':
|
| 1399 |
+
res = symbolic_check()
|
| 1400 |
+
stored_update_record('symbolic', res)
|
| 1401 |
+
print(json.dumps(res))
|
| 1402 |
+
sys.exit(0 if res['startup_exact'] and res['step_exact'] else 1)
|
| 1403 |
elif cmd == 'run':
|
| 1404 |
gens = int(sys.argv[2]) if len(sys.argv) > 2 else 3
|
| 1405 |
res = run_stored(gens)
|