Move the circuit layer onto llogic, and take a specification as input
The circuit parsing and representation here duplicated what llogic
had grown: a component-library parser, a circuit model, a renderer. All
of it is llogic's now, reached through its hierarchical DSL, and what
remains is the synthesis -- the miter, the QBF encoding, the search.
The logic is untouched; only what it is built out of changed.
Synthesizing from a specification
--smt-target takes an lmodulo .smt file where a reference circuit
would go. The specification is converted to a netlist and handed to the
existing miter unchanged, so the QBF encoding, the component library and
the search are as they were -- only where the requirement comes from is
new. The thing being resynthesized no longer has to be a circuit
somebody drew: s == a + b is a valid target.
Symmetry breaking
C6 constrains consecutive universal cells lexicographically, behind a flag that defaults off. It is guarded and padded so that it cannot exclude a satisfying assignment, and validated against the enumeration counts it must leave unchanged.
Housekeeping
The HDF5 profiler is gone, along with the four copies of its enumeration
that each named the same fourteen things, its -p option, and every
call site -- and with it the h5py dependency. ExitStatus went too:
it was written in the exception handlers and read only by the profiler,
and its NORMAL is 1, so it was never a process exit code.
Two local helpers whose whole job was wrapping a gate name in a
one-element tuple are retired, netlist.Gate doing it now. No
leading-underscore names. Dependencies are what is imported and nothing
else: pydepqbf and pylgl arrive through llogic, lcfgen went when
its generators moved there, bidict is unused, and mpi4py -- imported
behind a fallback to a single process -- is an extra rather than a
requirement.