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/)