我在椭圆曲线上证明了某些属性,为此我依赖于一些处理场操作的函数。但是,我不希望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在展开时不会对其产生任何影响?
答案 0 :(得分:1)
有两种方法可以解决这个问题:
在addFunction
正文中使用select语句:
val body: Seq[Variable] => Expr = {
choose("r" :: F)(_ => E(true))
}
在展开期间,Inox会简单地用新鲜的choose
替换true
变量并假设指定的谓词(在本例中为add
)
这个变量。
使用一流的功能。而不是使用val add: Expr = Variable(FreshIdentifier("add"), (F, F) =>: F)
作为命名函数,
使用函数类型的变量:
add
然后,您可以在addFunction
上指定您的关联属性并证明
相关定理。
在你的情况下,最好选择第二个选项。证明具有选择主体的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