z3数据日志中表示最优性的否定

z3数据日志中表示最优性的否定,z3,datalog,Z3,Datalog,我将Z3与:fixedpoint.engine设置为datalog。 我有一个枚举过滤器关系(f pos min max)。假设我们有(f#x10#x100000#x200000),(f#x20#x150000#x200000)和(f#x20#x30000#x500000) 对于给定的x,我搜索最大的pos,这样(f pos min max)和minZ3的默认数据日志表都超过了具体的值,因此如果使用大位向量,Z3可能最终会创建巨大的表。 您可以尝试一种更简单的表数据结构,它支持更少的操作,但它是

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


对于给定的
x
,我搜索最大的
pos
,这样
(f pos min max)
minZ3的默认数据日志表都超过了具体的值,因此如果使用大位向量,Z3可能最终会创建巨大的表。
您可以尝试一种更简单的表数据结构,它支持更少的操作,但它是稀疏的(使用“不在乎”位)。

你可以用:z3 fixedpoint.engine=datalog fixedpoint.datalog.default\u relationship=doc file.smt2来试试。我可以知道为什么这个问题被否决了吗?该示例是精心设计的,但它试图捕捉“匹配”的本质,即在编程语言、防火墙或路由表中使用第一个过滤器(优先级是前缀的长度)。f和match通常更复杂。新用户提出的问题最终会由general进行审查,因此可能没有足够的专业知识来理解和公平判断,因此有可能进行否决票。除了问题描述中没有包含a之外,我认为这是一个好问题。不过,我不知道是否可以给予一个具体的答案。您可以添加一个吗?谢谢您的编辑。我添加了所有声明和查询,以便示例可以作为
z3test.smt2
运行。谢谢,这是一种我没有尝试过的关系类型。不幸的是,doc似乎不支持位向量比较(在
bvule
上失败),至少有一个否定(前两个查询可以)。我曾尝试将其调整为更简单的情况,使用更经典的位算法(由前缀和掩码定义的过滤器,如果
x&mask=prefix
和最长掩码的优先级相匹配),但即使如此,我也发现在包含
=
bvor
bvnot
的表达式上不会处理保护表达式。
doc
支持哪些操作?在哪个上下文中?请参见此处:添加对bvor和类似操作的支持应该很简单。。
; 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)