0

this question is a follow up to the following quesion:

Building custom theories in Z3

As Nikolaj suggested, I implemented a lazy-loop approach, but I have a few questions about it.

1. I am using the get_func_interp function of the model class to get the interpretation given to my custom predicates by Z3. It works fine most of the time, but sometimes, the interpretation is defined in terms of other functions generated by Z3 (Example below)

Model:

(define-fun path1() Int 712)

(define-fun path2 () Int
  38)
(define-fun z3contians ((x!1 Int) (x!2 Int)) Bool
  true)
(define-fun k!15 ((x!1 Int)) Int
  (ite (= x!1 1) 1
    0))
(define-fun z3connects!16 ((x!1 Int) (x!2 Int) (x!3 Int)) Bool
  (ite (and (= x!1 712) (= x!2 0) (= x!3 1)) true
  (ite (and (= x!1 38) (= x!2 1) (= x!3 5)) true
    false)))
(define-fun k!13 ((x!1 Int)) Int
  (ite (>= x!1 712) (ite (>= x!1 1001) 1001 712) 38))
(define-fun k!14 ((x!1 Int)) Int
  (ite (= x!1 1) 1
    5))
(define-fun z3connects ((x!1 Int) (x!2 Int) (x!3 Int)) Bool
  (z3connects!16 (k!13 x!1) (k!15 x!2) (k!14 x!3)))

In these cases, theg get_func_interp function seems insufficient. I can't iterate over all possible inputs to the function and use eval, because I don't know the number of non-default cases for that function.

2. While using the lazy loop approach, I noticed that Z3 sometimes misses the right models because it attempts to change values that need not really be changed. I have written a small example to illustrate the case:

(declare-fun path1 () Int)
(declare-fun path2 () Int)
(declare-fun pred1 (Int) Bool)
(declare-fun pred2 (Int) Bool)
(assert (pred1 path1))
(assert (pred2 path2))
(check-sat)
(get-model)

Now, if we consider pred1(x) to be (x==12), and pred2(x) to be (x==11), we can see that Z3 never gets the model, because it always reports only models with (path1=1, path2=2), (path1=2,path2=3)...(path1=10,path2=11),(path1=11,path2=12).... and so on. Is there a tactic that I can specify to prevent this? I do understand that this is not a tool specific issue, but any insight would help.

Community
  • 1
  • 1
SPMP
  • 1,181
  • 1
  • 9
  • 24
  • Regarding 2: you probably have something in mind with respect to what is the "right" model. The main point would be to block not just a single model but a whole set of models when calling Z3. Suppose you get a sequence of models (1,2) (2,3) (3,4), .. What is wrong with this sequence? It depends on what your theory says of course. Now suppose that your theory requires that path1 > path2, then add instead path1 > path2 instead of (and (not (= path1 1)) (not (= path2 2))) – Nikolaj Bjorner Jan 29 '14 at 03:58
  • Regarding 1: I am not sure I understand that you "can't iterate over the inputs". The interpretation for your functions is a composition: first k!xx gets applied to arguments, then some other function is applied. To iterate over domains, here is a simple (non-optimized) approach: create the cross-product of non-default domain values + one extra value for the k!xx functions. Treat this as the new set of non-defaults. – Nikolaj Bjorner Jan 29 '14 at 04:10

0 Answers0