Z3如何处理具有未解释函数的forall命题?

时间:2013-01-06 11:20:00

标签: z3 forall

假设我们有两个未解释的函数func1和func2:

stuct_sort func1(struct_sort);
stuct_sort func2(struct_sort ,int).

他们有这种关系:

func2(p,n)=func1(p)  if n==1
func2(p,n)=func1(func2(p,n-1))  if n>1

我想知道的是,如果以下命题:

((forall i:[1,m].func2(p,i)==Z)&&(q==func1(p))) implies (forall i:[1,m-1].func2(q,i)==Z)

在Z3中可以证明是真的吗? 在我的程序中,证明结果为Z3_L_UNDEF

当我为m赋值为3时,命题现在为

((forall i:[1,3].func2(p,i)==Z)&&(q==func1(p))) implies (forall i:[1,3-1].func2(q,i)==Z);

结果是Z3_L_UNDEF。 但是当我按如下方式单独重写案例(不使用forall)时,结果为true

(func2(p,1)==Z)&&(func2(p,2)==Z)&&(func2(p,3)==Z)&&(q==func1(p)) implies (func2(q,1))&&(func2(q,2)).

我找不到原因并期待你的回答

1 个答案:

答案 0 :(得分:1)

我使用Z3 Python界面编码您的问题,Z3解决了它。它找到了猜想的一个反例。 当然,我在编码问题时可能犯了一个错误。 Python代码在帖子的最后。我们可以在rise4fun在线试用。 BTW,您使用的是哪个版本的Z3?我假设您正在使用C API。如果是这种情况,您能提供用于创建Z3公式的C代码吗?另一种可能性是创建一个记录应用程序和Z3交互的日志。要创建日志文件,我们必须在执行任何其他Z3 API之前执行Z3_open_log("z3.log");。我们可以使用日志文件重播您的应用程序和Z3之间的所有交互。

from z3 import *
# Declare stuct_sort 
S = DeclareSort('stuct_sort')
I = IntSort()
# Declare functions func1 and func2
func1 = Function('func1', S, S)
func2 = Function('func2', S, I, S)

# More declarations
p = Const('p', S)
n = Int('n')
m = Int('m')
i = Int('i')
q = Const('q', S)
Z = Const('Z', S)

# Encoding of the relations 
#    func2(p,n)=func1(p)  if n==1
#    func2(p,n)=func1(func2(p,n-1))  if n>1
Relations = And(func2(p, 1) == func1(p), 
                ForAll([n], Implies(n > 1, func2(p, n) == func1(func2(p, n - 1)))))

# Increase the maximum line width for the Z3 Python formula pretty printer
set_option(max_width=120)
print Relations

# Encoding of the conjecture
# ((forall i:[1,m].func2(p,i)==Z)&&(q==func1(p))) implies (forall i:[1,m-1].func2(q,i)==Z)
Conjecture = Implies(And(q == func1(p), ForAll([i], Implies(And(1 <= i, i <= m), func2(p, i) == Z))),
                     ForAll([i], Implies(And(1 <= i, i <= m - 1), func2(q, i) == Z)))
print Conjecture

prove(Implies(Relations, Conjecture))