z3 - 是否可以解决给定输入和输出的函数运算?

标签 z3 smt z3py

我有一个函数,它接受 2 个整数作为输入,并输出一个整数。

我有一组输入及其已知输出。

是否可以弄清楚该函数对输入应用了哪些操作以得出输出?

我不知道如何开始使用 z3 来模拟这样的问题。任何帮助将不胜感激。

示例数据:

f(1, 1) = 1
f(3, 7) = 28
f(3, 2) = 3
f(4, 6) = 56
f(10, 3) = 55
f(x, y) = f(y, x)

最佳答案

是的,你可以。但无论如何,结果都不会有趣,除非您至少规定了 f 的一些结构。

最明显的方法是将 f 声明为非解释函数,然后查看为其构建的模型。但这将是 f 的基本定义;也就是说,它会以最无趣的方式满足你的公理。您可以这样写:

from z3 import *
f = Function('f', IntSort(), IntSort(), IntSort())

s = Solver()
s.add(f( 1, 1) ==  1)
s.add(f( 3, 7) == 28)
s.add(f( 3, 2) ==  3)
s.add(f( 4, 6) == 56)
s.add(f(10, 3) == 55)
x, y = Ints('x y')
s.add(ForAll([x, y], f(x, y) == f(y, x)))

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

这是 z3 打印的内容:

sat
[f = [else ->
      If(And(Not(Var(0) == 6),
             Not(Var(0) == 4),
             Not(Var(0) == 10),
             Var(0) == 3,
             Not(Var(1) == 6),
             Not(Var(1) == 4),
             Var(1) == 10),
         55,
         If(And(Var(0) == 6, Not(Var(1) == 6), Var(1) == 4),
            56,
            If(And(Not(Var(0) == 6),
                   Not(Var(0) == 4),
                   Not(Var(0) == 10),
                   Not(Var(0) == 3),
                   Not(Var(0) == 1),
                   Var(0) == 2,
                   Not(Var(1) == 6),
                   Not(Var(1) == 4),
                   Not(Var(1) == 10),
                   Var(1) == 3),
               3,
               If(And(Not(Var(0) == 6),
                      Not(Var(0) == 4),
                      Not(Var(0) == 10),
                      Not(Var(0) == 3),
                      Not(Var(0) == 1),
                      Not(Var(0) == 2),
                      Not(Var(1) == 6),
                      Not(Var(1) == 4),
                      Not(Var(1) == 10),
                      Var(1) == 3),
                  28,
                  If(And(Not(Var(0) == 6),
                         Not(Var(0) == 4),
                         Var(0) == 10,
                         Not(Var(1) == 6),
                         Not(Var(1) == 4),
                         Not(Var(1) == 10),
                         Var(1) == 3),
                     55,
                     If(And(Not(Var(0) == 6),
                            Var(0) == 4,
                            Var(1) == 6),
                        56,
                        If(And(Not(Var(0) == 6),
                               Not(Var(0) == 4),
                               Not(Var(0) == 10),
                               Var(0) == 3,
                               Not(Var(1) == 6),
                               Not(Var(1) == 4),
                               Not(Var(1) == 10),
                               Not(Var(1) == 3),
                               Not(Var(1) == 1),
                               Var(1) == 2),
                           3,
                           If(And(Not(Var(0) == 6),
                                  Not(Var(0) == 4),
                                  Not(Var(0) == 10),
                                  Var(0) == 3,
                                  Not(Var(1) == 6),
                                  Not(Var(1) == 4),
                                  Not(Var(1) == 10),
                                  Not(Var(1) == 3),
                                  Not(Var(1) == 1),
                                  Not(Var(1) == 2)),
                              28,
                              If(And(Not(Var(0) == 6),
                                     Not(Var(0) == 4),
                                     Not(Var(0) == 10),
                                     Not(Var(0) == 3),
                                     Var(0) == 1,
                                     Not(Var(1) == 6),
                                     Not(Var(1) == 4),
                                     Not(Var(1) == 10),
                                     Not(Var(1) == 3),
                                     Var(1) == 1),
                                 1,
                                 12)))))))))]]

读取此输出的方法是将 x 替换为 Var(0),将 y 替换为 Var(1),并将嵌套的 if-then-elses 作为定义的定义子句。

虽然我没有逐行检查输出,但我确信它是正确的;从某种意义上说,它完全满足您的要求。但我能听到你说“这不是我真正想要的!”事实上,这并不是您想要看到的满足要求的通用/最小函数。按照 SMT 求解器的工作方式,除非您描述 z3 需要填充的一些骨架,否则您永远不会得到最小答案。

请注意,这是一个活跃的研究领域:如何使用(半)自动定理证明器、SMT 求解器等为我们“编写”代码。一般区域称为 SyGus(语法引导合成)。如果您想了解更多信息,请从 https://sygus.org 开始,其中包含问题的一般描述并阅读本文:https://sygus.org/assets/pdf/FMCAD'13_SyGuS.pdf

关于z3 - 是否可以解决给定输入和输出的函数运算?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73198576/

相关文章:

python - z3:解决八皇后难题

z3 C++ API & ite

z3 - 为什么 Z3 不能在不进行看似微不足道的修改的情况下解决这个实例?

z3 - 用户定义的 z3 排序问题

生成模型值的 Z3 随机性

z3:公式及其否定不可满足

c++ - 为程序中所有可能路径的运行生成数据

python - z3 (py) smt-lib2 输出

inheritance - z3 中的排序继承

z3 - 已签名的部门在 z3py 中不起作用