Closed disteph closed 4 years ago
I will take a look. It might take some time. In the meantime, if you have a way to make it the example smaller, that would be useful for debugging (e.g., no maybe try 2-bit bit-vectors, less variables, etc).
I'm trying out https://github.com/aniemetz/ddSMT to minimize the problem. But I get
function 'bvadd' expects (at least) 2 argument(s), 4 given
Indeed I give 4 arguments, but I thought that in SMTLib, bvadd
could take more than 2. The doc says The operators in {bvand, bvor, bvadd, bvmul} have the :left-assoc attribute.
at http://smtlib.cs.uiowa.edu/theories-FixedSizeBitVectors.shtml.
Anyway, I can change my pretty-printer to use binary bvadd
only... but I was just surprised.
Not sure if SMTLIB is flexible, but ddSMT parse is such so probably better to do binary.
Allowing n-ary bvadds is a relatively recent change. ddSMT was written before.
ah, thanks. I presume it's also the case of bvmul, etc.
Anyway, even with binary bvadd, ddsmt chokes on (check-sat-assuming-model...)
and (get-unsat-model-interpolant)
, understandably. Truncating the bitvector size from 32 to, say, 8, makes the problem disappear, so I'm running out of ideas to minimize the problem further.
For what it's worth, running yices-mcsat in debug with --trace mcsat::bv::conflict::check
doesn't complain, which tends to suggest that the theory lemmas are all correct...
Actually I was suggesting to used ddSMT on the original quantified problem.
I assume that your solver will crash (or report error) because of this bug. You can just use ddSMT to make the original problem smaller while still crashing. I would be surprized if this doesn't work.
Yeah, I've just tried that. It reduced the file size a bit. Same interpolant, I think. The archive below gives:
Another similar one RND_4_11.dd.zip
Ah, this one is smaller: RND_3_4.dd.zip
Copying from Slack the simplified version of RND_3_4.dd, just to keep everything in one place:
(set-option :produce-unsat-model-interpolants true)
(set-logic QF_BV)
(declare-fun x () (_ BitVec 32))
(declare-fun y () (_ BitVec 32))
(assert
(=
#b00000000000000000000000000111001
(bvadd
(bvmul #b11111111111111111111111111010011 x)
(bvmul #b11111111111111111111111111111000 y)))
)
(assert
(or
(=
(bvmul #b00000000000000000000000000111101 x)
#b11111111111111111111111111101110)
(bvsge
(bvmul #b00000000000000000000000001011011 x)
#b00000000000000000000000000111010)
(not
(=
#b00000000000000000000000000111001
(bvadd
#b11010000000000000000000000000000
(bvmul #b11111111111111111111111111010011 x))))))
(check-sat-assuming-model
(y x)
(#b00000110000000000000000000000000
#b00000000000000000000000000000000))
(get-unsat-model-interpolant)
2 variables, 2 constraints. You force the values of the two variables, you get UNSAT, i.e., the conjunction of the two constraints evaluates to false. In fact, the first constraint evaluates to false, the second evaluates to true. But the interpolant you get is exactly the second constraint, though the interpolant should evaluate to false. If you remove the second constraint, or replacing it by "true", you get an interpolant that looks more meaningful.
Attempt of fix committed. @disteph check it out and close if fixed.
It looks good, thanks!
I spoke too soon. It worked on the above example, and many others, but it still fails on another 53 instances. The smallest I find is this one:
(set-option :produce-unsat-model-interpolants true)
(set-logic QF_BV)
(declare-fun y!1 () (_ BitVec 8))
(declare-fun y!2 () (_ BitVec 8))
(declare-fun y!3 () (_ BitVec 8))
(declare-fun trig4 () Bool)
(assert
(or
(not
(or
(not
(=
#b00000001
y!1))
(not
(=
#b00000000
y!2))
(not
(=
(ite
(bvuge
y!1
#b01100100)
y!1
(bvadd y!1 y!2))
y!3))))
(not trig4)))
(check-sat-assuming-model
(trig4 y!3 y!2 y!1)
(true
#b00000000
#b00000000
#b00000000))
(get-unsat-model-interpolant)
It gives me unsat with the following interpolant
(or
(=
(ite
(bvuge
y!1
#b01100100)
y!1
(bvadd y!1 y!2))
y!3)
(not trig4))
and the following file checks that the interpolant evaluates to true, not false:
(set-option :produce-unsat-model-interpolants true)
(set-logic QF_BV)
(declare-fun y!1 () (_ BitVec 8))
(declare-fun y!2 () (_ BitVec 8))
(declare-fun y!3 () (_ BitVec 8))
(declare-fun trig4 () Bool)
(assert
(or
(=
(ite
(bvuge
y!1
#b01100100)
y!1
(bvadd y!1 y!2))
y!3)
(not trig4)))
(check-sat-assuming-model
(trig4 y!3 y!2 y!1)
(true
#b00000000
#b00000000
#b00000000))
Ok, yet another fix added. @disteph another round.
Btw, if you run it with --trace mcsat::interpolant::check
it will check the resulting interpolant.
Looks good now, thanks!
input file:
gives me interpolant
I can check via Yices' API that the "interpolant" evaluates to true in the model; my understanding is that it should evaluate to false. One can also check the evaluation by feeding the interpolant as a single assert, and then do
check-sat-assuming-model
, which should return unsat if the interpolant was correct. But I get sat, running on