在 Z3 中,[String -> Bool] 函数的最简单公式是什么,它只将某些值映射到 True 而将所有其他值映射到 False?

In Z3, what is the simplest formula over a [String -> Bool] function that only maps certain values to True and all others to False?

继续我的,如果你定义一个集合如下:

from z3 import *
s = Solver()
string_set = Function('string_set', StringSort(), BoolSort())
s.add(string_set(StringVal('foo')))
s.add(string_set(StringVal('bar')))
s.add(string_set(StringVal('baz')))

这并没有真正指定集合 {foo, bar, baz} 因为它没有说明集合中的哪些值是 而不是 ;如果要求找到一个模型,Z3 可以很容易地得出满足所有这些约束的函数 [else -> True]

指定函数为真 那些特定值的最简单方法是什么? objective 是生成模型:

[
  "foo" -> True,
  "bar" -> True,
  "baz" -> True,
  else -> False
]

我真的必须对不在该显式集合中的所有字符串进行量化吗?

严格来说,唯一的方法是使用量化:

from z3 import *

s = Solver()

string_set = Function('string_set', StringSort(), BoolSort())
dummy = String('dummy')
s.add(ForAll([dummy], string_set(dummy) == Or( dummy == StringVal('foo')
                                             , dummy == StringVal('bar')
                                             , dummy == StringVal('baz'))))

但是,我强烈警告不要在您的模型中引入量词,因为这无疑会导致求解器使用不再是决策程序的算法,即您 运行 有获得 unknown(或永远 运行ning);不必要地使问题复杂化。

Nikolaj 的 answer 隐含的意思是,如果您想以这种方式对集合建模,只要您没有 insertions/deletions,未解释的函数就是一个很好的方法。但是那些并不是真正的集合,只是纯函数。因此,您应该对它们进行建模。也就是说,要更字面地回答您的问题,即仅对这些给定值产生真实结果的“最简单”公式是什么,您需要将其设为实际函数:

def string_set(x):
   return (Or(x == 'foo', x == 'bar', x == 'baz'))

或者,如果你想让它成为求解器中的一个合适的函数:

from z3 import *

string_set = RecFunction("string_set", StringSort(), BoolSort())
dummy = String("dummy")
RecAddDefinition( string_set
                , [dummy]
                , Or(dummy == StringVal("foo"), dummy == StringVal("bar"), dummy == StringVal("baz"))
                )

从建模的角度来看,我认为对集合进行建模的最佳方法是数组,然后是我描述的函数