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

3

参照此示例(在此处找到: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)
2个回答

2

我找到了一个解决方案(将数据类型/枚举与字符串进行比较),即在 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)

注意:我没有关注通用的正确性。这种方法对于来说是有效的,但可能会导致您的代码出现问题。

1
Z3的Python接口对字符串的重载功能非常有限。您可以使用字符串字面量作为类型“String”。否则,字符串将不会被强制转换为其他类型。此外,使用字符串的方法也不适用于整数,例如:
 I = Int("I") 
 solve(I < "10")

这会抛出一个错误。

请注意,您已经可以使用Color.red或声明自己的简写:

red = Color.red

我考虑创建一个全局名称到值的映射(类似于您的“速记”),但我希望有一些“官方”的方式。您认为是否可能通过一些合理的努力来实现这样的功能? - stklik
看到我的(可能的)解决方案如下。我没有找到任何要运行的Python测试,所以我不想创建拉取请求。@Nikolaj-Bjorner - stklik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接