I modified the edge and path example in the z3 fixed-point tutorial
(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)
This runs fine without any problem.
But if I change this to a functionally equivalent script with an ite expression, I get back errors.
This is updated script using 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)
I get back the following errors:
(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
I have tried to create a new relation iteRel to simulate the effect of ite expression without any success.
(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)
The would make q3 unsat.
Is there any workaround to use ite expression in z3 fixed-points? I need to use them together in my dynamic symbolic execution engine. Thank you very much in advance!