Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SMTChecker: Upgrade CVC4 to cvc5 and switch from API to SMT-LIB2 interface #15078

Open
wants to merge 7 commits into
base: install-cvc5
Choose a base branch
from

Conversation

blishko
Copy link
Contributor

@blishko blishko commented May 6, 2024

Instead of compiling solc itself with CVC4 support, it is now enough to have cvc5 executable on PATH when running the compiler.
Instead of using API of CVC4, we now use SMT-LIB2 interface.
That means we write the queries to temporary SMT-LIB2 files and call the solver process directly to run on the file.

Depends on #15102

@blishko blishko force-pushed the smt-cvc4-switch branch 2 times, most recently from efbf366 to 06f5be1 Compare May 8, 2024 15:07
@blishko blishko changed the title SMTChecker: Switch CVC4 from API to SMT-LIB2 interface SMTChecker: Upgrade CVC4 to cvc5 and switch from API to SMT-LIB2 interface May 15, 2024
@blishko blishko force-pushed the smt-cvc4-switch branch 4 times, most recently from dbe0d74 to e2de0dd Compare May 15, 2024 19:02
@r0qs r0qs added has dependencies The PR depends on other PRs that must be merged first smt labels May 22, 2024
@blishko blishko changed the base branch from develop to install-cvc5 May 29, 2024 17:51
@blishko blishko marked this pull request as ready for review May 29, 2024 17:57
@blishko blishko force-pushed the smt-cvc4-switch branch 3 times, most recently from 06653aa to 012532d Compare June 3, 2024 06:43
CMakeLists.txt Outdated
Comment on lines 136 to 140
find_program(CVC5_PATH cvc5)
if (CVC5_PATH)
add_compile_definitions(CVC5_PATH=${CVC5_PATH})
message("cvc5 SMT solver found. This enables optional SMT checking with cvc5.")
endif()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was about to say that this is bad, since if you then use CVC5_PATH somewhere, it'll get the path hardcoded - but you actually don't use it anywhere, right :-)? So the add_compile_definitions is superfluous anyways?

Should we even have any kind of cmake logic here? I've not looked at the rest of the PR yet, but I'd guess that CVC5 is purely a runtime dependency with the change, so we don't need to do anything special at cmake configure time, do we?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point. I thought we need to give some sort of a message at configuration time, but most likely we don't.
Yes, cvc5 is now a runtime dependency. It works the same way as Eldarica, so basically the executable must be present in PATH.

I'll remove this cmake logic.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am wondering about the message below, which warns if Z3 nor CVC4 (now cvc5) is not enabled/has not been found.

Should there be any information/warning at cmake configure time about available solvers?

Copy link
Collaborator

@nikola-matic nikola-matic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've re-run the failing windows bytecode builds since they were failing (network err).

@@ -79,17 +78,19 @@ class CHCSmtLib2Interface: public CHCSolverInterface
/// Translates CHC solver response with a model to our representation of invariants. Returns None on error.
std::optional<smtutil::Expression> invariantsFromSolverResponse(std::string const& response) const;

/// Hook to setup external solver call
virtual void setupSmtCallback() {}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably smtAssert(false) here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot do that yet, because --model-checker-solvers smtlib2 is a valid option now, and it will instantiate this base class.
What will happen is that it will try to call SMTCommand, but that will do nothing.

I think eventually we should just drop smtlib2 as a possible choice for the solver (once also z3 migrates to the new usage).

libsmtutil/SMTPortfolio.cpp Outdated Show resolved Hide resolved
protected:
void setupSmtCallback() override;

bool m_computeInvariants;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be private, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change to private both in EldaricaCHCSmtLib2Inteface and in Cvc5SmtLib2Interface.

Copy link
Collaborator

@pgebal pgebal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we merge into develop?

There are still some references to CVC4 in config.yml and in some files cmake/toolchains dir. Search for CVC4 in all files in the repo.

Copy link
Collaborator

@pgebal pgebal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very minor comments + let's update the changelog and remove references to CVC4 in cmake/toolchain and config.yml.

libsolidity/formal/Cvc5SMTLib2Interface.cpp Show resolved Hide resolved
libsolidity/formal/Cvc5SMTLib2Interface.cpp Outdated Show resolved Hide resolved
else
{
m_arguments.push_back("--rlimit");
m_arguments.push_back(std::to_string(12000));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optionally we could define 12000 as a named constant so it's not buried here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where do you suggest to put the constant?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I admit I don't know what's the best place. First I thought about using #define, but I've learned it's not recommended. We can leave it like it is now.

@blishko
Copy link
Contributor Author

blishko commented Jun 5, 2024

Very minor comments + let's update the changelog and remove references to CVC4 in cmake/toolchain and config.yml.

Added an entry to changelog and removed the missed references to CVC4. Thanks!

Instead of compiling `solc` itself with CVC4 support, it is now enough
to have `cvc5` executable on PATH when running the compiler.
Instead of using API of CVC4, we now use SMT-LIB2 interface.
That means we write the queries to temporary SMT-LIB2 files and call
the solver process directly to run on the file.
We are using SMTCommand inside UniversalCallback to call external
solvers on queries produced my our engines.

Previous mechanism set the external solver once during initialization
and it was not possible to change it later. This meant, that it would
not be possible to use, e.g., Eldarica and cvc5 at the same time.

Here we move the proper setup for SMTCommand just before we call it.
This setup is customized by subclasses of (CHC)SmtLib2Interface, which
call corresponding external solvers.
Copy link
Member

@r0qs r0qs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, but I believe we also need to update solc-js. For instance, see: https://github.com/ethereum/solc-js/blob/fa19cf85208d24f10e29646f6e33b1ce23719341/smtsolver.ts#L21

@r0qs
Copy link
Member

r0qs commented Jun 7, 2024

Why don't we merge into develop?

Not sure if this was already answered, but the reason is because this PR relies on cvc5 being installed on the images used by the CI. Thus it depends on #15102 being merged first.

@@ -1104,7 +1104,7 @@ jobs:
environment:
<<: *base_ubuntu2204_large_env
CMAKE_BUILD_TYPE: Debug
CMAKE_OPTIONS: -DCMAKE_CXX_STANDARD=20 -DUSE_CVC4=OFF
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, doesn't this mean that cvc5 will be used if found? Should this be the default behavior now in these images?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cvc5 will be used only in tests that explicitly request it.
It is now runtime dependency, not a compile-time dependency, as CVC4 was.

Not sure what you mean by default behaviour. As I understand it, default behaviour does not change.

@blishko
Copy link
Contributor Author

blishko commented Jun 7, 2024

Looks good to me, but I believe we also need to update solc-js. For instance, see: https://github.com/ethereum/solc-js/blob/fa19cf85208d24f10e29646f6e33b1ce23719341/smtsolver.ts#L21

Hmm, OK, yes, we should probably do that. Even though, it is probably an independent thing, if I understand it correctly, no?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
has dependencies The PR depends on other PRs that must be merged first smt
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants