Recursion 如何利用Z3检测或证明周期序列的递推关系?

Recursion 如何利用Z3检测或证明周期序列的递推关系?,recursion,z3,z3py,Recursion,Z3,Z3py,如何检测或证明这种递归关系定义了一个周期序列 下面是一个示例,其中A>0是固定的 其中A,x是自然数,函数f返回自然值 你能建议用周期序列来检测这种类型的递归关系吗?我已经尝试过使用SMT(Z3)程序来检测这种复发(如果我错了,请纠正我) 你能指出我的问题是什么吗?另一种可能的方法是什么,如何检测或证明递归关系是周期序列?也许 (declare-fun f (Int Int) Int) (assert (forall ((a Int)) (= (f 0 a) 0))) (assert (fo

如何检测或证明这种递归关系定义了一个周期序列

下面是一个示例,其中A>0是固定的

其中A,x是自然数,函数f返回自然值

你能建议用周期序列来检测这种类型的递归关系吗?我已经尝试过使用SMT(Z3)程序来检测这种复发(如果我错了,请纠正我)

你能指出我的问题是什么吗?另一种可能的方法是什么,如何检测或证明递归关系是周期序列?

也许

(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)
(声明fun f(Int)Int)
(断言(forall((a Int))(=(f0a)0)))
(assert(for all((x Int)(a Int))(=>(and(>=x0)(>=a0)(>(fxa)a))(=(f(+x1)a)(((fxa)1))))
(assert(对于所有((x Int)(a Int))(=>(和(>=x0)(>=a0)((和(>=x0)(>yx)(>=a0))(而不是(=(fxa)(fya)))))
(检查sat)
虽然它并没有说f是周期性的。

也许

(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)
(声明fun f(Int)Int)
(断言(forall((a Int))(=(f0a)0)))
(assert(for all((x Int)(a Int))(=>(and(>=x0)(>=a0)(>(fxa)a))(=(f(+x1)a)(((fxa)1))))
(assert(对于所有((x Int)(a Int))(=>(和(>=x0)(>=a0)((和(>=x0)(>yx)(>=a0))(而不是(=(fxa)(fya)))))
(检查sat)

虽然它没有说f是周期性的。

请始终在示例中包含完整的代码;因为您提供的代码对于运行和观察的人来说是无效的

假设您的代码实际上如下所示:

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))))))
如果运行此脚本,您将获得:

(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
但期望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:

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 -v:10 a.smt2 a.smt2
它会告诉你它在做什么的很多步骤。我猜它在量词实例化过程中丢失了。典型的解决方案是提供量词模式,但我不清楚在这种情况下它们会是什么。这里有一些例子
不过,这可能会有所帮助。

请始终在示例中包含完整的代码;因为您提供的代码不是供人们运行和观察的有效代码

假设您的代码实际上如下所示:

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))))))
如果运行此脚本,您将获得:

(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
但期望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:

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 -v:10 a.smt2 a.smt2
它会告诉你它在做什么的很多步骤。我猜它在量词实例化过程中丢失了。典型的解决方案是提供量词模式,但我不清楚在这种情况下它们会是什么。这里有一些例子
这可能会有所帮助。

非常感谢你的回答。你能帮我理解s=Solver()s.add(a>0)s.add(ForAll([n]),暗指(n>=0,y4(n1+1)==If(y4(n)0,n>=0),y4(n)==y4(n+k()))为什么它会对你的回答返回很多未回答。你能帮我理解s=Solver()s.add(a>0)s.add(ForAll([n]),暗指(n>=0,y4)吗(n1+1)=如果(y4(n)0,n>=0),y4(n)==y4(n+k‘‘‘‘‘)为什么返回unsat