如何检测或证明此递归关系定义了周期性序列。
这是一个例子A> 0是固定的
其中A,x是自然数,函数f返回自然值。
你能建议任何检测这种类型的递归关系的方法是周期序列吗?我试过跟踪SMT(Z3)程序来检测这种复发(如果我错了请纠正我)
s=Solver()
s.add(A>0)
s.add(ForAll([n],Implies(n>=0,y4(n1 + 1) == If(y4(n)<=A,y4(n) + 1,y4(n)-1))))
s.add(y4(0) == 0)
s.add(Not(ForAll([n],Exists([k],Implies(And(k>0,n>=0),y4(n)==y4(n+k))))))
查询返回"unsat"
。但是我发现,对于跟随查询Z3,返回相同的结果"unsat"
。
s=Solver()
s.add(A>0)
s.add(ForAll([n],Implies(n>=0,y4(n1 + 1) == If(y4(n)<=A,y4(n) + 1,y4(n)+2))))
s.add(y4(0) == 0)
s.add(Not(ForAll([n],Exists([k],Implies(And(k>0,n>=0),y4(n)==y4(n+k))))))
请指出我的查询中有什么问题?如何检测或证明递归关系的另一种可能方式是周期序列?
答案 0 :(得分:1)
也许
(declare-fun f (Int Int) Int)
(assert (forall ((a Int)) (= (f 0 a) 0)))
(assert (forall ((x Int) (a Int)) (=> (and (>= x 0) (>= a 0) (> (f x a) a)) (= (f (+ x 1) a) (- (f x a) 1)))))
(assert (forall ((x Int) (a Int)) (=> (and (>= x 0) (>= a 0) (<= (f x a) a)) (= (f (+ x 1) a) (+ (f x a) 1)))))
(assert (forall ((x Int) (y Int) (a Int)) (=> (and (>= x 0) (> y x) (>= a 0)) (not (= (f x a) (f y a))))))
(check-sat)
虽然没有说f是周期性的。
答案 1 :(得分:1)
请始终在样品中包含完整代码;因为你所提供的并不是人们运行和观察的有效代码。
假设您的代码实际上是以下内容:
from z3 import *
s=Solver()
A=Int('A')
n=Int('n')
k=Int('k')
y4 = Function('f', IntSort(), IntSort())
s.add(A>0)
s.add(ForAll([n],Implies(n>=0,y4(n + 1) == If(y4(n)<=A,y4(n) + 1,y4(n)-1))))
s.add(y4(0) == 0)
s.add(Not(ForAll([n],Exists([k],Implies(And(k>0,n>=0),y4(n)==y4(n+k))))))
您可以通过添加以下内容来了解Z3的产品:
print s.sexpr()
print s.check()
如果您运行此脚本,则会获得:
(declare-fun A () Int)
(declare-fun f (Int) Int)
(assert (> A 0))
(assert (forall ((n Int))
(let ((a!1 (= (f (+ n 1)) (ite (<= (f n) A) (+ (f n) 1) (- (f n) 1)))))
(=> (>= n 0) a!1))))
(assert (= (f 0) 0))
(assert (let ((a!1 (forall ((n Int))
(exists ((k Int))
(=> (and (> k 0) (>= n 0)) (= (f n) (f (+ n k))))))))
(not a!1)))
unsat
你可以看到问题;你的最后一个断言说存在n
,这样对于所有k
周期都不会成立。 (因为你放了一个Not
包装器。)显然,那是unsat
。
在更惯用的Z3中,我按如下方式对您的问题进行编码:
from z3 import *
s = Solver ()
A = Int ('A')
s.add(A > 0)
f = Function('f', IntSort(), IntSort())
x = Int ('x')
s.add(f(0) == 0)
s.add(ForAll(x, Implies(x >= 0, f(x + 1) == If(A >= f(x), f(x)+1, f(x)-1))))
k = Int('k')
s.add(ForAll(x, Exists(k, f(x+k) == f(x))))
print s.sexpr()
print s.check()
但期待Z3证明这将是天真的。的确,当我运行它时,我得到了:
(declare-fun A () Int)
(declare-fun f (Int) Int)
(assert (> A 0))
(assert (= (f 0) 0))
(assert (forall ((x Int))
(let ((a!1 (= (f (+ x 1)) (ite (>= A (f x)) (+ (f x) 1) (- (f x) 1)))))
(=> (>= x 0) a!1))))
(assert (forall ((x Int)) (exists ((k Int)) (= (f (+ x k)) (f x)))))
[Ctrl-C]
在这种情况下,建模对我来说是正确的,但Z3无法回答,所以我不得不在一段时间后按Ctrl-C停止它。
但好处是你可以把SMTLib放在一个文件中,最后附上一个(check-sat)
,然后按如下方式运行Z3:
z3 -v:10 a.smt2 a.smt2
它会给你打印很多关于它正在做什么的步骤。我的猜测是它在量词实例化过程中丢失了。典型的解决方案是提供量词模式,但我不清楚在这种情况下它们会是什么。这里有一些例子 http://ericpony.github.io/z3py-tutorial/advanced-examples.htm虽然可能有所帮助。