关于Z3如何操作数组,我有两个问题。
1)在模型中,数组有一个" else"元素以及相应的值。有没有办法在" else"上指定约束?公式中数组上的元素?例如,我们可以指定数组的第一个元素是否大于5而所有其他元素是否小于5?
2)在命令行通过z3检查以下公式时,
(set-logic QF_AX)
(declare-sort Index 0)
(declare-sort Element 0)
(declare-fun a1 () (Array Index Element))
(declare-fun i0 () Index)
(declare-fun i1 () Index)
(assert
(let
(
(?v_1 (select a1 i0))
(?v_2 (select a1 i1))
)
(
not(= ?v_1 ?v_2)
)
)
)
Z3生成以下输出。
sat
(model
;; universe for Index:
;; Index!val!1 Index!val!0
;; -----------
;; definitions for universe elements:
(declare-fun Index!val!1 () Index)
(declare-fun Index!val!0 () Index)
;; cardinality constraint:
(forall ((x Index)) (or (= x Index!val!1) (= x Index!val!0)))
;; -----------
;; universe for Element:
;; Element!val!1 Element!val!0
;; -----------
;; definitions for universe elements:
(declare-fun Element!val!1 () Element)
(declare-fun Element!val!0 () Element)
;; cardinality constraint:
(forall ((x Element)) (or (= x Element!val!1) (= x Element!val!0)))
;; -----------
(define-fun i1 () Index
Index!val!1)
(define-fun a1 () (Array Index Element)
(_ as-array k!0))
(define-fun i0 () Index
Index!val!0)
(define-fun k!0 ((x!1 Index)) Element
(ite (= x!1 Index!val!0) Element!val!0
(ite (= x!1 Index!val!1) Element!val!1
Element!val!0)))
)
通过Z3py检查相同的公式后,将生成以下模型。
[i1 = Index!val!1,
a1 = [Index!val!0 -> Element!val!0,
Index!val!1 -> Element!val!1,
else -> Element!val!0],
i0 = Index!val!0,
k!0 = [Index!val!0 -> Element!val!0,
Index!val!1 -> Element!val!1,
else -> Element!val!0]]
有趣的是,k!0
中对a1
的引用是"已取消引用"在Z3py中,即a1
指的是FuncInterp
个对象。总是这样吗?具体来说,如果程序遍历Z3py提供的模型,是否可以安全地假设所有as_array
表达式都将被解析为基础函数定义?
答案 0 :(得分:0)
数组是一种特殊情况,因为它们有一个func_interp作为模型。在Python API中,我们可以依赖于dereferenced
,它是为我们执行此操作的get_interp
函数:
def get_interp(self, decl):
...
if decl.arity() == 0:
r = _to_expr_ref(Z3_model_get_const_interp(self.ctx.ref(), self.model, decl.ast), self.ctx)
if is_as_array(r):
return self.get_interp(get_as_array_func(r)) # <-- Here.
else:
return r