Z3 PDR和muZ答案未知的不动点
我创建了这个文件,它应该代表Dekker的算法Z3 PDR和muZ答案未知的不动点,z3,Z3,我创建了这个文件,它应该代表Dekker的算法 给定类型为proc的变量Turn和两个数组want和crit映射到bools 对于所有proc p 我可以不确定地采取以下三种转变之一: req:如果存在proc p导致want[p]=false则want'[p]=true enter:如果存在proc p,使得want[p]=true和turn=p那么crit'[p]=true exit:如果存在proc p,使得crit[p]=true那么want'[p]=false,crit'[p]=f
- 给定类型为
的变量proc
和两个数组Turn
和want
映射到boolscrit
- 对于所有
proc p
- 我可以不确定地采取以下三种转变之一:
:如果存在req
导致proc p
则want[p]=false
want'[p]=true
:如果存在enter
,使得proc p
和want[p]=true
那么turn=p
crit'[p]=true
:如果存在exit
,使得proc p
那么crit[p]=true
,want'[p]=false
和crit'[p]=false
(turn=?
表示任何?
都可以归因于proc p'
)turn
- 如果存在两个
和proc p1
使得p2
crit[p1]=crit[p2]=true
(set-logic HORN)
(define-sort proc () Int)
(define-sort myarray () (Array proc Bool))
(declare-var turn proc)
(declare-var want myarray)
(declare-var crit myarray)
(declare-fun reachable (proc myarray myarray) Bool)
;; Init
(rule
(=>
(forall ((z proc))
(and
(= (select want z) false)
(= (select crit z) false)
)
)
(reachable turn want crit)
)
)
;; Unsafe
(assert
(exists ((z1 proc) (z2 proc))
(=>
(and
(not (= z1 z2))
(= (select want z1) true)
(= (select want z2) true)
)
(reachable turn want crit)
)
)
)
;; Req
(assert
(exists ((z proc))
(=>
(and
(= (select want z) false)
(reachable turn want crit)
)
(reachable turn (store want z true) crit)
)
)
)
;; Enter
(assert
(exists ((z proc))
(=>
(and
(= (select want z) true)
(= turn z)
(reachable turn want crit)
)
(reachable turn want (store crit z true))
)
)
)
;; Exit
(assert
(exists ((z1 proc)
(z2 proc)
)
(=>
(and
(= (select crit z1) true)
(reachable turn want crit)
)
(and
(reachable
z2
(store want z1 false)
(store crit z1 false)
)
)
)
)
)
(check-sat)
(set-logic HORN)
(declare-fun reachable (Int
(Array Int Bool)
(Array Int Bool)) Bool)
;; Init
(assert
(forall ((Turn Int)
(Want (Array Int Bool))
(Crit (Array Int Bool))
)
(=>
(forall ((z Int))
(and
(= (select Want z) false)
(= (select Crit z) false)
))
(reachable Turn Want Crit)
)))
;; Unsafe
(assert
(forall ((Turn Int)
(Want (Array Int Bool))
(Crit (Array Int Bool))
)
(=>
(reachable Turn Want Crit)
(not
(exists ((z1 Int) (z2 Int))
(and (not (= z1 z2))
(= (select Crit z1) true)
(= (select Crit z2) true)
)
)
)
)
)
)
;; Transitions
(assert
(forall (
(Turn Int)
(Want (Array Int Bool))
(Crit (Array Int Bool))
(Turn_ Int)
(Want_ (Array Int Bool))
(Crit_ (Array Int Bool))
)
(=>
(and
(reachable Turn Want Crit)
(or
;;req
(exists ((n Int))
(and (= (select Want n) false)
(= Turn_ Turn)
(= Want_ (store Want n true))
(= Crit_ Crit)
)
)
;;req
(exists ((n Int))
(and (= (select Want n) true)
(= Turn n)
(= Turn_ Turn)
(= Want_ Want)
(= Crit_ (store Crit n true))
)
)
;;req
(exists ((n Int) (n2 Int))
(and (= (select Crit n) true)
(= Turn_ n2)
(= Want_ (store Want n false))
(= Crit_ (store Crit n false))
)
)
)
)
(reachable Turn_ Want_ Crit_)
)
)
)
(check-sat)
但是当我调用z3 dekker.smt2
时,它会给我unknown
作为答案
如果我试着这样做:
(set-logic HORN)
(define-sort proc () Int)
(define-sort myarray () (Array proc Bool))
(declare-var turn proc)
(declare-var want myarray)
(declare-var crit myarray)
(declare-fun reachable (proc myarray myarray) Bool)
;; Init
(rule
(=>
(forall ((z proc))
(and
(= (select want z) false)
(= (select crit z) false)
)
)
(reachable turn want crit)
)
)
;; Unsafe
(assert
(exists ((z1 proc) (z2 proc))
(=>
(and
(not (= z1 z2))
(= (select want z1) true)
(= (select want z2) true)
)
(reachable turn want crit)
)
)
)
;; Req
(assert
(exists ((z proc))
(=>
(and
(= (select want z) false)
(reachable turn want crit)
)
(reachable turn (store want z true) crit)
)
)
)
;; Enter
(assert
(exists ((z proc))
(=>
(and
(= (select want z) true)
(= turn z)
(reachable turn want crit)
)
(reachable turn want (store crit z true))
)
)
)
;; Exit
(assert
(exists ((z1 proc)
(z2 proc)
)
(=>
(and
(= (select crit z1) true)
(reachable turn want crit)
)
(and
(reachable
z2
(store want z1 false)
(store crit z1 false)
)
)
)
)
)
(check-sat)
(set-logic HORN)
(declare-fun reachable (Int
(Array Int Bool)
(Array Int Bool)) Bool)
;; Init
(assert
(forall ((Turn Int)
(Want (Array Int Bool))
(Crit (Array Int Bool))
)
(=>
(forall ((z Int))
(and
(= (select Want z) false)
(= (select Crit z) false)
))
(reachable Turn Want Crit)
)))
;; Unsafe
(assert
(forall ((Turn Int)
(Want (Array Int Bool))
(Crit (Array Int Bool))
)
(=>
(reachable Turn Want Crit)
(not
(exists ((z1 Int) (z2 Int))
(and (not (= z1 z2))
(= (select Crit z1) true)
(= (select Crit z2) true)
)
)
)
)
)
)
;; Transitions
(assert
(forall (
(Turn Int)
(Want (Array Int Bool))
(Crit (Array Int Bool))
(Turn_ Int)
(Want_ (Array Int Bool))
(Crit_ (Array Int Bool))
)
(=>
(and
(reachable Turn Want Crit)
(or
;;req
(exists ((n Int))
(and (= (select Want n) false)
(= Turn_ Turn)
(= Want_ (store Want n true))
(= Crit_ Crit)
)
)
;;req
(exists ((n Int))
(and (= (select Want n) true)
(= Turn n)
(= Turn_ Turn)
(= Want_ Want)
(= Crit_ (store Crit n true))
)
)
;;req
(exists ((n Int) (n2 Int))
(and (= (select Crit n) true)
(= Turn_ n2)
(= Want_ (store Want n false))
(= Crit_ (store Crit n false))
)
)
)
)
(reachable Turn_ Want_ Crit_)
)
)
)
(check-sat)
我得到的答案是:
PDR cannot solve non-ground tails: (let ((a!1 (forall ((z Int))
(and (= (select reachable_1_n z) false)
(= (select reachable_2_n z) false)))))
(= a!1 true))
unknown
这是一个非常Z3/muZ特定的问题。你可以把你的问题作为一个问题来提问,这样你可能会跑得更好,我想这会得到一个快速的答案。然后你可以总结你的学习,并在这里为我们其他人发布/接受你自己的答案!