1

Z3 provides unknown for the simple problem:

(assert
(forall ((y (Array Int Int)))
   (= (select y 1) 0))
 )
(check-sat)

I've found that it becomes sat if negate the forall, but this seems like a particularly simple thing to be unable to solve.

This is causing issues because the class of problems I want to solve are more like,

(declare-fun u () Int)
(assert
 (forall ((y (Array Int Int)) )
     (=> 
        (= u 0) (<= (select y 1) 0))
 )
)
(check-sat)

Where negating the forall alone is not the same problem, so that cannot be done here. Is there some way to pose this style of problem to Z3 to get an un/sat result?

Dval
  • 352
  • 1
  • 10

2 Answers2

3

Problems with quantifiers are always problematic with SMT solvers, especially if they involve arrays and alternating quantifiers like in your example. You essentially have exits u. forall y. P(u, y). Z3, or any other SMT solver, will have hard time dealing with these sorts of problems.

When you have a quantified assertion like you do where you have forall's either at the top-level or nested with exists, the logic becomes semi-decidable. Z3 uses MBQI (model-based quantifier instantiation) to heuristically solve such problems, but it more often than not fails to do so. The issue isn't merely that z3 is not capable: There's no decision procedure for such problems, and z3 does its best.

You can try giving quantifier patterns for such problems to help z3, but I don't see an easy way to apply that in your problem. (Quantifier patterns apply when you have uninterpreted functions and quantified axioms. See https://rise4fun.com/z3/tutorialcontent/guide#h28). So, I don't think it'll work for you. Even if it did, patterns are very finicky to program with, and not robust with respect to changes in your specification that might otherwise look innocuous.

If you're dealing with such quantifiers, SMT solvers are probably just not a good fit. Look into semi-automated theorem provers such as Lean, Isabelle, Coq, etc., which are designed to deal with quantifiers in a much more disciplined way. Of course, you lose full automation, but most of these tools can use an SMT solver to discharge subgoals that are "easy" enough. That way, you still do the "heavy-lifting" manually, but most subgoals are automatically handled by z3. (Especially in the case of Lean, see here: https://leanprover.github.io/)

alias
  • 28,120
  • 2
  • 23
  • 40
0

There's one extra closing (right) parentheses, which needs to be removed. Also, add assert before the forall statement.

(assert ( forall ( (y (Array Int Int) ) ) 
   (= (select y 1) 0) 
))
(check-sat)

Run the above code and you should get unsat as the answer.

For the second program, alias' answer may be useful to you.

user8616916
  • 73
  • 1
  • 7