我修改了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表达式是否有任何解决方法?我需要在动态符号执行引擎中一起使用它们。非常感谢你提前!
答案 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表达式的唯一方法是它们不包含 任何已定义的谓词。也就是说,它们的迭代表达式是绑定变量和解释函数(通过位向量)。