如何在Inox中声明一个抽象函数

时间:2017-04-16 15:22:18

标签: leon

我在椭圆曲线上证明了某些属性,为此我依赖于一些处理场操作的函数。但是,我不希望Inox推断这些功能的实现,而只是假设它们具有某些属性。

比方说,我证明点p1 = (x1,y1) and p2 = (x2,y2)的加法是可交换的。为了实现点的添加,我需要一个在其组件上实现加法的函数(即字段的元素)。

添加将具有以下形状:

val addFunction = mkFunDef(addID)() { case Seq() => 
    val args: Seq[ValDef] = Seq("f1" :: F, "f2" :: F)  
    val retType: Type = F
    val body: Seq[Variable] => Expr = { case Seq(f1,f2) =>
      //do the addition for this field
    } 
    (args, retType, body)
}

对于这个功能,我可以声明属性,如:

val addAssociative: Expr = forall("x" :: F, "y" :: F, "z" :: F){ case (x, y, z) => 
    (x ^+ (y ^+ z)) === ((x ^+ y) ^+ z)
}

其中^+只是与this其他问题中显示的添加相对应的中缀运算符。

在正文中插入什么是正确的表达式,以便Inox在展开时不会对其产生任何影响?

1 个答案:

答案 0 :(得分:1)

有两种方法可以解决这个问题:

  1. addFunction正文中使用select语句:

    val body: Seq[Variable] => Expr = {
      choose("r" :: F)(_ => E(true))
    }
    

    在展开期间,Inox会简单地用新鲜的choose替换true 变量并假设指定的谓词(在本例中为add) 这个变量。

  2. 使用一流的功能。而不是使用val add: Expr = Variable(FreshIdentifier("add"), (F, F) =>: F) 作为命名函数, 使用函数类型的变量:

    add

    然后,您可以在addFunction上指定您的关联属性并证明 相关定理。

  3. 在你的情况下,最好选择第二个选项。证明具有选择主体的add的事情的问题在于,你不能用val thm = forallI("add" :: ((F,F) =>: F)) { add => implI(isAssociative(add)) { isAssoc => someProperty } } 替换你所展示的定理中的其他函数。但是,由于第二个选项只显示有关自由变量的内容,因此您可以使用具体的函数实现来实例化您的定理。

    你的定理看起来像是:

    val isAssocAdd: Theorem = ... /* prove associativity of concreteAdd */
    val somePropertyForAdd = implE(
      forallE(thm)(\("x" :: F, "y" :: F)((x,y) => E(concreteAdd)()(x, y))), 
      isAssocAdd
    )
    

    您可以通过

    实例化它
    step