-
Notifications
You must be signed in to change notification settings - Fork 35
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
Non-model variables #208
Comments
It might be more flexible to just give more control when calling |
Interesting idea. So, you want
You only want to see one model per unique value of Is that what you are after? |
Yes, that's exactly right. For now I've reimplemented the logic of |
I haven't read the above too carefully, but it does sound to me like Yices's exists/forall solver might be interesting (http://smt2015.csl.sri.com/wp-content/uploads/2015/06/2015-Dutertre-Solving-Exists-Forall-Problems-With-Yices.pdf). Perhaps SBV could add support for... not fully mixed quantification but special cases such as what Yices now supports? |
@rwbarton We can indeed add support for such uninteresting variables; but I suspect whatever we consider "uninteresting" now will not be sufficient for the next person who needs something like this. And it does sound like you already have a way of "iterating" over each call and adding enough constraints to discard what you consider uninteresting for that particular domain. I'm also reminded of a similar example that already exists in the repo: https://hackage.haskell.org/package/sbv-5.8/docs/Data-SBV-Examples-Misc-ModelExtract.html It only relates to one variable there, where we consider interesting to be differing by at least Regarding performance: It's not going to be any better or worse than what Unless SMT solvers adopt this sort off "all-models" command, I don't think we can do any better. The only solver that I know has some support for all-models is alt-ergo; though SBV doesn't talk to it directly yet. You might want to look into that if the performance becomes an issue and we can add a bridge for it. Let me know if the above example is sufficient to address your needs. |
@TomMD Bruno's paper is indeed interesting, and something I'd like SBV to take advantage of if possible; though it's not directly related to the problem @rwbarton wants to address. In the latter case, all the variables are existential, just some of them are not really interesting. In Bruno's case, there's a strict alternation of universals coming right after existentials. The so called existential-universal problem arises all the time in optimization as well; and is actually precisely how the |
Well, no not really. I'm doing exactly what I said in my original post. Instead of a problem of the form
I am interested in problems of the form:
This doesn't require any more power from the underlying solver, and I found it a little surprising that "existential" variables don't work like this already. It seems like a particularly natural thing to want. On the subject of performance: it's not a real problem for me; but my problems typically have thousands of variables with the number of constraints being a smallish constant factor longer, so the total time to find n solutions quickly becomes quadratic; and the constant factors are much worse when pushing the constraints rejecting old solutions through the whole system--I think The real performance gains would come from an interface to interactive mode, so the solver doesn't have to start from scratch for each solution... any thoughts on that? |
I'm not sure what you mean by Re performance: Quite right. All-sat is smart about not reconstructing the problem, but just adding the refuting model. However, the solver is started from scratch and typically it's the solver time that dominates the computation, not problem construction time. But I can see that could be an issue. I'm not opposed to adding an Re: incremental interface: That's a whole another beast and I'm hesitant to tackle; should've been built from day-one I think. It's hard to graft it on. One reason is that to use incrementality in its full power, SBV needs to talk to the solvers and ask queries/get-answers etc.; and every solver seems to behave slightly differently. As the SMT-Lib standard matures, however, one can imagine adding a standardized interface. Perhaps that should be a separate library built on top of SBV to keep it clean. |
I'm talking about the difference between |
No; Prelude Data.SBV> let f x y = x + y .== (0::SInteger)
Prelude Data.SBV> sat f
Satisfiable. Model:
s0 = 0 :: Integer
s1 = 0 :: Integer
Prelude Data.SBV> prove f
Falsifiable. Counter-example:
s0 = 1 :: Integer
s1 = 0 :: Integer That's the whole motivation behind So "free" doesn't really mean "auxiliary" in this particular sense; but rather "pick the quantifier accordingly." Whether this was the right design choice is up for discussion of course, but it's sort of baked-in by now. |
@rwbarton Just committed a simple change to accommodate for such variables. Here's an example: t = allSat $ do
x <- free "x"
y <- free "y"
constrain $ x .>= 0
constrain $ x .<= 2
return $ x - abs y .== (0 :: SInteger) This produces: *Main> t
Solution #1:
x = 0 :: Integer
y = 0 :: Integer
Solution #2:
x = 1 :: Integer
y = -1 :: Integer
Solution #3:
x = 2 :: Integer
y = -2 :: Integer
Solution #4:
x = 2 :: Integer
y = 2 :: Integer
Solution #5:
x = 1 :: Integer
y = 1 :: Integer
Found 5 different solutions. But, if we say: t = allSatWith z3{nonModelVars = ["y"]} $ do
x <- free "x"
y <- free "y"
constrain $ x .>= 0
constrain $ x .<= 2
return $ x - abs y .== (0 :: SInteger) Then we get: *Main> t
Solution #1:
x = 0 :: Integer
Solution #2:
x = 1 :: Integer
Solution #3:
x = 2 :: Integer
Found 3 different solutions. Is this a satisfactory solution for your needs? I'm open to other design options to make sure it handles your case well. Note that we don't even print the value for |
Example: http://github.com/LeventErkok/sbv/blob/master/Data/SBV/Examples/Misc/Auxiliary.hs I'll make a new release once @rwbarton OKs this design/solution. |
This works for me, thanks! I might be using it in a slightly unintended way, by giving all my non-model variables the same name (say |
Oh, and one of my tests (generating all of the 1072 Hamiltonian cycles in a 6x6 grid) now runs in ~12 minutes, rather than ~30 minutes. Still painfully quadratic, but certainly a large improvement! |
Nice.. Using duplicate names is sneaky; the fact that it works is because I didn't think about checking for duplicates :-) I don't think anything really relies on names being unique, but I can imagine it being at least confusing when models are printed. And if you ever need those witness variables, they'd be hard to extract from the dictionary. Perhaps a better design is to make |
Yes, I think that's probably a better way to go. |
Great; I'll make a release after that change later tonight. @rwbarton If you could tell me your full name (your github profile doesn't have it so far as I can see), I'd like to put it into the ack list.. |
This is a feature request, though it's possible I've missed some existing functionality which provides this.
I want to solve problems of the form:
"Find all (v1, ..., vn) such that there exist (e1, ..., em) such that P(v1, ..., vn, e1, ..., em)."
I don't care about the values of the variables ej in a satisfying assignment, and for a particular solution (v1, ..., vn), there may be (even infinitely) many values of (e1, ..., em) that satisfy the predicate P. For example, the (v1, ..., vn) may determine the structure of a graph, and the (e1, ..., em) may represent a witness of some property of the graph, such as connectedness, which is most easily encoded by taking advantage of nondeterminism. I want to generate each connected graph just once.
I would like to use the very convenient
allSat
, but in order to do so I need to tell it, when generating clauses that reject previously found solutions, to include only the variables v1, ..., vn and not the variables e1, ..., em. I hoped that this might be the difference between "free" variables and "existential" variables, but that seems not to be the case.The text was updated successfully, but these errors were encountered: