我想创建一个SMT序列,这样我就有了一个完整的顺序。
示例1:
a < b
和b < c
应该可以满足
示例2:
a < b
和c < d
应该不可满足。
通过添加b < c
,我们将获得满意度。
有没有人知道这一般是否可能? 到目前为止,我尝试了以下内容:
(declare-fun my_rel (Int Int) (Bool))
(assert (forall ((i Int)(j Int)) (implies (my_rel i j) (> i j))))
(declare-const a Int)
(declare-const b Int)
(declare-const c Int)
(declare-const d Int)
(assert (my_rel a b))
(assert (my_rel c d))
(check-sat)
这应该返回UNSAT
。通过添加(assert (my_rel b c))
,它应该满足。
答案 0 :(得分:1)
我相信你想要的是一种方法来检查有限元素集合x_1 ... x_n上的传递顺序是否必须是或者必须是完整的和完全的,因为关于该命令的一组用户断言P
&lt;在您的示例中,关系似乎是隐式传递的。将隐式传递二元关系组合在一起的简单方法是使用未解释的函数将任意域嵌入到完全有序的解释域中。确保为此目的添加的未解释功能仅出现在此&#34;嵌入订单&#34;感。
(declare-fun foo (U) (Int))
(define-fun my_rel_strict ((i U) (j U)) (Bool) (> (foo i) (foo j)))
(define-fun my_rel_nonstrict ((i U) (j U)) (Bool)
(or (= (foo i) (foo j)) (my_rel_strict i j))
两个my_rel关系都是可传递的,my_rel_strict具有整体条件((my_real_nonstrict i j)或(my_rel_nonstrict j i)成立)。 (参见http://en.wikipedia.org/wiki/Total_order)由于my_rel没有反对称性,因此也不是总订单。为了避免潜在的问题,域的基数应该至少是codomain的基数(或者两者都是无限的)。 (my_rel_nonstrict的编码不是很好。我在实践中尝试&lt; =。
接下来我相信你想要的是一个蕴涵检查。给定一组断言P,用户定义的传递顺序(我现在写为&lt;)必须是总数吗?我们为有限元素集创建了一个公式total(x_1 ... x_n):
total(x_1 ... x_n) = (and_{for all i,j} (or (< x_i x_j) (= x_i x_j) (> x_i x_j)))
(不是一个非常令人愉快的总编码,但编码都是一样的。)要检查P是否需要总数(...),我们用以下方法查询smt求解器:
(assert P) (assert (not total(...)))
; You may also need (assert (distinct x_1 ... x_n))
如果它不能令人满意,则蕴含着。如果它是令人满意的,那么蕴涵有一个反例并且不成立。
订单编码可能很棘手,因此我的建议可能不适用于您的应用程序。 (还要带上一粒盐。我不是百分之百的。)