I am implementing a user theory plug-in. I want to test inconsistency in the user theory to prune some models.
More specifically, in my theory, x is a variable of the user sort of set and f is the function returning the size of the set. I have two assertions: x = set1 OR x = set2 and f x > 2. Suppose the size of set1 is 1 and the size of set2 is 3.
In the search, Z3 goes with x = set1 first. So I can add another assertion f x = 1, which will be inconsistent in the INT part. I want to test the inconsistency so that I can negate the current assignment, let Z3 backtrack and try the other option.
My question is that how I can do that.
I tried 3 approaches:
(1) Add the assertion f x = 1 directly using Z3_theory_assert_axiom(). Then the search terminates immediately returning UNSAT.
(2) I tried to use Z3_check_assumptions() with f x = 1 as the assumption to check with current context. But Z3_check_assumptions() doesn't allow such a compound formula. So, it can not be the solution.
(3) I firstly push the context, add the assertion f x = 1 with Z3_assert_cnstr(), test the consistency with Z3_check_and_get_model(), and then pop the context just pushed. In the test, if it's not consistent, I get current assignment with Z3_get_context_assignment(ctx) and assert the negated assignment to trigger the backtrack. What I observe is that Z3 does find the inconsistency but the current assignment only contains assertions about the size part like (= 1 (f x)). Or in other word, the assertions about the user theory like (= x set1) and not (= x set2) is missing. So even I negate the current assignment, after the backtracking, Z3 still tries the x = set1 instead of the other option x = set2.
Where I was wrong? Thanks!