Graph Z3,哈密顿图,命题逻辑

Graph Z3,哈密顿图,命题逻辑,graph,logic,z3,Graph,Logic,Z3,我希望就如何实现这一目标提出建议: 定义: 无向图G由顶点集V和边集E定义,其中每条边是大小为2的V的子集,即无序的顶点对{u,V}。G中长度为k的圈是不同顶点的序列v_1,…,v_k,其中{v_1,v_2},{v_2,v_3},…,{v_k-1,v_k},{v_k,v_1}都是G的边。G中的哈密顿圈是长度为n=|v|的圈,即一个恰好通过图的每个顶点一次的圈。我们称G为哈密顿量,如果它有一个哈密顿圈 问题: 提供以下决策问题的命题逻辑公式:给定undi- 直图G是哈密顿量吗?配方将由Z3进行检查

我希望就如何实现这一目标提出建议:

定义: 无向图G由顶点集V和边集E定义,其中每条边是大小为2的V的子集,即无序的顶点对{u,V}。G中长度为k的圈是不同顶点的序列v_1,…,v_k,其中{v_1,v_2},{v_2,v_3},…,{v_k-1,v_k},{v_k,v_1}都是G的边。G中的哈密顿圈是长度为n=|v|的圈,即一个恰好通过图的每个顶点一次的圈。我们称G为哈密顿量,如果它有一个哈密顿圈

问题: 提供以下决策问题的命题逻辑公式:给定undi- 直图G是哈密顿量吗?配方将由Z3进行检查

输入格式为:

4
0 1
1 2
2 3
3 0
1 3
其中,第一个数字表示顶点的数量,其余对都是G中的边

输出应为:0 1 2 3

显然,输出总是数字1,…,n-1的某种排列,其中n=| V |,但我不知道如何仅使用命题逻辑处理整数

任何建议都将不胜感激

问候

这里有一个适用于给定输入的解决方案。如果我可以编写一个perl例程来生成边的组合(n选择k),那么我可以将其推广到任意数量的输入:

(declare-const v0 Bool)
(declare-const v1 Bool)
(declare-const v2 Bool)
(declare-const v3 Bool)

(declare-const e1 Bool)
(declare-const e2 Bool)
(declare-const e3 Bool)
(declare-const e4 Bool)
(declare-const e5 Bool)

(assert (xor (and e1 e2 e3 e4) (and e1 e2 e3 e5) (and e1 e2 e4 e5) (and e1 e3 e4 e5) (and e2 e3 e4 e5)))

(assert (and v0 v1 v2 v3))

(assert (=> e1 (and v0 v1)))
(assert (=> e2 (and v1 v2)))
(assert (=> e3 (and v2 v3)))
(assert (=> e4 (and v3 v0)))
(assert (=> e5 (and v1 v3)))

(check-sat)
(get-model)

想法是让SMT解算器生成n个数字,比如a1..an,然后断言以下所有内容:

  • 所有这些数字都在0和n-1之间
  • 所有的数字都是不同的
  • 顶点a1。。形成循环,即检查a1-a2、a2-a3、…、a(n-1)-an和an-a1之间是否存在边
也就是说,您只需描述什么是“哈密顿循环”,SMT解算器将找到一个,如果它确实存在

现在,困难在于如何在SMTLib2中表达所有这些,以便Z3能够解析它。当然这是可以做到的,但我建议使用更高级的语言,为SMT解算器提供绑定。例如,Haskell和Scala是两种可以编写Z3脚本的语言。这样,您只需关注问题,宿主语言将在幕后为您处理翻译。这需要在学习宿主语言和相关库方面进行一些投资,但在我看来这是非常值得的


例如,以下是使用Haskell和Z3解决此问题的方法:。解决方案只有7行Haskell代码,您可以使用它查询任意大小的图形。该解决方案利用了Haskell的表达能力和Z3的SMT解算器功能,提供了一个干净的界面。

您可以使用布尔变量对边关系进行编码,例如使用R-5-4表示R中的if(5,4)

设E为输入边关系

将关系R约束为E的子集,使每个顶点恰好连接到R中的两条边

现在将关系T约束为R的传递闭包


如果T是完全连通的(所有T-n1-n2都是真的),R是一个Hamilton圈,(V,E)是一个Hamilton图。

问题是我仅限于命题逻辑:和,或不是蕴涵。我不能生成数字。如果N是一个常数(或者至少如果你知道一个上限),那么你可以使用位字符串(通常的二进制扩展)对数字进行编码。对于这个问题,您需要进行比较,这可以按词典进行。(这本质上类似于“爆破”,SMT解算器将位向量问题转化为SAT实例。)这并不漂亮。关于smt2限制:如果您愿意,您仍然可以使用Haskell库,有一个API调用来吐出生成的SMT lib文件,您可以轻松提取该文件。当然,生成的代码从来都不容易阅读,但它可能比手工编写的代码更紧凑/正确。谢谢。但我需要比这低技术多的东西。基本上,我必须编写一个Perl程序,为Z3生成一个smt2文件,当哈密顿循环存在时,该文件将返回必须为真的边。我仅限于使用命题逻辑对作为输入的节点和边进行断言。我编辑了我的帖子以展示一个特别的解决方案。我需要能够通过编写一个接受边组合(n选择k)的例程来概括它。但我不知道该怎么做。