我们可以在Z3固定点查询中使用ite表达式吗?

时间:2016-03-20 22:46:28

标签: z3 fixed-point

我修改了z3定点教程

中的边和路径示例
(set-option :fixedpoint.engine datalog)
(define-sort s () (_ BitVec 3))
(declare-rel edge (s s))
(declare-rel path (s s))
(declare-var a s)
(declare-var b s)
(declare-var c s)

(rule (=> (edge a b) (path a b)))
(rule (=> (and (path a b) (path b c)) (path a c)))

(rule (edge #b001 #b010))
(rule (edge #b001 #b011))
(rule (edge #b010 #b100))

(declare-rel q1 ())
(declare-rel q2 ())
(declare-rel q3 (s))
(rule (=> (path #b001 #b100) q1))
(rule (=> (path #b011 #b100) q2))
(rule (=> (and (path #b001 b) (path #b010 b)) (q3 b))); I modified this rule by adding a conjunct in the antecedent

(query q1)
(query q2)
(query q3 :print-answer true)

这没有任何问题。

但是,如果我将其更改为具有ite表达式的功能相同的脚本,我会收到错误。

这是使用ite:

更新的脚本
(set-option :fixedpoint.engine datalog)
(define-sort s () (_ BitVec 3))
(declare-rel edge (s s))
(declare-rel path (s s))
(declare-var a s)
(declare-var b s)
(declare-var c s)

(rule (=> (edge a b) (path a b)))
(rule (=> (and (path a b) (path b c)) (path a c)))

(rule (edge #b001 #b010))
(rule (edge #b001 #b011))
(rule (edge #b010 #b100))

(declare-rel q1 ())
(declare-rel q2 ())
(declare-rel q3 (s))
(rule (=> (path #b001 #b100) q1))
(rule (=> (path #b011 #b100) q2))
(rule (=> (and (path #b001 b) (not (= (ite (path #b010 b) 1 0) 0))) (q3 b))) ; I added ite expression here

(query q1)
(query q2)
(query q3 :print-answer true) 

我找回了以下错误:

(error "query failed: Rule contains nested predicates q3(#0) :- path(#b001,#0), (not (= (ite (path #b010 (:var 0)) 1 0) 0)). ") 
unknown 
(error "query failed: Rule contains nested predicates q3(#0) :- path(#b001,#0), (not (= (ite (path #b010 (:var 0)) 1 0) 0)). ") 
unknown 
(error "query failed: Rule contains nested predicates q3(#0) :- path(#b001,#0), (not (= (ite (path #b010 (:var 0)) 1 0) 0)). ") 
unknown

我试图创建一个新的关系iteRel来模拟ite表达式的效果而没有任何成功。

(set-option :fixedpoint.engine datalog)
(define-sort s () (_ BitVec 3))
(declare-rel edge (s s))
(declare-rel path (s s))
(declare-var a s)
(declare-var b s)
(declare-var c s)

(rule (=> (edge a b) (path a b)))
(rule (=> (and (path a b) (path b c)) (path a c)))

(rule (edge #b001 #b010))
(rule (edge #b001 #b011))
(rule (edge #b010 #b100))

(declare-rel q1 ())
(declare-rel q2 ())
(declare-rel q3 (s))

(declare-rel iteRel (s s Int Int Int))

(rule (forall ((x s) (y s) (z1 Int) (z2 Int))
  (=> (and (iteRel x y z1 z2 z1))
     (path x y)) 
))

(rule (=> (path #b001 #b100) q1))
(rule (=> (path #b011 #b100) q2))
(rule (=> (and (path #b001 b) (iteRel #b010 b 1 0 1)) (q3 b)))

(query q1)
(query q2)
(query q3 :print-answer true)

这将使q3不饱和。

在z3定点中使用ite表达式是否有任何解决方法?我需要在动态符号执行引擎中一起使用它们。非常感谢你提前!

1 个答案:

答案 0 :(得分:1)

首先,对于依赖于分层否定的应用程序,它是 更好地坚持有限域,因为分层否定 没有为整数域等定义。

您可以使用horn子句定义任意公式 分层否定:这样做的方法是提供一个名称 对于子公式,然后是定义子公式的规则。 例如,如果要定义(ite(P x)(Q y)(R z)),则使用以下规则引入谓词(ITEPQR x y):

   (rule (=> (and (P x) (Q y)) (ITEPQR x y)))
   (rule (=> (and (not (P x)) (R y)) (ITEPQR x y)))

你应该能够使用ite表达式的唯一方法是它们不包含 任何已定义的谓词。也就是说,它们的迭代表达式是绑定变量和解释函数(通过位向量)。