【问题标题】:Trivial change but different results (ForAll and Exists)微小的变化但不同的结果(ForAll 和 Exists)
【发布时间】:2020-02-15 13:00:16
【问题描述】:

我有一组不等式,我想找到一个(微不足道的)解决方案。

当我使用 Exists 运算符时,一切正常,正如您在此 Z3 script 及其 Z3Py 版本中所见。

#!/bin/python

from z3 import *

# we have that
s = Solver()
## mu0_px is the initial marking for place px; 
mu_p1, mu_p2, mu_p3 = 0, 0, 1

## pi_tj is the pre-condition from place pi to transition tj
p1_t1, p1_t2, p1_t3 = 1, 0, 0
p2_t1, p2_t2, p2_t3 = 0, 1, 0
p3_t1, p3_t2, p3_t3 = 0, 0, 1

## tj_pi is the post-condition from transition tj to place pi
t1_p1, t2_p1, t3_p1 = 0, 1, 0
t1_p2, t2_p2, t3_p2 = 1, 0, 0
t1_p3, t2_p3, t3_p3 = 0, 0, 0

## find the values for the faulty transitions 
f_p1, p1_f = Ints('f_p1 p1_f')
f_p2, p2_f = Ints('f_p2 p2_f')
f_p3, p3_f = Ints('f_p3 p3_f')

# where they should be 
s.add( f_p1 == 1, f_p2 == 0, f_p3 == 0 )
s.add( p1_f == 0, p2_f == 0, p3_f == 1 )

## l \in Naturals ; 
l11 = Int('l11')

# Sequence 11: t1,t2,t3
s11_t1, s11_t2, s11_t3 = 1, 1, 0


# It does works! :o
s.add( l11 == 1 )
s.add(
   Exists([l11],
      Or(
         mu_p1 + (t1_p1-p1_t1)*s11_t1 + (t2_p1-p1_t2)*s11_t2 + (t3_p1-p1_t3)*s11_t3 + l11 * (f_p1 - p1_f) < p1_t3,
         mu_p2 + (t1_p2-p2_t1)*s11_t1 + (t2_p2-p2_t2)*s11_t2 + (t3_p2-p2_t3)*s11_t3 + l11 * (f_p2 - p2_f) < p2_t3,
         mu_p3 + (t1_p3-p3_t1)*s11_t1 + (t2_p3-p3_t2)*s11_t2 + (t3_p3-p3_t3)*s11_t3 + l11 * (f_p3 - p3_f) < p3_t3,
      )
   )
)


print(s)
print(s.check())
print(s.model())

但是,当我将存在量词替换为 Forall 时,如 link 和下面的 Python 代码中,当我认为它仍然应该是 sat 时,没有解决方案

#!/bin/python

from z3 import *

# we have that
s = Solver()
## mu0_px is the initial marking for place px; 
mu_p1, mu_p2, mu_p3 = 0, 0, 1

## pi_tj is the pre-condition from place pi to transition tj
p1_t1, p1_t2, p1_t3 = 1, 0, 0
p2_t1, p2_t2, p2_t3 = 0, 1, 0
p3_t1, p3_t2, p3_t3 = 0, 0, 1

## tj_pi is the post-condition from transition tj to place pi
t1_p1, t2_p1, t3_p1 = 0, 1, 0
t1_p2, t2_p2, t3_p2 = 1, 0, 0
t1_p3, t2_p3, t3_p3 = 0, 0, 0

## find the values for the faulty transitions 
f_p1, p1_f = Ints('f_p1 p1_f')
f_p2, p2_f = Ints('f_p2 p2_f')
f_p3, p3_f = Ints('f_p3 p3_f')

# where they should be 
s.add( f_p1 == 1, f_p2 == 0, f_p3 == 0 )
s.add( p1_f == 0, p2_f == 0, p3_f == 1 )

## l \in Naturals ; 
l11 = Int('l11')

# Sequence 11: t1,t2,t3
s11_t1, s11_t2, s11_t3 = 1, 1, 0


# It does not work! :(
s.add( l11 == 1 )
s.add(
   ForAll([l11],
      Or(
         mu_p1 + (t1_p1-p1_t1)*s11_t1 + (t2_p1-p1_t2)*s11_t2 + (t3_p1-p1_t3)*s11_t3 + l11 * (f_p1 - p1_f) < p1_t3,
         mu_p2 + (t1_p2-p2_t1)*s11_t1 + (t2_p2-p2_t2)*s11_t2 + (t3_p2-p2_t3)*s11_t3 + l11 * (f_p2 - p2_f) < p2_t3,
         mu_p3 + (t1_p3-p3_t1)*s11_t1 + (t2_p3-p3_t2)*s11_t2 + (t3_p3-p3_t3)*s11_t3 + l11 * (f_p3 - p3_f) < p3_t3,
      )
   )
)


print(s)
print(s.check())
print(s.model())

以前有人遇到过这样的问题吗?

【问题讨论】:

    标签: z3 z3py


    【解决方案1】:

    您声明的变量l11 与量化中使用的变量完全不同:特别是,您声明它等于1 与量化公式无关。所以你得到sat 存在但unsat 具有通用性,因为该公式显然不适用于l11 的所有值。

    这可能令人困惑,但这是预期的行为。要查看效果,只需打印 smtlib 等效项,您就会看到变量是如何分配的。

    【讨论】:

    • 感谢@alias 的回复,我该如何表达我想要解决方案ForAll l11 &gt;= 1 的约束?我更改了以下 URL 中的代码,但我仍然想知道这是否是在通用量词中表达这种约束的正确方法。 gist.github.com/damascenodiego/d66b8d53ccda58dc389141e213cadb27
    • 照你说的写就行了(模数语法:)ForAll ([l1], Implies (l1 &gt;= 1, condition))
    • 感谢@alias 的帮助
    猜你喜欢
    • 2015-10-30
    • 2017-04-01
    • 1970-01-01
    • 2021-04-04
    • 2021-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多