在Inox / Welder中证明套件的性能

时间:2017-03-25 00:44:13

标签: scala formal-verification leon

我想在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吗?

1 个答案:

答案 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中可用的不同结构的详尽列表,请查看Inox中的Expressions文件。