Python 检查公式是否为Z3Py中的术语
在Z3Py中,我需要使用标准语法Python 检查公式是否为Z3Py中的术语,python,z3,Python,Z3,在Z3Py中,我需要使用标准语法术语:=const | var | f(t1,…,tn))检查某个词是否是术语。我编写了下面的函数来确定这一点,但是我检查n元函数的方法似乎不是很理想 有没有更好的办法?这些实用程序函数是术语,是原子,是文字,等等都有助于包含在Z3中。我会把它们放在contrib部分 CONNECTIVE_OPS = [Z3_OP_NOT,Z3_OP_AND,Z3_OP_OR,Z3_OP_IMPLIES,Z3_OP_IFF,Z3_OP_ITE] REL_OPS = [Z3_OP_
术语:=const | var | f(t1,…,tn)
)检查某个词是否是术语。我编写了下面的函数来确定这一点,但是我检查n元函数的方法似乎不是很理想
有没有更好的办法?这些实用程序函数是术语
,是原子
,是文字
,等等都有助于包含在Z3中。我会把它们放在contrib部分
CONNECTIVE_OPS = [Z3_OP_NOT,Z3_OP_AND,Z3_OP_OR,Z3_OP_IMPLIES,Z3_OP_IFF,Z3_OP_ITE]
REL_OPS = [Z3_OP_EQ,Z3_OP_LE,Z3_OP_LT,Z3_OP_GE,Z3_OP_GT]
def is_term(a):
"""
term := const | var | f(t1,...,tn)
"""
if is_const(a):
return True
else:
r = (is_app(a) and \
a.decl().kind() not in CONNECTIVE_OPS + REL_OPS and \
all(is_term(c) for c in a.children()))
return r
功能合理,有几点意见:
def get_expr_id(e):
return Z3_get_ast_id(e.ctx.ref(), e.ast)
def is_term_aux(a, seen):
if get_expr_id(a) in seen:
return True
else:
seen[get_expr_id(a)] = True
r = (is_app(a) and \
a.decl().kind() not in CONNECTIVE_OPS + REL_OPS and \
all(is_term_aux(c, seen) for c in a.children()))
return r
def is_term(a):
return is_term_aux(a, {})
一阶逻辑中使用的术语、原子和文字的“教科书”定义不能直接应用于Z3表达式。在Z3中,我们允许表达式如f(和(a,b))>0
和f(ForAll([x],g(x)==0))
,其中f
是从布尔值到整数的函数。这种扩展不会增加表达能力,但在编写问题时非常方便。SMT 2.0标准还允许“术语”if-then-else
表达式。这是另一个允许我们在“术语”中嵌套“公式”的特性。示例:g(如果(和(a,b),1,0))
在实现操作Z3表达式的过程时,我们有时需要区分布尔表达式和非布尔表达式。在本例中,“术语”只是一个没有布尔排序的表达式
def is_term(a):
return not is_bool(a)
在其他情况下,我们希望以特殊方式处理布尔连接词(和
,或
,…)。例如,我们正在定义一个CNF转换器。在本例中,我们将“原子”定义为任何不是量词、是(自由)变量或不是布尔连接词之一的应用程序的布尔表达式
def is_atom(a):
return is_bool(a) and (is_var(a) or (is_app(a) and a.decl().kind() not in CONNECTIVE_OPS))
定义原子后,可以将文字定义为:
def is_literal(a):
return is_atom(a) or (is_not(a) and is_atom(a.arg(0)))
以下是演示这些功能的示例(也可在线访问):
x = Int('x')
p, q = Bools('p q')
f = Function('f', IntSort(), BoolSort())
g = Function('g', IntSort(), IntSort())
print is_literal(Not(x > 0))
print is_literal(f(x))
print is_atom(Not(x > 0))
print is_atom(f(x))
print is_atom(x)
print is_term(f(x))
print is_term(g(x))
print is_term(x)
print is_term(Var(1, IntSort()))