【问题标题】:Which encodings are preferable to use Z3 to solve a partial order theory?哪种编码更适合使用 Z3 来解决偏序理论?
【发布时间】:2019-12-03 18:27:44
【问题描述】:

我正在考虑对偏序关系进行编码以提供 Z3 的多种方法。

问题已经以各种方式受到限制,并使用 QF_ 逻辑变体(主要是 LIA 或 LRA)。

我有额外的约束,我可以用偏序来优化解决方案,形式为,如果变量ei>0 => a0 precedes ai,其中ei 是我的问题的一个变量,而ai 变量是新的,并表示“先于”偏序约束。

因此,这种偏序将以多种方式限制根据 ei 获得的解。

一个解决方案可能是使用未解释的函数,例如这个例子: https://rise4fun.com/Z3/fZQc

; Coding a partial order precedes relation with UF
(declare-sort A)
(declare-fun pre (A A) Bool)
; non reflexive
(assert (forall ((x A)) (not (pre x x))))
; transitive
(assert (forall ((x A) (y A) (z A))
          (=> (and (pre x y) (pre y z)) 
              (pre x z)))) 
; anti symetric
(assert (forall ((x A) (y A))
          (=> (pre x y)  
              (not (pre y x)))))
; an UNSAT example
(declare-const a0 A)
(declare-const a1 A)
(declare-const a2 A)
(assert (pre a0 a1))
(assert (pre a1 a2))
(assert (pre a2 a0))
(check-sat)

这正是我想要表达的,但这也引入了一个新的量词逻辑。

另一种选择是将我的元素放入一个具体的域中,例如 Real 或 Int : https://rise4fun.com/Z3/U0Hp

; Coding a partial order precedes relation with Real
; an UNSAT example
(declare-const a0 Real)
(declare-const a1 Real)
(declare-const a2 Real)
(assert (< a0 a1))
(assert (< a1 a2))
(assert (< a2 a0))
(check-sat)

代码更简单并且不使用量词,但它迫使(也许?)求解器过度思考,因为 Real 比第一个版本中的抽象域 A 具有更多的属性。

那么通常应该首选哪种编码来编码部分订单? 是否有我应该考虑的其他参数,或者我可以配置哪些策略来帮助解决此类问题?

【问题讨论】:

  • reals 的问题是它们是完全有序的......如果这是可以接受的,那么它肯定是更简单的方法。如果有一个很好的嵌入到量词上不太重的数据类型中,我会考虑一下。
  • 好吧,因为我的约束不谈论相等,所以即使我陷入实数,我最终还是会得到一个偏序,两个不同的变量可能是相等的;但是是的,这是强制结合的额外约束,例如两个完全独立的因果链最终会以实数“完全”排序,或者至少求解者必须考虑一下。

标签: z3 smt partial-ordering


【解决方案1】:

您还可以尝试特殊关系的内置功能。 至少他们改进了实例化的二次开销 偏序公理。内置的偏序关系是自反的, 所以如果你想要一个反身版本,那么定义一个排除的宏 反身案例。 (_ partial-order 0) 是一个关系,它接受两个相同类型的参数并返回一个布尔值。 (_ partial-order 1) 将是不同的关系,因此您可以使用参数索引不同的偏序。

(declare-sort A)
(define-fun pre ((x A) (y A)) Bool (and (not (= x y)) ((_ partial-order 0) x y)))
; an UNSAT example
(declare-const a0 A)
(declare-const a1 A)
(declare-const a2 A)
(assert (pre a0 a1))
(assert (pre a1 a2))
(assert (pre a2 a0))
(check-sat)

【讨论】:

  • 感谢您的建议,我不知道 Z3 的该功能,但它确实似乎接近我的用例。我会尝试并与其他选项进行比较。
  • 抱歉,您能否详细说明如何使这些功能可用,例如Rise4Fun(和我的实验)都抱怨:invalid use of indexed identifier, unknown builtin function partial-order。我也搜索了文档,但我能找到的只是 you 显然创作的这个文件:D github.com/Z3Prover/z3/blob/…
  • 所以基于这个例子,我可以得到一个部分订单来工作,但这是 Python API,我无法找到或使 SMT2 语法中的示例工作。 github.com/Z3Prover/doc/blob/master/programmingz3/code/… 这个页面上还有这个“特殊关系”功能的文档:theory.stanford.edu/~nikolaj/… 但这又是 Py API。
  • 好的,所以问题与“set-logic”有关,任何set-logic 命令显然都禁用了这个“special_relations”功能,所以我不确定rise4fun 是如何配置的(它不起作用即使没有设置逻辑),但是一旦我从我的代码中删除了我的set-logic,它就会运行而不会抱怨我的本地 z3 实例。
【解决方案2】:

尽可能避免使用量词。 SMT 求解器对它们并不擅长,尤其是在理论组合方面。如果你能坚持IntReal,那就太好了。如果您可以使用位向量,那就更好了,因为即使存在非线性函数,逻辑也将保持可判定性。

如果您的模型确实需要量词,我认为 SMT 求解器根本不适合。在这种情况下,请查看 Isabelle、Coq、HOL 等半自动化系统。

【讨论】:

  • 感谢您的回答,哪种符合我的直觉,但在理论之间相互作用的有限情况下,求解器不应该看到它可以使用例如Tarjan 在我的抽象类型 A 上,而不是用实数实例化?
  • 不试就无法分辨。问题在于求解器的内部或多或少是一个黑盒:即使是对输入的微小更改也可能导致它发散,并且很难调试。如果可以避免,请远离量词。
  • 在尝试了这两种解决方案之后,对于我的用例,存在巨大的性能差距(秒或“未知”到毫秒),有利于不使用量词,即。我们应该更喜欢使用“进入 Nat 或 Real”的方法。所以我会接受这个答案。
猜你喜欢
  • 2015-08-16
  • 1970-01-01
  • 2011-03-19
  • 2017-01-29
  • 1970-01-01
  • 2013-07-16
  • 1970-01-01
  • 2017-04-11
  • 2010-11-15
相关资源
最近更新 更多