在Inox中建模类层次结构

时间:2017-04-15 12:08:20

标签: leon

我想在Inox求解器界面中建模以下Scala层次结构:

abstract class Element()
abstract class nonZero() extends Element
final case class Zero() extends Element
final case class One() extends nonZero()
final case class notOne() extends nonZero()

如何为nonZero建模?

如果我将其建模为构造函数

def mkConstructor(id: Identifier, flags: Flag*)
                 (tParamNames: String*)
                 (sort: Option[Identifier])
                 (fieldBuilder: Seq[TypeParameter] => Seq[ValDef]) = {
  val tParams = tParamNames map TypeParameter.fresh
  val tParamDefs = tParams map (TypeParameterDef(_))
  val fields = fieldBuilder(tParams)
  new ADTConstructor(id, tParamDefs, sort, fields, flags.toSet)
}

然后我无法指定它有其他构造函数扩展它。如果我把它建模为一种类型:

def mkSort(id: Identifier, flags: Flag*)
          (tParamNames: String*)
          (cons: Seq[Identifier]) = {
  val tParams = tParamNames map TypeParameter.fresh
  val tParamDefs = tParams map (TypeParameterDef(_))
  new ADTSort(id, tParamDefs, cons, flags.toSet)
}

然后我不能指定它是Element的子类型。

为什么我需要

我需要这个层次结构,因为我需要声明属性:

  

字段的非零元素集合,一个,反向和   乘以非零元素形成一个组。

然后我需要一些机制来生成一个类型来限制排序的构造函数,在这种情况下,将Element的构造函数限制为OnenotZeroOne()。在那种情况下,我会建模:

abstract class Element()
final case class Zero() extends Element
final case class One() extends Element()
final case class notZeroOne() extends Element()

对此最干净的解决方案是什么?

1 个答案:

答案 0 :(得分:1)

不幸的是,"类层次结构" Inox仅限于具有一系列具体构造函数的单个抽象父级(构造函数之间不可进行子类型化)。此限制反映了对基础SMT求解器支持的代数数据类型理论的限制。

如果要在非零元素上声明属性,为什么不使用(elem !== Zero()) ==> someProperty形式的含义?请注意,通常,您可以通过详尽枚举允许的构造函数的具体谓词来模拟上面提出的nonZero()类型。例如,

def nonZero(e: Expr): Expr = e.isInstOf(T(one)()) || e.isInstOf(T(notOne)())

然后,您可以使用nonZero(e) ==> property(e)来声明非零元素的属性。