Java Z3找到的模型中集合的值

Java Z3找到的模型中集合的值,java,z3,smt,Java,Z3,Smt,我有一个类似于这里的问题: 从中我不知道如何在模型中打印集合的值。我有一个枚举排序(Java代码): EnumSort rSort=ctx.mkEnumSort(ctx.mkSymbol(“res”)、ctx.mkSymbol(“res1”) 我从中创建了一个集合排序: SetSort rSet=ctx.mkSetSort(rSort) 通过使用此集合排序,我创建了一个Z3常量rID,并定义了一个简单的成员表达式: BoolExpr c1=(BoolExpr)ctx.mkSetMemb

我有一个类似于这里的问题: 从中我不知道如何在模型中打印集合的值。我有一个枚举排序(Java代码):

  • EnumSort rSort=ctx.mkEnumSort(ctx.mkSymbol(“res”)、ctx.mkSymbol(“res1”)
我从中创建了一个集合排序:

  • SetSort rSet=ctx.mkSetSort(rSort)
通过使用此集合排序,我创建了一个Z3常量rID,并定义了一个简单的成员表达式:

  • BoolExpr c1=(BoolExpr)ctx.mkSetMembership(rSort.getConsts()[0],rID)
当c1是可满足的时,我希望看到模型中rID的一个可能值。如果我尝试使用常量解释(即m.GetContinterp(e),其中e是模型中的FuncDecl),我会得到:“非零算术函数和数组将函数解释作为模型。使用FuncInterp。”


当我尝试func解释(即m.getFuncInterp(e))时,我得到“参数不是数组常量”。我做错什么了吗?难道不能打印set对象的值吗?或者,有没有更好的方法来表示可能包含排序中的多个值的变量?

集合在内部由数组表示,而数组又具有作为模型的功能。GetContinterp失败,因为
rID
是set类型(内部数组类型),它会引发相应的异常。从示例中不清楚
e
是什么,但下面是一个如何获取rID的FuncInterp的示例:

Context ctx = new Context(cfg);

EnumSort rSort = ctx.mkEnumSort(ctx.mkSymbol("res"), ctx.mkSymbol("res1"));
SetSort rSet = ctx.mkSetSort(rSort);
Expr rID = ctx.mkConst("rID", rSet);
BoolExpr c1 = (BoolExpr)ctx.mkSetMembership(rSort.getConsts()[0], rID);

Solver s = ctx.mkSolver();
s.add(c1);
Status status = s.check();
Model m = s.getModel();

System.out.println(status);
System.out.println("Model = " + m);

FuncInterp fi = m.getFuncInterp(rID.getFuncDecl());
System.out.println("fi="+ fi);

请注意,对
getFuncInterp
的调用获取常量rID的FuncDecl,这可能是混淆的原因。

这很有效,谢谢!我意识到,如果我显式地将解算器设置为QF_LIA,我就会得到那个错误。我没有仔细考虑为什么,但我假设集合变量在LIA中不起作用。另一个与处理集合有关的问题是,集合上是否有基数约束的实现?这里()我看到有一个Scala实现,但我不确定Z3的其他实现中是否有。