在Inox中使用TypedADT构造

时间:2017-04-12 16:04:41

标签: scala leon

inox文档说明了以下内容

  

Inox提供实用程序类型TypedADTSort和TypedADTConstructor   (参见文件inox / ast / Definitions.scala)对应于ADT   类型参数已使用具体实例化的定义   类型。可以使用它们来访问参数/字段并附上   具有实例化类型的表达式。

以下对象包含建模数学字段所需的排序和构造函数。

import inox._
import inox.trees.{forall => _, _}
import inox.trees.dsl._

import welder._

object Field { 
  /*
    A non trivial field has elements different from zero.
    We can further assume the existence of a nonzero element called one.
    Any other element is of type notOne.

    field -> zero
          -> nonZero -> one
                     -> notOne
  */

  val element = FreshIdentifier("element")
  val zero = FreshIdentifier("zero")
  val nonZero = FreshIdentifier("nonZero")
  val one = FreshIdentifier("one")
  val notOne = FreshIdentifier("notOne")

  val elementADT = mkSort(element)()(Seq(zero, one, nonZero, notOne))
  val nonZeroADT = mkConstructor(nonZero)()(Some(element)) {_ => Seq()}
  val zeroADT = mkConstructor(zero)()(Some(element)) {_ => Seq()}
  val oneADT = mkConstructor(one)()(Some(nonZero)) {_ => Seq()}
  val notOneADT = mkConstructor(notOne)()(Some(nonZero)) {_ => Seq()}


  val symbols = NoSymbols
    .withADTs(Seq(elementADT, nonZeroADT, zeroADT, oneADT, notOneADT))
    .withFunctions(Seq(/*Register functions*/))

  val program = InoxProgram(Context.empty, symbols)

  val theory = theoryOf(program)
  import theory._
}

现在我介绍用于建模椭圆曲线的仿射点的种类和构造。

import inox._
import inox.trees.{forall => _, _}
import inox.trees.dsl._

import welder._

object Curve {

  val F: ADTType = T(Field.element)()
  val affinePoint = FreshIdentifier("affinePoint")
  val infinitePoint = FreshIdentifier("infinitePoint")
  val finitePoint = FreshIdentifier("finitePoint")
  val x = FreshIdentifier("x")
  val y = FreshIdentifier("y")

  val affinePointADT = mkSort(affinePoint)("F")(Seq(infinitePoint,finitePoint))
  val infiniteADT = mkConstructor(infinitePoint)("F")(Some(affinePoint))(_ => Seq())
  val finiteADT = mkConstructor(finitePoint)("F")(Some(affinePoint)){ case Seq(fT) =>
    Seq(ValDef(x, fT), ValDef(y, fT))
  }

  val affine = TypedADTSort(affinePointADT,Seq(F))
  val infinite = TypedADTConstructor(infiniteADT,Seq(F))
  val finite = TypedADTConstructor(finiteADT,Seq(F))

  val symbols = NoSymbols
    .withADTs(Seq(affinePointADT, infiniteADT, finiteADT))
    .withFunctions(Seq(/*Register functions here*/))
}

您可以观察到最后我使用TypedADTSortTypedADTConstructor来使用字段元素作为参数而不是通用参数。我需要这个来讨论关于仿射点的场元素的操作。

编译错误

编译它会产生类型错误

could not find implicit value for parameter symbols: inox.trees.Symbols
[error]   val affine = TypedADTSort(affinePointADT,Seq(F))
[error]                            ^
could not find implicit value for parameter symbols: inox.trees.Symbols
[error]   val infinite = TypedADTConstructor(infiniteADT,Seq(F))

为什么会这样?有什么解决方案?

1 个答案:

答案 0 :(得分:0)

在这种情况下,不需要使用TypedADT构造。只需使用排序和构造函数对以下层次结构进行建模即可。

abstract class Element
abstract class AffinePoint[T]

困难的部分可能是认为AffinePoint[Element]可以使用here中的Inox DSL建模为T(affinePoint)(T(element)())

在任何情况下,我得到的编译错误都是因为我需要将一个隐式参数传递给相应的调用。