runtimeverification / haskell-backend

The symbolic execution engine powering the K Framework
BSD 3-Clause "New" or "Revised" License
212 stars 42 forks source link

Dynamic prelude #4034

Open PetarMax opened 3 months ago

PetarMax commented 3 months ago

I've had an idea:

:boom: The prelude should not be fixed. It should be reset dynamically, removing all uninterpreted function symbols (and associated SMT lemmas) that are not in the ground truth plus the predicates to be checked. :boom:

What do we lose? Forall-quantified statements that we know are difficult for the solver to handle. What do we gain? SATs and UNSATs instead of unknowns.

Why am I thinking of this - because I am running some new (potental engagement) tests and I am getting a real Unknown from Z3, and the constraints contain modInt because that is what the code uses. When the smt-lemma

rule chop ( I:Int ) => I modInt pow256 [concrete, smt-lemma]

is present, Z3 really returns Unknown, no matter how large I set the timeout, when it’s removed I get an instant SAT/UNSAT.

This means that that modInt in the SMT lemma is :magic_wand: soMehOw :magic_wand: interacting with the solver, it’s trying to define chop as a function and failing, but chop is not relevant to this query and there is no need for it to be there.

goodlyrottenapple commented 3 months ago

Would you be able to provide a bug report as a starting point for addressing this issue?

PetarMax commented 3 months ago

Actually, I think we can put this on hold for now. I have a way of handling it by replacing the smt-lemma with simplifications.

jberthold commented 3 months ago

Precompute several relations from the definition's SMT components

Iterative algorithm to select lemmas, functions, and sorts to declare:

For checkPredicates, the input is the definition, a ground truth (path condition) and a predicate. A. filter ground truth to only include things that the predicate mentions

The last step should not require any loop back to 2. 🤞

Related booster code is in Booster.SMT.Translate

jberthold commented 2 months ago

As a first (and probably sufficient?) step, the SMT lemmas in the definition according to which functions are actually used by the predicates in question. This requires computing a relation FunctionSymbol x SMTLemma, which will be turned into a lookup table FunctionSymbol -> Set SMTLemma to select the lemmas. Furthermore, the lemmas part of the prelude needs to be recomputed for each request, the SMT solver setup and interface will have to change to accommodate it.