digital circuits
SICP §3.3.4's digital-circuit simulator, traced one agenda item at a time. A wire holds a signal (0 or 1) and a list of gates to run when the signal changes. A gate computes its output from its current inputs and schedules the new value after its own delay. The agenda is a list of time segments, each holding a queue of pending actions; propagation repeatedly advances the clock to the earliest segment and runs its next item – FIFO order (SICP's own default) or LIFO order (ex. 3.32), your choice.
Pick a circuit – a bare AND gate, a half-adder, a full-adder, or an N-bit ripple-carry adder – and watch it settle. The schematic panel lays out wires and gates by topological level with a barycenter row ordering; the timing diagram shows every wire's history as a waveform, and clicking an input's lane toggles a stimulus there. Two toggles matter beyond FIFO/LIFO: composing an or-gate from inverters and an and-gate (ex. 3.29, De Morgan's law) changes its delay and internal wire count but never its logical function; and skipping add-action!'s initial call (ex. 3.31) turns out to be worse than a merely transient glitch – for any circuit with more than one gate in series, it can leave the final answer permanently wrong, because a gate whose inputs never genuinely change from their zero default never runs even once. The comparison table at the bottom runs the same circuit and stimulus through all four FIFO/LIFO x init-on/init-off combinations side by side.
The pure model (`build-circuit`, the agenda-based `simulate`, the
independent combinational-logic oracle `expected`, and the static-timing
analysis `longest-from`) lives in wal-sh.tools.digital-circuits.core
(host-neutral .cljc, tested on the JVM with test.check: the simulation's
settled state agrees with the oracle across random stimuli and circuit
kinds, ripple-carry arithmetic is exact, the or-gate composition is
logically equivalent to the primitive, and static timing bounds actual
settling time). The browser adapter is
wal-sh.tools.digital-circuits.browser. Build: gmake tools-cljs; debug in
isolation: gmake dev-tool TOOL=digital-circuits.