Properties.lean
The trusted statement of add as named properties: proved, not trusted.
- Properties
- 5
- Lines
- 67
Each definition below is one property of the trusted statement (Statement). The theorem statement_iff_properties proves that the statement holds exactly when they all do, and Lean's kernel checks it, so this file adds nothing to what is trusted.
| property | Lean name | line | on the task page |
|---|---|---|---|
PARAMS_IN_RANGE | ParamsInRange | 17 | the card |
INTERFACE | Interface | 22 | the card |
UNCLOCKED | Unclocked | 26 | the card |
LOOP_FREE | LoopFree | 30 | the card |
TERMINATES | Terminates | 35 | the card |
COMPUTES_SUM | ComputesSum | 39 | the card |
statement_iff_properties | the theorem | 50 |
- file
svgolf/tasks/add/Properties.lean- module
tasks.add.Properties- sha256
77231210ca82b41c8eed9f0060605af0c2c5336a3186e0c095476893574f0f1b
svgolf/tasks/add/Properties.leanProperties.lean
import tasks.add.Spec
/-!
# Task `add`: the statement as named properties (proved, not trusted)
`Spec.lean`'s `Statement` is one formula. This file gives each part of it a name, one definition
per thing a design must satisfy, and proves `statement_iff_properties`: the statement holds
exactly when, at every `N` in range, every property holds. The theorem is checked by Lean's
kernel, so the properties cover the whole statement and nothing else; this file adds nothing to
the trusted base. `properties.json` explains each property in plain words.
-/
namespace SvGolf.Tasks.Add.Properties
open SvGolf LeanModels.Sv
/-- The widths the statement covers: every `N` with `1 ≤ N < 2^31` (the values an `int` parameter
holds). -/
def ParamsInRange (N : Nat) : Prop :=
1 ≤ N ∧ N < 2 ^ 31
/-- Exactly these ports, in this order, with these widths. -/
def Interface (N : Nat) (d : Design2) : Prop :=
inputPorts d = [("a", N), ("b", N), ("cin", 1)] ∧ outputPorts d = [("s", N), ("cout", 1)]
/-- No process runs at a clock edge (no `always_ff`, no `always @(posedge …)`). -/
def Unclocked (d : Design2) : Prop :=
∀ p ∈ d.processes.toList, p.isEdgePhase = false
/-- No combinational loop: the design lowers to continuous assigns (`Design2.lowerComb`) that are
ranked (`Acyclic`): each reads only what lower-ranked ones write. -/
def LoopFree (d : Design2) : Prop :=
∃ d', d.lowerComb = some d' ∧ Acyclic d'
/-- Under every schedule and every stimulus, the run completes. -/
def Terminates (d : Design2) : Prop :=
∀ (σ : ScheduleOracle) (stim : List SvState), ∃ tr, Runs2 d σ stim tr
/-- In every completed run, every cycle whose stimulus drives `a`, `b`, `cin` with known values
ends with `s` and `cout` holding the low `N` bits and the carry of `a + b + cin`. -/
def ComputesSum (N : Nat) (d : Design2) : Prop :=
d ⊨₂ spec2 fun stim tr =>
∀ (c : Nat) (inputs st : SvState), stim[c]? = some inputs → tr[c]? = some st →
∀ (a b : BitVec N) (cin : BitVec 1),
HoldAll inputs [("a", N), ("b", N), ("cin", 1)] (a, b, cin, ()) →
HoldAll st [("s", N), ("cout", 1)]
(BitVec.ofNat N (a.toNat + b.toNat + cin.toNat),
BitVec.ofNat 1 ((a.toNat + b.toNat + cin.toNat) / 2 ^ N), ())
/-- **The statement is exactly the properties.** -/
theorem statement_iff_properties (sem : Nat → Design2) :
Statement sem ↔ ∀ N, ParamsInRange N →
Interface N (sem N) ∧ Unclocked (sem N) ∧ LoopFree (sem N) ∧ Terminates (sem N) ∧ ComputesSum N (sem N) := by
constructor
· intro h N hN
obtain ⟨hi, ⟨hu, hl, ht⟩, hc⟩ := h N hN
refine ⟨hi, hu, hl, ht, ?_⟩
intro σ stim tr hr c inputs st hs hst a b cin hv
exact hc σ stim tr hr c inputs st hs hst (a, b, cin, ()) hv
· intro h N hN
obtain ⟨hi, hu, hl, ht, hc⟩ := h N hN
refine ⟨hi, ⟨hu, hl, ht⟩, ?_⟩
intro σ stim tr hr c inputs st hs hst v hv
obtain ⟨a, b, cin, ⟨⟩⟩ := v
exact hc σ stim tr hr c inputs st hs hst a b cin hv
end SvGolf.Tasks.Add.Properties