-
Notifications
You must be signed in to change notification settings - Fork 159
Description
Setup
Right now, Bluespec links directly into Yices or STP for doing solving of various bitvector-like constraints. Or something like that. The default for now is Yices, and STP is optional, and we link to their object files, and that's really what matters.
However, doing this has a number of downsides:
-
We must vendor
yices
and possibly other packages likestep
. We should be moving away from this. It requires tooling like submodules, makes build integration more complicated, and ultimately third party systems already package things like this. -
More substantially, linking to the Yices API means the Bluespec compiler is a derived work under the GPLv3, and also, any codebase derived from
bsc
will be, too. It's important to note that the code ofbsc
itself can fully be BSD2, but it is the linking part that actually produces the derived work (and implies a requirement to the source code, for resulting binaries, under the derivative/GPL clause). IANAL, but this is my understanding.
The first is problematic for a number of technical reasons (submodules, etc) but the second really hurts. People are also prone to get strange about licensing issues and may find this "deceptive" (because you advertise the codebase as BSD3, but some results are under the GPLv3 by law.)
Proposed solution
I think it should be possible to avoid all this by doing something else instead: most modern SMT solvers (including Yices, Z3, STP from what I can tell, Boolector, and more) support formats like SMT-Lib. This is a project-neutral standard format you can feed a solver and have it produce answers for you.
The most prominent library for this is sbv in my opinion:
- It's well-maintained, and Levent is very responsive.
- It's seen successful, widespread use (in both commercial and open source projects, such as Cryptol, and others I can't speak much about.)
- It doesn't require ANY FFI integration or libraries. Rather, it does the tricky work of portably launching the solver programs (
yices.exe
,z3.exe
) in a cross platform manner, feeding them problem sets, and returning the results encoded as Haskell values.
These combination of features, IMO, make it the most worthy route to investigate, and feature 3 in particular not only breaks the GPLv3-by-linking problem, but opens the door to other solvers (z3
, boolector
) etc as well.
For anyone who wants to tackle this, I suggest looking for uses of Yices
in the compiler codebase. The actual amount of uses of the Yices FFI library are small, so I'd suggest trying to surgically replace what we have with SBV, to the extent possible. We can then just fix the SBV solve function to use Yices for now.
Upsides
- Fixes the GPLv3 issue. This is good for everyone and sets proper exectations.
- Makes solver choice more flexible. This means we don't have to worry if users want STP, Z3, Yices, whatever.
- Will reduce build time. No need to build Yices (mandatory) or STP (optional), which will help build time a lot.
Problems and risks
-
Problem: This is a potentially behavior-inducing change, and requires testing.
Solution: We MUST have the testsuite available, and have it working in CI. This I feel is really important and can't be worked around.
Note: Perhaps if the change is small and easy enough, Julie could run tests for us to let it go through. -
Problem: SBV has many several dependencies. These aren't too bad, but in general
comp
has a very spartan set of dependencies right now. Going forward, though, it seems unlikely to continue to the same degree (~10 years of GHC support is a bit much. :)
Solution: Doing this will probably require us to move to a new mechanism for integrating Haskell dependencies, for example, usingcabal new-build
with Cabal 3.0 to build packages, and this will probably have impacts on the CI and build process as a result. We'll need to actually pick a supported compiler range, and show people how to install it and the tools. This can be done pretty easily for Debian with Herbert's PPA, though RHEL needs some review since I'm not familiar with it. (This will pave the way to producing.rpm
and.deb
packages, and so it should happen before doing that.) -
Problem: We probably should test solvers a bit. Joe Schmo's random SMT solver from GitHub probably isn't worth doing QA or testing for. Yices, Z3, etc all seem reasonable.
Solution: The CI could reasonably test multiple solvers if it's fast enough, but who knows about this. Solver edge cases can definitely be supported as regression tests. We should pick a minimum set of solvers and tell users to stick with them.