Z3可以在变量决策期间调用python函数吗?

Z3可以在变量决策期间调用python函数吗?,z3,z3py,Z3,Z3py,我试图解决一个问题,例如,我有一个4分,每两个点之间有一个成本。现在我想找到一个节点序列,它的总开销小于一个界限。我已经写了一个代码,但它似乎不起作用。主要的问题是我定义了一个python函数,并试图在约束中调用它 这是我的代码:我有一个函数def getValn1,n2:其中n1,n2是Int-Sort。line Nodes=[Intn_U%s%i for i in rangetotalNodeNumber]将4个点定义为Int sort,当我添加约束s.addgetValNodes[0]、N

我试图解决一个问题,例如,我有一个4分,每两个点之间有一个成本。现在我想找到一个节点序列,它的总开销小于一个界限。我已经写了一个代码,但它似乎不起作用。主要的问题是我定义了一个python函数,并试图在约束中调用它

这是我的代码:我有一个函数def getValn1,n2:其中n1,n2是Int-Sort。line Nodes=[Intn_U%s%i for i in rangetotalNodeNumber]将4个点定义为Int sort,当我添加约束s.addgetValNodes[0]、Nodes[1]+getValNodes[1]、Nodes[2]<100时,它会立即调用getVal函数。但我想知道,当Z3将决定节点[0]、节点[1]、节点[2]、节点[3]的值时,应该调用函数来获取到点之间的成本

from z3 import *
import random

totalNodeNumber = 4
Nodes = [ Int("n_%s" % (i)) for i in range(totalNodeNumber) ]
def getVal(n1,n2):
    # I need n1 and n2 values those assigned by Z3
    cost = random.randint(1,20)
    print cost
    return IntVal(cost)

s = Solver()

#constraint: Each Nodes value should be distinct
nodes_index_distinct_constraint  = Distinct(Nodes)
s.add(nodes_index_distinct_constraint)

#constraint: Each Nodes value should be between 0 and totalNodeNumber
def get_node_index_value_constraint(i):
    return And(Nodes[i] >= 0, Nodes[i] < totalNodeNumber)
nodes_index_constraint  = [ get_node_index_value_constraint(i) for i in range(totalNodeNumber)]
s.add(nodes_index_constraint)

#constraint: Problem with this constraint
# Here is the problem it's just called python getVal function twice without assiging Nodes[0],Nodes[1],Nodes[2] values
# But I want to implement that - Z3 will call python function during his decission making of variables
s.add(getVal(Nodes[0], Nodes[1]) + getVal(Nodes[1], Nodes[2]) + getVal(Nodes[2], Nodes[3]) < 100)

if s.check() == sat:
    print "SAT"
    print "Model: "
    m = s.model()
    nodeIndex = [ m.evaluate(Nodes[i]) for i in range(totalNodeNumber) ]
    print nodeIndex
else:
    print "UNSAT"
    print "No solution found !!"

如果这不是一个解决问题的正确方法,那么你能告诉我其他的解决方法吗。我能用Z3解算器对这类问题进行编码以找到最优的路径点序列吗?

我不明白您需要解决什么问题。当然,getVal的公式化方式毫无意义。它不使用参数n1、n2。如果您想检查模型生成的值,那么在Z3从check调用返回后执行此操作

我认为不能在SMT逻辑中使用python函数。您也可以将getVal定义为如下函数

getVal = Function('getVal',IntSort(),IntSort(),IntSort())
并将边权重约束为

s.add(And(getVal(0,1)==1,getVal(1,2)==2,getVal(0,2)==3))

getVal的前两个输入参数表示节点ID,最后一个整数表示权重。

您好,谢谢您的回复。我的问题是:我有一个具有大量节点的完全连通图。每一个边缘都有代价。给出了起始节点和结束节点。我想应用增量Sat求解来找到从开始到结束节点的最短路径。这几乎就像一个有其他约束的TSP问题。