Z3和或SMT的通用数据类型建模(v2.6)

Z3和或SMT的通用数据类型建模(v2.6),z3,smt,Z3,Smt,我想在SMT v2.6中对通用数据类型的行为进行建模。我使用Z3作为约束解算器。基于,我以以下方式将通用列表建模为参数化数据类型: (declare-datatypes (T) ((MyList nelem (cons (hd T) (tl MyList))))) (declare-const x (MyList Int)) (declare-const y (MyList Real)) 我希望列表对于数据类型是通用的。稍后,我将以以下方式声明常量: (declare-datatypes (

我想在SMT v2.6中对通用数据类型的行为进行建模。我使用Z3作为约束解算器。基于,我以以下方式将通用列表建模为参数化数据类型:

(declare-datatypes (T) ((MyList nelem (cons (hd T) (tl MyList)))))
(declare-const x (MyList Int))
(declare-const y (MyList Real))
我希望列表对于数据类型是通用的。稍后,我将以以下方式声明常量:

(declare-datatypes (T) ((MyList nelem (cons (hd T) (tl MyList)))))
(declare-const x (MyList Int))
(declare-const y (MyList Real))
但是,现在我想在通用数据类型
MyList
上定义函数(例如,长度操作、空操作等),以便它们可用于所有
T
。你知道我怎样才能做到这一点吗?我确实试过这样的方法:

(declare-sort K)
(define-fun isEmpty ((in (MyList K))) Bool
    (= in nelem)
) 
但这给了我一个错误信息;对于这个例子,我想Z3需要进行一些类型推断


如果你能给我一个提示就太好了

SMT库不允许多态用户定义函数。第4.1.5节规定:

使用排序或术语的命令所需的良好分类检查, 始终针对当前签名执行。这是一个错误 声明或定义已在当前符号中的符号的步骤 签名。这尤其意味着,与理论相反 函数符号,用户定义的函数符号不能重载

脚注-29对此作了进一步扩展:

不重载用户定义符号的动机是简化 通过解算器对其进行处理。此限制仅对以下情况有效: 希望扩展脚本使用的理论签名的用户 使用一个新的多态函数符号,即,其秩 如果是理论符号,则包含参数化排序。例如, 想要在任意列表上声明“反向”函数的用户, 必须为每个(混凝土)定义不同的反向功能符号 列出脚本中使用的排序。此限制可以在中删除 未来版本


因此,正如您所怀疑的,您无法在用户级别定义“多态”函数。但正如脚注所示,这一限制可能会在未来被取消,随着SMT解决方案的广泛部署,这种情况很可能会发生。然而,这可能发生的确切时间是任何人的猜测。

非常感谢您的详尽回答!请注意,您对“MyList”的声明也不正确。看起来Z3让它通过了,但实际上它在语法上是无效的。这里也没有递归。特别是,
nelem
在这里是一个无效的标记。我相信您也必须将
nelem
括起来,并明确地提到参数:类似这样的内容:
(声明数据类型MyList(par(T)((nelem)(cons(hdt)(tl(MyList T);))
)。请参阅《非常感谢》第62页。数据类型声明似乎不适用于Z3(4.5.1)的最新版本,CVC4 4.2.1似乎也不解析它。完全正确。我认为这要么是Z3中的一个bug,要么就是它们还不支持数据类型声明。(注意,数据类型在SMT库中是相当新的)。您应该向他们的问题追踪者询问: