2017-04-14 43 views
0
定义管道符

我曾经在一个领域中的加法运算以下简单求定义:要与中间符号和当前的解决方案,我觉得做使用在焊机

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

object Field { 

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

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

    val addID = FreshIdentifier("add") 

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

    //-------Helper functions for arithmetic operations and zero element of field---------------- 
    implicit class ExprOperands(private val lhs: Expr) extends AnyVal{ 
    def +(rhs: Expr): Expr = E(addID)(T(element)())(lhs, rhs) 
    } 

} 

我想这个操作所以在Scala中给出here。所以这就是为什么我在底部包含隐式类。

现在说我想用另外的定义是:

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

import welder._ 

object Curve{ 

    val affinePoint = FreshIdentifier("affinePoint") 
    val infinitePoint = FreshIdentifier("infinitePoint") 
    val finitePoint = FreshIdentifier("finitePoint") 
    val first = FreshIdentifier("first") 
    val second = FreshIdentifier("second") 
    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(first, fT), ValDef(second, fT)) 
    } 

    val F = T(Field.element)() 
    val affine = T(affinePoint)(F) 
    val infinite = T(infinitePoint)(F) 
    val finite = T(finitePoint)(F) 

    val onCurveID = FreshIdentifier("onCurve") 

    val onCurveFunction = mkFunDef(onCurveID)() { case Seq() => 
    val args: Seq[ValDef] = Seq("p" :: affine, "a" :: F, "b" :: F) 
    val retType: Type = BooleanType 
    val body: Seq[Variable] => Expr = { case Seq(p,a,b) => 
     if_(p.isInstOf(finite)){ 
     val x: Expr = p.asInstOf(finite).getField(first) 
     val y: Expr = p.asInstOf(finite).getField(second) 
     x === y+y 
     } else_ { 
     BooleanLiteral(true) 
     } 
    } 
    (args, retType, body) 
    } 

    //---------------------------Registering elements----------------------------------- 

    val symbols = NoSymbols 
    .withADTs(Seq(affinePointADT, 
        infiniteADT, 
        finiteADT, 
        Field.zeroADT, 
        Field.oneADT, 
        Field.elementADT)) 
    .withFunctions(Seq(Field.addFunction, 

         onCurveFunction)) 

    val program = InoxProgram(Context.empty, symbols) 
    val theory = theoryOf(program) 
    import theory._ 

    val expr = (E(BigInt(1)) + E(BigInt(1))) === E(BigInt(2)) 

    val theorem: Theorem = prove(expr) 

} 

这不会编译给以下错误:

java.lang.ExceptionInInitializerError 
    at Main$.main(Main.scala:4) 
    at Main.main(Main.scala) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
Caused by: inox.ast.TypeOps$TypeErrorException: Type error: if (p.isInstanceOf[finitePoint[element]]) { 
    p.asInstanceOf[finitePoint[element]].first == p.asInstanceOf[finitePoint[element]].second + p.asInstanceOf[finitePoint[element]].second 
} else { 
    true 
}, expected Boolean, found <untyped> 
    at inox.ast.TypeOps$TypeErrorException$.apply(TypeOps.scala:24) 
    at inox.ast.TypeOps$class.typeCheck(TypeOps.scala:264) 
    at inox.ast.SimpleSymbols$SimpleSymbols.typeCheck(SimpleSymbols.scala:12) 
    at inox.ast.Definitions$AbstractSymbols$$anonfun$ensureWellFormed$2.apply(Definitions.scala:166) 
    at inox.ast.Definitions$AbstractSymbols$$anonfun$ensureWellFormed$2.apply(Definitions.scala:165) 
    at scala.collection.TraversableLike$WithFilter$$anonfun$foreach$1.apply(TraversableLike.scala:733) 
    at scala.collection.immutable.Map$Map2.foreach(Map.scala:137) 
    at scala.collection.TraversableLike$WithFilter.foreach(TraversableLike.scala:732) 
    at inox.ast.Definitions$AbstractSymbols$class.ensureWellFormed(Definitions.scala:165) 
    at inox.ast.SimpleSymbols$SimpleSymbols.ensureWellFormed$lzycompute(SimpleSymbols.scala:12) 
    at inox.ast.SimpleSymbols$SimpleSymbols.ensureWellFormed(SimpleSymbols.scala:12) 
    at inox.solvers.unrolling.AbstractUnrollingSolver$class.assertCnstr(UnrollingSolver.scala:129) 
    at inox.solvers.SolverFactory$$anonfun$getFromName$1$$anon$1.inox$tip$TipDebugger$$super$assertCnstr(SolverFactory.scala:115) 
    at inox.tip.TipDebugger$class.assertCnstr(TipDebugger.scala:52) 
    at inox.solvers.SolverFactory$$anonfun$getFromName$1$$anon$1.assertCnstr(SolverFactory.scala:115) 
    at inox.solvers.SolverFactory$$anonfun$getFromName$1$$anon$1.assertCnstr(SolverFactory.scala:115) 
    at welder.Solvers$class.prove(Solvers.scala:51) 
    at welder.package$$anon$1.prove(package.scala:10) 
    at welder.Solvers$class.prove(Solvers.scala:23) 
    at welder.package$$anon$1.prove(package.scala:10) 
    at Curve$.<init>(curve.scala:61) 
    at Curve$.<clinit>(curve.scala) 
    at Main$.main(Main.scala:4) 
    at Main.main(Main.scala) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 

事实上,正在发生的事情是,在表达x === y + y +未正确应用,因此它是无类型的。我记得在焊接证明的对象内部,我们不能定义嵌套的对象或类,我不知道这是否与它有关。

不管怎么说,我必须忘记在我的代码中使用中缀符号吗?或者有解决方案吗?

回答

1

这里的问题是,当您创建y+y(您需要导入Field._以使其可见时),您定义的隐式类不可见。

我不记得分辨率究竟如何隐含发生在Scala中,所以可能增加import Field._曲线对象将覆盖来自INOX DSL(这是正在应用的一个,当你写y+y,给人+你需要一个算术加表达式,它需要整型参数,因此类型错误)。否则,你将不幸地在隐式解析中含糊不清,我不确定在没有放弃整个dsl的情况下可以使用中缀+运算符。