Z3不变检查

Z3不变检查,z3,Z3,我想要一种方法,在给定一个不变量和一个或多个操作的效果的情况下,检查在操作执行后,该不变量是否仍然有效 关于如何实现这一点有什么想法吗 使用Z3,我想做一些类似的事情 (declare-const a Int) (declare-const b Int) (declare-const c Int) (declare-const d Int) (define-fun invariant () Bool (= a b c d 2) ) (assert invariant) (assert (

我想要一种方法,在给定一个不变量和一个或多个操作的效果的情况下,检查在操作执行后,该不变量是否仍然有效

关于如何实现这一点有什么想法吗

使用Z3,我想做一些类似的事情

(declare-const a Int)
(declare-const b Int)
(declare-const c Int)
(declare-const d Int)

(define-fun invariant () Bool
  (= a b c d 2)
)

(assert invariant)
(assert (= a 1)) ;operation1
(assert (= b 2)) ;operation2
(assert (not invariant))
(check-sat)
如果(check-sat)返回unsat,那么我认为操作后系统的状态是有效的

显然,我不能做以上的事情

(assert invariant)
(assert (not invariant))
总是使定理不成立


但是我需要断言初始状态是有效的,这样当我运行时,系统中没有被操作改变的部分是有效的(断言(非不变量))。

我假设您的操作会改变某种状态(局部变量、程序堆等),因此不变量应该是状态的函数

作为一个小例子,考虑具有局部变量的假设命令程序:

var start: Int := 0
var end: Int := 0
var arr: Array[Int] := new Array(10) // Array of ints, size 10
fill(arr, 0) // Fill the array with zeros

def invariant() =
     (0 < start <= end)
  && forall i in [start, end - 1) :: arr(i) < arr(i + 1) // Sorted

assert invariant() // holds
end := end + 1
assert invariant() // holds
end := end + 1
assert invariant() // fails
arr(start + 1) := arr(start + 1) + 1
assert invariant() // holds
var开始:Int:=0
变量结束:Int:=0
var arr:Array[Int]:=新数组(10)//整数数组,大小10
fill(arr,0)//用零填充数组
def不变量()=
(0<已恢复开始不变)
(流行音乐)
Cesare Tinelli的这篇文章可能与您有关。我意识到(assert(=a 1))不是一项任务。我只是尝试将系统的状态建模为一个例子。我不知道我是否说得足够清楚。该演示似乎很有意义,但我需要一些时间来解释它的内容。谢谢您的建议。
(define-fun invariant ((start Int) (end Int) (arr (Array Int Int))) Bool
  (and
    (<= 0 start)
    (<= start end)
    (forall ((i Int))
      (implies
        (and (<= start i) (< i (- end 1)))
        (< (select arr i) (select arr (+ i 1)))))))

(declare-const start0 Int)
(declare-const end0 Int)
(declare-const arr0 (Array Int Int))

(assert (= start0 0))
(assert (= end0 0))
(assert (= arr0 ((as const (Array Int Int)) 0)))

(push)
  (assert (not (invariant start0 end0 arr0)))
  (check-sat) ;; UNSAT --> Invariant holds
(pop)

;; Operation: end := end + 1

(declare-const end1 Int)
(assert (= end1 (+ end0 1)))

(push)
  (assert (not (invariant start0 end1 arr0)))
  (check-sat) ; UNSAT --> Invariant still holds
(pop)

;; Operation: end := end + 1

(declare-const end2 Int)
(assert (= end2 (+ end1 1)))

(push)
  (assert (not (invariant start0 end2 arr0)))
  (check-sat) ; SAT --> Invariant has been broken!
(pop)

;; Operation: arr[start + 1] := arr[start + 1] + 1

(declare-const arr1 (Array Int Int))
(assert (= arr1 (store arr0 (+ start0 1) (+ (select arr0 (+ start0 1)) 1))))

(push)  
  (assert (not (invariant start0 end2 arr1)))
  (check-sat) ; UNSAT --> Invariant has been restored
(pop)