Z3素数

时间:2014-01-23 17:18:26

标签: functional-programming z3

我正在尝试学习z3,这是我写的第一个程序。

在本练习中,我试图确定x是否为素数。如果x是素数,则返回SAT,否则,返回UNSAT及其两个因子。

这是我到目前为止所拥有的 http://rise4fun.com/Z3/STlX

我的问题是我认为代码现在没有做任何事情。无论我做什么,它都会返回SAT。即如果我断言7是素数,则返回SAT,如果断言7不是素数,则返回SAT。

我不确定递归是如何在z3中起作用的,但我已经看到了一些例子,我试图模仿它们如何进行递归。

如果你们能够看一看并告诉我哪里出错了,我会非常感激。

3 个答案:

答案 0 :(得分:1)

我已经习惯于递归思考,在篡改了几个小时后,我找到了另一种方法来实现它。对于任何有兴趣的人,这是我的实施。

http://rise4fun.com/Z3/1miFN

答案 1 :(得分:0)

以下公式未达到您的评论指定的内容:

; recursively call divides on y++ 
;; as long as y < x
;; Change later to y < sqrt(x)
(declare-fun hasFactors (Int Int) Bool)
(assert
   (and (and (not (divides x y)) 
      (not (hasFactors x (+ y 1)))) (< y x))
)

第一个问题是x,y是免费的。它们之前被声明为常量。 你的评论说你想递归调用divides,递增y直到达到x。 您可以使用量化公式来指定满足此属性的关系。 你必须写下以下内容:

   (assert (forall ((x Int) (y Int)) (iff (hasFactors x y) (and (< y x) (or (divides y x) (hasFactors x (+ y 1))))))

在调用check-sat之前,您还必须指定要检查的公式。 使用SMT求解器查找素数当然不会是实用的,但会说明当Z3实例化量词时所获得的一些行为,这取决于 问题域和编码可以快速或非常昂贵。

答案 2 :(得分:0)

感谢部分解决方案! isPrime的完整解决方案是:

http://rise4fun.com/Z3/jBr0

(define-fun isPrime ((x Int)) Bool
  (and 
    (> x 1) 
    (not (exists ((z Int) (y Int))
      (and (< y x) (< z x) (> y 1) (> z 1) (= x (* y z)))))))

告诉我的不仅仅是我愿意承认要做对。

相关问题