【发布时间】:2015-03-28 07:17:14
【问题描述】:
基于"Test-Only Development" with the Z3 Theorem Prover,我正在尝试在SMT-LIB中编码Project Euler problem 4并使用Z3解决它。
问题是找到两个三位数的最大回文整数乘积。解决方案是993 * 913 = 906609。
在下面的代码中,我只能将两个三位数字编码为回文。这会产生正确的但不是最大的604406 值。
如何更改我的代码以便找到906609 的最大值?
我试过使用(maximize (* p q)),但是会报错,说Objective function '(* p q)' is not supported。我可以调整a 的范围,但我正在寻找一种方法让 Z3 为我做到这一点。
到目前为止我所拥有的是:
(declare-const a Int)
(declare-const b Int)
(declare-const c Int)
(declare-const p Int)
(declare-const q Int)
(declare-const pq Int)
(define-fun satisfy ((pq Int)) Bool
(and
(<= 1 a 9)
(<= 0 b 9)
(<= 0 c 9)
(<= 100 p 999)
(<= p q 999)
(= pq
(* p q)
(+ (* 100001 a)
(* 10010 b)
(* 1100 c)))))
(assert (satisfy pq))
; Does not work:
;(maximize (* p q))
(check-sat)
(get-model)
使用z3 -smt2 e4.smt2 按原样运行会产生:
sat
(model
(define-fun q () Int
913)
(define-fun p () Int
662)
(define-fun c () Int
4)
(define-fun b () Int
0)
(define-fun a () Int
6)
(define-fun pq () Int
604406)
)
【问题讨论】:
-
使用
maximize需要构建Z3的优化分支。寻找最大值的另一种可能的解决方案是断言没有更小的解决方案。我从来没有为 Euler 4 工作过(请参阅我博客上的 cmets),但我对 this somewhat simpler problem 使用了类似的解决方案。 -
是的,我设法找到了 opt 分支,而且我对理论 CS 知之甚少,无法知道为什么最大化不起作用(似乎抱怨不支持乘法;我想这必须与我们在复杂性树中处于高位这一事实有关)。