z3py 将数据类型/枚举与字符串进行比较

z3py compare Datatype / Enum to string

按照此示例(在此处找到:z3py),我可以将 c 与例如Color.green.

Color = Datatype('Color')
Color.declare('red')
Color.declare('green')
Color.declare('blue')
Color = Color.create()

# Let c be a constant of sort Color
c = Const('c', Color)
# Then, c must be red, green or blue
prove(Or(c == Color.green, 
         c == Color.blue,
         c == Color.red))

在我的应用程序中,我必须将 c 与 python 字符串进行比较: 我想要这样的东西:

c = Const('c', Color)
solve(c == "green") # this doesn't work, but it works with Color.green

该方法有效,例如IntSort(见下文),但不是我自己的数据类型。

i = Int("i")
solve(i < 10)

Z3 python 接口对字符串的重载非常有限。您可以使用 'String' 类型的字符串文字。否则字符串不会被强制转换为其他类型。此外,使用字符串的方法也不适用于整数,例如

 I = Int("I") 
 solve(I < "10")

会抛出错误。

请注意,您可以使用 Color.red 或声明您自己的 shorthand:

red = Color.red

一个对我有用的解决方案(将 Datatypes/Enums 与字符串进行比较)是向 z3.py 中的 class DatatypeSortRef(SortRef) 添加一个 cast 例程。 它将尝试找到与给定字符串匹配的构造函数并使用它,否则继续现有行为 (super().cast(val))

这是我使用的代码:

def cast(self, val):
    """This is so we can cast a string to a Z3 DatatypeRef. This is useful if we want to compare strings with a Datatype/Enum to a String.

    >>> Color = Datatype("Color")
    >>> Color.declare("red")
    >>> Color.declare("green")
    >>> Color.declare("blue")
    >>> Color = Color.create()

    >>> x = Const("x", Color)
    >>> solve(x != "red", x != "blue")
    [x = green]
    """
    if type(val) == str:
        for i in range(self.num_constructors()):
            if self.constructor(i).name() == val:
                return self.constructor(i)()
    return super().cast(val)

注意:我没有注意一般正确性。此方法适用于 ,但可能会导致您的代码出现问题。