如何打印Z3 Set对象?

时间:2013-04-10 19:46:59

标签: z3

我无法打印/显示作为Z3模型的一部分返回的设置对象。请考虑以下示例(在F#中):

let ctx:Context = new Context()
let ASort = ctx.MkEnumSort("S",[| "A"; "B"; "C"|])
let ASetSort = ctx.MkSetSort(ASort)
let xs = ctx.MkConst("xs",ASetSort)
let p = mkPredDecl ctx ("p",[|ASetSort|])
let px = ctx.MkApp(p,xs) :?> BoolExpr
let s = ctx.MkSolver()
s.Assert (ctx.MkAnd(px, ctx.MkNot(ctx.MkEq(xs,ctx.MkEmptySet(ASort)))))
assert (s.Check() = Status.SATISFIABLE)
let xs_interp = s.Model.Eval(xs)
xs_interp

求解器返回一个集合(在这种情况下是单例集{A},但它无关紧要)。我看不出任何实际打印出来的方法。标准ToString()方法简单地说它是一个数组,并且显示模型显示该集合在内部使用查询函数表示。我尝试了以下

let foo xs x =
  let mem= ctx.MkSetMembership(x,xs_interp) :?> BoolExpr
  s.Assert mem
  s.Check()= Status.SATISFIABLE
Array.filter (foo xs) ASort.Consts

它不仅笨重,而且不起作用!我想我可以遍历集合的查询函数表示,但是如果Z3中的集合的表示发生更改,它对我来说似乎不太好,这会破坏我的代码。 API中有什么我缺少的吗?是否可以修改ToString()方法以实际打印设置内容?

1 个答案:

答案 0 :(得分:1)

Z3允许您定义一些集合操作,例如成员资格测试,联合, 依赖于数组理论的交集和空集。 Set Sorts只是布尔数组。 集合操作被编译成数组理论, 这样空集就对应一个假的布尔数组 对域中的所有值。 成员资格测试只是数组选择。 因此,从Z3返回的模型将以数组的形式表示所有内容。

数组模型使用辅助函数是正确的。 这使得遍历变得有点困难。原则上,您可以模式匹配条款 由模型返回(它应该将数组值表示为“(as-array k!32)”术语), 然后你可以遍历模型k!32(或恰好被称为),这是一个 所谓的功能解释。对不起,这不是获取模型的最直接方式 对于有限数组,但表示允许Z3作为函数在数组之间来回传递。

论文:http://academic.research.microsoft.com/Paper/6558823显示了一些集合操作如何表示为数组。