最近,我将使用.NET API的应用程序从Z3 4.1升级到4.3版。但是,我注意到MkSolver()
中的某些更改现在导致我在4.1中返回unsat
的一些查询现在在4.3中返回unknown
。特别是,我一直使用Context
选项ELIM_QUANTIFIERS
设置为true,根据我在尝试使用求解器时收到的错误消息已弃用:
QUANT_ELIM option is deprecated, please consider using the 'qe' tactic.
如果未启用此选项,我的某些查询可能会收到未知。我已尝试在4.3中使用各种策略,包括量词消除qe
,但不幸的是,我无法找出与Z3 4.1中的MkSolver创建的等效策略集。例如,以下内容不起作用(即,对于4.1中我不满意的查询,我仍然在4.3中未知):
Context z3 = new Context();
Params p = z3.MkParams();
p.Add("produce-models", true);
p.Add("candidate-models", true);
p.Add("mbqi", true);
p.Add("auto-config", false);
p.Add("ematching", true);
p.Add("pull-nested-quantifiers", true);
Tactic tqe = z3.With(z3.MkTactic("qe"), p);
Tactic tsmt = z3.With(z3.MkTactic("smt"), p);
Tactic t = z3.Repeat(tqe, tsmt);
Solver s = t.Solver;
... // assert and check assertions
如果在4.3中对于MkSolver
中创建的MBQI = true
中存在等效的求解策略,那么它是什么或者如何才能搞清楚?我在4.1中使用了各种其他上下文选项,我尝试在4.3中使用适当的策略,例如:AUTO_CONFIG = false
,ELIM_NLARITH_QUANTIFIERS = true
,EMATCHING = true
,MACRO_FINDER = true
,PI_PULL_QUANTIFIERS = true
,PULL_NESTED_QUANTIFIERS = true
,DISTRIBUTE_FORALL = true
,PULL_NESTED_QUANTIFIERS = true
和unknown
。
这是一个示例查询,现在返回unsat
,之前返回LB
(注意它只有一些额外的断言,这很长,但这是断言的格式)现在给出了未知。LS
,vmin
,vmax
和LS = 7
都是真正的常量[断言将它们等同于常量值,例如q
],x
是一个从整数到位向量的函数,next
是一个从整数到实数的函数,last
是一个从整数到整数的函数,delta * t_1
是一个函数。整数,同样对于它们的引导版本;同样,请注意它的一部分是非线性的,例如delta * t_2
和(set-option :auto-config false)
;(set-option :elim-quantifiers true)
(set-option :elim-nlarith-quantifiers true)
(set-option :mbqi true)
(set-option :produce-models true)
(set-option :proof-mode 1)
(declare-const LB Real)
(declare-const LS Real)
(declare-const vmin Real)
(declare-const vmax Real)
(declare-const Base (_ BitVec 2))
(declare-const N Int)
(declare-fun q (Int) (_ BitVec 2))
(declare-fun |q'| (Int) (_ BitVec 2))
(declare-fun x (Int) Real)
(declare-fun |x'| (Int) Real)
(declare-fun next (Int) Int)
(declare-fun |next'| (Int) Int)
(declare-const last Int)
(declare-const |last'| Int)
(declare-const t_1 Real)
(declare-const t_2 Real)
(declare-const delta Real)
(assert (= Base #b01))
(assert (= vmin 1.0))
(assert (= vmax 2.0))
(assert (= LS 7.0))
(assert (= LB 28.0))
(assert (not (=> (and (forall ((i Int) (j Int))
(=> (and (>= i 1) (<= i N) (>= j 1) (<= j N))
(=> (and (not (= i j))
(= (q i) Base)
(= (q j) Base)
(= (next j) i))
(>= (- (x i) (x j)) LS))))
(exists ((t_1 Real))
(and (>= t_1 0.0)
(forall ((h Int))
(=> (and (>= h 1) (<= h N))
(and (exists ((delta Real))
(forall ((t_2 Real))
(=> (and (>= t_2 0.0) (<= t_2 t_1))
(and true
true
(or (not (= (q h) Base))
(and (<= (+ (x h) (* delta t_2)) LB)
(or (not (>= (+ (x h)
(* delta t_2))
LB))
(= t_1 t_2))
(= (|x'| h)
(+ (x h) (* delta t_1)))
(>= delta vmin)
(<= delta vmax)))
true))))
(= (q h) (|q'| h))
(= (next h) (|next'| h))
(= last |last'|)))))))
(forall ((i Int) (j Int))
(or (not (and (>= i 1) (<= i N) (>= j 1) (<= j N)))
(not (and (not (= i j))
(= (|q'| i) Base)
(= (|q'| j) Base)
(= (|next'| j) i)))
(>= (+ (|x'| i) (* (- 1.0) (|x'| j))) LS))))))
(check-sat) ; toggles between unknown and sat when toggling elim-nlarith-quantifiers
):
{{1}}
基本上,我想创建与此处使用的任何解算器相对应的策略解算器,因为这种切换行为是我在4.1中看到的,但是在4.3中没有看到,因为我无法使用ELIM_QUANT通过上下文选项了。