用Z3编码部分映射
我想在Z3中对部分映射进行编码,支持询问映射是否为某个键定义 它还应该支持操作用Z3编码部分映射,z3,smt,Z3,Smt,我想在Z3中对部分映射进行编码,支持询问映射是否为某个键定义 它还应该支持操作(update_map m1 m2),该操作使用m2中的映射更新m1,以便m2的映射覆盖m1的映射 我尝试使用数组和自定义的选项数据类型对其进行编码,并公理化地指定了update\u map函数。然而,Z3似乎甚至不能处理我的update\u map规范:它在以下代码中返回unknown: (declare-datatypes (T) ((option None (Some (option-value T))))) (
(update_map m1 m2)
,该操作使用m2
中的映射更新m1
,以便m2
的映射覆盖m1
的映射
我尝试使用数组和自定义的选项
数据类型对其进行编码,并公理化地指定了update\u map
函数。然而,Z3似乎甚至不能处理我的update\u map
规范:它在以下代码中返回unknown
:
(declare-datatypes (T) ((option None (Some (option-value T)))))
(define-sort map (K V) (Array K (option V)))
(declare-sort V)
(declare-sort K)
(define-const empty_map (map K V)
((as const (Array K (option V))) None))
(define-fun get ((m (map K V)) (k K)) (option V)
(select m k))
(define-fun put ((m (map K V)) (k K) (v V)) (map K V)
(store m k (Some v)))
(declare-fun update_map ((map K V) (map K V)) (map K V))
(assert (forall ((m1 (map K V)) (m2 (map K V)) (k K))
(=> (= (get m2 k) None)
(= (get (update_map m1 m2) k) (get m1 k)))))
(assert (forall ((m1 (map K V)) (m2 (map K V)) (k K) (v V))
(=> (= (get m2 k) (Some v))
(= (get (update_map m1 m2) k) (Some v)))))
(check-sat)
所以我有两个问题:
更新地图的事实
Z3无法证明可满足性,即无法为您的公式构建模型。不幸的是,我不知道更确切的原因——可能是Z3对数组、量词或组合的模型查找能力受到限制 如果您最终对寻找模型不感兴趣,而是对反例(unsat核心)感兴趣,那么添加一个不可满足的公式,并尝试获得unsat。例如,尝试以下内容(免责声明:我并没有真正尝试过,但我相信你已经明白了):
作为在数组顶部对映射进行公理化的替代方法,请查看。这些公理是用Boogie语言提供的,但到Z3的翻译通常是直截了当的。Z3无法证明可满足性,即无法为公式构建模型。不幸的是,我不知道更确切的原因——可能是Z3对数组、量词或组合的模型查找能力受到限制 如果您最终对寻找模型不感兴趣,而是对反例(unsat核心)感兴趣,那么添加一个不可满足的公式,并尝试获得unsat。例如,尝试以下内容(免责声明:我并没有真正尝试过,但我相信你已经明白了):
作为在数组顶部对映射进行公理化的替代方法,请查看。公理是用Boogie语言提供的,但是到Z3的翻译通常是直接的。我尝试了一些查询,比如
(assert(不是((get(update_-map(put empty_-map 2-2)(put empty_-map 1-1))1))
,但总是得到未知的。实际上,我对寻找作为引理反例的模型很感兴趣,所以我对获得sat
答案感兴趣,然后我进行优化,直到得到unsat
,在这一点上,我知道我已经证明了我的引理。我试图直接使用Dafny进行这个例子,但第一次尝试时效果不太好,看到这个问题:我尝试了一些查询,比如(assert(不是((get(update_-map(put empty_-map 2-2)(put empty_-map 1-1))1))
,但总是得到未知的
。实际上,我对寻找作为引理反例的模型很感兴趣,所以我对获得sat
答案很感兴趣,然后我进行优化,直到得到unsat
,在这一点上我知道我已经证明了我的引理。我试图直接使用Dafny来处理这个例子,但在第一次尝试时效果不太好,请看这个问题:
(assert (not
(=
(get
(update_map
(put empty_map 2 -2)
(put empty_map 1 -1))
-1))))