Z3 量化公式的奇怪结果

Z3 量化公式的奇怪结果,z3,Z3,当我使用ForAll量词时,我得到了一些奇怪的结果。我的目标是将函数foo的解释限制为以下内容: \Ax,y. foo(x,y)= if x=A && y=B then C1 else C2 因此,如果我在上下文中断言上述内容,我应该得到一个对foo的解释,它本质上等同于上述内容。但是我没有。我得到的回报是 foo(x,y)= if x=A && y=B then C1 else C1 我不知道为什么。我使用的代码如下(通过.NETAPI访问Z3) 其中get

当我使用ForAll量词时,我得到了一些奇怪的结果。我的目标是将函数foo的解释限制为以下内容:

\Ax,y. foo(x,y)= if x=A && y=B then C1 else C2
因此,如果我在上下文中断言上述内容,我应该得到一个对foo的解释,它本质上等同于上述内容。但是我没有。我得到的回报是

foo(x,y)= if x=A && y=B then C1 else C1
我不知道为什么。我使用的代码如下(通过.NETAPI访问Z3)

其中
getZ3Id
将给定字符串转换为枚举中的相应常量

let getZ3Id (id,sort:EnumSort) = 
  let matchingConst zconst = zconst.ToString().Equals(id)
  Array.find matchingConst sort.Consts
满足
是:

let satisfy (s:Solver) formula =
    s.Assert (formula)
    let res = s.Check() 
    assert (res = Status.SATISFIABLE)
    s.Model
模型返回对foo的解释,无论发生什么情况,该解释都返回C1

(define-fun foo ((x!1 S1) (x!2 S2)) S3
  (ite (and (= x!1 A) (= x!2 B)) C1
    C1))
有人能指出我错在哪里吗? 谢谢 另外,对MkForAll的两个API调用之间有什么区别?一个调用排序和名称,另一个调用“绑定常量”


这是我进一步的问题: 如果我定义

let set1 = Set.map (fun (p:string)-> ctx.MkConst(p,Sort3)) 
                   (new Set<string>(["C1"]))
在哪里

let mkZ3Set (ctx:Context) exprs sort =
  Set.fold (fun xs x-> ctx.MkSetAdd(xs,x)) (ctx.MkEmptySet(sort)) exprs
Z3公式看起来是合理的

form= (forall ((s1 S1))
  (= (foo s1)
     (ite (and (= s1 A))
          (store ((as const (Array S3 Bool)) false) C1 true)
          ((as const (Array S3 Bool)) false))))

然而,Z3的回报并不令人满意。你能告诉我为什么吗?

问题在于量词的抽象。它不会抽象出您想要的变量

 let form = ctx.MkForall(types, names, body, std_weight, null, null, null, null) 
       :> BoolExpr
应改为:

 let form = ctx.MkForall(vars, body, std_weight, null, null, null, null) 
       :> BoolExpr
背景是Z3公开了两种不同的方法来量化变量

选项1:可以抽象公式中出现的常量。您应该将这些常量的数组传递给量词抽象。这是我更正时使用的版本


选项2:您可以提取公式中自由出现的de Brujin索引。然后可以使用示例中使用的ctx.MkForall重载。但它要求每当引用绑定变量时,都要使用绑定索引(使用ctx.MkBound创建的索引)。

问题在于量词抽象。它不会抽象出您想要的变量

 let form = ctx.MkForall(types, names, body, std_weight, null, null, null, null) 
       :> BoolExpr
应改为:

 let form = ctx.MkForall(vars, body, std_weight, null, null, null, null) 
       :> BoolExpr
背景是Z3公开了两种不同的方法来量化变量

选项1:可以抽象公式中出现的常量。您应该将这些常量的数组传递给量词抽象。这是我更正时使用的版本


选项2:您可以提取公式中自由出现的de Brujin索引。然后可以使用示例中使用的ctx.MkForall重载。但它要求每当引用绑定变量时,都使用绑定索引(使用ctx.MkBound创建的索引)。

是的,这看起来很奇怪。我正在调查。好的,谢谢。但我现在还有一个问题。如果我将Foo的返回类型更改为Sort3的集合,而不是Sort3,并将约束更改为返回某个集合,那么它将变得不可满足,而且我也不知道为什么。Unf。S/O不允许您在回复框中进行太多格式化,因此我“回答了我自己的问题”。请看一看,我正要澄清Z3不会返回不满意但未知的结果。我想我的问题可能与MBQI有关,需要打开它。但是,我不知道如何通过API实现这一点。(Z3主文档页面关闭了,一些类的链接也关闭了,比如
STATUS
。我已经在codeplex上提交了一份错误报告)。《用户指南》介绍了如何仅为SMTLIB InterfaceEyes打开它,这看起来很奇怪。我正在调查。好的,谢谢。但我现在还有一个问题。如果我将Foo的返回类型更改为Sort3的集合,而不是Sort3,并将约束更改为返回某个集合,那么它将变得不可满足,而且我也不知道为什么。Unf。S/O不允许您在回复框中进行太多格式化,因此我“回答了我自己的问题”。请看一看,我正要澄清Z3不会返回不满意但未知的结果。我想我的问题可能与MBQI有关,需要打开它。但是,我不知道如何通过API实现这一点。(Z3主文档页面关闭了,一些类的链接也关闭了,比如
STATUS
。我已经在codeplex上提交了一份错误报告)。《用户指南》介绍了如何仅为SMTLIB接口打开它