Simplify function interpretation in model

↘锁芯ラ 提交于 2019-12-12 03:36:25

问题


In SMT: check uniqueness and totality of function I gave a function axiomatization and asked Z3 for a model. However because solving something with quantifiers in it is undecidable in general, Z3 times out.

Here is a modified version in which the "int" case is modelled as a single value:

(declare-datatypes () ((ABC int error none)))
(declare-fun f (ABC ABC) ABC)
(assert (forall ((x ABC)) (=> (or (= x int) (= x error) (= x none)) (= (f none x) none))))
(assert (forall ((x ABC)) (=> (or (= x int) (= x error) (= x none)) (= (f x none) none))))
(assert (forall ((x ABC)) (=> (or (= x int) (= x error)) (= (f error x) error))))
(assert (forall ((x ABC)) (=> (or (= x int) (= x error)) (= (f x error) error))))
(assert (forall ((x ABC) (y ABC)) (=> (and (= x int) (= y int)) (= (f x y) int))))
(check-sat)
(get-model)

Because there now are finitely many cases, Z3 gives an answer quickly:

sat
(model
  (define-fun k!26 ((x!0 ABC)) ABC
    (ite (= x!0 error) error
    (ite (= x!0 int) int
      none)))
  (define-fun f!28 ((x!0 ABC) (x!1 ABC)) ABC
    (ite (and (= x!0 error) (= x!1 int)) error
    (ite (and (= x!0 int) (= x!1 error)) error
    (ite (and (= x!0 error) (= x!1 error)) error
    (ite (and (= x!0 int) (= x!1 int)) int
      none)))))
  (define-fun k!27 ((x!0 ABC)) ABC
    (ite (= x!0 error) error
    (ite (= x!0 int) int
      none)))
  (define-fun f ((x!0 ABC) (x!1 ABC)) ABC
    (f!28 (k!27 x!0) (k!26 x!1)))
)

Both k!26 and k!27 actually just return their input (this is easily seen by checking all three cases). Is it possible to simplify the model by eliminating these two functions automatically?

Optimally I would like to have something like the following, although I see that might not be possible:

(define-fun f ((x!0 ABC) (x!1 ABC)) ABC
  (ite (or (= x!0 none) (= x!1 none)) none
  (ite (or (= x!0 error) (= x!1 error)) error
    int)))

I'm using Z3Py, but both general Z3-specific and Z3Py-specific answers are welcome.


回答1:


I don't think there's much you can do to guide Z3 to provide a "simpler" answer here; as the model generated depends on how the proof was done and even simple changes to the problem can have unpredictable results. In particular, the model you get can change with the next version of Z3.

Having said that, a common trick is to eval terms in the model. Since your current problem only involves a finite domain, you can enumerate it. If you add the following lines at the end of your script:

(eval (f int   int))
(eval (f int   error))
(eval (f int   none))
(eval (f error int))
(eval (f error error))
(eval (f error none))
(eval (f none  int))
(eval (f none  error))
(eval (f none  none))

Then Z3 will print:

int
error
none
error
error
none
none
none
none

Perhaps you can use that output to construct a "simpler" model yourself. Of course, this only works if the domain is finite; but you can use the same trick to evaluate "interesting" parts of the input domain, depending on your problem.



来源:https://stackoverflow.com/questions/37501984/simplify-function-interpretation-in-model

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!