Logic 具有Z3py的horn子句上的不变归纳

Logic 具有Z3py的horn子句上的不变归纳,logic,z3,z3py,logic-programming,Logic,Z3,Z3py,Logic Programming,我目前正在使用Z3py来推导一些不变量,这些不变量被编码为horn子句的连接,同时也为不变量提供了一个模板。如果您看到下面的代码片段,我首先从一个简单的示例开始 x = 0; while(x < 5){ x += 1 } assert(x == 5) x=0; 而(xInv(x) xInv(x+1) 非(xx=5 这里的不变量是x有两件事阻止了原始编码的工作: 1) 对于所有x的x\u 2==x+1,对于x\u 2的单个值,不可能满足x\u 2==x+1。因此,如果你要写x_2==x

我目前正在使用Z3py来推导一些不变量,这些不变量被编码为horn子句的连接,同时也为不变量提供了一个模板。如果您看到下面的代码片段,我首先从一个简单的示例开始

x = 0;
while(x < 5){
  x += 1
}
assert(x == 5)
x=0;
而(x<5){
x+=1
}
断言(x==5)
这就转化为霍恩条款

x=0=>Inv(x)

x<5/\Inv(x)=>Inv(x+1)

非(x<5)/\Inv(x)=>x=5


这里的不变量是x有两件事阻止了原始编码的工作:

1) 对于所有
x
x\u 2==x+1
,对于
x\u 2
的单个值,不可能满足
x\u 2==x+1
。因此,如果你要写
x_2==x+1
,那么
x
x_2
都需要被普遍量化


2) 有些令人惊讶的是,这个问题在整数中是可满足的,但在实数中不是。您可以看到子句
x<5/\Inv(x)=>Inv(x+1)
的问题。如果
x
是一个整数,那么
x可以满足这个要求,我想我已经解决了。我将所有real都更改为int,并按照编辑中的描述删除了x_2定义。突然它工作了,我得到了x的适当不变量,非常感谢!是的,模板有点多余。这是因为我正在开发一个模板生成器,它查看可能引入冗余的基本组件的组合(例如“+”和“-”)。这是我以后将要优化的东西。
x = Real('x')
x_2 = Real('x_2')
a = Real('a')
b = Real('b')
c = Real('c')
s = Solver()
s.add(ForAll([x],And(
Implies(x == 0 , a*x + b <= c),
Implies(And(x_2 == x + 1, x < 5, a*x + b <= c), a*x_2 + b <= c),
Implies(And(a*x + b <= c, Not(x < 5)), x==5)
)))
if (s.check() == sat):
    print(s.model())
from z3 import *

# Changing these from 'Int' to 'Real' changes the problem from sat to unsat.
x = Int('x')
x_2 = Int('x_2')
a = Int('a')
b = Int('b')
c = Int('c')

def Inv(x):
    return a*x + b <= c

s = Solver()

# I think this is the simplest encoding for your problem.
clause1 = Implies(x == 0 , Inv(x))
clause2 = Implies(And(x < 5, Inv(x)), Inv(x + 1))
clause3 = Implies(And(Inv(x), Not(x < 5)), x == 5)
s.add(ForAll([x], And(clause1, clause2, clause3)))

# Alternatively, if clause2 is specified with x_2, then x_2 needs to be
# universally quantified.  Note the ForAll([x, x_2]...
#clause2 = Implies(And(x_2 == x + 1, x < 5, Inv(x)), Inv(x_2))
#s.add(ForAll([x, x_2], And(clause1, clause2, clause3)))

# Print result all the time, to avoid confusing unknown with unsat.
result = s.check()
print result
if (result == sat):
    print(s.model())