Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python z3数据类型为数组的建模图_Python_Z3_Z3py - Fatal编程技术网

Python z3数据类型为数组的建模图

Python z3数据类型为数组的建模图,python,z3,z3py,Python,Z3,Z3py,我试图在z3中建模一个有向图,但我被卡住了。我在图中添加了一条公理,即边的存在意味着它连接的节点的存在。但仅仅是这一点就导致了不安全 GraphSort = Datatype('GraphSort') GraphSort.declare('Graph', ('V', ArraySort(IntSort(), BoolSort())), ('E', ArraySort(IntSort(), ArraySort(IntSort(), BoolSort()))), ) GraphSor

我试图在z3中建模一个有向图,但我被卡住了。我在图中添加了一条公理,即边的存在意味着它连接的节点的存在。但仅仅是这一点就导致了不安全

GraphSort = Datatype('GraphSort')
GraphSort.declare('Graph',
    ('V', ArraySort(IntSort(), BoolSort())),
    ('E', ArraySort(IntSort(), ArraySort(IntSort(), BoolSort()))),
)
GraphSort = GraphSort.create()
V = GraphSort.V
E = GraphSort.E

G = Const('G', GraphSort)
n, m = Consts('n m', IntSort())
Graph_axioms = [
    ForAll([G, n, m], Implies(E(G)[n][m], And(V(G)[n], V(G)[m]))),
]

s = Solver()
s.add(Graph_axioms)
我试图对图形进行建模,使得
V(G)[n]
表示节点
n
的存在,
E(G)[n][m]
表示从
n
m
的边的存在。有人知道这里出了什么问题吗?甚至更好的是,有没有在z3中建模图形的一般技巧

编辑:

根据所给出的解释,我提出了以下略显粗糙的解决方案:

from itertools import product
from z3 import *
import networkx as nx


GraphSort = Datatype('GraphSort')
GraphSort.declare('Graph',
    ('V', ArraySort(IntSort(), BoolSort())),
    ('E', ArraySort(IntSort(), ArraySort(IntSort(), BoolSort()))),
)
GraphSort = GraphSort.create()
V = GraphSort.V
E = GraphSort.E

class Graph(DatatypeRef):
    def __new__(cls, name):
        # Hijack z3 DatatypeRef instance
        inst = Const(name, GraphSort)
        inst.__class__ = Graph
        return inst

    def __init__(G, name):
        G.axioms = []
        n, m = Ints('n m')
        G.add(ForAll(
            [n, m],
            Implies(E(G)[n][m], And(V(G)[n], V(G)[m]))
        ))

    def add(G, *v):
        G.axioms.extend(v)

    def add_networkx(G, nx_graph):
        g = nx.convert_node_labels_to_integers(nx_graph)

        Vs = g.number_of_nodes()
        Es = g.number_of_edges()

        n = Int('n')
        G.add(ForAll(n, V(G)[n] == And(0 <= n, n < Vs)))
        G.add(*[E(G)[i][k] for i, k in g.edges()])
        G.add(Sum([
            If(E(G)[i][k], 1, 0) for i, k in product(range(Vs), range(Vs))
        ]) == Es)

    def assert_into(G, solver):
        for ax in G.axioms:
            solver.add(ax)


s = Solver()
G = Graph('G')
G.add_networkx(nx.petersen_graph())
G.assert_into(s)
来自itertools导入产品的

从z3进口*
将networkx导入为nx
GraphSort=数据类型('GraphSort')
GraphSort.declare('Graph',
('V',ArraySort(IntSort(),BoolSort()),
('E',ArraySort(IntSort(),ArraySort(IntSort(),BoolSort())),
)
GraphSort=GraphSort.create()
V=图形排序
E=图形排序
类图(DatatypeRef):
定义新名称(cls,名称):
#劫持z3 DatatypeRef实例
inst=Const(名称、图形排序)
安装类=图形
返回仪表
定义初始化(G,名称):
G.公理=[]
n、 m=整数('n m')
G.add(ForAll)(
[n,m],
暗示(E(G)[n][m]和(V(G)[n],V(G)[m]))
))
def添加(G,*v):
G.公理扩展(v)
def add_网络X(G,nx_图形):
g=nx。将节点标签转换为整数(nx图)
Vs=g.节点的数量()
Es=g.边的数量()
n=Int('n')

加上所有的(n,V(G)[n]==和(0)P>你的模型是“代码> UNSAT</CODE”,因为数据类型是自由生成的。这是一个常见的误解:当你创建一个数据类型并声明一个公理时,你不限制Z3只考虑那些满足公理的模型。你要说的是检查这个数据类型的所有实例是否满足公理。早期不正确,因此
unsat
。这类似于说:

a = Int("a")
s.add(ForAll([a], a > 0))
出于同样的原因,这也是
unsat
;但希望更容易理解原因。关于“自由生成”的含义,请参见以下答案:


要对这样的图进行建模,您应该只在图的节点的单个实例上陈述这些公理,而不是一般化/量化公理。与其断言这些公理,不如关注您试图建模的其他方面。因为您没有真正向我们提供您想要解决的问题的任何详细信息,所以很难发表意见更进一步。

谢谢!这很好地澄清了问题!:D有没有一种方法可以对类型进行约束?或者一种“正常”的实现方法,例如,将实例包装在声明公理的函数中?对类型进行约束称为谓词子类型,但SMTLib不支持它。(早期版本的Yices用于支持谓词子类型,但我相信即使在现在的Yices中也不再有这种支持。)简言之,没有办法在SMT解算器中直接对类型施加这样的约束。要做到这一点,您需要一个更强大的系统,也就是说,可能SAL可以用于此目的(),或类似Isabelle/HOL等系统。谢谢!更新了我的答案,使用了一种使界面保持z3yHmm的解决方案,我不确定它是如何工作的;但如果它能为您完成任务,那就太好了!一般来说,我认为您应该从一个空图开始(即,一个存储所有
False
的数组),然后通过插入节点以增量方式更新数组来构建图形。这当然假设您有一个固定的图形。但很难从您的问题中确切地说出您要解决的问题。我只是在探索可能性,我是非常新的z3、SMT甚至SAT解算器。我想尝试下一步生成一组将一个图形转换为另一个图形的操作,例如,两个相似的图形,其中一个缺少边。可能是
add_边(G0,n,m)==G1
。不过,我的尝试并没有终止,所以我还有很长的路要走,才能感觉到z3可以在合理的时间内解决什么问题。接下来,我将尝试一种从空图开始的方法,然后它也将更类似于数组!谢谢提示!