如何在z3中的GADT上重载运算符?

时间:2019-02-07 18:44:42

标签: python z3 z3py

客观

我的目标是从事一种理论,在这种理论下,我可以访问整数并可以推论整数,并且具有已知的函数bar

我希望能够求解如下方程:

bar(bar(x)) == bar(y)  Solution: y = bar(x), bar is unknown
2 + bar(2) == bar(x)   Solution: x is unknown, bar is unknown

问题是bar最终是可计算的,但不能用整数算术编码,因此我试图将其映射到“未知”函数。

具体示例

z3中,我正在使用以下自定义数据类型。

import pytest
from z3 import Datatype, IntSort

def test_stackoverflow():
    FooBar = Datatype('FooBar')
    FooBar.declare('foo', ('unfoo', IntSort()))
    FooBar.declare('bar', ('unbar', FooBar))
    FooBar = FooBar.create()

    foo = FooBar.foo
    unfoo = FooBar.unfoo
    bar = FooBar.bar
    unbar = FooBar.unbar

我可以重载+运算符以跨foo值来工作,例如:

Forall([x, y], foo(x) + foo(y) == foo(x + y))

有没有做到这一点而又不降低可判定性的方法?

1 个答案:

答案 0 :(得分:0)

从纯z3 / SMTLib的角度来看:您不能使用SMTLib或通常的SMT-Lib说法来做到这一点。如果要添加FooBar,则必须为此定义一个自定义函数。

从“ Python”的角度来看:我敢肯定有些Python魔咒会重载+的{​​{1}}(您可能必须先将其隐藏在某个类的后面),所以看起来定期添加。但是请记住,这与Z3或SMTLib无关,这仅仅是Python的把戏。

即使这是可能的,我也强烈建议不要这样做:尽管超载很可爱,但它几乎总是最终导致更多的麻烦,而不是值得的。 SMTLib对多态事物的工作方式非常挑剔:它仅对FooBar / +等符号具有“烘焙”多态性;特别是它明确禁止用户定义的多态性。