查找两个节点之间的路径

时间:2014-11-25 08:12:59

标签: z3 smt z3py

我想知道是否有办法在z3py中构建拓扑,如果给出6个节点,即:n1,n2,n3,n4,n5,n6,它们之间有某些链接,例如: l12(这意味着节点n1和n2之间存在链路),l16,l23,l25,l34,l35,l36。我可以将l_ {i} {j}定义为bool变量,以便它可以引用2个节点或节点之间是否存在任何链接(当然,我必须以这种方式定义所有可能的链接)。问题是如何在Z3py中定义路径的概念,以便我可以判断两个节点之间是否存在任何路径(SAT或UNSAT,如果SAT是哪个路径?)。我试着寻找z3py教程,但它不再在线提供,我是z3的新手,所以请耐心等待我。我只能在python中找出以下建模,这非常天真。是否可以在z3py中将路径建模为未解释的函数?

graph = {'n1': ['n2', 'n6'],
         'n2': ['n3', 'n5'],
         'n3': ['n4', 'n5','n6'],
         'n4': ['n3'],
         'n5': ['n2', 'n3'],
         'n6': ['n3','n1']}
def path_finder (graph, start, end, path=[]):
    path = path + [start]
    if start == end:
        return path
    if not graph.has_key(start):
        return None
    for node in graph[start]:
        if node not in path:
            newpath = path_finder (graph, node, end, path)
            if newpath: return newpath
    return None

print path_finder (graph, 'n1','n4')

1 个答案:

答案 0 :(得分:0)

我修改了Fixpoint example以完成路径搜索

from z3 import *

#  cf. https://ericpony.github.io/z3py-tutorial/fixpoint-examples.htm

fp = Fixedpoint()
fp.set(engine='datalog')

#  3 bits are sufficient to model our 6 nodes
s = BitVecSort(3)
edge = Function('edge', s, s, BoolSort())
path = Function('path', s, s, BoolSort())
a = Const('a', s)
b = Const('b', s)
c = Const('c', s)

#  the rules:
#  a path can be a single edge or
#  a combination of a path and an edge
fp.register_relation(path,edge)
fp.declare_var(a, b, c)
fp.rule(path(a, b), edge(a, b))
fp.rule(path(a, c), [edge(a, b), path(b, c)])

n1 = BitVecVal(1, s)
n2 = BitVecVal(2, s)
n3 = BitVecVal(3, s)
n4 = BitVecVal(4, s)
n5 = BitVecVal(5, s)
n6 = BitVecVal(6, s)
n7 = BitVecVal(7, s)

graph = {n1: [n2, n6, n7],
         n2: [n3, n5],
         n3: [n4, n5, n6],
         n4: [n3],
         n5: [n2, n3],
         n6: [n3, n1]}

#  establish facts by enumerating the graph dictionary
for i, (source, nodes) in enumerate(graph.items()):
    for destination in nodes:
        fp.fact(edge(source, destination))

print("current set of rules:\n", fp)

print(fp.query(path(n1, n4)), "yes, we can reach n4 from n1\n")

print(fp.query(path(n7, n1)), "no, we cannot reach n1 from n7\n")