用于表达最优性的z3数据记录中的否定

时间:2018-03-19 21:44:41

标签: z3 datalog

我使用Z3并将:fixedpoint.engine设置为datalog。 我有一个枚举的过滤器关系(f pos min max)。我们假设有(f #x10 #x100000 #x200000)(f #x20 #x150000 #x200000)(f #x20 #x300000 #x500000)

对于给定的x,我搜索最大pos(f pos min max)min <= x <= max (这里我使用间隔,但过滤器可以任意复杂)< / em>的。优先级(排序t)和值(排序s)是BitVectors,但xminmax位于相当大的空间(例如.24位)

; configuration 
(set-option :fixedpoint.engine datalog)
; sorts
(define-sort s () (_ BitVec 24))
(define-sort t () (_ BitVec 8))
; Relations
(declare-rel f (t s s))
(declare-rel match (t s))
(declare-rel better (t s))
(declare-rel best (t s))
(declare-rel a (t))
(declare-rel b ())
(declare-rel c ())
(declare-var x s)
(declare-var xmin s)
(declare-var xmax s)
(declare-var p t)
(declare-var q t)
; Facts (EDB)
(rule (f #x10 #x100000 #x200000))
(rule (f #x20 #x150000 #x200000))
(rule (f #x20 #x300000 #x500000))
; Rules
(rule (=> (and (f p xmin xmax) (bvule xmin x) (bvule x xmax))
          (match p x)))
(rule (=> (and (match q x) (bvugt q p))
          (better p x)))
(rule (=> (and (match p x) (not (better p x)))
          (best p x)))
; Queries
(rule (=> (match p #x170000) (a p)))
(rule (=> (better #x10 #x170000) b))
(rule (=> (best #x10 #x170000) c))
; output: sat
; (or (= (:var 0) #x20) (= (:var 0) #x10))
(query (a p) :print-answer true)
; output: sat
(query b)
; Output 'WARNING: creating large table of size 16777216 for relation better' and fails
(query c)
  • (match p x)对优先级p的过滤器过滤x这一事实进行了编码。
  • (better p x)如果优先级高于p的规则会过滤x
  • (best p x)代码匹配x的最佳过滤条件具有优先级p

如果我查询(match p #x170000),我会很快得到#x10#x20。如果我问(better #x10 #x170000)我很快就会得到 优先级#20的答案相同。但是(best p #x170000)上的查询无法在合理的时间和合理的空间内执行。

似乎(not (better p x))独立于(match p x)计算,因此由非常大的表表示(x的可能值不会被转发)。在某些情况下,我可以通过更好的中的一些技巧来限制x(有时我知道我只对显式出现在其他关系中的x感兴趣)以便空间是减少,但这不是一个真正的通用解决方案,有时我被卡住了。

我应该如何重新解释这个问题,或者我应该使用哪些选项来避免这个问题?

1 个答案:

答案 0 :(得分:1)

Z3的默认数据记录表超过具体值,因此如果使用大位向量,Z3最终可能会创建巨大的表。 您可以尝试更简单的表数据结构,它支持更少的操作,但它很稀疏(使用&#34;不关心&#34;位)。 您可以尝试使用:z3 fixedpoint.engine = datalog fixedpoint.datalog.default_relation = doc file.smt2