确定任意命题公式中变量的上限/下限

时间:2012-01-24 22:17:14

标签: z3 sat-solvers

给定一个任意的命题公式PHI(某些变量的线性约束),确定每个变量的(近似)上限和下限的最佳方法是什么?

某些变量可能无限制。在这种情况下,算法应该断定这些变量没有上限/下限。

例如,PHI =(x = 3且y> = 1)。 x的上限和下限均为3.y的下限为1,y没有上限。

这是一个非常简单的例子,但是一般有解决方案(可能使用SMT求解器)吗?

2 个答案:

答案 0 :(得分:3)

这假设每个变量的SAT / UNSAT域是连续的。

  1. 使用SMT解算器检查公式的解决方案。如果没有解决方案那么这意味着没有上限/下限,所以停止。
  2. 对于公式中的每个变量,在变量的域上进行两次二进制搜索,一次搜索下限,另一次搜索上限。搜索每个变量的起始值是步骤1中找到的解决方案中变量的值。使用SMT求解器探测每个搜索值的可满足性,并有条理地括起每个变量的边界。
  3. 搜索函数的伪代码,假设整数域变量:

    lower_bound(variable, start, formula)
    {
        lo = -inf;
        hi = start;
        last_sat = start;
        incr = 1;
        do {
            variable = (lo + hi) / 2;
            if (SMT(formula) == UNSAT) {
                lo = variable + incr;
            } else {
                last_sat = variable;
                hi = variable - incr;
            }
        } while (lo <= hi);
        return last_sat;
    }
    

    upper_bound(variable, start, formula)
    {
        lo = start;
        hi = +inf;
        last_sat = start;
        do {
            variable = (lo + hi) / 2;
            if (SMT(formula) == SAT) {
                last_sat = variable;
                lo = variable + incr;
            } else {
                hi = variable - incr;
            }
        } while (lo <= hi);
        return last_sat;
    }
    

    -inf / + inf是每个变量域中可表示的最小/最大值。如果lower_bound返回-inf,则变量没有下限。如果upper_bound返回+ inf,则变量没有上限。

答案 1 :(得分:2)

在实践中,大多数此类优化问题需要在SMT求解器之上进行某种迭代 - 直到最大/最小类型的外部驱动程序。量化方法也可以利用SMT求解器的特定功能,但实际上这些约束对于底层求解器来说太难了。特别参见此讨论:How to optimize a piece of code in Z3? (PI_NON_NESTED_ARITH_WEIGHT related)

话虽如此,大多数高级语言绑定包括简化生活的必要机制。例如,如果您使用Haskell SBV库来编写脚本z3,则可以:

Prelude> import Data.SBV
Prelude Data.SBV> maximize Quantified head 2 (\[x, y] -> x.==3 &&& y.>=1) 
Just [3,1]
Prelude Data.SBV> maximize Quantified (head . tail) 2 (\[x, y] -> x.==3 &&& y.>=1) 
Nothing
Prelude Data.SBV> minimize Quantified head 2 (\[x, y] -> x.==3 &&& y.>=1) 
Just [3,1]
Prelude Data.SBV> minimize Quantified (head . tail) 2 (\[x, y] -> x.==3 &&& y.>=1) 
Just [3,1]

第一个结果表明x = 3,y = 1相对于谓词x == 3&amp;&amp; Y'GT; = 1。 第二个结果表明没有相对于同一谓词最大化y的值。 第三次调用说x = 3,y = 1使关于x的谓词最小化。 第四次调用说x = 3,y = 1使关于y的谓词最小化。 (有关详细信息,请参阅http://hackage.haskell.org/packages/archive/sbv/0.9.24/doc/html/Data-SBV.html#g:34。)

您还可以使用“Iterative”选项(而不是Quantified)让库迭代地执行优化,而不是使用量词。这两种技术等效,因为后者可能会卡在局部最小值/最大值中,但迭代方法可能会解决量化版本对于SMT求解器来说无法处理的问题。