相当于记录的数组存储
Equilvalent of array store for a record
一个数组可以存储一个新值,这样做 returns 一个新数组。我知道我可以使用 MkApp 函数访问记录的选择器,然后如何替换记录的值?我正在使用 .NET 绑定,但作为问题的示例,这里有一些 SMT:
(declare-datatypes (T1 T2) ((Pair (mk-pair (first T1) (second T2)))))
(declare-const p1 (Pair Int Int))
(declare-const p2 (Pair Int Int))
(assert (= p1 p2))
(assert (> (second p1) 20))
;How to replace (second p1) with 0
(check-sat)
(get-model)
我认为没有统一的方法来更新记录的第 n 个部分,您基本上必须 "unroll" 更新的定义:更新数组 a 时,您基本上假设“对于所有 j,要么 i 是 j,a[j] 因此是新值,要么 a[j] 具有旧值”。由于一条记录有有限多个元素,您可以展开相应的更新定义:
(declare-datatypes (T1 T2) ((Pair (mk-pair (first T1) (second T2)))))
(declare-const p1 (Pair Int Int))
(assert (= (first p1) 1))
(assert (= (second p1) 2)) ;; p1 is (1, 2)
(declare-const p2 (Pair Int Int))
(assert
(and
(= (first p2) (first p1))
(= (second p2) 0)))
(check-sat)
(get-model) ;; p2 could be (1, 0)
这不像内置更新功能那么简洁,但是还可以;特别是,如果您的 SMT 代码是由工具生成的。
您还可以引入更新关系(函数符号和量词也可以,但可能会因触发而出现问题):
;; Read: "updating p1's second element to v yields p2"
(define-fun setSecond ((p1 (Pair Int Int)) (v Int) (p2 (Pair Int Int))) Bool ;; analogous for setFirst
(and
(= (first p2) (first p1))
(= (second p2) v)))
(declare-const p3 (Pair Int Int))
(assert (setSecond p2 77 p3))
(check-sat)
(get-model) ;; p3 is (1, 77)
或者,更一般地说:
;; Read: "updating p1's ith element to v yields p2"
(define-fun setNth ((p1 (Pair Int Int)) (i Int) (v Int) (p2 (Pair Int Int))) Bool
(and
(= (first p2) (ite (= i 1) v (first p1)))
(= (second p2) (ite (= i 2) v (second p1)))))
(declare-const p4 (Pair Int Int))
(assert (setNth p3 1 -77 p4))
(check-sat)
(get-model) ;; p4 is (-77, 77)
和以前一样,从特定记录的定义中生成这些更新函数很简单。
注意:尚不支持多态函数,您需要一个函数 setNth_T1_T2
每个元素类型 T1
,T2
您的对可以有。
一个数组可以存储一个新值,这样做 returns 一个新数组。我知道我可以使用 MkApp 函数访问记录的选择器,然后如何替换记录的值?我正在使用 .NET 绑定,但作为问题的示例,这里有一些 SMT:
(declare-datatypes (T1 T2) ((Pair (mk-pair (first T1) (second T2)))))
(declare-const p1 (Pair Int Int))
(declare-const p2 (Pair Int Int))
(assert (= p1 p2))
(assert (> (second p1) 20))
;How to replace (second p1) with 0
(check-sat)
(get-model)
我认为没有统一的方法来更新记录的第 n 个部分,您基本上必须 "unroll" 更新的定义:更新数组 a 时,您基本上假设“对于所有 j,要么 i 是 j,a[j] 因此是新值,要么 a[j] 具有旧值”。由于一条记录有有限多个元素,您可以展开相应的更新定义:
(declare-datatypes (T1 T2) ((Pair (mk-pair (first T1) (second T2)))))
(declare-const p1 (Pair Int Int))
(assert (= (first p1) 1))
(assert (= (second p1) 2)) ;; p1 is (1, 2)
(declare-const p2 (Pair Int Int))
(assert
(and
(= (first p2) (first p1))
(= (second p2) 0)))
(check-sat)
(get-model) ;; p2 could be (1, 0)
这不像内置更新功能那么简洁,但是还可以;特别是,如果您的 SMT 代码是由工具生成的。
您还可以引入更新关系(函数符号和量词也可以,但可能会因触发而出现问题):
;; Read: "updating p1's second element to v yields p2"
(define-fun setSecond ((p1 (Pair Int Int)) (v Int) (p2 (Pair Int Int))) Bool ;; analogous for setFirst
(and
(= (first p2) (first p1))
(= (second p2) v)))
(declare-const p3 (Pair Int Int))
(assert (setSecond p2 77 p3))
(check-sat)
(get-model) ;; p3 is (1, 77)
或者,更一般地说:
;; Read: "updating p1's ith element to v yields p2"
(define-fun setNth ((p1 (Pair Int Int)) (i Int) (v Int) (p2 (Pair Int Int))) Bool
(and
(= (first p2) (ite (= i 1) v (first p1)))
(= (second p2) (ite (= i 2) v (second p1)))))
(declare-const p4 (Pair Int Int))
(assert (setNth p3 1 -77 p4))
(check-sat)
(get-model) ;; p4 is (-77, 77)
和以前一样,从特定记录的定义中生成这些更新函数很简单。
注意:尚不支持多态函数,您需要一个函数 setNth_T1_T2
每个元素类型 T1
,T2
您的对可以有。