我想在Inox / Welder上证明集合的某些属性,但我缺少帮助我弄清楚如何执行此操作的示例。说我想证明:
内容(y :: xs).contains(x)&& x!= y ==>含量(XS)。载(x)的
我定义了属性:
def property(xs: Expr) =
forall("x"::A,"y"::A){case (x,y)
content(ConsA(y,xs)).contains(x) && x !== y ==> content(xs).contains(x)
}
但事实证明这个属性不会编译,因为它没有很好地表达(显然错误的部分是.contains,&&,!== ...)
那么,制定财产的正确方法是什么?在这里,我假设我有一个内容函数定义为:
val contentFunction = mkFunDef(contentID)("A") { case Seq(aT) => (
Seq("l" :: T(list)(aT)), SetType(aT), { case Seq(l) =>
if_ (l.isInstOf(T(cons)(aT))) {
SetAdd(E(contentID)(aT)(l.asInstOf(T(cons)(aT)).getField(tail)), l.asInstOf(T(cons)(aT)).getField(head))
} else_ {
FiniteSet(Seq.empty, aT)
}
})
}
关于证明部分想象我给了函数:
def without(x: A, xs: List[A]) = xs match{
case Nil() => Nil()
case y :: ys if(x == y) => without(x,ys)
case y :: ys if(x != y) => y :: without(x,ys)
}
应该从列表xs中删除x并说我要证明
内容(不含(x,l))== content(l) - Set(x)
你能描述一下怎么做吗?我应该使用BuiltInNames,例如SetDifference吗?
答案 0 :(得分:1)
您看到的编译错误可能来自您在制作财产时case
之后的遗失箭头。另外,请务必使用content
的正确标识符。
def property(xs: Expr) =
forall("x"::A,"y"::A) { case (x,y) =>
contentID(ConsA(y,xs)).contains(x) && x !== y ==> contentID(xs).contains(x)
}
否则,使用Inox DSL正确编码该属性。
关于证明本身,它认为without
函数不是完全必要的。证明应该通过列表xs
上的结构归纳顺利进行。
structuralInduction(property(_), "xs" :: T(List)(A)) { case (ihs, goal) =>
ihs.expression match {
case C(`Cons`, head, tail) => // Your case for Cons here.
case C(`Nil`) => // Your case for Nil here.
}
}
ListAndTrees展示了许多此类证明。
BuiltInName
关于BuiltInNames
类,它用于当前在Welder中开发的Inox表达式的解析器中。很可能很快就会将这个项目放在一个单独的项目中。
此解析器在Welder中使用,因此您可以使用更友好的语法编写Inox表达式。例如,您的财产可以表示为:
def property(xs: Expr) =
e"forall x, y. contains(content(Cons(y, $xs)), x) && x != y ==> contains(content($xs), x)"
最后一点。如果您正在寻找Inox中可用的不同结构的详尽列表,请查看Inox中的Expressions文件。