diff --git a/.travis.yml b/.travis.yml index cdd5421f0d..db05759cbc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,31 +1,42 @@ sudo: required dist: trusty - -# Tricks to avoid unnecessary cache updates before_cache: - - find $HOME/.sbt -name "*.lock" | xargs rm - - find $HOME/.ivy2 -name "ivydata-*.properties" | xargs rm - -# These directories are cached to S3 at the end of the build +- find $HOME/.sbt -name "*.lock" | xargs rm +- find $HOME/.ivy2 -name "ivydata-*.properties" | xargs rm cache: directories: - - $HOME/.ivy2/cache - - $HOME/.sbt + - "$HOME/.ivy2/cache" + - "$HOME/.sbt" language: scala - jdk: - - oraclejdk9 - -script: - - sbt -jvm-opts .travis.jvmopts test -# enable scoverage after SpamSpecification timeout issue is resolved -# - sbt -jvm-opts .travis.jvmopts coverage test - -after_success: -# - sbt coverageReport coveralls - - sbt -jvm-opts .travis.jvmopts publish - +- oraclejdk8 +stages: +- test +# - coverage +- name: release + if: tag =~ ^v +- name: snapshot + if: NOT tag IS present +jobs: + include: + - stage: test + script: sbt -jvm-opts .travis.jvmopts test + # enable scoverage after SpamSpecification timeout issue is resolved + # script: sbt -jvm-opts .travis.jvmopts coverage test +# - stage: coverage +# script: sbt coverageReport coveralls + - stage: release + script: sbt -jvm-opts .travis.jvmopts publishSigned sonatypeBundleRelease + - stage: snapshot + script: sbt -jvm-opts .travis.jvmopts publish env: global: - secure: IGwd+lY2TfkAeX1SfzaYBwyhiiPaFrTxoF0e+4R1bkGxiGCce1hBYjn15z1HRfK+k3hgEZh/FBG7dv8LQfNWQ6AJY5PQ2zwckd4ArYMhTVpiY4eRzUMqO1/gjTCCbbTjfFKOMsR2pAw+TGeglqoX4eyziIaS8nR901dZcFvHuC1Fr5EdKFZ0x+WHnX8vaSQoDE4u1MoBnyo5cRVumXG+xvs1Q0nZXm/hd/Flfx5u3L7veKAkGtvbHmdsJoSSySTbc1MGYQtofQjbjd9AVvUhgfP32J63UCC2SqgWWKVvIjW+dUn414BV3lelnWR3FdzhC7AUJqYWVfSILh1aj3STnizRnjtCScmyoRz4ldUQ3jr4jBJOREUEus5YH2EqY1MGjX+8kUu9IjDYiQyNy1EdivcmMlXCOcAW2mi4rGDRxZOeFt1ZSHzxqSghZOFwvk/OFcdDzV4/3OnAcGz8LH5qjZU/edjmfkSls5CqxuAFqeD7RZWIu0ccjt6dzQZAf02lBX9kQuwIruC4x4E0iEjml7jmaEeOT4Hqk7wAo6EFMSEkj4EnS/Kln6Wr7JBut5qrMk0+PDgvxaKCaN8LeycCSQdoXfPO602WzfasNcOJexSmGMAE5NYfeXjq1h3F9AVHJ3TbNAOdlQTHbSOqt7WO10JphljYnFEu4aSzvaA3E60= - secure: g4Egz1orKgCAgTckMYHHbpsFY8ppldLLUkBi0GasHN4M2zhfYlqzaJ+ZZ4soMPNshcS3XutGS+/ERF5zrnHF1C9h3txW6AJkgMkTF1q4UyKan25chdPnz1nNUrdQOvaCA4CzLIN3aQAHN40p44ELxfNTARTfbUAIcqNSrKmXZsUbhQg9yyM+gFL6cCw7SYQphC9GJq4mvW19dzzpU8MQ0AtktB6mscuUyiWgniHsnFAmeQBv0csCiMyjUsT1buIkO0gSvZBKkLXu7kXhash/mLjrBYGapVGGFORA3pWy9JCB9OfxV8Bj1wNUqPyAImjGgVfgK6RxOnQ/C4GTsf8uVH/sYIiPnzPmbCrO7fQee68/+SWtZc1kko8HuiqHvouNHmKQy+Hwku2AIdp6nZDhOuFtQTP1PbkYLrdNj1evAI6913rq51e7vDWTriWmOKjMz2m4Tj2HGJx0VS0pNOZkpxwVhHOdyc1UXurpBKgkYis1HVcaEM3trFzhsMf7kllNvJLA1COwg7KbVebKwA9gXfYrKAp6p76YMaSYodSDq9VaSDPF/2MVCZYXs+FAUZ3MzcsAZ7TegSX2OWrrneGArjcQgdMLUetm+UgBFZF7pG3BpjMLVwMgp9ulUNkq1sP1vLU08cvQv6A3W/kcyrVyCNzg80XTQqDpxz7hCTbyBSw= + - secure: gfhEv/PXEckwZPnwJHl4fBCJKCrCKK4KMeYCPNZZtKuV1gC4mZscvECm8r+kgB+o2G3i4tEIYcIC5Jbdcbjf4bk6uNZW/X3dna0irl/Mdswt7rTLzLan1rPz3k8Bylgs8ehETFBGr8HyNitEa8ODyaEXa84MPQaucXUmpHS+sUEhQn0Z70T70d1H9ZubUhGv9VLltNoSWkPGW5CPZlpQTHl63ZShfmylfQuQVTbVMdL8LLUHn2x2edlDKMGD8YPH5d+of0AKc3IKnlnMM36WjgYVsf1yehfLi0NH/b2Dzk7wLjetu/bw8Cu9Ne6/u0Lu83Hbh4DyS2iPQivDUGB+JXlHDFI4uji3GurnvpFDku1gbc4HVoFqhgOWyXQAiRllj2BXmq2vwp6797TUG4HrD2EVzIJV7eIZdWNN/QttZtNxNdSbBq8QQc92G2SU4q7PcogMSr0LpX05SfyL1sMgX2WeGzFzyMIu/+rAJhG0lPt7krBxEfQrRtTLdJ9eyeFjFQlxM6G/9gk68j+Nida6KunLwe9QEl2T+t1YbE4i9pndoCMJFxAOjirhw5OM3PfSWfb/mU7zXd4PSNK7RQIdOaPJff5C6UEM7h/iQ6riRZp1Pn7d/rxppTXsvUbtvwUYnkoOeUZyMvQNQsPI6Slns8jWl0zp5XiTmzSRVOuH3ME= +# decrypt the private key (exported via https://docs.scala-lang.org/overviews/contributors/index.html#export-your-pgp-key-pair ) +before_install: +- openssl aes-256-cbc -K $encrypted_98cf3af00429_key -iv $encrypted_98cf3af00429_iv + -in ci/secring.asc.enc -out ci/secring.asc -d +# import decrypted private key +before_script: gpg --import ci/secring.asc \ No newline at end of file diff --git a/build.sbt b/build.sbt index 821f27969f..e1b62c16dc 100644 --- a/build.sbt +++ b/build.sbt @@ -14,11 +14,8 @@ lazy val commonSettings = Seq( resolvers += Resolver.sonatypeRepo("public"), licenses := Seq("CC0" -> url("https://creativecommons.org/publicdomain/zero/1.0/legalcode")), homepage := Some(url("https://github.com/ScorexFoundation/sigmastate-interpreter")), + description := "Interpreter of a Sigma-State language", pomExtra := - - git@github.com:ScorexProject/scrypto.git - git@github.com:ScorexFoundation/sigmastate-interpreter.git - kushti @@ -30,14 +27,14 @@ lazy val commonSettings = Seq( Alexander Slesarenko https://github.com/aslesarenko/ + + greenhat + Denys Zadorozhnyi + https://github.com/greenhat/ + , publishMavenStyle := true, - publishTo := { - val nexus = "https://oss.sonatype.org/" - if (isSnapshot.value) { Some("snapshots" at nexus + "content/repositories/snapshots") } - else { Some("releases" at nexus + "service/local/staging/deploy/maven2") } - } - + publishTo := sonatypePublishToBundle.value, ) enablePlugins(GitVersioning) @@ -76,27 +73,24 @@ val scrypto = "org.scorexfoundation" %% "scrypto" % "2.1.6" val scorexUtil = "org.scorexfoundation" %% "scorex-util" % "0.1.4" val macroCompat = "org.typelevel" %% "macro-compat" % "1.1.1" val paradise = "org.scalamacros" %% "paradise" % "2.1.0" cross CrossVersion.full +val debox = "org.spire-math" %% "debox" % "0.8.0" +val kiama = "org.bitbucket.inkytonik.kiama" %% "kiama" % "2.1.0" +val fastparse = "com.lihaoyi" %% "fastparse" % "1.0.0" +val commonsIo = "commons-io" % "commons-io" % "2.5" +val configs = "com.github.kxbmap" %% "configs" % "0.4.4" -val specialVersion = "master-5136809e-SNAPSHOT" -val specialCommon = "io.github.scalan" %% "common" % specialVersion -val specialCore = "io.github.scalan" %% "core" % specialVersion -val specialLibrary = "io.github.scalan" %% "library" % specialVersion - +val specialVersion = "0.6.1" val meta = "io.github.scalan" %% "meta" % specialVersion val plugin = "io.github.scalan" %% "plugin" % specialVersion -val libraryapi = "io.github.scalan" %% "library-api" % specialVersion -val libraryimpl = "io.github.scalan" %% "library-impl" % specialVersion val libraryconf = "io.github.scalan" %% "library-conf" % specialVersion val testingDependencies = Seq( "org.scalatest" %% "scalatest" % "3.0.5" % "test", "org.scalactic" %% "scalactic" % "3.0.+" % "test", "org.scalacheck" %% "scalacheck" % "1.14.+" % "test", + "com.storm-enroute" %% "scalameter" % "0.8.2" % Test, "junit" % "junit" % "4.12" % "test", "com.novocode" % "junit-interface" % "0.11" % "test", - specialCommon, (specialCommon % Test).classifier("tests"), - specialCore, (specialCore % Test).classifier("tests"), - specialLibrary, (specialLibrary % Test).classifier("tests"), ) lazy val testSettings = Seq( @@ -113,22 +107,18 @@ libraryDependencies ++= Seq( scorexUtil, "org.bouncycastle" % "bcprov-jdk15on" % "1.+", "com.typesafe.akka" %% "akka-actor" % "2.4.+", - "org.bitbucket.inkytonik.kiama" %% "kiama" % "2.1.0", - "com.lihaoyi" %% "fastparse" % "1.0.0", - "org.spire-math" %% "debox" % "0.8.0" + kiama, fastparse, debox ) ++ testingDependencies val circeVersion = "0.10.0" +val circeCore = "io.circe" %% "circe-core" % circeVersion +val circeGeneric = "io.circe" %% "circe-generic" % circeVersion +val circeParser = "io.circe" %% "circe-parser" % circeVersion -libraryDependencies ++= Seq( - "io.circe" %% "circe-core", - "io.circe" %% "circe-generic", - "io.circe" %% "circe-parser" -).map(_ % circeVersion) +libraryDependencies ++= Seq( circeCore, circeGeneric, circeParser ) scalacOptions ++= Seq("-feature", "-deprecation") - // set bytecode version to 8 to fix NoSuchMethodError for various ByteBuffer methods // see https://github.com/eclipse/jetty.project/issues/3244 // these options applied only in "compile" task since scalac crashes on scaladoc compilation with "-release 8" @@ -144,71 +134,153 @@ publishArtifact in Test := true pomIncludeRepository := { _ => false } -credentials += Credentials(Path.userHome / ".sbt" / ".sigma-sonatype-credentials") +val credentialFile = Path.userHome / ".sbt" / ".sigma-sonatype-credentials" +credentials ++= (for { + file <- if (credentialFile.exists) Some(credentialFile) else None +} yield Credentials(file)).toSeq credentials ++= (for { username <- Option(System.getenv().get("SONATYPE_USERNAME")) password <- Option(System.getenv().get("SONATYPE_PASSWORD")) } yield Credentials("Sonatype Nexus Repository Manager", "oss.sonatype.org", username, password)).toSeq + +// PGP key for signing a release build published to sonatype +// signing is done by sbt-pgp plugin +// how to generate a key - https://central.sonatype.org/pages/working-with-pgp-signatures.html +// how to export a key and use it with Travis - https://docs.scala-lang.org/overviews/contributors/index.html#export-your-pgp-key-pair +pgpPublicRing := file("ci/pubring.asc") +pgpSecretRing := file("ci/secring.asc") +pgpPassphrase := sys.env.get("PGP_PASSPHRASE").map(_.toArray) +usePgpKeyHex("28E27A67AEA38DA458C72228CA9254B5E0640FE4") + def libraryDefSettings = commonSettings ++ testSettings ++ Seq( scalacOptions ++= Seq( -// s"-Xplugin:${file(".").absolutePath }/scalanizer/target/scala-2.12/scalanizer-assembly-better-costing-2a66ed5c-SNAPSHOT.jar" +// s"-Xplugin:${file(".").absolutePath }/scalanizer/target/scala-2.12/scalanizer-assembly-core-opt-0d03a785-SNAPSHOT.jar" ) ) +lazy val common = Project("common", file("common")) + .settings(commonSettings ++ testSettings, + libraryDependencies ++= Seq( + "org.scala-lang" % "scala-reflect" % scalaVersion.value, + debox, commonsIo + )) + .settings(publish / skip := true) + +lazy val libraryapi = Project("library-api", file("library-api")) + .dependsOn(common % allConfigDependency) + .settings(libraryDefSettings :+ addCompilerPlugin(paradise), + libraryDependencies ++= Seq( + )) + .settings(publish / skip := true) + +lazy val libraryimpl = Project("library-impl", file("library-impl")) + .dependsOn(libraryapi % allConfigDependency) + .settings(libraryDefSettings, + libraryDependencies ++= Seq( debox )) + .settings(publish / skip := true) + +lazy val core = Project("core", file("core")) + .dependsOn(common % allConfigDependency, libraryapi % allConfigDependency) + .settings(commonSettings, + libraryDependencies ++= Seq( configs, debox )) + .settings(publish / skip := true) + +lazy val library = Project("library", file("library")) + .dependsOn(common % allConfigDependency, core % allConfigDependency, libraryapi, libraryimpl) + .settings(//commonSettings, + libraryDefSettings ++ testSettings, + libraryDependencies ++= Seq( debox )) + .settings(publish / skip := true) + lazy val sigmaconf = Project("sigma-conf", file("sigma-conf")) - .settings(commonSettings, - libraryDependencies ++= Seq( - plugin, libraryconf - )) + .settings(commonSettings, + libraryDependencies ++= Seq( + plugin, libraryconf + )) + .settings(publish / skip := true) lazy val scalanizer = Project("scalanizer", file("scalanizer")) - .dependsOn(sigmaconf) - .settings(commonSettings, - libraryDependencies ++= Seq(meta, plugin, libraryapi, libraryimpl), -// publishArtifact in(Compile, packageBin) := false, - assemblyOption in assembly ~= { _.copy(includeScala = false, includeDependency = true) }, - artifact in(Compile, assembly) := { - val art = (artifact in(Compile, assembly)).value - art.withClassifier(Some("assembly")) - }, - addArtifact(artifact in(Compile, assembly), assembly) - ) + .dependsOn(sigmaconf, libraryapi, libraryimpl) + .settings(commonSettings, + libraryDependencies ++= Seq(meta, plugin), + assemblyOption in assembly ~= { _.copy(includeScala = false, includeDependency = true) }, + assemblyMergeStrategy in assembly := { + case PathList("scalan", xs @ _*) => MergeStrategy.first + case other => (assemblyMergeStrategy in assembly).value(other) + }, + artifact in(Compile, assembly) := { + val art = (artifact in(Compile, assembly)).value + art.withClassifier(Some("assembly")) + }, + addArtifact(artifact in(Compile, assembly), assembly) + ) + .settings(publish / skip := true) lazy val sigmaapi = Project("sigma-api", file("sigma-api")) - .settings(libraryDefSettings :+ addCompilerPlugin(paradise), - libraryDependencies ++= Seq( - specialCommon, libraryapi, macroCompat, scrypto, bouncycastleBcprov - )) + .dependsOn(common, libraryapi) + .settings(libraryDefSettings :+ addCompilerPlugin(paradise), + libraryDependencies ++= Seq( + macroCompat, scrypto, bouncycastleBcprov + )) + .settings(publish / skip := true) lazy val sigmaimpl = Project("sigma-impl", file("sigma-impl")) - .dependsOn(sigmaapi % allConfigDependency) - .settings(libraryDefSettings, - libraryDependencies ++= Seq( - libraryapi, libraryimpl, scrypto, bouncycastleBcprov - )) + .dependsOn( + sigmaapi % allConfigDependency, + libraryapi % allConfigDependency, + libraryimpl % allConfigDependency, + library % allConfigDependency) + .settings(libraryDefSettings, + libraryDependencies ++= Seq( scrypto, bouncycastleBcprov )) + .settings(publish / skip := true) lazy val sigmalibrary = Project("sigma-library", file("sigma-library")) - .dependsOn(sigmaimpl % allConfigDependency) - .settings(libraryDefSettings, - libraryDependencies ++= Seq( - specialCommon, (specialCommon % Test).classifier("tests"), - specialCore, (specialCore % Test).classifier("tests"), - libraryapi, (libraryapi % Test).classifier("tests"), - libraryimpl, (libraryimpl % Test).classifier("tests"), - specialLibrary, (specialLibrary % Test).classifier("tests"), - scrypto, - bouncycastleBcprov - )) + .dependsOn( + sigmaimpl % allConfigDependency, + common % allConfigDependency, + core % allConfigDependency, + libraryapi % allConfigDependency, + libraryimpl % allConfigDependency, + library % allConfigDependency) + .settings(libraryDefSettings, + libraryDependencies ++= Seq( + scrypto, + bouncycastleBcprov + )) + .settings(publish / skip := true) + +lazy val sigmastate = (project in file("sigmastate")) + .dependsOn(sigmaimpl % allConfigDependency, sigmalibrary % allConfigDependency) + .settings(libraryDefSettings) + .settings(libraryDependencies ++= Seq( + scorexUtil, kiama, fastparse, circeCore, circeGeneric, circeParser)) + .settings(publish / skip := true) lazy val sigma = (project in file(".")) - .aggregate(sigmaapi, sigmaimpl, sigmalibrary, sigmaconf, scalanizer) - .dependsOn(sigmaimpl % allConfigDependency, sigmalibrary % allConfigDependency) - .settings(commonSettings: _*) + .aggregate( + sigmastate, common, core, libraryapi, libraryimpl, library, + sigmaapi, sigmaimpl, sigmalibrary, sigmaconf, scalanizer) + .settings(libraryDefSettings, rootSettings) + .settings(publish / aggregate := false) + .settings(publishLocal / aggregate := false) + +lazy val aggregateCompile = ScopeFilter( + inProjects(common, core, libraryapi, libraryimpl, library, sigmaapi, sigmaimpl, + sigmalibrary, sigmastate), + inConfigurations(Compile)) + +lazy val rootSettings = Seq( + sources in Compile := sources.all(aggregateCompile).value.flatten, + libraryDependencies := libraryDependencies.all(aggregateCompile).value.flatten, + mappings in (Compile, packageSrc) ++= (mappings in(Compile, packageSrc)).all(aggregateCompile).value.flatten, + mappings in (Test, packageBin) ++= (mappings in(Test, packageBin)).all(aggregateCompile).value.flatten, + mappings in(Test, packageSrc) ++= (mappings in(Test, packageSrc)).all(aggregateCompile).value.flatten, +) def runErgoTask(task: String, sigmastateVersion: String, log: Logger): Unit = { - val ergoBranch = "ergolikectx-json" + val ergoBranch = "sigma-core-opt" val sbtEnvVars = Seq("BUILD_ENV" -> "test", "SIGMASTATE_VERSION" -> sigmastateVersion) log.info(s"Testing current build in Ergo (branch $ergoBranch):") diff --git a/ci/pubring.asc b/ci/pubring.asc new file mode 100644 index 0000000000..cf75b9dfab --- /dev/null +++ b/ci/pubring.asc @@ -0,0 +1,30 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQENBF2utdgBCAClRGOfWeus4AlHvCBgJVXH2CLqXLKCBggE2vwKbKvFdW1DTPZQ +T1RI6zBtMdaSNVm4ISO4dOO67VGdajr8/6kFt2+di2b7hMVaULf4UgYuZ+vvVUPp +3oSEJnHheh5ZfjV+jvL5GSAu+vgnC8qbPutCEpXBfx5zAOdLtiyegzx72asJvvkz +ghvyXVrg8gnXVtiSBV1EpfES7gZJmpuzv2dYrCtL2irlRlySLQ5JFKXrfOQvf4K9 +TCxRye1UNb+3ybL0ilXoRn3jDS9RLbLxiVMjjx/Bqk/mc3MNMoa+juzvI6xIxFG0 +3fwNOTXdQ6gLCjHJ9/nFvygkBW5bkeMujBhhABEBAAG0JlNpZ21hc3RhdGUgYm90 +IDxkZW55c0B6YWRvcm96aG55aS5jb20+iQFUBBMBCAA+FiEEKOJ6Z66jjaRYxyIo +ypJUteBkD+QFAl2utdgCGwMFCQPCZwAFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AA +CgkQypJUteBkD+Tt4Af/f5o2Yoc8ebOwMiNUYDkfUqFLzH1WySEKfAt2iXrIgVjV +NF6ddyaLadSYdU6HGJ6txn2a16TuItdBQJSTpnmiw1qtqNVJVRnUoytXeCYN0Utn ++3zYTOhkbhnIczGao+qlqhovfO8x+WPZ/2Fczm20A5TNAg7NzmeF7FP9OWLpnI4v +yktmAbpZaSoCZWC3ZPG2H3SOHUn8Lt0++ni4R0gT0HclwbyzuDgT0cmxarVzEFQQ +7nhNOhU1+1MYRpQ9wBUWFLwMvMUgA6rQeg7idtAXklGEZaN0RK3HpL1I+XAE9rYW +tdejY67u/hdInm33oqe5aJrPmH5DFNCpBpc2w2NzGbkBDQRdrrXYAQgAxGs1Fclq +MQJjIwu3dH+vBY5vdZ0M1Mhd2fjXu8s0tEZ8RjBBbtZ03KI5t97+oXs5rgKCCtRH +v+RfSDn1eTeKRIwYxsowd86SlC8rjhSAyJfWS7er7+4Jpsa1W91TucrMQMue4qEX +udlg18oNcX/MGDB+lPirL1zxp6jfysjlebx01dcKVj2a+rpyPeNNrV2M8Ywlm5/c +lmRciSXLMb+phhvcyYyvi4UmguQi7/o3hCNhRlEj4XqF6CT1S57X6nTuYRP1dcjG +GVxvlybrDIBV0oDGW0TEjGWaBwKOpqZDi8Jzj5P398nqnP0UDrW7q/qmrZcdE5ov +qYWERLqXzGwBFwARAQABiQE8BBgBCAAmFiEEKOJ6Z66jjaRYxyIoypJUteBkD+QF +Al2utdgCGwwFCQPCZwAACgkQypJUteBkD+Qbqwf+IR030kbKsE6rOLwlKUGN9pah +tZjoSxnq5K+nXn621K578z9r76rGkP84UeAvZqt2MkadhwyEqwv99DftoZCXNM8b +5oRsDOAbA0YTSPKIa8E7S8XhWzE6VCx+2DFtjrYeGhybVGd9aq6jeQgEkqioZT0n +l3acH1VsuFQdFNwBrEgAFORBt5zXtSn7lXmnOh4ZFeYCncdR3+L6nJ/PAPz0hWMz +CZjc7vGcEvAtTNb2brtHtvox0Gc0Xphe0iCaWyzN7P32+rJgsfCMj9FFQUxToZMY +ozM9at2zWzk9wOb41RLnY+rGBNQ3xNR23shWF4fcOwk6BIp+OYsSqnsEYYXuDw== +=huRW +-----END PGP PUBLIC KEY BLOCK----- diff --git a/ci/secring.asc.enc b/ci/secring.asc.enc new file mode 100644 index 0000000000..2cc0474c89 Binary files /dev/null and b/ci/secring.asc.enc differ diff --git a/common/src/main/java/scalan/Builtin.java b/common/src/main/java/scalan/Builtin.java new file mode 100644 index 0000000000..83a1c37b84 --- /dev/null +++ b/common/src/main/java/scalan/Builtin.java @@ -0,0 +1,17 @@ +package scalan; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +/** Relate annotated element with internal type or method given by `value` property. +* Applied to entities that should be replaced during virtualization by related type. +* The given related type is said to be pre-virtualized. +* The 'value' is a name of the class which can be resolved in a Scalan cake. E.g. IsoUR*/ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Builtin { + String value() default ""; // default value interpreted as "virtualized name is equal to annotated element name" +} diff --git a/common/src/main/java/scalan/Constructor.java b/common/src/main/java/scalan/Constructor.java new file mode 100644 index 0000000000..0caecfe3d9 --- /dev/null +++ b/common/src/main/java/scalan/Constructor.java @@ -0,0 +1,14 @@ +package scalan; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** Used in generated wrappers. + * Annotates a wrapper method of the companion of a virtualized type wrapper, + * which (the method) corresponds to the constructor of wrapped type. */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Constructor { +} diff --git a/common/src/main/java/scalan/ContainerType.java b/common/src/main/java/scalan/ContainerType.java new file mode 100644 index 0000000000..c3768cda3c --- /dev/null +++ b/common/src/main/java/scalan/ContainerType.java @@ -0,0 +1,14 @@ +package scalan; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** Annotates Special DSL types which implement the interface of containers. +* Each container is described using Cont[_] descriptors. +* Special supporting code is generated for annotated entities. */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.CLASS) +public @interface ContainerType { +} diff --git a/common/src/main/java/scalan/Convertible.java b/common/src/main/java/scalan/Convertible.java new file mode 100644 index 0000000000..662f5f6ee3 --- /dev/null +++ b/common/src/main/java/scalan/Convertible.java @@ -0,0 +1,12 @@ +package scalan; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** Marks annotated type as having support for generic Converter generation. */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Convertible { +} diff --git a/common/src/main/java/scalan/External.java b/common/src/main/java/scalan/External.java new file mode 100644 index 0000000000..e8e2864c7c --- /dev/null +++ b/common/src/main/java/scalan/External.java @@ -0,0 +1,15 @@ +package scalan; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** Relate annotated element with an external type or method given by `value` property. +* For example WOption related to Option is annotated as @External("Option") +* This annotation is used to separate wrapper Entity from user defined virtualized Entity. +* See WrapperEntity object. */ +@Target({ElementType.TYPE, ElementType.METHOD}) +public @interface External { + String value() default ""; // default value interpreted as "external name is equal to annotated element name" +} diff --git a/common/src/main/java/scalan/FunctorType.java b/common/src/main/java/scalan/FunctorType.java new file mode 100644 index 0000000000..9832d78271 --- /dev/null +++ b/common/src/main/java/scalan/FunctorType.java @@ -0,0 +1,13 @@ +package scalan; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** Used to annotate container types (like Option, Coll), which have + * functor semantics. Special code is generated for such entities. */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.CLASS) +public @interface FunctorType { +} diff --git a/common/src/main/java/scalan/InlineAt.java b/common/src/main/java/scalan/InlineAt.java new file mode 100644 index 0000000000..0590456be7 --- /dev/null +++ b/common/src/main/java/scalan/InlineAt.java @@ -0,0 +1,18 @@ +package scalan; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** Specifies the predicate when the annotated method should be inlined. +* The predicate is given by the parsable formula which can be used to +* create runtime predicate functions. +* Default empty string is interpreted as never invoke, in which case scalanizer +* don't perform virtualization of the method body and replace it with delayInvoke. */ +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface InlineAt { + String Never = ""; + String value() default Never; +} diff --git a/common/src/main/java/scalan/Internal.java b/common/src/main/java/scalan/Internal.java new file mode 100644 index 0000000000..1555984ccc --- /dev/null +++ b/common/src/main/java/scalan/Internal.java @@ -0,0 +1,14 @@ +package scalan; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** Used to annotate type and methods, which should not be virtualized. + * Everything marked @Internal are invisible for virtualization process. + */ +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Internal { +} diff --git a/common/src/main/java/scalan/Isospec.java b/common/src/main/java/scalan/Isospec.java new file mode 100644 index 0000000000..d5c2498537 --- /dev/null +++ b/common/src/main/java/scalan/Isospec.java @@ -0,0 +1,12 @@ +package scalan; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** Marks annotated type as having support for isomorphic specialization. */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Isospec { +} diff --git a/common/src/main/java/scalan/Liftable.java b/common/src/main/java/scalan/Liftable.java new file mode 100644 index 0000000000..83dc56bc17 --- /dev/null +++ b/common/src/main/java/scalan/Liftable.java @@ -0,0 +1,12 @@ +package scalan; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** Marks annotated type as having support for lifting values to IR nodes. */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Liftable { +} diff --git a/common/src/main/java/scalan/NeverInline.java b/common/src/main/java/scalan/NeverInline.java new file mode 100644 index 0000000000..39b63e9a0c --- /dev/null +++ b/common/src/main/java/scalan/NeverInline.java @@ -0,0 +1,12 @@ +package scalan; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** Equvalent to InlineAt(Never). */ +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface NeverInline { +} diff --git a/common/src/main/java/scalan/OverloadId.java b/common/src/main/java/scalan/OverloadId.java new file mode 100644 index 0000000000..c167013698 --- /dev/null +++ b/common/src/main/java/scalan/OverloadId.java @@ -0,0 +1,13 @@ +package scalan; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** Assigns an alternative name to the overloaded method. */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface OverloadId { + String value(); +} diff --git a/common/src/main/java/scalan/Reified.java b/common/src/main/java/scalan/Reified.java new file mode 100644 index 0000000000..bd49e53118 --- /dev/null +++ b/common/src/main/java/scalan/Reified.java @@ -0,0 +1,19 @@ +package scalan; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** Type argument T should be reified in virtualized code type descriptor Elem[T] available +* in the scope where T is visible. This can be done either by explicitly passing additional +* parameter eT: Elem[T] or by proving that Elem[T] can be retrieved from the other arguments +* of the method or class. For example if x: Rep[T] then eT can be obtained by x.elem. +* The need for reified type arguments come from ClassTag[T], RType[T] context bounds or +* implicit parameters in the source code. +*/ +@Target({ElementType.TYPE, ElementType.TYPE_PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Reified { + String value() default ""; +} diff --git a/common/src/main/java/scalan/WithMethodCallRecognizers.java b/common/src/main/java/scalan/WithMethodCallRecognizers.java new file mode 100644 index 0000000000..37e229ed01 --- /dev/null +++ b/common/src/main/java/scalan/WithMethodCallRecognizers.java @@ -0,0 +1,17 @@ +package scalan; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** Marks annotated method or trait/class as having support for pattern matching. + * Extractor methods will be generated by codegen for each method either annotated or + * belonging to the annotated type. + * Extractors can be used in rewriting rules to recognize IR nodes of MethodCall type, + * which represents the call of the annotated method. + */ +@Target({ElementType.METHOD,ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface WithMethodCallRecognizers { +} diff --git a/common/src/main/scala/scalan/AnyVals.scala b/common/src/main/scala/scalan/AnyVals.scala new file mode 100644 index 0000000000..29b5a1ad7b --- /dev/null +++ b/common/src/main/scala/scalan/AnyVals.scala @@ -0,0 +1,48 @@ +package scalan + +import java.util.HashMap + +/** Allocation free alternative to scala.Option with similar interface. + * Using this in recognizers allows: + * 1) to avoid allocation of Some(x) + * 2) reading random memory location (where Some is stored) to access x + **/ +class Nullable[+T](val x: T) extends AnyVal { + @inline final def isEmpty = x == null + @inline final def get: T = x + @inline final def isDefined = x != null + @inline final def getOrElse[B >: T](default: =>B): B = if (x != null) x else default + @inline final def toList: List[T] = if (x == null) Nil else x :: Nil + @inline final def toOption: Option[T] = if (x == null) None else Some(x) +} +object Nullable { + final val None: Nullable[Null] = new Nullable(null) + final def apply[T](x: T): Nullable[T] = new Nullable(x) + final def unapply[T](opt: Nullable[T]): Nullable[T] = opt +} + +/** Allocation free alternative to scala.collection.mutable.Map with similar interface. + * This simplifies optimization of performance critical code. */ +class AVHashMap[K,V](val hashMap: HashMap[K,V]) extends AnyVal { + @inline final def isEmpty: Boolean = hashMap.isEmpty + @inline final def get(key: K): Nullable[V] = Nullable(hashMap.get(key)) + @inline final def apply(key: K): V = hashMap.get(key) + @inline final def containsKey(key: K): Boolean = hashMap.containsKey(key) + @inline final def put(key: K, value: V): V = hashMap.put(key, value) + @inline final def clear(): Unit = { + hashMap.clear() + } + final def getOrElseUpdate(key: K, op: => V): V = { + var v = hashMap.get(key) + if (v == null) { + v = op + hashMap.put(key, v) + } + v + } + @inline final def keySet: java.util.Set[K] = hashMap.keySet() +} +object AVHashMap { + def apply[K,V](initialCapacity: Int) = new AVHashMap[K,V](new HashMap[K,V](initialCapacity)) +} + diff --git a/common/src/main/scala/scalan/DFunc.scala b/common/src/main/scala/scalan/DFunc.scala new file mode 100644 index 0000000000..4083792132 --- /dev/null +++ b/common/src/main/scala/scalan/DFunc.scala @@ -0,0 +1,11 @@ +package scalan + +/** Function interface which support specialization and thus unboxed invocations. */ +abstract class DFunc[@specialized(Int) A, B] { + def apply(x: A): B +} + +/** Convenient but SLOW adapter to be used in tests. */ +class DFuncAdapter[A,B](f: A => B) extends DFunc[A, B] { + override def apply(x: A): B = f(x) +} diff --git a/src/main/scala/sigmastate/eval/ExactNumeric.scala b/common/src/main/scala/scalan/ExactIntegral.scala similarity index 67% rename from src/main/scala/sigmastate/eval/ExactNumeric.scala rename to common/src/main/scala/scalan/ExactIntegral.scala index 92cb166d4d..74d85462ab 100644 --- a/src/main/scala/sigmastate/eval/ExactNumeric.scala +++ b/common/src/main/scala/scalan/ExactIntegral.scala @@ -1,17 +1,20 @@ -package sigmastate.eval +package scalan -import sigma.util.Extensions._ +import scalan.util.Extensions._ -import scala.math.Numeric.{IntIsIntegral, ByteIsIntegral, ShortIsIntegral, LongIsIntegral} +import scala.math.Numeric.{ByteIsIntegral, LongIsIntegral, ShortIsIntegral, IntIsIntegral} -/** Numeric operations with overflow checks. +/** Integral operations with overflow checks. * Raise exception when overflow is detected. * Each instance of this typeclass overrides three methods `plus`, `minus`, `times`. - * All other methods are implemented by delegating to the corresponding Numeric instance from + * All other methods are implemented by delegating to the corresponding Integral instance from * standard Scala library. + * This trait is used in core IR to avoid implicitly using standard scala implementations. */ -trait ExactNumeric[T] extends Numeric[T] { - val n: Numeric[T] +trait ExactIntegral[T] extends Integral[T] { + val n: Integral[T] + override def quot(x: T, y: T): T = n.quot(x, y) + override def rem(x: T, y: T): T = n.rem(x, y) override def negate(x: T): T = n.negate(x) override def fromInt(x: Int): T = n.fromInt(x) override def toInt(x: T): Int = n.toInt(x) @@ -22,34 +25,33 @@ trait ExactNumeric[T] extends Numeric[T] { } /** ExactNumeric instances for all types. */ -object ExactNumeric { +object ExactIntegral { - object ByteIsExactNumeric extends ExactNumeric[Byte] { + implicit object ByteIsExactIntegral extends ExactIntegral[Byte] { val n = ByteIsIntegral override def plus(x: Byte, y: Byte): Byte = x.addExact(y) override def minus(x: Byte, y: Byte): Byte = x.subtractExact(y) override def times(x: Byte, y: Byte): Byte = x.multiplyExact(y) } - object ShortIsExactNumeric extends ExactNumeric[Short] { + implicit object ShortIsExactIntegral extends ExactIntegral[Short] { val n = ShortIsIntegral override def plus(x: Short, y: Short): Short = x.addExact(y) override def minus(x: Short, y: Short): Short = x.subtractExact(y) override def times(x: Short, y: Short): Short = x.multiplyExact(y) } - object IntIsExactNumeric extends ExactNumeric[Int] { + implicit object IntIsExactIntegral extends ExactIntegral[Int] { val n = IntIsIntegral override def plus(x: Int, y: Int): Int = Math.addExact(x, y) override def minus(x: Int, y: Int): Int = Math.subtractExact(x, y) override def times(x: Int, y: Int): Int = Math.multiplyExact(x, y) } - - object LongIsExactNumeric extends ExactNumeric[Long] { + + implicit object LongIsExactIntegral extends ExactIntegral[Long] { val n = LongIsIntegral override def plus(x: Long, y: Long): Long = Math.addExact(x, y) override def minus(x: Long, y: Long): Long = Math.subtractExact(x, y) override def times(x: Long, y: Long): Long = Math.multiplyExact(x, y) } - } diff --git a/common/src/main/scala/scalan/ExactNumeric.scala b/common/src/main/scala/scalan/ExactNumeric.scala new file mode 100644 index 0000000000..734938ce34 --- /dev/null +++ b/common/src/main/scala/scalan/ExactNumeric.scala @@ -0,0 +1,61 @@ +package scalan + +import scalan.util.Extensions._ + +import scala.math.Numeric.{ByteIsIntegral, LongIsIntegral, ShortIsIntegral, IntIsIntegral} + +/** Numeric operations with overflow checks. + * Raise exception when overflow is detected. + * Each instance of this typeclass overrides three methods `plus`, `minus`, `times`. + * All other methods are implemented by delegating to the corresponding Numeric instance from + * standard Scala library. + * This trait is used in core IR to avoid implicitly using standard scala implementations + */ +trait ExactNumeric[T] { + val n: Numeric[T] + def plus(x: T, y: T): T + def minus(x: T, y: T): T + def times(x: T, y: T): T + def negate(x: T): T = n.negate(x) + def fromInt(x: Int): T = n.fromInt(x) + def toInt(x: T): Int = n.toInt(x) + def toLong(x: T): Long = n.toLong(x) + def toFloat(x: T): Float = n.toFloat(x) + def toDouble(x: T): Double = n.toDouble(x) + def compare(x: T, y: T): Int = n.compare(x, y) + def zero: T = n.zero + def one: T = n.one + def abs(x: T): T = n.abs(x) +} + +/** ExactNumeric instances for all types. */ +object ExactNumeric { + + implicit object ByteIsExactNumeric extends ExactNumeric[Byte] { + val n = ByteIsIntegral + override def plus(x: Byte, y: Byte): Byte = x.addExact(y) + override def minus(x: Byte, y: Byte): Byte = x.subtractExact(y) + override def times(x: Byte, y: Byte): Byte = x.multiplyExact(y) + } + + implicit object ShortIsExactNumeric extends ExactNumeric[Short] { + val n = ShortIsIntegral + override def plus(x: Short, y: Short): Short = x.addExact(y) + override def minus(x: Short, y: Short): Short = x.subtractExact(y) + override def times(x: Short, y: Short): Short = x.multiplyExact(y) + } + + implicit object IntIsExactNumeric extends ExactNumeric[Int] { + val n = IntIsIntegral + override def plus(x: Int, y: Int): Int = Math.addExact(x, y) + override def minus(x: Int, y: Int): Int = Math.subtractExact(x, y) + override def times(x: Int, y: Int): Int = Math.multiplyExact(x, y) + } + + implicit object LongIsExactNumeric extends ExactNumeric[Long] { + val n = LongIsIntegral + override def plus(x: Long, y: Long): Long = Math.addExact(x, y) + override def minus(x: Long, y: Long): Long = Math.subtractExact(x, y) + override def times(x: Long, y: Long): Long = Math.multiplyExact(x, y) + } +} diff --git a/common/src/main/scala/scalan/ExactOrdering.scala b/common/src/main/scala/scalan/ExactOrdering.scala new file mode 100644 index 0000000000..a727233588 --- /dev/null +++ b/common/src/main/scala/scalan/ExactOrdering.scala @@ -0,0 +1,27 @@ +package scalan + +import scala.math.Numeric.{ByteIsIntegral, LongIsIntegral, ShortIsIntegral, IntIsIntegral} + +/** Ordering operations to be used with other Exact traits. + * All methods are implemented by delegating to the corresponding Ordering instance from + * standard Scala library. + * This trait is used in core IR to avoid implicitly using standard scala implementations. + */ +trait ExactOrdering[T] extends Ordering[T] { + val n: Ordering[T] + override def compare(x: T, y: T): Int = n.compare(x, y) +} + +class ExactOrderingImpl[T](val n: Ordering[T]) extends ExactOrdering[T] + +/** ExactOrdering instances for all types. */ +object ExactOrdering { + + implicit object ByteIsExactOrdering extends ExactOrderingImpl[Byte](ByteIsIntegral) + + implicit object ShortIsExactOrdering extends ExactOrderingImpl[Short](ShortIsIntegral) + + implicit object IntIsExactOrdering extends ExactOrderingImpl[Int](IntIsIntegral) + + implicit object LongIsExactOrdering extends ExactOrderingImpl[Long](LongIsIntegral) +} diff --git a/common/src/main/scala/scalan/Exceptions.scala b/common/src/main/scala/scalan/Exceptions.scala new file mode 100644 index 0000000000..8ab128a06e --- /dev/null +++ b/common/src/main/scala/scalan/Exceptions.scala @@ -0,0 +1,11 @@ +package scalan + +/** + * Can be thrown in staged method body to prevent body unfolding. + * When this exception is thrown, the caller can catch it and reify + * this invocation as MethodCall graph node. + */ +class DelayInvokeException extends Exception { + override def fillInStackTrace(): Throwable = this // to avoid spending time on recording stack trace +} + diff --git a/common/src/main/scala/scalan/Lazy.scala b/common/src/main/scala/scalan/Lazy.scala new file mode 100644 index 0000000000..bb0495fb5a --- /dev/null +++ b/common/src/main/scala/scalan/Lazy.scala @@ -0,0 +1,33 @@ +package scalan + +/** Non-thread safe (but efficient on single thread) immutable lazy value. + * The `block` is executed only once. */ +class Lazy[A] private (block: => A) { + @volatile private[this] var _isSet: Boolean = false + private[this] var _value: A = _ + + def value: A = { + if (!_isSet) { + _value = block + _isSet = true + } + _value + } + + @inline def isSet = _isSet + + override def toString = { + if (!_isSet) + "" + else + value.toString + } +} + +object Lazy { + def apply[A](block: => A): Lazy[A] = new Lazy(block) +} + + + + diff --git a/common/src/main/scala/scalan/ModuleInfo.scala b/common/src/main/scala/scalan/ModuleInfo.scala new file mode 100644 index 0000000000..2d8e10116a --- /dev/null +++ b/common/src/main/scala/scalan/ModuleInfo.scala @@ -0,0 +1,13 @@ +package scalan + +import scalan.meta.SSymName + +/** Information about generated Special library module. + * Instances are created in generated code. + * @see *Impl.scala files + */ +case class ModuleInfo(packageName: String, moduleName: String, extension: String = ".scalan") { + val name = SSymName(packageName, moduleName) + def getKey = name.mkFullName + def sourceFileName = packageName.replace('.', '/') + s"/$moduleName$extension" +} diff --git a/common/src/main/scala/scalan/MutableLazy.scala b/common/src/main/scala/scalan/MutableLazy.scala new file mode 100644 index 0000000000..e7cd3aee78 --- /dev/null +++ b/common/src/main/scala/scalan/MutableLazy.scala @@ -0,0 +1,33 @@ +package scalan + +/** Non-thread safe (but efficient on single thread) immutable lazy value with reset. + * The `block` may execute potentially many times, but only once before each reset. */ +final class MutableLazy[A] private (block: => A) { + @volatile private[this] var _isSet: Boolean = false + private[this] var _value: A = _ + + def value: A = { + if (!_isSet) { + _value = block + _isSet = true + } + _value + } + + @inline def isSet = _isSet + + @inline def reset() = { _isSet = false } + + override def toString = { + if (!_isSet) + "" + else + value.toString + } +} + +object MutableLazy { + @inline final def apply[A](block: => A): MutableLazy[A] = new MutableLazy(block) + + @inline final implicit def mutableLazyToValue[T](ml: MutableLazy[T]): T = ml.value +} \ No newline at end of file diff --git a/common/src/main/scala/scalan/OverloadHack.scala b/common/src/main/scala/scalan/OverloadHack.scala new file mode 100644 index 0000000000..685946979e --- /dev/null +++ b/common/src/main/scala/scalan/OverloadHack.scala @@ -0,0 +1,26 @@ +package scalan + +/** Scala specific trick to appease erasure of methods argument types. + * Example usage: + * def m1(l: List[Int])(implicit o: Overloaded1) + * def m2(l: List[String])(implicit o: Overloaded2) + * Without the implicit arguments the methods would have identical signatures + * after erasure, which is a compilation time error. + */ +object OverloadHack { + trait Overloaded + class Overloaded1 extends Overloaded { override def toString = "O1"} + class Overloaded2 extends Overloaded { override def toString = "O2"} + class Overloaded3 extends Overloaded { override def toString = "O3"} + class Overloaded4 extends Overloaded { override def toString = "O4"} + class Overloaded5 extends Overloaded { override def toString = "O5"} + class Overloaded6 extends Overloaded { override def toString = "O6"} + class Overloaded7 extends Overloaded { override def toString = "O7"} + implicit val overloaded1 = new Overloaded1 + implicit val overloaded2 = new Overloaded2 + implicit val overloaded3 = new Overloaded3 + implicit val overloaded4 = new Overloaded4 + implicit val overloaded5 = new Overloaded5 + implicit val overloaded6 = new Overloaded6 + implicit val overloaded7 = new Overloaded7 +} \ No newline at end of file diff --git a/common/src/main/scala/scalan/TypeDesc.scala b/common/src/main/scala/scalan/TypeDesc.scala new file mode 100644 index 0000000000..32e5208bb8 --- /dev/null +++ b/common/src/main/scala/scalan/TypeDesc.scala @@ -0,0 +1,162 @@ +package scalan + +import scala.reflect.ClassTag +import scala.annotation.implicitNotFound + +/** Base type for all runtime type descriptors. */ +@implicitNotFound(msg = "No Elem available for ${A}.") +abstract class RType[A] { + /** Class tag suitable for construct instances of Array[A]. */ + def classTag: ClassTag[A] + + /** Syntactically correct type name (type expression as String) */ + def name: String = this.toString + + /** Returns true is data size of `x: A` is the same for all `x`. + * This is useful optimizations of calculating sizes of collections. */ + def isConstantSize: Boolean +} + +object RType { + /** Helper to request RType instances from an implicit scope.*/ + def apply[A](implicit t: RType[A]): RType[A] = t + + /** Helper cast from untyped descriptor to the typed one. */ + @inline def asType[T](t: RType[_]): RType[T] = t.asInstanceOf[RType[T]] + + def fromClassTag[A](ctA: ClassTag[A]): RType[A] = (ctA match { + case ClassTag.Boolean => BooleanType + case ClassTag.Byte => ByteType + case ClassTag.Short => ShortType + case ClassTag.Int => IntType + case ClassTag.Long => LongType + case ClassTag.Char => CharType + case ClassTag.Float => FloatType + case ClassTag.Double => DoubleType + case ClassTag.Unit => UnitType + case _ => GeneralType[A](ctA) + }).asInstanceOf[RType[A]] + + type SomeType = RType[_] + + /** Type descriptor for types with limited type information like Any, AnyRef, Nothing. + * It also used to wrap class tags which are GenericClassTag instances + * (also with limited information about type structure). + * To describe structure of the type more precisely use concrete classes + * in the hierarchy of RType. + */ + case class GeneralType[A](classTag: ClassTag[A]) extends RType[A] { + override def name: String = classTag match { + case ClassTag.Any => "Any" + case ClassTag.AnyRef => "AnyRef" + case ClassTag.Nothing => "Nothing" + case ct => ct.runtimeClass.getSimpleName() + } + override def isConstantSize: Boolean = false + } + + /** Descriptor used to represent primitive types. */ + case class PrimitiveType[A](classTag: ClassTag[A]) extends RType[A] { + override def name: String = classTag.toString() + /** We assume all primitive types have inhabitants of the same size. */ + override def isConstantSize: Boolean = true + } + + val AnyType : RType[Any] = GeneralType[Any] (ClassTag.Any) + val AnyRefType : RType[AnyRef] = GeneralType[AnyRef] (ClassTag.AnyRef) + val NothingType : RType[Nothing] = GeneralType[Nothing] (ClassTag.Nothing) + + implicit val BooleanType : RType[Boolean] = PrimitiveType[Boolean] (ClassTag.Boolean) + implicit val ByteType : RType[Byte] = PrimitiveType[Byte] (ClassTag.Byte) + implicit val ShortType : RType[Short] = PrimitiveType[Short] (ClassTag.Short) + implicit val IntType : RType[Int] = PrimitiveType[Int] (ClassTag.Int) + implicit val LongType : RType[Long] = PrimitiveType[Long] (ClassTag.Long) + implicit val CharType : RType[Char] = PrimitiveType[Char] (ClassTag.Char) + implicit val FloatType : RType[Float] = PrimitiveType[Float] (ClassTag.Float) + implicit val DoubleType : RType[Double] = PrimitiveType[Double] (ClassTag.Double) + implicit val UnitType : RType[Unit] = PrimitiveType[Unit] (ClassTag.Unit) + + /** Descriptor of the type A narrowed to the single inhabitant `value`. */ + case class SingletonType[A](value: A, classTag: ClassTag[A])() extends RType[A] { + override def isConstantSize: Boolean = true // since the type has only one inhabitant + } + + implicit case object StringType extends RType[String] { + override def classTag: ClassTag[String] = ClassTag[String](classOf[String]) + override def name: String = "String" + override def isConstantSize: Boolean = false + } + + /** Descriptor of descriptor to represent type of RType[_] instances. + * This describes any possible descriptor, disregarding its underlying type. + * Thus the underlying type is assumed to be Any. */ + case object RTypeType extends RType[RType[_]] { + val classTag: ClassTag[RType[_]] = ClassTag[RType[_]](classOf[RType[_]]) + override def name: String = s"RType[Any]" + override def isConstantSize: Boolean = false // since all type terms of different size + } + /** Implicitly obtain the single RTypeType descriptor casted to the given type A. */ + implicit def rtypeRType[A]: RType[RType[A]] = asType[RType[A]](RTypeType) + + implicit def pairRType[A,B](implicit tA: RType[A], tB: RType[B]): RType[(A,B)] = PairType(tA, tB) + + case class PairType[A,B](tFst: RType[A], tSnd: RType[B]) extends RType[(A,B)] { + val classTag: ClassTag[(A, B)] = scala.reflect.classTag[(A,B)] + override def name: String = s"(${tFst.name}, ${tSnd.name})" + override def isConstantSize: Boolean = tFst.isConstantSize && tSnd.isConstantSize + } + implicit def extendPairType[A,B](pt: RType[(A,B)]): PairType[A,B] = pt.asInstanceOf[PairType[A,B]] + + implicit def eitherRType[A,B](implicit tA: RType[A], tB: RType[B]): RType[Either[A,B]] = EitherType(tA, tB) + + case class EitherType[A,B](tLeft: RType[A], tRight: RType[B]) extends RType[Either[A,B]] { + val classTag: ClassTag[Either[A, B]] = scala.reflect.classTag[Either[A,B]] + override def name: String = s"(${tLeft.name} | ${tRight.name})" + override def isConstantSize: Boolean = tLeft.isConstantSize && tRight.isConstantSize + } + + implicit def funcRType[A,B](implicit tDom: RType[A], tRange: RType[B]): RType[A => B] = FuncType(tDom, tRange) + + case class FuncType[A,B](tDom: RType[A], tRange: RType[B]) extends RType[A => B] { + val classTag: ClassTag[A => B] = scala.reflect.classTag[A => B] + override def name: String = s"${tDom.name} => ${tRange.name}" + override def isConstantSize: Boolean = false + } + + implicit def arrayRType[A](implicit tA: RType[A]): RType[Array[A]] = ArrayType(tA) + + case class ArrayType[A](tA: RType[A]) extends RType[Array[A]] { + val classTag: ClassTag[Array[A]] = { + implicit val ctA: ClassTag[A] = tA.classTag + scala.reflect.classTag[Array[A]] + } + override def name: String = s"Array[${tA.name}]" + override def isConstantSize: Boolean = false + } + + implicit def optionRType[A](implicit tA: RType[A]): RType[Option[A]] = OptionType(tA) + + case class OptionType[A](tA: RType[A]) extends RType[Option[A]] { + val classTag: ClassTag[Option[A]] = { + implicit val ctA: ClassTag[A] = tA.classTag + scala.reflect.classTag[Option[A]] + } + override def name: String = s"Option[${tA.name}]" + override def isConstantSize: Boolean = tA.isConstantSize + } + + /** Underlying type of Thunk[A] values (or by-name values of type A). */ + type ThunkData[A] = () => A + + implicit def thunkRType[A](implicit tA: RType[A]): RType[ThunkData[A]] = ThunkType(tA) + + case class ThunkType[A](tA: RType[A]) extends RType[ThunkData[A]] { + val classTag: ClassTag[ThunkData[A]] = { + implicit val ctA: ClassTag[A] = tA.classTag + scala.reflect.classTag[ThunkData[A]] + } + override def name: String = s"Thunk[${tA.name}]" + override def isConstantSize: Boolean = false + } + +} diff --git a/common/src/main/scala/scalan/Typeclass.scala b/common/src/main/scala/scalan/Typeclass.scala new file mode 100644 index 0000000000..9c94a3a181 --- /dev/null +++ b/common/src/main/scala/scalan/Typeclass.scala @@ -0,0 +1,3 @@ +package scalan + +class Typeclass extends scala.annotation.StaticAnnotation diff --git a/common/src/main/scala/scalan/WrapSpec.scala b/common/src/main/scala/scalan/WrapSpec.scala new file mode 100644 index 0000000000..5eda48bc88 --- /dev/null +++ b/common/src/main/scala/scalan/WrapSpec.scala @@ -0,0 +1,6 @@ +package scalan + +/** Base type for all wrapper specification classes. + * @see OptionWrapSpec as an example */ +trait WrapSpec { +} diff --git a/common/src/main/scala/scalan/meta/SSymName.scala b/common/src/main/scala/scalan/meta/SSymName.scala new file mode 100644 index 0000000000..7574f8d8e2 --- /dev/null +++ b/common/src/main/scala/scalan/meta/SSymName.scala @@ -0,0 +1,22 @@ +package scalan.meta + +import scalan.util.StringUtil._ + +case class ImportItem(packageName: String, importedNames: List[String]) + +case class SSymName(packageName: String, name: String) { + import SSymName._ + def this(name: String) = this("", name) + def mkFullName = fullNameString(packageName, name) + def isImportedBy(item: ImportItem): Boolean = { + if (packageName != item.packageName) return false + item.importedNames.contains(SSymName.ImportAllWildcard) || item.importedNames.contains(name) + } +} + +object SSymName { + /** Wildcard character used to signify imporing all names from namespace */ + val ImportAllWildcard = "*" + def fullNameString(packageName: String, name: String): String = + if (packageName.isNullOrEmpty) name else s"$packageName.$name" +} \ No newline at end of file diff --git a/common/src/main/scala/scalan/package.scala b/common/src/main/scala/scalan/package.scala new file mode 100644 index 0000000000..ab705c62e8 --- /dev/null +++ b/common/src/main/scala/scalan/package.scala @@ -0,0 +1,9 @@ +import scala.reflect.ClassTag + +package object scalan { + + /** Allows implicit resolution to find appropriate instance of ClassTag in + * the scope where RType is implicitly available. */ + implicit def rtypeToClassTag[A](implicit t: RType[A]): ClassTag[A] = t.classTag + +} diff --git a/common/src/main/scala/scalan/util/BenchmarkUtil.scala b/common/src/main/scala/scalan/util/BenchmarkUtil.scala new file mode 100644 index 0000000000..8ed69a8707 --- /dev/null +++ b/common/src/main/scala/scalan/util/BenchmarkUtil.scala @@ -0,0 +1,42 @@ +package scalan.util + +import scala.concurrent.duration.Duration +import scala.concurrent.{Future, Await} +import scala.concurrent.ExecutionContext.Implicits.global + +/** Helper classes for measuring time and printing timings. */ +object BenchmarkUtil { + + /** Execute `action` given number of iterations printing time for each iteration + * and the total time. */ + def measure[T](nIters: Int, okShowIterTime: Boolean = true)(action: Int => Unit): Unit = { + var sum = 0L + for (i <- 0 until nIters) { + val start = System.currentTimeMillis() + val res = action(i) + val end = System.currentTimeMillis() + val iterTime = end - start + if (okShowIterTime) + println(s"Iter $i: $iterTime ms") + sum += iterTime + } + println(s"Total time: $sum ms") + } + + /** Execute block and measure the time of its execution. */ + def measureTime[T](action: => T): (T, Long) = { + val t0 = System.currentTimeMillis() + val res = action + val t = System.currentTimeMillis() + (res, t - t0) + } + + def runTasks(nTasks: Int)(block: Int => Unit) = { + val (_, total) = measureTime { + val tasks = (1 to nTasks).map(iTask => Future(block(iTask))) + val res = Await.result(Future.sequence(tasks), Duration.Inf) + } + println(s"Completed $nTasks tasks in $total msec") + } + +} diff --git a/common/src/main/scala/scalan/util/ClassLoaderUtil.scala b/common/src/main/scala/scalan/util/ClassLoaderUtil.scala new file mode 100644 index 0000000000..332b34466f --- /dev/null +++ b/common/src/main/scala/scalan/util/ClassLoaderUtil.scala @@ -0,0 +1,16 @@ +package scalan.util + +import java.io.File +import java.net.URLClassLoader + +object ClassLoaderUtil { + def classPath(loader: ClassLoader): Seq[File] = loader match { + case loader: URLClassLoader => + loader.getURLs.map(FileUtil.urlToFile) ++ classPath(loader.getParent) + case _ => + Nil + } + + def URLClassLoader(files: TraversableOnce[File], parent: ClassLoader): URLClassLoader = + new URLClassLoader(files.map(_.toURI.toURL).toArray, parent) +} diff --git a/common/src/main/scala/scalan/util/CollectionUtil.scala b/common/src/main/scala/scalan/util/CollectionUtil.scala new file mode 100644 index 0000000000..aae8ebdca4 --- /dev/null +++ b/common/src/main/scala/scalan/util/CollectionUtil.scala @@ -0,0 +1,337 @@ +package scalan.util + +import java.util +import java.util.Objects +import java.util.function.BiConsumer + +import scala.collection.{Seq, mutable, GenIterable} +import scala.collection.mutable.{HashMap, ArrayBuffer} +import scala.collection.generic.CanBuildFrom +import scala.reflect.ClassTag + +object CollectionUtil { + + def concatArrays[T](xs: Array[T], ys: Array[T]): Array[T] = { + val len = xs.length + ys.length + val result = (xs match { + case arr: Array[AnyRef] => new Array[AnyRef](len) + case arr: Array[Byte] => new Array[Byte](len) + case arr: Array[Short] => new Array[Short](len) + case arr: Array[Int] => new Array[Int](len) + case arr: Array[Long] => new Array[Long](len) + case arr: Array[Char] => new Array[Char](len) + case arr: Array[Float] => new Array[Float](len) + case arr: Array[Double] => new Array[Double](len) + case arr: Array[Boolean] => new Array[Boolean](len) + }).asInstanceOf[Array[T]] + Array.copy(xs, 0, result, 0, xs.length) + Array.copy(ys, 0, result, xs.length, ys.length) + result + } + + def deepHashCode[T](arr: Array[T]): Int = arr match { + case arr: Array[AnyRef] => util.Arrays.deepHashCode(arr) + case arr: Array[Byte] => util.Arrays.hashCode(arr) + case arr: Array[Short] => util.Arrays.hashCode(arr) + case arr: Array[Int] => util.Arrays.hashCode(arr) + case arr: Array[Long] => util.Arrays.hashCode(arr) + case arr: Array[Char] => util.Arrays.hashCode(arr) + case arr: Array[Float] => util.Arrays.hashCode(arr) + case arr: Array[Double] => util.Arrays.hashCode(arr) + case arr: Array[Boolean] => util.Arrays.hashCode(arr) + } + + def foldRight[A,B](xs: Seq[A])(proj: A => B)(f: (A,B) => B): B = + xs.foldRight[B](null.asInstanceOf[B]) { case (a, b) => + b match { + case null => proj(a) + case _ => f(a, b) + } + } + + def createMultiMap[K,V](kvs: GenIterable[(K,V)]): Map[K, ArrayBuffer[V]] = { + val res = HashMap.empty[K, ArrayBuffer[V]] + kvs.foreach { case (k, v) => + if (res.contains(k)) + res(k) += v + else + res += k -> ArrayBuffer(v) + () + } + res.toMap + } + + def joinSeqs[O, I, K](outer: GenIterable[O], inner: GenIterable[I])(outKey: O=>K, inKey: I=>K): GenIterable[(O,I)] = { + val kvs = createMultiMap(inner.map(i => (inKey(i), i))) + val res = outer.flatMap(o => { + val ko = outKey(o) + kvs(ko).map(i => (o,i)) + }) + res + } + + def outerJoinSeqs[O, I, K, R] + (outer: Seq[O], inner: Seq[I]) + (outKey: O=>K, inKey: I=>K) + (projO: (K,O) => R, projI: (K,I) => R, proj:(K,O,I) => R): Seq[(K,R)] = { + val res = ArrayBuffer.empty[(K,R)] + val kis = inner.map(i => (inKey(i), i)) + val kvs = createMultiMap(kis) + val outerKeys = mutable.Set.empty[K] + for (o <- outer) { + val ko = outKey(o) + outerKeys += ko + if (!kvs.contains(ko)) + res += ((ko, projO(ko, o))) + else + for (i <- kvs(ko)) + res += ((ko, proj(ko, o, i))) + } + for ((k,i) <- kis if !outerKeys.contains(k)) + res += ((k, projI(k, i))) + res + } + + def outerJoin[K, L, R, O] + (left: Map[K, L], right: Map[K, R]) + (l: (K,L) => O, r: (K,R) => O, inner: (K,L,R) => O): Map[K,O] = { + val res = HashMap.empty[K, O] + val lks = left.keySet + val rks = right.keySet + val leftOnly = lks diff rks + val rightOnly = rks diff lks + val both = lks intersect rks + for (lk <- leftOnly) + res += lk -> l(lk, left(lk)) + for (rk <- rightOnly) + res += rk -> r(rk, right(rk)) + for (k <- both) + res += k -> inner(k, left(k), right(k)) + res.toMap + } + + def join[K,V,R](ks: List[K], kv: Map[K,V])(f: (K,V) => R): List[R] = { + val vs = ks.map(k => kv.get(k) match { + case Some(v) => v + case None => sys.error(s"Cannot find value for key $k") + }) + (ks zip vs).map(f.tupled) + } + + implicit class AnyOps[A](val x: A) extends AnyVal { + def zipWithExpandedBy[B](f: A => List[B]): List[(A,B)] = { + val ys = f(x) + List.fill(ys.length)(x) zip ys + } + def traverseDepthFirst(f: A => List[A]): List[A] = { + var all: List[A] = Nil + var stack = List(x) + while (stack.nonEmpty) { + val h = stack.head + stack = stack.tail + + var next = f(h).reverse + while (next.nonEmpty) { + stack = next.head :: stack + next = next.tail + } + all = h :: all + } + all.reverse + } + } + + implicit class AnyRefOps[A <: AnyRef](val x: A) extends AnyVal { + def transformConserve(f: A => A) = { + val newX = f(x) + if (newX eq x) x else newX + } + } + + implicit class OptionOps[A](val source: Option[A]) extends AnyVal { + def mergeWith[K](other: Option[A], merge: (A,A) => A): Option[A] = (source, other) match { + case (_, None) => source + case (None, Some(_)) => other + case (Some(x), Some(y)) => Some(merge(x, y)) + } + } + implicit class OptionOfAnyRefOps[A <: AnyRef](val source: Option[A]) extends AnyVal { + def mapConserve[B <: AnyRef](f: A => B): Option[B] = source match { + case Some(a) => + val b = f(a) + if (b.eq(a)) source.asInstanceOf[Option[B]] + else Some(b) + case None => None + } + } + + implicit class HashMapOps[K,V](val source: java.util.HashMap[K,V]) extends AnyVal { + def toImmutableMap: Map[K,V] = { + var res = Map[K,V]() + source.forEach((t: K, u: V) => res = res + (t -> u)) + res + } + } + + implicit class TraversableOps[A, Source[X] <: GenIterable[X]](val xs: Source[A]) extends AnyVal { + + def filterCast[B:ClassTag](implicit cbf: CanBuildFrom[Source[A], B, Source[B]]): Source[B] = { + val b = cbf() + for (x <- xs) { + x match { + case y: B => + b += y + case _ => + } + } + b.result() + } + + def cast[B:ClassTag](implicit cbf: CanBuildFrom[Source[A], B, Source[B]]): Source[B] = { + for (x <- xs) { + assert(x match { case _: B => true case _ => false}, s"Value $x doesn't conform to type ${reflect.classTag[B]}") + } + xs.asInstanceOf[Source[B]] + } + + /** Applies 'f' to elements of 'xs' until 'f' returns Some(b), + * which is immediately returned as result of this method. + * If not such element found, returns None as result. */ + def findMap[B](f: A => Option[B]): Option[B] = { + for (x <- xs) { + val y = f(x) + if (y.isDefined) return y + } + return None + } + + def filterMap[B](f: A => Option[B])(implicit cbf: CanBuildFrom[Source[A], B, Source[B]]): Source[B] = { + val b = cbf() + for (x <- xs) { + f(x) match { + case Some(y) => + b += y + case None => + } + } + b.result() + } + + def mapUnzip[B1, B2](f: A => (B1,B2)) + (implicit cbf1: CanBuildFrom[Source[A], B1, Source[B1]], + cbf2: CanBuildFrom[Source[A], B2, Source[B2]]): (Source[B1], Source[B2]) = + { + val b1 = cbf1() + val b2 = cbf2() + for (x <- xs) { + val (y1, y2) = f(x) + b1 += y1; b2 += y2 + } + (b1.result(), b2.result()) + } + + def mapUnzip[B1, B2, B3](f: A => (B1,B2,B3)) + (implicit cbf1: CanBuildFrom[Source[A], B1, Source[B1]], + cbf2: CanBuildFrom[Source[A], B2, Source[B2]], + cbf3: CanBuildFrom[Source[A], B3, Source[B3]]): (Source[B1], Source[B2], Source[B3]) = + { + val b1 = cbf1() + val b2 = cbf2() + val b3 = cbf3() + for (x <- xs) { + val (y1, y2, y3) = f(x) + b1 += y1; b2 += y2; b3 += y3 + } + (b1.result(), b2.result(), b3.result()) + } + + def distinctBy[K](key: A => K)(implicit cbf: CanBuildFrom[Source[A], A, Source[A]]): Source[A] = { + val keys = mutable.Set[K]() + val b = cbf() + for (x <- xs) { + val k = key(x) + if (!keys.contains(k)) { + b += x + keys += k + } + } + b.result() + } + + /** Apply m for each element of this collection, group by key and reduce each group using r. + * @returns one item for each group in a new collection of (K,V) pairs. */ + def mapReduce[K, V](map: A => (K, V))(reduce: (V, V) => V) + (implicit cbf: CanBuildFrom[Source[A], (K,V), Source[(K,V)]]): Source[(K, V)] = { + val result = scala.collection.mutable.LinkedHashMap.empty[K, V] + xs.foldLeft(result)((r, x) => { + val (key, value) = map(x) + result.update(key, if (result.contains(key)) reduce(result(key), value) else value) + result + }) + val b = cbf() + for (kv <- result) b += kv + b.result() + } + + def mergeWith[K] + (ys: Source[A], key: A => K, merge: (A,A) => A) + (implicit cbf: CanBuildFrom[Source[A], A, Source[A]]): Source[A] = { + val b = cbf() + for (v <- (xs ++ ys).mapReduce(x => (key(x), x))(merge)) + b += v._2 + b.result() + } + + def partitionByType[B <: A, C <: A] + (implicit tB: ClassTag[B], + cbB: CanBuildFrom[Source[A], B, Source[B]], + cbC: CanBuildFrom[Source[A], C, Source[C]]): (Source[B], Source[C]) = { + val bs = cbB() + val cs = cbC() + for (x <- xs) + if (tB.runtimeClass.isAssignableFrom(x.getClass)) + bs += x.asInstanceOf[B] + else + cs += x.asInstanceOf[C] + (bs.result(), cs.result()) + } + + private def flattenIter(i: Iterator[_]): Iterator[_] = i.flatMap(x => x match { + case nested: GenIterable[_] => nested + case arr: Array[_] => arr.iterator + case _ => Iterator.single(x) + }) + + def sameElements2[B >: A](that: GenIterable[B]): Boolean = { + val i1: Iterator[Any] = flattenIter(xs.iterator) + val i2: Iterator[Any] = flattenIter(that.iterator) + i1.sameElements(i2) + } + + def deepHashCode: Int = { + var result: Int = 1 + for (x <- xs) { + val elementHash = x match { + case arr: Array[_] => CollectionUtil.deepHashCode(arr) + case _ => Objects.hashCode(x) + } + result = 31 * result + elementHash; + } + result + } + } + + private def sameLengthErrorMsg[A,B](xs: Seq[A], ys: Seq[B]) = { + s"Collections should have same length but was ${xs.length} and ${ys.length}:\n xs=$xs;\n ys=$ys" + } + + def assertSameLength[A,B](xs: Seq[A], ys: Seq[B]) = { + assert(xs.length == ys.length, sameLengthErrorMsg(xs, ys)) + } + + def requireSameLength[A,B](xs: Seq[A], ys: Seq[B]) = { + require(xs.length == ys.length, sameLengthErrorMsg(xs, ys)) + } +} + + diff --git a/common/src/main/scala/scalan/util/Extensions.scala b/common/src/main/scala/scalan/util/Extensions.scala new file mode 100644 index 0000000000..d2162d9c7c --- /dev/null +++ b/common/src/main/scala/scalan/util/Extensions.scala @@ -0,0 +1,210 @@ +package scalan.util + +import java.math.BigInteger +import java.nio.ByteBuffer + +import scala.language.higherKinds + +object Extensions { + implicit class BooleanOps(val b: Boolean) extends AnyVal { + /** Convert true to 1 and false to 0 + * @since 2.0 + */ + def toByte: Byte = if (b) 1 else 0 + } + + /** @hotspot it is used in deserialization so we avoid allocation by any means. */ + @inline final def toUByte(b: Byte) = b & 0xFF + + implicit class ByteOps(val b: Byte) extends AnyVal { + @inline def toUByte: Int = Extensions.toUByte(b) + + def addExact(b2: Byte): Byte = { + val r = b + b2 + if (r < Byte.MinValue || r > Byte.MaxValue) + throw new ArithmeticException("Byte overflow") + r.toByte + } + + def subtractExact(b2: Byte): Byte = { + val r = b - b2 + if (r < Byte.MinValue || r > Byte.MaxValue) + throw new ArithmeticException("Byte overflow") + r.toByte + } + + def multiplyExact(b2: Byte): Byte = { + val r = b * b2 + if (r < Byte.MinValue || r > Byte.MaxValue) + throw new ArithmeticException("Byte overflow") + r.toByte + } + + def toShort: Short = b.toShort + def toInt: Int = b.toInt + def toLong: Long = b.toLong + + /** Absolute value of this numeric value. + * @since 2.0 + */ + def toAbs: Byte = if (b < 0) (-b).toByte else b + + /** Compares this numeric with that numeric for order. Returns a negative integer, zero, or a positive integer as the + * `this` is less than, equal to, or greater than `that`. + */ + def compare(that: Byte): Byte = if (b < that) -1.toByte else if (b == that) 0.toByte else 1.toByte + } + + implicit class ShortOps(val x: Short) extends AnyVal { + def toByteExact: Byte = { + if (x < Byte.MinValue || x > Byte.MaxValue) + throw new ArithmeticException("Byte overflow") + x.toByte + } + + def addExact(y: Short): Short = { + val r = x + y + if (r < Short.MinValue || r > Short.MaxValue) + throw new ArithmeticException("Short overflow") + r.toShort + } + + def subtractExact(y: Short): Short = { + val r = x - y + if (r < Short.MinValue || r > Short.MaxValue) + throw new ArithmeticException("Short overflow") + r.toShort + } + + def multiplyExact(y: Short): Short = { + val r = x * y + if (r < Short.MinValue || r > Short.MaxValue) + throw new ArithmeticException("Short overflow") + r.toShort + } + } + + implicit class IntOps(val x: Int) extends AnyVal { + def toByteExact: Byte = { + if (x < Byte.MinValue || x > Byte.MaxValue) + throw new ArithmeticException("Byte overflow") + x.toByte + } + + def toShortExact: Short = { + if (x < Short.MinValue || x > Short.MaxValue) + throw new ArithmeticException("Short overflow") + x.toShort + } + + /** Absolute value of this numeric value. + * @since 2.0 + */ + def toAbs: Int = if (x < 0) -x else x + + /** Compares this numeric with that numeric for order. Returns a negative integer, zero, or a positive integer as the + * `this` is less than, equal to, or greater than `that`. + */ + def compare(that: Int): Int = if (x < that) -1 else if (x == that) 0 else 1 + } + + implicit class LongOps(val x: Long) extends AnyVal { + def toByteExact: Byte = { + if (x < Byte.MinValue || x > Byte.MaxValue) + throw new ArithmeticException("Byte overflow") + x.toByte + } + + def toShortExact: Short = { + if (x < Short.MinValue || x > Short.MaxValue) + throw new ArithmeticException("Short overflow") + x.toShort + } + + def toIntExact: Int = { + if (x < Int.MinValue || x > Int.MaxValue) + throw new ArithmeticException("Int overflow") + x.toInt + } + } + + implicit class BigIntegerOps(val x: BigInteger) extends AnyVal { + /** Returns this `mod` Q, i.e. remainder of division by Q, where Q is an order of the cryprographic group. + * @since 2.0 + */ + def modQ: BigInt = ??? + + /** Adds this number with `other` by module Q. + * @since 2.0 + */ + def plusModQ(other: BigInt): BigInt = ??? + + /** Subracts this number with `other` by module Q. + * @since 2.0 + */ + def minusModQ(other: BigInt): BigInt = ??? + + /** Multiply this number with `other` by module Q. + * @since 2.0 + */ + def multModQ(other: BigInt): BigInt = ??? + + /** Multiply this number with `other` by module Q. + * @since Mainnet + */ + def multInverseModQ: BigInt = ??? + + /** Checks this {@code BigInteger} can be cust to 256 bit two's-compliment representation, + * checking for lost information. If the value of this {@code BigInteger} + * is out of the range of the 256 bits, then an {@code ArithmeticException} is thrown. + * + * @return this {@code BigInteger} if the check is successful + * @throws ArithmeticException if the value of {@code this} will + * not exactly fit in a 256 bit range. + * @see BigInteger#longValueExact + */ + @inline final def to256BitValueExact: BigInteger = { + if (x.bitLength() <= 255) x + else + throw new ArithmeticException("BigInteger out of 256 bit range"); + } + } + + implicit class OptionOps[T](val opt: Option[T]) extends AnyVal { + /** Elvis operator for Option. See https://en.wikipedia.org/wiki/Elvis_operator*/ + def ?:(whenNone: => T): T = if (opt.isDefined) opt.get else whenNone + } + + implicit class ProductOps(val source: Product) extends AnyVal { + def toArray: Array[Any] = { + val arity = source.productArity + val res = new Array[Any](arity) + var i = 0 + while (i < arity) { + res(i) = source.productElement(i) + i += 1 + } + res + } + } + + implicit class ByteBufferOps(val buf: ByteBuffer) extends AnyVal { + def toBytes: Array[Byte] = { + val res = new Array[Byte](buf.position()) + buf.array().copyToArray(res, 0, res.length) + res + } + def getBytes(size: Int): Array[Byte] = { + val res = new Array[Byte](size) + buf.get(res) + res + } + def getOption[T](getValue: => T): Option[T] = { + val tag = buf.get() + if (tag != 0) + Some(getValue) + else + None + } + } +} diff --git a/common/src/main/scala/scalan/util/FileUtil.scala b/common/src/main/scala/scalan/util/FileUtil.scala new file mode 100644 index 0000000000..56e138e85f --- /dev/null +++ b/common/src/main/scala/scalan/util/FileUtil.scala @@ -0,0 +1,278 @@ +package scalan.util + +import java.io._ +import java.net.{JarURLConnection, URL} +import java.nio.charset.Charset +import java.nio.file._ +import java.nio.file.attribute.BasicFileAttributes +import java.util.jar.JarFile +import org.apache.commons.io.{FileUtils, IOUtils} +import scala.Console +import scala.collection.JavaConverters._ +import scalan.util.StringUtil.StringUtilExtensions +import scalan.util.CollectionUtil.AnyOps + +object FileUtil { + def read(file: File): String = FileUtils.readFileToString(file, Charset.defaultCharset()) + + def withFile(file: File)(f: PrintWriter => Unit): Unit = { + if (file.isDirectory && !file.delete()) { + throw new RuntimeException(s"File $file is a non-empty directory") + } else { + file.getParentFile.mkdirs() + val stream = new PrintWriter(new FileOutputStream(file)) + try { + f(stream) + } finally { + stream.close() + } + } + } + + def write(file: File, text: String): Unit = withFile(file) { _.print(text) } + + def withStdOutAndErr(out: PrintStream)(func: => Unit): Unit = { + val oldStdOut = System.out + val oldStdErr = System.err + try { + System.setOut(out) + System.setErr(out) + Console.withOut(out)(Console.withErr(out)(func)) + } finally { + out.flush() + System.setOut(oldStdOut) + System.setErr(oldStdErr) + } + } + + def captureStdOutAndErr(func: => Unit): String = { + val out = new ByteArrayOutputStream + val ps = new PrintStream(out) + try {withStdOutAndErr(ps)(func)} + finally {ps.close() } + out.toString + } + + def copy(source: File, target: File): Unit = + if (source.isFile) + FileUtils.copyFile(source, target, false) + else + FileUtils.copyDirectory(source, target, false) + + def copyFromClassPath(source: String, target: File, classLoader: ClassLoader = getClass.getClassLoader): Unit = { + target.getParentFile.mkdirs() + val urls = classLoader.getResources(source) + if (urls.hasMoreElements) { + if (source.endsWith("/")) { + urls.asScala.foreach { url => + url.getProtocol match { + case "file" => + FileUtils.copyDirectory(urlToFile(url), target, false) + case "jar" => + val jarFile = new JarFile(jarUrlToJarFile(url)) + jarFile.entries().asScala.foreach { entry => + val entryPath = entry.getName + if (entryPath.startsWith(source)) { + val entryTarget = new File(target, entryPath.stripPrefix(source)) + if (entry.isDirectory) + entryTarget.mkdirs() + else { + // copyInputStreamToFile closes stream + FileUtils.copyInputStreamToFile(jarFile.getInputStream(entry), entryTarget) + } + } + } + } + } + } else { + val url = urls.nextElement() + if (urls.hasMoreElements) { + throw new IllegalArgumentException(s"Multiple $source resources found on classpath") + } else { + // copyInputStreamToFile closes stream + FileUtils.copyInputStreamToFile(url.openStream(), target) + } + } + } else + throw new IllegalArgumentException(s"Resource $source not found on classpath") + } + + def classPathLastModified(source: String, classLoader: ClassLoader = getClass.getClassLoader) = { + def urlLastModified(url: URL): Long = { + url.getProtocol match { + case "file" => + val file = urlToFile(url) + if (file.isDirectory) { + var result = file.lastModified() + Files.walkFileTree(file.toPath, new SimpleFileVisitor[Path]() { + override def visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult = { + result = math.max(result, file.toFile.lastModified()) + FileVisitResult.CONTINUE + } + + override def postVisitDirectory(dir: Path, exc: IOException): FileVisitResult = { + if (exc == null) { + result = math.max(result, dir.toFile.lastModified()) + FileVisitResult.CONTINUE + } else { + throw exc + } + } + }) + result + } else + file.lastModified() + case "jar" => + jarUrlToJarFile(url).lastModified() + } + } + + val urls = classLoader.getResources(source) + if (urls.hasMoreElements) { + urls.asScala.map(urlLastModified).max + } else + throw new IllegalArgumentException(s"Resource $source not found on classpath") + } + + def jarUrlToJarFile(url: URL) = { + val jarFileUrl = url.openConnection().asInstanceOf[JarURLConnection].getJarFileURL + urlToFile(jarFileUrl) + } + + /** + * Copy file source to targetDir, keeping the original file name + */ + def copyToDir(source: File, targetDir: File): Unit = + copy(source, new File(targetDir, source.getName)) + + def move(source: File, target: File): Unit = + if (source.isFile) + FileUtils.moveFile(source, target) + else + FileUtils.moveDirectory(source, target) + + /** + * Add header into the file + */ + def addHeader(file: File, header: String): Unit = write(file, header + "\n" + read(file)) + + /** + * Like fileOrDirectory.delete() but works for non-empty directories + * and throws exceptions instead of returning false on failure + */ + def delete(fileOrDirectory: File): Unit = { + deleteRecursive(fileOrDirectory.toPath) + } + + def deleteIfExist(fileOrDirectory: File): Unit = { + if (fileOrDirectory.exists()) delete(fileOrDirectory) + } + + def deleteRecursive(path: Path) { + Files.walkFileTree(path, new SimpleFileVisitor[Path]() { + override def visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult = { + Files.delete(file) + FileVisitResult.CONTINUE + } + + override def visitFileFailed(file: Path, exc: IOException): FileVisitResult = { + Files.delete(file) + FileVisitResult.CONTINUE + } + + override def postVisitDirectory(dir: Path, exc: IOException): FileVisitResult = { + if (exc == null) { + Files.delete(dir) + FileVisitResult.CONTINUE + } + else { + throw exc + } + } + }) + } + + def currentWorkingDir = Paths.get("").toAbsolutePath.toFile + + def file(first: String, rest: String*): File = + file(new File(first), rest: _*) + + def file(first: File, rest: String*): File = + rest.foldLeft(first) { (file, child) => new File(file, child) } + + final val AcceptAllFiles = new FilenameFilter { + override def accept(dir: File, name: String): Boolean = !file(dir, name).isDirectory + } + final val AcceptAllDirectories = new FilenameFilter { + override def accept(dir: File, name: String): Boolean = file(dir, name).isDirectory + } + + /** + * Same as dir.listFiles(filter), except it returns empty array instead of null + * if dir doesn't exist or is not a directory + */ + def listFiles(dir: File, filter: FilenameFilter = AcceptAllFiles): Array[File] = dir.listFiles(filter) match { + case null => Array.empty + case array => array + } + + def listDirectories(dir: File): Array[File] = listFiles(dir, AcceptAllDirectories) + + /** Starts from dir and builds an array of sub-directories including dir */ + def listDirectoriesRecursive(dir: File): Array[File] = { + dir.traverseDepthFirst(f => listDirectories(f).toList).toArray + } + + def listFilesRecursive(dir: File): Array[File] = { + val dirs = listDirectoriesRecursive(dir) + for {d <- dirs; f <- listFiles(d)} yield f + } + + def readAndCloseStream(stream: InputStream) = { + try { + IOUtils.toString(stream, Charset.defaultCharset()) + } finally { + IOUtils.closeQuietly(stream) + } + } + + def stripExtension(fileName: String) = + fileName.lastIndexOf('.') match { + case -1 => + fileName + case n => + fileName.substring(0, n) + } + + def replaceOrAppendExtension(fileName: String, extension: String): String = + s"${stripExtension(fileName) }.$extension" + + def modifyName(file: File)(f: String => String): File = { + val parent = file.getParentFile + val name = file.getName + val newName = f(name) + new File(parent, newName) + } + + def urlToFile(url: URL) = Paths.get(url.toURI).toFile + + /** Accepts an arbitrary (printable) string and returns a similar string + * which can be used as a file name. For convenience, replaces spaces with hyphens. + */ + def cleanFileName(string: String) = string. + replaceAll("""[ /\\:;<>|?*^]""", "_"). + replaceAll("""['"]""", "") + + def isBadFileName(string: String) = cleanFileName(string) != string + + def extractModuleName(path: String, sourceDir: String = "src/main/scala"): String = { + val moduleDir = path.prefixBefore("/" + sourceDir) + if (moduleDir.length == path.length) return "" + moduleDir.lastComponent('/') + } + +} + +case class ExtensionFilter(extension: String) extends FilenameFilter { + override def accept(dir: File, name: String): Boolean = name.toLowerCase.endsWith(s".$extension") +} diff --git a/common/src/main/scala/scalan/util/GraphUtil.scala b/common/src/main/scala/scalan/util/GraphUtil.scala new file mode 100644 index 0000000000..df6e44f4ff --- /dev/null +++ b/common/src/main/scala/scalan/util/GraphUtil.scala @@ -0,0 +1,69 @@ +package scalan.util + +import scalan.DFunc +import debox.{Set => DSet, Buffer => DBuffer} +import spire.syntax.all.cfor +import scala.reflect.ClassTag + +object GraphUtil { + + /** Build a set of reachable nodes starting form the given nodes and following + * the given neighbours relations. Depth first search algorithm is used. + * @tparam A type of value representing node, should implement equality which is used in debox.Set + * @param starts starting nodes for the search + * @param neighbours a function representing the adjacency matrix of the graph + * @return Set of nodes reachable from the `starts` including `starts` themselves + */ + def depthFirstSetFrom[@specialized(Int) A: ClassTag](starts: DBuffer[A])(neighbours: DFunc[A, DBuffer[A]]): DSet[A] = { + val visited = DSet.ofSize[A](starts.length) + + def visit(s: A): Unit = { + if (!(visited(s))) { + visited += s + val ns = neighbours(s) + cfor(0)(_ < ns.length, _ + 1) { i => + visit(ns(i)) + } + } + } + + cfor(0)(_ < starts.length, _ + 1) { i => + visit(starts(i)) + } + visited + } + + /** Collect and topologically order all reachable nodes starting form the given nodes and following + * the given neighbours relations. Depth first search algorithm is used. + * @tparam A type of value representing node, should implement equality which is used in debox.Set + * @param starts starting nodes for the search + * @param neighbours a function representing the adjacency matrix of the graph + * @return Topologically ordered sequence of nodes reachable from the `starts` including `starts` themselves + */ + def depthFirstOrderFrom[@specialized(Int) A: ClassTag](starts: DBuffer[A], neighbours: DFunc[A, DBuffer[A]]): DBuffer[A] = { + val visited = DSet.ofSize[A](starts.length) + val res = DBuffer.ofSize[A](starts.length) + def visit(s: A): Unit = { + if (!(visited(s))) { + visited += s + // first visit all deps recursively + val ns = neighbours(s) + cfor(0)(_ < ns.length, _ + 1) { i => + visit(ns(i)) + } + // then append this node to result + res += s + } + } + + val len = starts.length + cfor(0)(_ < len, _ + 1) { i => + visit(starts(i)) + } + res + } + +} + + + diff --git a/common/src/main/scala/scalan/util/MemoizedFunc.scala b/common/src/main/scala/scalan/util/MemoizedFunc.scala new file mode 100644 index 0000000000..48df94788a --- /dev/null +++ b/common/src/main/scala/scalan/util/MemoizedFunc.scala @@ -0,0 +1,28 @@ +package scalan.util + +import scalan.AVHashMap + +/** Transforms a given function into memoized equivalent function. + * Memoization is implemented by computing function f only once for each + * argument value and storing computed result in a hash table, so that + * it can be later retrieved on repeated invocations with the same argument. + * The cache of computed results can be cleared by calling `reset`. + */ +class MemoizedFunc(f: AnyRef => AnyRef) { + private var _table: AVHashMap[AnyRef, AnyRef] = AVHashMap(100) + /** Apply the function to the given argument using memoized result if available. */ + def apply[T <: AnyRef](x: T): AnyRef = { + var v = _table(x) + if (v == null) { + v = f(x) + _table.put(x, v) + } + v + } + /** Clears the cache of memoized results. */ + def reset() = { + _table = AVHashMap(100) + } +} + + diff --git a/common/src/main/scala/scalan/util/PrintExtensions.scala b/common/src/main/scala/scalan/util/PrintExtensions.scala new file mode 100644 index 0000000000..d9639560cb --- /dev/null +++ b/common/src/main/scala/scalan/util/PrintExtensions.scala @@ -0,0 +1,38 @@ +package scalan.util + +/** Helper methods for pretty printing of collections and optional values. */ +object PrintExtensions { + implicit class AnyExtension[A](x: A) { + def when(p: A => Boolean, show: A => String, default: String = "") = if (p(x)) show(x) else default + } + implicit class IterableExtensions[A](val it: Iterable[A]) extends AnyVal + { + def opt(show: Iterable[A] => String = _.mkString, default: String = ""): String = + if (it.isEmpty) default else show(it) + + def rep(show: A => String = _.toString, sep: String = ", "): String = it.map(show).mkString(sep) + + def asTypeParams(show: A => String = _.toString) = + if (it.nonEmpty) it.map(show).mkString("[", ", ", "]") else "" + + def optList(start: String, end: String, sep: String = ", ", show: A => String = _.toString) = + if (it.nonEmpty) it.map(show).mkString(start, sep, end) else "" + } + + implicit class OptionExtensions[A](val opt: Option[A]) extends AnyVal { + def opt(show: A => String = _.toString, default: String = ""): String = opt match { + case None => default + case Some(a) => show(a) + } + def ifDefined(value: String): String = if (opt.isDefined) value else "" + } + + implicit class BooleanExtensions(val opt: Boolean) extends AnyVal { + def opt(show: => String, default: => String = ""): String = if(opt) show else default + } + + def join(xs: Any*) = xs.map { + case x: Iterable[_] => x.rep() + case x => x.toString + }.filter(_.nonEmpty).rep() +} diff --git a/common/src/main/scala/scalan/util/ProcessUtil.scala b/common/src/main/scala/scalan/util/ProcessUtil.scala new file mode 100644 index 0000000000..55bafb07bb --- /dev/null +++ b/common/src/main/scala/scalan/util/ProcessUtil.scala @@ -0,0 +1,56 @@ +package scalan.util + +import java.io.File + +import scala.collection.mutable +import scala.sys.process.ProcessLogger + +case class ProcessOutput(stdOutLines: Seq[String], stdErrLines: Seq[String], interleavedLines: Seq[String]) { + lazy val stdOutAll = stdOutLines.mkString("\n") + lazy val stdErrAll = stdErrLines.mkString("\n") + lazy val interleavedAll = interleavedLines.mkString("\n") +} + +object ProcessUtil { + /** Similar to scala.sys.process.ProcessBuilder.!!, but collects both error and output streams and includes + * the complete output into the exception message on failure */ + def launch(command: Seq[String], workingDir: File = FileUtil.currentWorkingDir, extraEnv: Map[String, String] = Map.empty, printToConsole: Boolean = false): ProcessOutput = { + val absoluteWorkingDir = workingDir.getAbsoluteFile + val builder = scala.sys.process.Process(command, absoluteWorkingDir, extraEnv.toSeq: _*) + val stdOutBuffer = mutable.ArrayBuffer.empty[String] + val stdErrBuffer = mutable.ArrayBuffer.empty[String] + val interleavedBuffer = mutable.ArrayBuffer.empty[String] + val logger = ProcessLogger( + outLine => { + if (printToConsole) { Console.out.println(outLine) } + stdOutBuffer += outLine + interleavedBuffer += outLine + }, + errLine => { + if (printToConsole) { Console.err.println(errLine) } + stdErrBuffer += errLine + interleavedBuffer += errLine + } + ) + (builder ! logger) match { + case 0 => + ProcessOutput(stdOutBuffer, stdErrBuffer, interleavedBuffer) + case exitCode => + val envPrefix = extraEnv.map { + case (name, value) => s"$name=${escapeCommandLineArg(value)} " + }.mkString("") + val commandString = command.map(escapeCommandLineArg).mkString(" ") + throw new RuntimeException(s"Executing `$envPrefix$commandString` in directory $absoluteWorkingDir returned exit code $exitCode with following output:\n${interleavedBuffer.mkString("\n")}") + } + } + + private def escapeCommandLineArg(arg: String) = { + if (arg.contains(" ") && !arg.contains("'")) + "'" + arg + "'" + else { + val escaped = arg.replace("""\""", """\\""").replace("$", """\$"""). + replace("`", """\`""").replace("\"", """\"""").replace("\n", "\\\n") + if (escaped.contains(" ") || escaped != arg) StringUtil.quote(escaped) else arg + } + } +} diff --git a/common/src/main/scala/scalan/util/ReflectionUtil.scala b/common/src/main/scala/scalan/util/ReflectionUtil.scala new file mode 100644 index 0000000000..e2f57af5ea --- /dev/null +++ b/common/src/main/scala/scalan/util/ReflectionUtil.scala @@ -0,0 +1,41 @@ +package scalan.util + +import java.lang.reflect.{Method, AnnotatedElement} + +import scala.reflect.{classTag, ClassTag} +import scalan.OverloadId + +object ReflectionUtil { + def jAnnotation[A <: java.lang.annotation.Annotation : ClassTag](element: AnnotatedElement) = + Option(element.getAnnotation(classTag[A].runtimeClass.asInstanceOf[Class[A]])) + + def overloadId(method: Method) = jAnnotation[OverloadId](method).map(_.value) + + /** Returns the superclass for an anonymous class produced by mixing in traits; the argument otherwise. */ + def namedSuperclass(clazz: Class[_]) = { + if (clazz.getSimpleName.contains("$anon$")) { + val superclass = clazz.getSuperclass + if (superclass == classOf[Object]) { + // clazz is composed of traits only, return the first one + clazz.getInterfaces.head + } else + superclass + } else + clazz + } + + implicit class ClassOps(val cl: Class[_]) extends AnyVal { + private def isSpecialChar(c: Char): Boolean = { + ('0' <= c && c <= '9') || c == '$' + } + def safeSimpleName: String = { + if (cl.getEnclosingClass == null) return cl.getSimpleName + val simpleName = cl.getName.substring(cl.getEnclosingClass.getName.length) + val length = simpleName.length + var index = 0 + while (index < length && isSpecialChar(simpleName.charAt(index))) { index += 1 } + // Eventually, this is the empty string iff this is an anonymous class + simpleName.substring(index) + } + } +} diff --git a/common/src/main/scala/scalan/util/ScalaNameUtil.scala b/common/src/main/scala/scalan/util/ScalaNameUtil.scala new file mode 100644 index 0000000000..fadc8126ef --- /dev/null +++ b/common/src/main/scala/scalan/util/ScalaNameUtil.scala @@ -0,0 +1,34 @@ +package scalan.util + +object ScalaNameUtil { + val opChars = Set('+', '-', '*', '/', ':', '>', '<', '=', '!', '@', '#', '%', + '&', '~', '?', '|', '\\', '^') + + def cleanNestedClassName(className: String): String = + cleanScalaName(className.substring(className.lastIndexOf("$") + 1)) + + def cleanScalaName(name: String): String = { + name.replace("$plus", "+").replace("$minus", "-"). + replace("$times", "*").replace("$div", "/"). + replace("$colon", ":").replace("$greater", ">"). + replace("$less", "<").replace("$eq", "="). + replace("$bang", "!").replace("$at", "@"). + replace("$hash", "#").replace("$percent", "%"). + replace("$amp", "&").replace("$tilde", "~"). + replace("$qmark", "?").replace("$bar", "|"). + replace("$bslash", "\\").replace("$up", "^") + } + + def isOpName(name: String) = !name.isEmpty && opChars.contains(name.last) + + object PackageAndName { + def unapply(name: String): Option[(List[String], String)] = { + val parts = name.split('.') + if (parts.length > 1) + Some((parts.slice(0, parts.length - 1).toList, parts.last)) + else + None + } + } + +} diff --git a/common/src/main/scala/scalan/util/StringUtil.scala b/common/src/main/scala/scalan/util/StringUtil.scala new file mode 100644 index 0000000000..b58a59662d --- /dev/null +++ b/common/src/main/scala/scalan/util/StringUtil.scala @@ -0,0 +1,67 @@ +package scalan.util + +import spire.syntax.all.cfor + +object StringUtil { + final def quote(x: Any) = "\"" + x + "\"" + + /** Uppercase the first character. */ + final def lowerCaseFirst(s: String) = if (s.isEmpty) { + s + } else { + s.substring(0, 1).toLowerCase + s.substring(1) + } + + /** Emit string representation of `x` into given builder `sb`, + * recursively descending into Array structure of `x`. + */ + final def deepAppend(sb: StringBuilder, x: Any): Unit = { + x match { + case arr: Array[_] => + sb.append("Array(") + if (arr.length > 0) { + deepAppend(sb, arr(0)) + cfor(1)(_ < arr.length, _ + 1) { i => + sb.append(", ") + deepAppend(sb, arr(i)) + } + } + sb.append(")") + case s: String => + sb.append("\"") + sb.append(s) + sb.append("\"") + case _ => sb.append(x) + } + } + + implicit class StringUtilExtensions(val str: String) extends AnyVal { + def isNullOrEmpty = str == null || str.isEmpty + + def stripAndTrim = str.stripMargin.stripPrefix("\n").stripPrefix("\r\n").stripLineEnd + + def lastComponent(sep: Char): String = { + str.substring(str.lastIndexOf(sep) + 1) + } + + def prefixBefore(substr: String): String = { + val pos = str.indexOf(substr) + val res = if (pos == -1) str else str.substring(0, pos) + res + } + + def replaceSuffix(suffix: String, newSuffix: String) = { + if (str.isNullOrEmpty || suffix.isNullOrEmpty) str + else { + val stripped = str.stripSuffix(suffix) + if (stripped.length == str.length) str + else + stripped + (if (newSuffix == null) "" else newSuffix) + } + } + + def opt(show: String => String = _.toString, default: String = ""): String = + if (str.nonEmpty) show(str) else default + } + +} diff --git a/common/src/main/scala/scalan/util/Variance.scala b/common/src/main/scala/scalan/util/Variance.scala new file mode 100644 index 0000000000..2e0ea84841 --- /dev/null +++ b/common/src/main/scala/scalan/util/Variance.scala @@ -0,0 +1,7 @@ +package scalan.util + +sealed trait Variance extends Product with Serializable +case object Invariant extends Variance +case object Covariant extends Variance +case object Contravariant extends Variance + diff --git a/src/main/scala/sigmastate/utils/ByteReader.scala b/common/src/test/resources/root/A.txt similarity index 100% rename from src/main/scala/sigmastate/utils/ByteReader.scala rename to common/src/test/resources/root/A.txt diff --git a/src/main/scala/sigmastate/utils/ByteWriter.scala b/common/src/test/resources/root/B.txt similarity index 100% rename from src/main/scala/sigmastate/utils/ByteWriter.scala rename to common/src/test/resources/root/B.txt diff --git a/src/test/scala/sigmastate/serialization/generators/ValueGenerators.scala b/common/src/test/resources/root/subdir/C.txt similarity index 100% rename from src/test/scala/sigmastate/serialization/generators/ValueGenerators.scala rename to common/src/test/resources/root/subdir/C.txt diff --git a/src/test/scala/sigmastate/utils/ByteArrayBuilderTests.scala b/common/src/test/resources/root/subdir/subsubdir/D.txt similarity index 100% rename from src/test/scala/sigmastate/utils/ByteArrayBuilderTests.scala rename to common/src/test/resources/root/subdir/subsubdir/D.txt diff --git a/common/src/test/scala/scalan/BaseTests.scala b/common/src/test/scala/scalan/BaseTests.scala new file mode 100644 index 0000000000..44542aab7e --- /dev/null +++ b/common/src/test/scala/scalan/BaseTests.scala @@ -0,0 +1,36 @@ +package scalan + +import org.scalatest.words.ResultOfStringPassedToVerb +import org.scalatest.{FlatSpec, _} + +/** + * Standard base class for most test suites. See BaseNestedTests and BaseShouldTests for alternatives + * + * See http://doc.scalatest.org/2.2.4/#org.scalatest.FunSuite. + */ +abstract class BaseTests extends FunSuite with TestUtils + +/** + * Standard base class for test suites with nested tests. + * + * See http://doc.scalatest.org/2.2.4/#org.scalatest.FunSpec. + */ +abstract class BaseNestedTests extends FunSpec with TestUtils + +/** + * See http://doc.scalatest.org/2.2.4/#org.scalatest.FlatSpec. + */ +abstract class BaseShouldTests extends FlatSpec with TestUtils { + protected final class InAndIgnoreMethods2(resultOfStringPassedToVerb: ResultOfStringPassedToVerb) { + + import resultOfStringPassedToVerb.rest + val _inner = new InAndIgnoreMethods(resultOfStringPassedToVerb) + def beArgFor(testFun: String => Unit) { + _inner.in(testFun(rest.trim)) + } + } + + protected implicit def convertToInAndIgnoreMethods2(resultOfStringPassedToVerb: ResultOfStringPassedToVerb) = + new InAndIgnoreMethods2(resultOfStringPassedToVerb) + +} diff --git a/common/src/test/scala/scalan/TestUtils.scala b/common/src/test/scala/scalan/TestUtils.scala new file mode 100644 index 0000000000..75c5568b6f --- /dev/null +++ b/common/src/test/scala/scalan/TestUtils.scala @@ -0,0 +1,43 @@ +package scalan + +import scalan.util.FileUtil +import org.scalactic.TripleEquals +import org.scalatest.{Inside, Matchers, TestSuite} + +/** + * Created by slesarenko on 11/10/2017. + */ +trait TestUtils extends TestSuite with Matchers with Inside with TripleEquals { + def testOutDir = "test-out" + + def testSuffixes = Seq("Suite", "Tests", "It", "_") + + lazy val prefix = { + val suiteName = testSuffixes.foldLeft(getClass.getName)(_.stripSuffix(_)) + val pathComponents = suiteName.split('.') + FileUtil.file(testOutDir, pathComponents: _*) + } + + /* if runs in continuous integration environment */ + def isCI = sys.env.get("CI").flatMap(toBoolean).getOrElse(false) + private def toBoolean(s: String): Option[Boolean] = + scala.util.Try(s.toBoolean).toOption + def pendingOnCI(): Unit = if (isCI) { pending } + + private val _currentTestName = new ThreadLocal[String] + + override def withFixture(test: NoArgTest) = { + _currentTestName.set(test.name) + val outcome = super.withFixture(test) + _currentTestName.set(null) + outcome + } + + protected def currentTestName: String = { + val testName = _currentTestName.get() + assert(testName != null, "currentTestName called outside a test") + testName + } + + protected def currentTestNameAsFileName: String = FileUtil.cleanFileName(currentTestName) +} diff --git a/common/src/test/scala/scalan/util/CollectionUtilTests.scala b/common/src/test/scala/scalan/util/CollectionUtilTests.scala new file mode 100644 index 0000000000..be92a01790 --- /dev/null +++ b/common/src/test/scala/scalan/util/CollectionUtilTests.scala @@ -0,0 +1,226 @@ +package scalan.util + +import scalan.BaseTests + +import scala.collection.{Seq, mutable} +import scala.reflect.ClassTag + +class CollectionUtilTests extends BaseTests { + import scalan.util.CollectionUtil._ + import java.lang.{Byte => JByte, Integer} + + test("concatArrays") { + val xs = Array[Byte](1,2,3) + val ys = Array[Byte](4,5,6) + val zs = concatArrays(xs, ys) + assertResult(Array[Byte](1, 2, 3, 4, 5, 6))(zs) + +// val jxs = Array[JByte](new JByte(1), new JByte(2), new JByte(3)) +// val jys = Array[JByte](new JByte(4), new JByte(5), new JByte(6)) +// val jzs = concatArrays(jxs, jys) +// assertResult(Array[Byte](1, 2, 3, 4, 5, 6))(jzs) + } + + def join(l: Map[Int,Int], r: Map[Int,Int]) = + outerJoin(l, r)((_,l) => l, (_,r) => r, (k,l,r) => l + r) + def joinSeqs(l: Seq[Int], r: Seq[Int]) = + outerJoinSeqs(l, r)(l => l, r => r)((_,l) => l, (_,r) => r, (k,l,r) => l + r).map(_._2) + def joinPairs(l: Seq[(String,Int)], r: Seq[(String,Int)]) = + outerJoinSeqs(l, r)(l => l._1, r => r._1)((_,l) => l._2, (_,r) => r._2, (k,l,r) => l._2 + r._2) + + test("outerJoin maps") { + val left = Map(1 -> 1, 2 -> 2, 3 -> 3) + val right = Map(2 -> 2, 3 -> 3, 4 -> 4) + + assertResult(Map(1 -> 1, 2 -> 4, 3 -> 6, 4 -> 4))(join(left,right)) + assertResult(Map(1 -> 1, 2 -> 2, 3 -> 3))(join(left,Map())) + assertResult(Map(2 -> 2, 3 -> 3, 4 -> 4))(join(Map(), right)) + assertResult(Map(2 -> 4, 3 -> 6, 4 -> 8))(join(right, right)) + } + + test("outerJoinSeqs") { + val left = Seq(1, 2, 3) + val right = Seq(2, 3, 4) + + assertResult(Seq(1, 4, 6, 4))(joinSeqs(left, right)) + assertResult(Seq(1, 2, 3))(joinSeqs(left,Seq())) + assertResult(Seq(2, 3, 4))(joinSeqs(Seq(), right)) + assertResult(Seq(4, 6, 8))(joinSeqs(right, right)) + + val inner = Seq("a" -> 1, "b" -> 2, "c" -> 3) + val outer = Seq("b" -> 2, "c" -> 3, "d" -> 4) + + assertResult(Seq("a" -> 1, "b" -> 4, "c" -> 6, "d" -> 4))(joinPairs(inner, outer)) + assertResult(Seq("a" -> 1, "b" -> 2, "c" -> 3))(joinPairs(inner,Seq())) + assertResult(Seq("b" -> 2, "c" -> 3, "d" -> 4))(joinPairs(Seq(), outer)) + assertResult(Seq("b" -> 4, "c" -> 6, "d" -> 8))(joinPairs(outer, outer)) + } + + test("filterMap") { + val xs = List(1, 2, 3) + xs.filterMap(x => if (x <= 2) Some(s"x = $x") else None) should be(List("x = 1", "x = 2")) + } + + test("mapUnzip") { + val xs = Seq(1, 2, 3) + + { + val (ints, strings, plus1s) = xs.mapUnzip(x => (x, x.toString, x + 1)) + ints shouldBe Seq(1, 2, 3) + strings shouldBe Seq("1", "2", "3") + plus1s shouldBe Seq(2, 3, 4) + } + + { + val (ints, strings) = xs.mapUnzip(x => (x, x.toString)) + ints shouldBe Seq(1, 2, 3) + strings shouldBe Seq("1", "2", "3") + } + } + + test("mapFirst") { + val xs = List(1, 2, 3) + xs.findMap(x => if (x > 2) Some(s"x = $x") else None) should be(Some("x = 3")) + xs.findMap(x => if (x > 3) Some(x) else None) should be(None) + } + + val items: Iterable[(Int, String)] = Array((1, "a"), (2, "b"), (1, "c")) + + test("distinctBy") { + val res = items.distinctBy(_._1) + assertResult(Array((1, "a"), (2, "b")))(res) + } + + test("mapReduce") { + val res = items.mapReduce(p => (p._1, p._2))((v1, v2) => v1 + v2) + assertResult(List((1, "ac"), (2, "b")))(res) + } + + test("mergeWith") { + type V = (Int, String) + def key(p: V) = p._1 + def merge(v1: V, v2: V) = (v1._1, v1._2 + v2._2) + + { + val res = List().mergeWith(List(), key, merge) + assertResult(List())(res) + } + { + val res = List((1, "a"), (2, "b"), (1, "c")).mergeWith(List(), key, merge) + assertResult(List((1, "ac"), (2, "b")))(res) + } + { + val res = List().mergeWith(List((1, "a"), (2, "b"), (1, "c")), key, merge) + assertResult(List((1, "ac"), (2, "b")))(res) + } + { + val ys = List((2, "c"), (3, "d")) + val res = List((1, "a"), (2, "b"), (1, "c")).mergeWith(ys, key, merge) + assertResult(List((1, "ac"), (2, "bc"), (3, "d")))(res) + } + } + + test("zipWithExpandedBy") { + assertResult(Array((2, 0), (2, 1)))(2.zipWithExpandedBy(x => List.range(0,x))) + assertResult(Array((3, 0), (3, 1), (3, 2)))(3.zipWithExpandedBy(x => List.range(0,x))) + } + + def treeStep(tree: Array[List[Int]]): Int => List[Int] = i => tree(i) + + test("traverseDepthFirst") { + { + val tree = Array( + List(1, 2), // 0 + List(), // 1 + List(3), // 2 + List()) // 3 + assertResult(List(0, 1, 2, 3))(0.traverseDepthFirst(treeStep(tree))) + } + { + /* + 0 + 1 + 3 + 5 + 6 + 2 + 4 + */ + val tree = Array( + List(1, 2), // 0 + List(3), // 1 + List(4), // 2 + List(5,6), // 3 + List(), // 4 + List(), // 5 + List() // 6 + ) + assertResult(List(0, 1, 3, 5, 6, 2, 4))(0.traverseDepthFirst(treeStep(tree))) + } + } + + test("partitionByType") { + val xs: List[Any] = List(1, "a", "b", 2, 3, 1.0, 2.0) + val (ints, others) = xs.partitionByType[Integer, Any] + ints shouldBe(List(1,2,3)) + val (strs, doubles) = others.partitionByType[String, Double] + strs shouldBe(List("a", "b")) + doubles shouldBe(List(1.0, 2.0)) + } + + test("mapConserve") { + class A(val x: Int) + val x = new A(10) + val opt = Option(x) + opt.mapConserve(a => a) shouldBe theSameInstanceAs(opt) + opt.mapConserve(a => new A(a.x)) should not be theSameInstanceAs(opt) + } + + test("transformConserve") { + class A(val x: Int) + val x = new A(10) + x.transformConserve(a => a) shouldBe theSameInstanceAs(x) + x.transformConserve(a => new A(a.x)) should not be theSameInstanceAs(x) + } + + test("sameElements2") { + Seq(1, 2).sameElements2(List(1, 2)) shouldBe true + new mutable.WrappedArray.ofInt(Array(1, 2)).sameElements2(Vector(1, 2)) shouldBe true + Seq(new mutable.WrappedArray.ofInt(Array(1, 2)), 3).sameElements2(Array(Vector(1, 2), 3)) shouldBe true + Seq(Array(1, 2), 3).sameElements2(Array(Vector(1, 2), 3)) shouldBe true + Seq(Array(1, 2), Option(3)).sameElements2(Array(Vector(1, 2), List(3))) shouldBe false + + Seq(1, 2).sameElements2(List(1, 2, 3)) shouldBe false + new mutable.WrappedArray.ofInt(Array(1, 2, 3)).sameElements2(Vector(1, 2)) shouldBe false + Seq(new mutable.WrappedArray.ofInt(Array(1, 2, 3)), 3).sameElements2(Array(Vector(1, 2), 3)) shouldBe false + + } + + def unboxedArray[T:ClassTag](in: Seq[T]): Array[T] = { + in.toArray[T] + } + + test("unboxedArray") { + // empty list + unboxedArray(Seq[Any]()).isInstanceOf[Array[Any]] shouldBe true + + // primitive types + unboxedArray(Seq[Byte](java.lang.Byte.valueOf(1.toByte))).isInstanceOf[Array[Byte]] shouldBe true + Seq[Any](java.lang.Byte.valueOf(1.toByte)).toArray.isInstanceOf[Array[Byte]] shouldBe false + Seq[Byte](1.toByte).toArray[Byte].isInstanceOf[Array[Byte]] shouldBe true + + unboxedArray(Seq[Short](java.lang.Short.valueOf(1.toShort))).isInstanceOf[Array[Short]] shouldBe true + unboxedArray(Seq[Int](java.lang.Integer.valueOf(1))).isInstanceOf[Array[Int]] shouldBe true + unboxedArray(Seq[Long](java.lang.Long.valueOf(1))).isInstanceOf[Array[Long]] shouldBe true + unboxedArray(Seq[Double](java.lang.Double.valueOf(1.0))).isInstanceOf[Array[Double]] shouldBe true + unboxedArray(Seq[Float](java.lang.Float.valueOf(1.0f))).isInstanceOf[Array[Float]] shouldBe true + unboxedArray(Seq[Boolean](java.lang.Boolean.valueOf(true))).isInstanceOf[Array[Boolean]] shouldBe true + unboxedArray(Seq[Char](java.lang.Character.valueOf('a'))).isInstanceOf[Array[Char]] shouldBe true + unboxedArray(Seq[String]("str")).isInstanceOf[Array[String]] shouldBe true + + // non-primitive type + unboxedArray(Seq[Any](Option.empty[Boolean])).isInstanceOf[Array[Any]] shouldBe true + unboxedArray(Seq[Seq[Any]](Seq())).isInstanceOf[Array[Seq[Any]]] shouldBe true + } + +} diff --git a/common/src/test/scala/scalan/util/FileUtilTests.scala b/common/src/test/scala/scalan/util/FileUtilTests.scala new file mode 100644 index 0000000000..6a265b1367 --- /dev/null +++ b/common/src/test/scala/scalan/util/FileUtilTests.scala @@ -0,0 +1,39 @@ +package scalan.util + +import scalan.BaseNestedTests + +class FileUtilTests extends BaseNestedTests { + import FileUtil._ + describe("File traversals") { + val root = file("common/src/test/resources/root") + val subdir = file(root, "subdir") + val subsubdir = file(subdir, "subsubdir") + val empty = { val dir = file(root, "empty"); dir.mkdir(); dir } + val A = file(root, "A.txt") + val B = file(root, "B.txt") + val C = file(subdir, "C.txt") + val D = file(subsubdir, "D.txt") + + it("list all files") { + listFiles(root).toSet shouldBe Set(A, B) + listFiles(empty) shouldBe Array() + } + it("list directories") { + listDirectories(root).toSet shouldBe Set(subdir, empty) + } + it("list directories recursive") { + listDirectoriesRecursive(root).toSet shouldBe Set(root, subdir, empty, subsubdir) + } + it("list files recursive") { + listFilesRecursive(root).toSet shouldBe Set(A, B, C, D) + } + } + describe("file path methods") { + it("extractModuleName") { + extractModuleName("src/main/scala/d") shouldBe("") + extractModuleName("/src/main/scala/d") shouldBe("") + extractModuleName("b/src/main/scala/d") shouldBe("b") + extractModuleName("a/b/src/main/scala/d") shouldBe("b") + } + } +} diff --git a/common/src/test/scala/scalan/util/GraphUtilTests.scala b/common/src/test/scala/scalan/util/GraphUtilTests.scala new file mode 100644 index 0000000000..b467ab6e2f --- /dev/null +++ b/common/src/test/scala/scalan/util/GraphUtilTests.scala @@ -0,0 +1,42 @@ +package scalan.util + +import scalan.{BaseNestedTests, DFunc} +import debox.{Set => DSet, Buffer => DBuffer} + +class GraphUtilTests extends BaseNestedTests { + import GraphUtil._ + + describe("Collecting dependencies") { + val graph = Array( + List(1, 2), // 0 + List(3), // 1 + List(4), // 2 + List(5, 6), // 3 + List(6), // 4 + List(6), // 5 + List() // 6 + ) + + val neighbours: DFunc[Int, DBuffer[Int]] = { node: Int => + val ns = DBuffer.empty[Int] + graph(node) foreach (ns.+=) + ns + } + + it("depthFirstSetFrom") { + depthFirstSetFrom(DBuffer(6))(neighbours) shouldBe (DSet(6)) + depthFirstSetFrom(DBuffer(5))(neighbours) shouldBe (DSet(5, 6)) + depthFirstSetFrom(DBuffer(3))(neighbours) shouldBe (DSet(3, 5, 6)) + depthFirstSetFrom(DBuffer(2))(neighbours) shouldBe (DSet(2, 4, 6)) + depthFirstSetFrom(DBuffer(0))(neighbours) shouldBe (DSet(0, 1, 2, 3, 4, 5, 6)) + } + it("depthFirstOrderFrom") { + val succ: DFunc[Int, DBuffer[Int]] = {id: Int => DBuffer(graph(id):_*)} + depthFirstOrderFrom(DBuffer(6), succ) shouldBe (DBuffer(6)) + depthFirstOrderFrom(DBuffer(5), succ) shouldBe (DBuffer(6, 5)) + depthFirstOrderFrom(DBuffer(3), succ) shouldBe (DBuffer(6, 5, 3)) + depthFirstOrderFrom(DBuffer(2), succ) shouldBe (DBuffer(6, 4, 2)) + depthFirstOrderFrom(DBuffer(0), succ) shouldBe (DBuffer(6, 5, 3, 1, 4, 2, 0)) + } + } +} diff --git a/common/src/test/scala/scalan/util/ScalaNameUtilSuite.scala b/common/src/test/scala/scalan/util/ScalaNameUtilSuite.scala new file mode 100644 index 0000000000..0f115784fe --- /dev/null +++ b/common/src/test/scala/scalan/util/ScalaNameUtilSuite.scala @@ -0,0 +1,26 @@ +package scalan.util + +import scalan.BaseTests + +class ScalaNameUtilSuite extends BaseTests { + def +\() = ??? + + import ScalaNameUtil._ + + test("Operator names should be decoded correctly") { + cleanScalaName("$plus$bslash$up") shouldEqual("""+\^""") + } + + test("Method names obtained by reflection should be decoded") { + val methodNames = classOf[ScalaNameUtilSuite].getDeclaredMethods.map { + m => cleanScalaName(m.getName) + }.toList.filterNot(n => n.startsWith("$")) + + methodNames should equal(List("""+\""")) + } + + test("extract package and name") { + val name = "com.my.Class" + PackageAndName.unapply(name) should equal(Some((List("com", "my"), "Class"))) + } +} diff --git a/common/src/test/scala/scalan/util/StringUtilTests.scala b/common/src/test/scala/scalan/util/StringUtilTests.scala new file mode 100644 index 0000000000..9e465b7953 --- /dev/null +++ b/common/src/test/scala/scalan/util/StringUtilTests.scala @@ -0,0 +1,31 @@ +package scalan.util + +import scalan.BaseNestedTests + +class StringUtilTests extends BaseNestedTests { + import StringUtil._ + + describe("StringExtension methods") { + it("lastComponent") { + "a/b/c".lastComponent('/') shouldBe("c") + "a/b/".lastComponent('/') shouldBe("") + "a".lastComponent('/') shouldBe("a") + "".lastComponent('/') shouldBe("") + } + it("prefixBefore") { + "a/b/c".prefixBefore("/b") shouldBe("a") + "a/b/c".prefixBefore("/c") shouldBe("a/b") + "a/b/c".prefixBefore("a/b/c") shouldBe("") + "a/b/c".prefixBefore("") shouldBe("") + } + it("replaceSuffix") { + "a.old".replaceSuffix(null, ".new") shouldBe("a.old") + (null: String).replaceSuffix(".old", ".new") shouldBe(null) + "a.old".replaceSuffix("", ".new") shouldBe("a.old") + "a.".replaceSuffix(".old", ".new") shouldBe("a.") + "a.old".replaceSuffix(".old", ".new") shouldBe("a.new") + "a.old".replaceSuffix(".old", "") shouldBe("a") + "a.old".replaceSuffix(".old", null) shouldBe("a") + } + } +} diff --git a/common/src/test/scala/scalan/util/StronglyConnectedComponentsTests.scala b/common/src/test/scala/scalan/util/StronglyConnectedComponentsTests.scala new file mode 100644 index 0000000000..2019515885 --- /dev/null +++ b/common/src/test/scala/scalan/util/StronglyConnectedComponentsTests.scala @@ -0,0 +1,7 @@ +package scalan.util + +import scalan.BaseTests + +class StronglyConnectedComponentsTests extends BaseTests { + +} \ No newline at end of file diff --git a/core/src/main/resources/reference.conf b/core/src/main/resources/reference.conf new file mode 100644 index 0000000000..57c0d948ed --- /dev/null +++ b/core/src/main/resources/reference.conf @@ -0,0 +1,32 @@ +# Reference configuration file for Scalan. Put overrides into application.conf. +scalan { + # If true, collects extra debugging information, see scalan.Debugging + debug = false + verbosity = 0 + addControlDeps = true + + # classPath for loading plugins, consists of jar files and directories separated with File.pathSeparator + plugins.extraClassPath = "" + + # Settings for graphs produced during compilation + graphviz { + # Whether any graphs will be emitted. If false, other settings don't matter + emitGraphs = true + # Use "svg" to see tooltips and open files in browser + format = dot + # Portrait or Landscape + orientation = Portrait + # Maximum line length of node label before line wrapping + maxLabelLineLength = 50 + # Whether Lambdas, Thunks and other subgraphs should be shown as clusters + subgraphClusters = true + # Maximum type name length before it receives an automatic alias. Disabled by default. + # maxTypeNameLength = 45 + # Whether to show edges from nodes whose type is an alias to the alias + typeAliasEdges = false + # Whether to show metadata + emitMetadata = false + # Whether symbol id for return value of a lambda should be shown + showLambdaReturnSym = false + } +} diff --git a/core/src/main/scala/scalan/Base.scala b/core/src/main/scala/scalan/Base.scala new file mode 100644 index 0000000000..75b0b0a5de --- /dev/null +++ b/core/src/main/scala/scalan/Base.scala @@ -0,0 +1,819 @@ +package scalan + +import java.lang.reflect.{Constructor => Constr} +import java.util.Arrays +import scalan.OverloadHack.Overloaded1 +import scala.annotation.implicitNotFound +import scala.annotation.unchecked.uncheckedVariance +import scalan.compilation.GraphVizConfig +import scalan.util.StringUtil +import debox.{Buffer => DBuffer} +import spire.syntax.all.cfor + +/** + * The Base trait houses common AST nodes. It also manages a list of encountered definitions which + * allows for common sub-expression elimination (CSE). + */ +abstract class Base { scalan: Scalan => + type |[+A, +B] = Either[A, B] + type RFunc[-A,+B] = Ref[Function1[A,B]] + type RPair[+A, +B] = Ref[(A,B)] + + // Consider if extra data should be Seq[Any] instead (change name in this case) + class StagingException(message: String, cause: Throwable, val syms: Seq[Ref[_]]) extends + RuntimeException(stagingExceptionMessage(message, syms), cause) { + def this(message: String, syms: Seq[Ref[_]]) = this(message, null, syms) + } + + class NotImplementedStagingException(message: String, syms: Seq[Ref[_]]) extends StagingException(message, null, syms) + + def ??? : Nothing = ???("Missing or incomplete implementation") + def ???(value: Any, syms: Ref[_]*): Nothing = throw new NotImplementedStagingException(value.toString, syms) + + /** Helper methods to throw errors */ + def !!! : Nothing = !!!("should not be called") + def !!!(msg: String, syms: Ref[_]*): Nothing = throw new StagingException(msg, syms) + def !!!(msg: String, e: Throwable, syms: Ref[_]*): Nothing = throw new StagingException(msg, e, syms) + + /** Log warning message to the log. + * This is default and simple implementation, which can be overriden.*/ + def logWarn(msg: => String): Unit = { + println(msg) + } + + /** Helper to type cast node references. */ + @inline final def asRep[T](x: Ref[_]): Ref[T] = x.asInstanceOf[Ref[T]] + + @inline implicit def liftToRep[A:Elem](x: A): Ref[A] = toRep(x) + + /** Base class for all IR nodes/operations/definitions. */ + abstract class Node extends Product { + private[scalan] var _nodeId: Int = freshId + + /** Unique id of the graph node assigned for each new instance using + * `freshId` generator. + * Doesn't participate in equality of this Def, thus definitions with + * different ids may still be structurally equal. + * Used to provide global Def numbering. */ + @inline final def nodeId: Int = _nodeId + + private var _deps: Array[Sym] = _ + + /** Dependencies of this definition from other definitions. + * If definition is interpreted as an operation, then dependencies are arguments + * of the operation. + * If definition if compound (like Lambda of ThunkDef) then `deps` is equals to + * free variables used in the body of the compound definition. + * This array also refers to predecessors of this graph node, so it is used + * to build topological ordering (execution schedule) of operations. + * @return array of referencies to other definitions.*/ + final def deps: Array[Sym] = { + if (_deps == null) { + _deps = getDeps + } + _deps + } + + /** Override to redefine how dependencies are computed. + * For example, in `core` implementation this is overriden in Lambda and ThunkDef using freeVars. */ + protected def getDeps: Array[Sym] = syms + + private var _syms: Array[Sym] = _ + private var _elements: Array[Any] = _ + + /** Generic method to extract `elements` and `syms` from this node.*/ + final private def initContent(): Unit = { + val len = productArity + _elements = new Array[Any](len + 1) + _elements(0) = getClass + val symsBuf = DBuffer.ofSize[Sym](len) + cfor(0)(_ < len, _ + 1) { i => + val element = productElement(i) + _elements(i + 1) = element + Def.extractSyms(element, symsBuf) + } + _syms = symsBuf.toArray() + } + + /** References to other nodes in this Def instance. + * Note: This is different form `deps` for compound definitions like Lambda and ThunkDef. */ + final def syms: Array[Sym] = { + if (null == _syms) initContent() + _syms + } + + /** All data elements of this graph node to be used in structural equality. + * @see equals where elements are used.*/ + final def elements: Array[AnyRef] = { + if (null == _elements) initContent() + _elements.asInstanceOf[Array[AnyRef]] + } + + /** Default equality of definitions. + * Two definitions are equal if they have same `elements`. */ + override def equals(other: Any) = (this eq other.asInstanceOf[AnyRef]) || { + val eq = canEqual(other) && Arrays.deepEquals(elements, other.asInstanceOf[Node].elements) + eq + } + + private var _hashCode: Int = 0 + /** Computed once and saved to avoid repeated computations, which is not necessary + * because definitions are immutable by default. + * If some definition require mutability, this method can be overriden accordingly. */ + override def hashCode = { + if (_hashCode == 0) { + _hashCode = Arrays.deepHashCode(elements) + } + _hashCode + } + + /** User readable string representation of this definition. (for debugging only) */ + override def toString = { + val sb = new StringBuilder + sb.append(productPrefix) + sb.append("(") + val iterator = productIterator + if (iterator.hasNext) { + StringUtil.deepAppend(sb, iterator.next) + } + while (iterator.hasNext) { + sb.append(", ") + StringUtil.deepAppend(sb, iterator.next) + } + sb.append(")") + sb.toString + } + } + + /** Base type for all graph nodes (aka computable value definitions). + * Each graph node or definition represent one operation node of the data flow graph. + */ + trait Def[+T] extends Node { + + /** Type of a resulting value produced by the operation represented by this definition. + * For example, if this definition represents application of `+: (Int, Int) => Int` operation + * then the result type is Int and `resultType` should return IntElement. */ + def resultType: Elem[T @uncheckedVariance] + + private var _self: Ref[T @uncheckedVariance] = _ + + /** Reference to this definition created lazily on demand. */ + final def self: Ref[T] = { + if (_self == null) _self = freshSym(this) + _self + } + + /** Create a copy of this definition applying the given transformer to all `syms`. */ + def transform(t: Transformer): Def[T] = + !!!(s"Cannot transfrom definition using transform($this)", self) + + /** Clone this definition transforming all symbols using `t`. + * If new Def[A] is created, it is added to the graph with collapsing and rewriting. + * Can be overriden to implement node-specific mirroring (see MethodCall). + * @param t mapping of symbols to symbols (Ref[_] => Ref[_]) + * @return symbol of the logical clone. If `d` don't contain symbols, then d.self is returned. */ + def mirror(t: Transformer): Ref[T] = { + val newD = transform(t) + reifyObject(newD) + } + } + + object Def { + def unapply[T](e: Ref[T]): Nullable[Def[T]] = def_unapply(e) + + /** Traverse `element` structure and extracts symbols to buf`. */ + final def extractSyms(element: Any, buf: DBuffer[Sym]): Unit = element match { + case s: Sym => + buf += s + case p: Product => + val len = p.productArity + cfor(0)(_ < len, _ + 1) { i => + extractSyms(p.productElement(i), buf) + } + case xs: Seq[_] => + val len = xs.length + cfor(0)(_ < len, _ + 1) { i => + extractSyms(xs(i), buf) + } + case _ => + } + } + + /** Logical AND between two pattern matches of the save value `x`. + * Can be used to construct patterns like `case P1 && P2 => ...` */ + object && { + def unapply[T](x: T): Option[(T,T)] = Some((x, x)) + } + + /** Base class for virtualized instances of type companions. + * Each virtualized entity type (trait or class) may have virtualized companion class. */ + abstract class CompanionDef[T] extends Def[T] { + override def productArity = 0 + override def productElement(n: Int) = !!!(s"productElement($n) called, but productArity = 0", self) + override def canEqual(other: Any) = other.isInstanceOf[CompanionDef[_]] + override def mirror(t: Transformer): Ref[T] = self + } + + /** Data type `ST` is liftable is there is Liftable[ST, T] instance for some type `T`. + * Liftable typeclass allows to define which types can have values embedded as literals + * into graph IR. */ + object Liftables { + + /** Base class for graph nodes which represent data values of liftable types + * as literal nodes in the graph IR. + * @tparam ST source type of the liftable value + * @tparam T virtualized type (aka IR type) corresponding to source type + */ + trait LiftedConst[ST, T] extends Def[T] { + /** Value of the source type embedded in this graph node. */ + def constValue: ST + + /** Evidence that constValue can be lifted to T */ + def liftable: Liftable[ST, T] + + /** This default implementation assumes there is no symbols in this node. + * Can be overriden if it is not true for some ST. */ + override def mirror(t: Transformer): Ref[T] = self + } + + /** Describes lifting data values of type ST (Source Type) to IR nodes of the correspoding staged type T. + * In general T is different type obtained by virtualization procedure from ST. + * However ST can be the same as T as is the case for Byte, Int, String etc. + */ + @implicitNotFound(msg = "Cannot find implicit for Liftable[${ST},${T}].") + abstract class Liftable[ST, T] { + /** Type descriptor of the source type */ + def sourceType: RType[ST] + /** Type descriptor of the IR type */ + def eW: Elem[T] + + /** Method to embedd source type instance into graph IR. */ + def lift(x: ST): Ref[T] + + /** Extract lifted value from graph node. + * @return constValue from LiftedConst if `w` refers to such a node. + * @throws StagingException if `w` is not refering to the appropritate LiftedConst node. */ + def unlift(w: Ref[T]): ST + + protected def unliftError(w: Ref[T]) = + !!!(s"Cannot unlift simbol $w using $this") + + /** We assume only single Liftable[ST, T] implementation for every IR type `T`. + * And all instances of it are equal. */ + override def hashCode(): Int = eW.hashCode() + 1 // to make Elem and Liftable differ + override def equals(obj: Any): Boolean = super.equals(obj) || (obj match { + case other: Liftable[_,_] => other.eW == eW + case _ => false + }) + override def toString: String = s"Liftable($eW)" + } + + /** Casts untyped Liftable to typed one. */ + @inline final def asLiftable[ST,T](l: Liftable[_,_]): Liftable[ST,T] = l.asInstanceOf[Liftable[ST,T]] + + /** Shortcut alternative to `implicitly[Liftable[ST,T]]` */ + @inline final def liftable[ST, T](implicit lT: Liftable[ST,T]) = lT + + /** Given data value of source type `ST` and `Liftable` instance between `ST` and `T`, + * produces `LiftedConst` node (some concrete implemenation) and returns it's symbol. + * This is generic way to put any liftable data object into graph and then use + * its symbol in other nodes. */ + @inline final def liftConst[ST,T](x: ST)(implicit lT: Liftable[ST,T]): Ref[T] = lT.lift(x) + + /** Liftable evidence for primitive (base) types (used in BaseElemLiftable). */ + class BaseLiftable[T](implicit val eW: Elem[T], override val sourceType: RType[T]) extends Liftable[T, T] { + def lift(x: T) = toRep(x) + def unlift(w: Ref[T]) = valueFromRep(w) + } + + /** Liftable evidence between `(SA, SB)` and `(A, B)` types. */ + class PairLiftable[SA,SB,A,B](implicit lA: Liftable[SA, A], lB: Liftable[SB, B]) extends Liftable[(SA,SB), (A,B)] { + val eW: Elem[(A, B)] = pairElement(lA.eW, lB.eW) + override val sourceType: RType[(SA, SB)] = RType.pairRType(lA.sourceType, lB.sourceType) + + def lift(x: (SA, SB)): Ref[(A, B)] = Pair(lA.lift(x._1), lB.lift(x._2)) + def unlift(w: Ref[(A, B)]): (SA, SB) = { val Pair(wa, wb) = w; (lA.unlift(wa), lB.unlift(wb)) } + } + + /** Every function can be lifted to the graph IR. */ + case class FuncConst[SA,SB,A,B](constValue: SA => SB)(implicit lA: Liftable[SA, A], lB: Liftable[SB, B]) + extends BaseDef[A => B]()(funcElement(lA.eW, lB.eW)) + with LiftedConst[SA => SB, A => B] { + val liftable = Liftables.liftable[SA => SB, A => B] + } + + class FuncLiftable[SA,SB,A,B](implicit lA: Liftable[SA, A], lB: Liftable[SB, B]) extends Liftable[SA => SB, A => B] { + val eW: Elem[A => B] = funcElement(lA.eW, lB.eW) + override val sourceType = RType.funcRType(lA.sourceType, lB.sourceType) + def lift(srcF: SA => SB): Ref[A => B] = FuncConst[SA,SB,A,B](srcF) + def unlift(f: Ref[A => B]): SA => SB = f.node match { + case FuncConst(srcF) => srcF.asInstanceOf[SA => SB] + case _ => unliftError(f) + } + } + + implicit lazy val BooleanIsLiftable = asLiftable[Boolean,Boolean](BooleanElement.liftable) + implicit lazy val ByteIsLiftable = asLiftable[Byte,Byte](ByteElement.liftable) + implicit lazy val ShortIsLiftable = asLiftable[Short,Short](ShortElement.liftable) + implicit lazy val IntIsLiftable = asLiftable[Int,Int](IntElement.liftable) + implicit lazy val LongIsLiftable = asLiftable[Long,Long](LongElement.liftable) + implicit lazy val StringIsLiftable = asLiftable[String,String](StringElement.liftable) + implicit lazy val FloatIsLiftable = asLiftable[Float,Float](FloatElement.liftable) + implicit lazy val DoubleIsLiftable = asLiftable[Double,Double](DoubleElement.liftable) + implicit lazy val UnitIsLiftable = asLiftable[Unit,Unit](UnitElement.liftable) + implicit lazy val CharIsLiftable = asLiftable[Char,Char](CharElement.liftable) + + implicit def PairIsLiftable[SA,SB,A,B] + (implicit lA: Liftable[SA, A], lB: Liftable[SB, B]): Liftable[(SA, SB), (A, B)] = + new PairLiftable[SA,SB,A,B] + + implicit def FuncIsLiftable[SA,SB,A,B] + (implicit lA: Liftable[SA, A], lB: Liftable[SB, B]): Liftable[SA => SB, A => B] = + new FuncLiftable[SA,SB,A,B] + } + + /** Base class for all objects generated for virtualized types to support + * staged evaluation machinery. + * Each object contains definitions which can be imported when necessary. + * All that objects are registered in `entityObjects` hash map, + * which is done while IR cake is constructed. + */ + class EntityObject(val entityName: String) + + private[this] val entityObjects = AVHashMap[String, EntityObject](300) + + @inline def getEntityObject(name: String): Nullable[EntityObject] = { + entityObjects.get(name) + } + + protected def registerEntityObject(name: String, obj: EntityObject): Unit = { + assert(!entityObjects.containsKey(name), s"EntityObject for entity $name already registered") + entityObjects.put(name, obj) + } + + /** Whether IR type descriptors should be cached. */ + val cacheElems = true + + /** Whether Tup instances should be cached. */ + val cachePairs = true + + /** Whether to perform extended checks of correctness, expected invariants and data consistency. + * NOTE: Since it may add substantial overhead, set it to `false` before using in production. */ + val debugModeSanityChecks: Boolean = false + + /** Abstract representation of a computable value. + * Default implementation is a simple lightweight reference to the corresponding definition. + * Every Ref have direct access to its Def via `node` property. + * Every Ref is typed, and the type is avaliable via `elem` property. + * @see SingleRep + */ + abstract class Ref[+T] { + /** Type of the computed value represented by the node refered by this rep.*/ + def elem: Elem[T @uncheckedVariance] + + /** Unique name that can be used as variable name.*/ + def varName: String + + /** Node of the graph refered by this Ref. */ + def node: Def[T] + + /** Most of the references are initialized when created. + * These methods are used in core to assign new value for the reference.*/ + private[scalan] def assignDef[B >: T](d: Def[B]): Unit + private[scalan] def assignDefFrom[B >: T](ref: Ref[B]): Unit + + /** Whether the underlying node is Placeholder. */ + @inline final def isPlaceholder: Boolean = node.isInstanceOf[Placeholder[_]] + /** Whether the underlying node is Variable. */ + @inline final def isVar: Boolean = node.isInstanceOf[Variable[_]] + /** Whether the underlying node is Const. */ + @inline final def isConst: Boolean = node.isInstanceOf[Const[_]] + /** Whether the underlying node is Lambda. */ + @inline final def isLambda: Boolean = node.isInstanceOf[Lambda[_,_]] + /** Is this reference of Companion type */ + @inline final def isCompanionType: Boolean = elem.isInstanceOf[CompanionElem[_]] + + /** Returns the string like `x45: Int = Const(10)` */ + def toStringWithDefinition: String + def varNameWithType = varName + ":" + elem.name + + /** Build graph of nodes starting from this node, generate dot file, + * and open it using system default viewer for dot extension. */ + def show(): Unit = show(defaultGraphVizConfig) + def show(emitMetadata: Boolean): Unit = show(defaultGraphVizConfig.copy(emitMetadata = emitMetadata)) + def show(config: GraphVizConfig): Unit = showGraphs(this)(config) + } + + /** Untyped shortcut sinonim of Ref, which is used as untyped reference to graph nodes (definitions). + * Following a tradition in compiler engineering we call references to definitions as symbols. + */ + type Sym = Ref[_] + + /** Base class for most predefined operations. */ + abstract class BaseDef[+T](implicit val resultType: Elem[T @uncheckedVariance]) extends Def[T] + + /** Default node type for embedding of literal values to graph IR. + * This can be used or those types `T` when `Elem[T]` is defined, + * but `Liftable[_,T]` is not, i.e. for non-liftable types. + * @param x literal value + * @param eT type descriptor of IR type T */ + case class Const[T](x: T)(implicit val eT: Elem[T]) extends BaseDef[T] { + override def mirror(t: Transformer): Ref[T] = self + } + + /** Node class for typed variables. In particular for lambda-bound variables. + * @param varId is independent from nodeId, shouldn't be used as node id. + * @param eT type descriptor of the variable type */ + case class Variable[T](varId: Int)(implicit eT: LElem[T]) extends Def[T] { + override def resultType: Elem[T] = eT.value + override def mirror(t: Transformer): Ref[T] = self + } + + @inline def variable[T](implicit eT: LElem[T]): Ref[T] = Variable[T](freshId) + + /** Symbols may temporary refer to this node until their target node is updated. */ + case class Placeholder[T](eT: LElem[T]) extends Def[T] { + def resultType: Elem[T] = eT.value + } + + @inline def placeholder[T](implicit eT: LElem[T]): Ref[T] = freshSym[T](Placeholder[T](eT)) + + /** Base class for Ref to Ref transformations. + * Each transformer keeps a mapping data between references to original nodes + * and references to the corresponding transformed nodes. + */ + abstract class Transformer { + /** Apply transformation. */ + def apply[A](x: Ref[A]): Ref[A] + /** Whether this transformer is defined for the given node. */ + def isDefinedAt(x: Sym): Boolean + /** Set of nodes where this transformer is defined. */ + def domain: Seq[Sym] + /** Transform a sequence of nodes into new sequence of nodes. */ + final def apply[A](xs: Seq[Ref[A]]): Seq[Ref[A]] = { + val len = xs.length + val res = new Array[Ref[A]](len) + cfor(0)(_ < len, _ + 1) { i => + res(i) = apply(xs(i)) + } + res + } + /** Apply this transformer to the nodes present in the sequence, + * and leave non-Ref items unchanged. */ + final def apply(xs: Seq[Any])(implicit o: Overloaded1): Seq[Any] = { + val len = xs.length + val res = new Array[Any](len) + cfor(0)(_ < len, _ + 1) { i => + val x = xs(i) match { case s: Ref[_] => apply(s); case s => s } + res(i) = x + } + res + } + + def +[A](key: Sym, value: Sym): Transformer + def merge(other: Transformer): Transformer + } + + /** Prettyprint exception message */ + protected def stagingExceptionMessage(message: String, syms: Seq[Ref[_]]) = { + // Skip syms already in the message, assume that's the only source for s + val symsNotInMessage = syms.map(_.toString).filterNot(message.contains) + + if (symsNotInMessage.isEmpty) { + message + } else { + val between = if (message.isEmpty) + "" + else + message.last match { + // determine whether the message lacks ending punctuation + case '.' | ';' | '!' | '?' => " " + case _ => ". " + } + + message + between + s"Sym${if (symsNotInMessage.length > 1) "s" else ""}: ${symsNotInMessage.mkString(", ")}" + } + } + + /** Variants of `owner` parameter of constructors of nested classes: + * 1) predefined node classes are owned by IR cake (ScalanOwner) + * 2) entity classes are owned by enclosing EntityObject */ + sealed abstract class OwnerKind + case object NoOwner extends OwnerKind + case object ScalanOwner extends OwnerKind + case class EntityObjectOwner(obj: EntityObject) extends OwnerKind + + /** Returns OwnerKind for the given constructor, using its first parameter. */ + protected def getOwnerKind(constructor: Constr[_]): OwnerKind = { + val paramTypes = constructor.getParameterTypes + val ownerParam = + if (paramTypes.length == 0) + NoOwner + else { + val firstParamClazz = paramTypes(0) + if (firstParamClazz.getSuperclass == classOf[EntityObject]) { + val className = firstParamClazz.getSimpleName + val entityName = className.substring(0, className.length - 1) + getEntityObject(entityName) match { + case Nullable(obj) => + EntityObjectOwner(obj) + case _ => + !!!(s"Unknown owner type $firstParamClazz") + } + } else { + ScalanOwner + } + } + ownerParam + } + + /** Transforms this object into new one by applying `t` to every Ref inside + * its structure. The structure is build out of Seq, Array, Option and Def values. + * Other structure items remain unchanged and copied to the new instance. + * @hotspot don't beautify the code */ + protected def transformProductParam(x: Any, t: Transformer): Any = x match { + case (_: UnOp[_, _]) | (_: BinOp[_, _]) => + // allows use of context bounds in classes extending UnOp/BinOp. + // Note that this must be overridden if some transformation _is_ needed (i.e. if the class contains Ref[_] somewhere) + x + case e: Ref[_] => t(e) + case seq: Seq[_] => + val len = seq.length + val res = new Array[AnyRef](len) + cfor(0)(_ < len, _ + 1) { i => res(i) = transformProductParam(seq(i), t).asInstanceOf[AnyRef] } + res: Seq[_] + case arr: Array[_] => + val len = arr.length + val res = new Array[AnyRef](len) + cfor(0)(_ < len, _ + 1) { i => res(i) = transformProductParam(arr(i), t).asInstanceOf[AnyRef] } + res + case opt: Option[_] => + if (opt.isEmpty) None else Some(transformProductParam(opt.get, t)) + case d: Def[_] => d.mirror(t).node + case x => x + } + + /** Prepend owner parameter depending on its kind. */ + private[scalan] def addOwnerParameter(ownerType: OwnerKind, params: Seq[Any]): Seq[AnyRef] = { + val finalParams = (ownerType match { + case EntityObjectOwner(obj) => obj +: params + case ScalanOwner => scalan +: params + case NoOwner => params + }) + finalParams.asInstanceOf[Seq[AnyRef]] + } + + /** Implicit injection of new definition (graph node) into universum of + * nodes with collapsing semantics. If there exists node `n` in this IR + * such that `obj equals n`, then the value of `n.self` is returned, i.e. + * the new node `obj` is collapsed with already existing one. + * This has an effect of Common Subexpression Elimination (CSE) when + * an expression tree is transformed to the graph and identical subtrees + * are collapsed. + * After a reference to the node is obtained, global rewriting rules are + * examined and the reference may be replaced with a new one. + */ + implicit def reifyObject[A](obj: Def[A]): Ref[A] = { + toExp(obj, obj.self) + } + + /** Lifting of data values to IR nodes. */ + def toRep[A](x: A)(implicit eA: Elem[A]): Ref[A] = eA match { + case _: BaseElem[_] => Const(x) + case _ => + !!!(s"Don't know how to create Ref for $x with element $eA") + } + + /** Extract data value from Const node or throw an exception. */ + @inline final def valueFromRep[A](x: Ref[A]): A = x.node match { + case Const(x) => x + case _ => delayInvoke + } + + def def_unapply[T](e: Ref[T]): Nullable[Def[T]] = new Nullable(e.node) + + object ExpWithElem { + def unapply[T](s: Ref[T]): Nullable[(Ref[T],Elem[T])] = Nullable((s, s.elem)) + } + + /** A Ref is a symbolic reference used internally to refer to graph nodes. + * Light weight stateless immutable reference to a graph node (Def[T]). + * Two symbols are equal if they refer to the nodes with the same id, + * which is due to Def unification means equal symbols refer to the same instance of Def. + * */ + final class SingleRef[+T] private[Base](private var _node: Def[T @uncheckedVariance]) extends Ref[T] { + override def elem: Elem[T @uncheckedVariance] = _node.resultType + override def node: Def[T] = _node + + private[scalan] def assignDefInternal[B >: T](d: Def[B]): Unit = { + assert(_node.isInstanceOf[Placeholder[_]]) + assert(_node.nodeId > 0) + val tab = _symbolTable + val oldId = _node.nodeId + if (tab(oldId) eq this) { + tab.update(oldId, null) + } + _node = d.asInstanceOf[Def[T]] + } + + private[scalan] def assignDef[B >: T](d: Def[B]): Unit = { + assignDefInternal(d) + updateSymbolTable(this, d) + } + + private[scalan] def assignDefFrom[B >: T](sym: Ref[B]): Unit = { + assignDefInternal(sym.node) + } + + private var _adapter: T @uncheckedVariance = _ + def adapter: T @uncheckedVariance = _adapter + def adapter_=(a: T @uncheckedVariance) = { _adapter = a } + + /** Helper method that lazily creates and attaches Adapter to this node reference. + * The adapter is created conditionally and on demand. + * If T is trait or class (i.e. entity) then created adapter instance implements all its methods. + * The the adapter class is generated as part of EntityObject for the entity T. + * @see EntityObject + */ + final def getAdapter[S >: T](isInstanceOfT: Boolean, createAdapter: Ref[S] => T @uncheckedVariance): T = { + if (isInstanceOfT) _node.asInstanceOf[T] + else { + val adapter = _adapter + if (adapter == null) { + _adapter = createAdapter(this) + } + _adapter + } + } + + override def varName = "s" + _node._nodeId + override def toString = varName + override def toStringWithDefinition = varNameWithType + s" = ${_node}" + + override def equals(obj: scala.Any): Boolean = (this eq obj.asInstanceOf[AnyRef]) || (obj match { + case other: Base#SingleRef[_] => _node._nodeId == other.node._nodeId + case _ => false + }) + + override def hashCode(): Int = _node.nodeId + } + + /** Global counter (inside Scalan cake) of the last generated node id. */ + private var currId: Int = 0 + + /** Get next fresh node id */ + @inline final def freshId: Int = { currId += 1; currId } + + /** Lookup of create reference to the given definition. + * To lookup `d.nodeId` is used as the index in the `_symbolTable`. + * If Ref is not found in `_symbolTable`, then new Ref instance is created + * and stored in `_symbolTable` at `d.nodeId` index. + */ + @inline final def freshSym[T](d: Def[T]): Ref[T] = { + updateSymbolTable(null, d) + } + + /** Should be invoked to reset IR global node counter. */ + @inline final private[scalan] def resetIdCounter() = { currId = 0 } + + /** Create or find symbol (node Ref) which refers to the given node in the table of all created symbols. + * The d.nodeId is the index in the _symbolTable which is DBuffer (backed by Array) + * @return new of existing symbol + * @hotspot the method should be allocation-free (make it sure by examining the generated Java code) + */ + final def updateSymbolTable[T](s: Ref[T], d: Def[T]): Ref[T] = { + val id = d.nodeId + val tab = _symbolTable // perf optimization + val delta = id - tab.length + if (delta < 0) { + val sym = tab.apply(id) + if (sym == null) { + val newSym = if (s == null) new SingleRef(d) else s // we really want this allocation to happen only when necessary + tab.update(id, newSym) + newSym + } else { + // don't create new symbol, but check invariant condition on existing one + assert(sym.node.nodeId == id, s"Each symbol should refer to correct node, but was $sym -> ${sym.node}") + sym.asInstanceOf[Ref[T]] + } + } else { + // grow table + cfor(0)(_ < delta, _ + 1) { _ => tab.append(null) } + val sym = if (s == null) new SingleRef(d) else s + tab += sym + assert(tab.length == id + 1) + sym + } + } + + /** Lookup node reference by its id. + * This is simple array access by index O(1) operation. */ + @inline final def getSym(id: Int): Sym = _symbolTable(id) + + val nInitialDefs = 10000 + /** Auto growing array backed buffer with constant time lookup by nodeId. */ + private[this] val _symbolTable: DBuffer[Sym] = DBuffer.ofSize(nInitialDefs) + + /** Hash map of all created definitions in this IR context. + * Note, that exactly the same instance of Def is used for both key an value of each entry. + * This helps to implement collapsing of equal Def instances. */ + private[this] var _globalDefs = AVHashMap[Def[_], Def[_]](nInitialDefs) + + /** Returns a number of definitions added to this IR context. */ + def defCount = _globalDefs.hashMap.size + + private val _intZero = MutableLazy(0: Ref[Int]) + + /** Zero literal node, which is lazily created and can be efficiently reused. + * Much faster alternative to `(0: Rep[Int])` or `toRep(0)`.*/ + @inline final def IntZero = _intZero.value + + def resetContext() = { + _globalDefs = AVHashMap[Def[_], Def[_]](nInitialDefs) + _symbolTable.clear() + _symbolTable.splice(0, DBuffer.ofSize[Sym](nInitialDefs)) + resetIdCounter() + tuplesCache.clear() + _intZero.reset() + onReset() + } + + /** Called during resetContext() operation after the core context state has been reset. + * Derived classes can override to define application specific initialization. + * Don't forget to call super method in the beginning of your overriding method. */ + protected def onReset(): Unit = { + } + + /** Lookup definition in this IR context's hash table of definitions. + * @return node reference to an instance stored in hash table, which is equal to `d` + * and null if there is no definition which is equal to `d` */ + def findGlobalDefinition[T](d: Def[T]): Ref[T] = { + val existingOpt = _globalDefs.get(d) + if (existingOpt.isDefined) + existingOpt.get.self.asInstanceOf[Ref[T]] + else + null + } + + /** Lookup `d` in the heap of nodes. If the lookup is successfull, then + * its reference is returned. If the node is not found in the heap, then it is added + * and `d.self` reference is returned. + * @param d node to be added to the head of nodes + * @param newSym producer of the reference to be used as the reference to `d` node. + * @return return a reference to `d` node in the heap + * @hotspot */ + def findOrCreateDefinition[T](d: Def[T], newSym: => Ref[T]): Ref[T] = { + val optScope = thunkStack.top + var sym = optScope match { + case Nullable(scope) => + scope.findDef(d) + case _ => + findGlobalDefinition(d) + } + if (sym == null) { + sym = createDefinition(optScope, newSym, d) + } +// assert(te.rhs == d, s"${if (te !) "Found" else "Created"} unequal definition ${te.rhs} with symbol ${te.sym.toStringWithType} for $d") + sym + } + + /** Create new definition entry in either given Thunk or in the global hash table. + * @param optScope optional thunk scope to put given definition + * @param s symbol refering to `d` + * @param d definition node to add to the scope of globally + * @return reference to `d` (which is `s`) + */ + protected def createDefinition[T](optScope: Nullable[ThunkScope], s: Ref[T], d: Def[T]): Ref[T] = { + assert(_symbolTable(d.nodeId).node.nodeId == d.nodeId) + assert(s.node eq d, s"Inconsistent Sym -> Def pair $s -> $d") + optScope match { + case Nullable(scope) => + scope += s + case _ => + _globalDefs.put(d, d) + } + s + } + + /** + * Updates the universe of symbols and definitions, then rewrites until fix-point + * @param d A new graph node to add to the universe + * @param newSym A symbol that will be used if d doesn't exist in the universe + * @tparam T + * @return The symbol of the graph which is semantically(up to rewrites) equivalent to d + */ + protected[scalan] def toExp[T](d: Def[T], newSym: => Ref[T]): Ref[T] = { + var res = findOrCreateDefinition(d, newSym) + var currSym = res + var currDef = d + do { + currSym = res + val ns = rewriteDef(currSym.node).asInstanceOf[Ref[T]] + if (null == ns) return currSym + res = ns + currDef = ns.node + } while (res != currSym) + res + } +} + diff --git a/core/src/main/scala/scalan/DefRewriting.scala b/core/src/main/scala/scalan/DefRewriting.scala new file mode 100644 index 0000000000..3b88b1638e --- /dev/null +++ b/core/src/main/scala/scalan/DefRewriting.scala @@ -0,0 +1,199 @@ +package scalan + +trait DefRewriting { scalan: Scalan => + + /** Rewrites given node to another equivalent node and returns its reference. + * @param d node to be matched against rewrite patterns + * @return reference of new node if RW pattern is found and applied + * null if no rewriting is defined. */ + def rewriteDef[T](d: Def[T]): Ref[_] = d match { + case First(p) if p.node.isInstanceOf[Tup[_,_]] => p.node.asInstanceOf[Tup[_,_]].a + case Second(p) if p.node.isInstanceOf[Tup[_,_]] => p.node.asInstanceOf[Tup[_,_]].b + case Tup(Def(First(a)), Def(Second(b))) if a == b => a + + // Rule: convert(eFrom, eTo, x, conv) if x.elem <:< eFrom ==> conv(x) + case Convert(eFrom: Elem[from], eTo: Elem[to], x, conv) if x.elem <:< eFrom => + mkApply(conv, x) + + case Apply(f @ Def(l: Lambda[a,b]), x, mayInline) if mayInline && l.mayInline => + mkApply(f, x) + + case call @ MethodCall(receiver, m, args, neverInvoke) => + call.tryInvoke match { + // Rule: receiver.m(args) ==> body(m).subst{xs -> args} + case InvokeSuccess(res) => res + case InvokeFailure(e) if !e.isInstanceOf[DelayInvokeException] => + throwInvocationException("Method invocation in rewriteDef", e, receiver, m, args) + case InvokeImpossible => + val res = rewriteNonInvokableMethodCall(call) + if (res != null) res + else + null + } + + case ThunkForce(th) => + th.node match { + // empty Thunk + case ThunkDef(root, sch) if sch.isEmpty => root + // constant in Thunk + case ConstantThunk(rootConst) => rootConst + case _ => null + } + + case ApplyUnOp(op, x) => rewriteUnOp(op, x) + + case ApplyBinOp(op, x, y) => rewriteBinOp(op, x, y) + + case _ => null + } + + /** Rewrites application of given unary operation to the given argument. + * @return null if no rewriting is defined. */ + final def rewriteUnOp[A,R](op: UnOp[A,R], x: Ref[A]): Ref[_] = { + op match { + case _: NumericNegate[_] => x.node match { + // -(-x) => x + case ApplyUnOp(_: NumericNegate[_], x) => x + case _ => null + } + // (x: Int).toInt => x + case NumericToInt(_) if x.elem == IntElement => x + // (x: Long).toLong => x + case NumericToLong(_) if x.elem == LongElement => x + // (x: Float).toFloat => x + case NumericToFloat(_) if x.elem == FloatElement => x + // (x: Double).toDouble => x + case NumericToDouble(_) if x.elem == DoubleElement => x + + case _ if op == Not => x.node match { + // Rule: !(x op y) ==> + case ApplyBinOp(op, x, y) => op.asInstanceOf[BinOp[_,_]] match { + case OrderingLT(ord) => + OrderingGTEQ(ord)(x, y) + case OrderingLTEQ(ord) => + OrderingGT(ord)(x, y) + case OrderingGT(ord) => + OrderingLTEQ(ord)(x, y) + case OrderingGTEQ(ord) => + OrderingLT(ord)(x, y) + case _ => null + } + // Rule: !(!(x)) ==> x + case ApplyUnOp(op, x) if op == Not => x + // Rule: !Const(x) => Const(!x) + case Const(x: Boolean) if currentPass.config.constantPropagation => Const(!x) + case _ => null + } + case _ => propagateUnOp(op, x) + } + } + + /** Rewrites application of given binary operation to the given arguments. + * @return null if no rewriting is defined. */ + final def rewriteBinOp[A,R](op: BinOp[A,R], x: Ref[A], y: Ref[A]): Ref[_] = { + op.asInstanceOf[BinOp[_,_]] match { + case _: Equals[_] => + if (x == y) Const(true) + else { + y.node match { + case Const(b: Boolean) if x.elem == BooleanElement => + if (b) x else Not(asRep[Boolean](x)) + case _ => + x.node match { + case Const(b: Boolean) if y.elem == BooleanElement => + if (b) y else Not(asRep[Boolean](y)) + case _ => + null + } + } + } + case _: NotEquals[_] => + if (x == y) Const(false) + else { + y.node match { + case Const(b: Boolean) if x.elem == BooleanElement => + if (b) Not(asRep[Boolean](x)) else x + case _ => + x.node match { + case Const(b: Boolean) if y.elem == BooleanElement => + if (b) Not(asRep[Boolean](y)) else y + case _ => + null + } + } + } + case And => + rewriteBoolConsts(x, y, x => x, _ => false, x => x, _ => false) + case Or => + rewriteBoolConsts(x, y, _ => true, x => x, x => x, _ => true) + case BinaryXorOp => + rewriteBoolConsts(x, y, x => !x.asInstanceOf[Ref[Boolean]], x => x.asInstanceOf[Ref[Boolean]], _ => false, _ => true) + + case NumericPlus(n: ExactNumeric[a]) => (x, y) match { + // x + 0 => x + case (x, Def(Const(zero))) if isZero(zero.asInstanceOf[a], n) => x + // 0 + x => x + case (Def(Const(zero)), x) if isZero(zero.asInstanceOf[a], n) => x + case _ => propagateBinOp(op, x, y) + } + + case NumericMinus(n: ExactNumeric[a]) => (x, y) match { + // x - 0 => x + case (x, Def(Const(zero))) if isZero(zero.asInstanceOf[a], n) => x + // 0 - x => -x + case (Def(Const(zero)), x) if isZero(zero.asInstanceOf[a], n) => + new NumericOpsCls(asRep[a](x))(n).unary_- + case _ => propagateBinOp(op, x, y) + } + + case NumericTimes(n: ExactNumeric[a]) => (x, y) match { + // _ * 0 => 0 + case (_, y@Def(Const(zero))) if isZero(zero.asInstanceOf[a], n) => y + // 0 * _ => 0 + case (y@Def(Const(zero)), _) if isZero(zero.asInstanceOf[a], n) => y + // x * 1 => x + case (x, Def(Const(one))) if isOne(one.asInstanceOf[a], n) => x + // 1 * x => x + case (Def(Const(one)), x) if isOne(one.asInstanceOf[a], n) => x + case _ => propagateBinOp(op, x, y) + } + + case _ => propagateBinOp(op, x, y) + } + } + + /** Perform constant propagation if enabled and argument is Const. + * @return null if propagation is not done + */ + def propagateUnOp[T,R](op: UnOp[T,R], x: Ref[T]): Ref[R] = { + if (currentPass.config.constantPropagation) { + if (x.isConst) { + val xVal = valueFromRep(x) + if (op.shouldPropagate(xVal)) + Const(op.applySeq(xVal))(op.eResult) + else + null + } + else null + } + else null + } + + /** Perform constant propagation if enabled and both arguments are Const. + * @return null if propagation is not done + */ + def propagateBinOp[T,R](op: BinOp[T,R], x: Ref[T], y: Ref[T]): Ref[R] = { + if (currentPass.config.constantPropagation) { + if (x.isConst && y.isConst) { + val xVal = valueFromRep(x) + val yVal = valueFromRep(y) + if (op.shouldPropagate(xVal, yVal)) + reifyObject(Const(op.applySeq(xVal, yVal))(op.eResult)) + else + null + } + else null + } else + null + } +} diff --git a/core/src/main/scala/scalan/Entities.scala b/core/src/main/scala/scalan/Entities.scala new file mode 100644 index 0000000000..cb8a333150 --- /dev/null +++ b/core/src/main/scala/scalan/Entities.scala @@ -0,0 +1,65 @@ +package scalan + +import java.util.Objects + +import scala.annotation.tailrec +import scala.language.higherKinds +import scalan.util.ReflectionUtil.ClassOps + +trait Entities extends TypeDescs { self: Scalan => + + /** Base class for all descriptors of staged traits. */ + abstract class EntityElem[A] extends Elem[A] with scala.Equals { + /** Optional parent type in inheritance hierarchy */ + def parent: Option[Elem[_]] = None + /** Name of the entity type without `Elem` suffix. */ + def entityName: String = { + val n = this.getClass.safeSimpleName.stripSuffix("Elem") + n + } + def convert(x: Ref[Def[_]]): Ref[A] = !!!("should not be called") + def canEqual(other: Any) = other.isInstanceOf[EntityElem[_]] + + override def equals(other: Any) = (this.eq(other.asInstanceOf[AnyRef])) || (other match { + case other: EntityElem[_] => + other.canEqual(this) && + this.getClass == other.getClass && + this.typeArgsDescs == other.typeArgsDescs + case _ => false + }) + + override def hashCode = Objects.hash(getClass, typeArgsDescs) + } + + /** Base class for all descriptors of staged traits with one type parameter. */ + abstract class EntityElem1[A, To, C[_]](val eItem: Elem[A], val cont: Cont[C]) + extends EntityElem[To] { + override def getName(f: TypeDesc => String) = { + s"$entityName[${f(eItem)}]" + } + override def canEqual(other: Any) = other match { + case _: EntityElem1[_, _, _] => true + case _ => false + } + override def equals(other: Any) = (this eq other.asInstanceOf[AnyRef]) || (other match { + case other: EntityElem1[_,_,_] => + other.canEqual(this) && cont == other.cont && eItem == other.eItem + case _ => false + }) + override def hashCode = eItem.hashCode * 41 + cont.hashCode + } + + /** Base class for all descriptors of staged classes. */ + trait ConcreteElem[TData, TClass] extends EntityElem[TClass] + + /** Base class for all descriptors of staged classes with one type parameter. + * Note, it doesn't inherit from ConcreteElem*/ + trait ConcreteElem1[A, TData, TClass, C[_]] + extends EntityElem1[A, TClass, C] { eClass => + } + + /** Base class for all descriptors of staged companions */ + abstract class CompanionElem[T] extends Elem[T] { _: scala.Equals => + override def buildTypeArgs = EmptyTypeArgs + } +} diff --git a/core/src/main/scala/scalan/MethodCalls.scala b/core/src/main/scala/scalan/MethodCalls.scala new file mode 100644 index 0000000000..e509bd47a9 --- /dev/null +++ b/core/src/main/scala/scalan/MethodCalls.scala @@ -0,0 +1,203 @@ +package scalan + +import java.lang.reflect.{InvocationTargetException, Method} +import scala.annotation.tailrec +import scala.reflect.ClassTag +import scalan.compilation.{GraphVizConfig, GraphVizExport} +import scalan.util.ScalaNameUtil +import debox.{Buffer => DBuffer} +import spire.syntax.all.cfor + +trait MethodCalls extends Base with GraphVizExport { self: Scalan => + + def delayInvoke = throw new DelayInvokeException + + /** Graph node to represent invocation of the method of some class. + * @param receiver node ref representing instance on which the method is called + * @param method method which is called (descriptor from `java.lang.reflect`) + * @param args node refs representing arguments passed to the method + * @param neverInvoke it true this method cannot be performed, even if the + * receiver node allow this + * @param resultType type descriptor of the method's result + * @param isAdapterCall whether this MC was created by generated adapter class. + * This typically means, that receiver node doesn't implement + * given `method`. + */ + case class MethodCall private[MethodCalls](receiver: Sym, method: Method, args: Seq[AnyRef], neverInvoke: Boolean) + (val resultType: Elem[Any], val isAdapterCall: Boolean = false) extends Def[Any] { + + override def mirror(t: Transformer): Ref[Any] = { + val len = args.length + val args1 = new Array[AnyRef](len) + cfor(0)(_ < len, _ + 1) { i => + args1(i) = transformProductParam(args(i), t).asInstanceOf[AnyRef] + } + val receiver1 = t(receiver) + // in the case neverInvoke is false, the method is invoked in rewriteDef + mkMethodCall(receiver1, method, args1, neverInvoke, isAdapterCall, resultType).asInstanceOf[Ref[Any]] + } + + override def toString = { + val methodStr = method.toString.replace("java.lang.", ""). + replace("public ", "").replace("abstract ", "") + s"MethodCall($receiver, $methodStr, [${args.mkString(", ")}], $neverInvoke)" + } + + /** Try invoke `method` on the node instance refered by `receiver`. + * Each MC node contains enough information to perform invocation using + * `java.lang.reflect.Method.invoke` method. However, this is not possible + * if the node pointed to by `receiver` don't implement this method, + * for example when receiver is Lambda variable pointing to Variable node + * instance (in which case this MC was created by adapter) + * @return invocation result descriptor. + * @see InvokeResult + */ + def tryInvoke: InvokeResult = + if (neverInvoke && !isAdapterCall) { + InvokeImpossible + } else { + invokeMethod[InvokeResult]( + receiver, method, args.toArray, + { res => InvokeSuccess(res.asInstanceOf[Sym]) }, + { InvokeFailure(_) }, + { InvokeImpossible } + ) + } + + import scalan.util.CollectionUtil.TraversableOps + override def equals(other: Any): Boolean = (this eq other.asInstanceOf[AnyRef]) || { + other match { + case other: MethodCall => + receiver == other.receiver && + method == other.method && + resultType.name == other.resultType.name && + neverInvoke == other.neverInvoke && + isAdapterCall == other.isAdapterCall && + args.length == other.args.length && + args.sameElements2(other.args) // this is required in case method have T* arguments + case _ => false + } + } + + override lazy val hashCode: Int = { + var h = receiver.hashCode() * 31 + method.hashCode() + h = h * 31 + resultType.name.hashCode + h = h * 31 + (if(neverInvoke) 1 else 0) + h = h * 31 + (if(isAdapterCall) 1 else 0) + h = h * 31 + args.hashCode() + h + } + } + + /** Represents invocation of constructor of the class described by `eA`. + * @param eA class descriptor for new instance + * @param args arguments of class constructor + */ + case class NewObject[A](eA: Elem[A], args: Seq[Any]) extends BaseDef[A]()(eA) { + override def transform(t: Transformer) = NewObject(eA, t(args)) + } + + /** Creates new MethodCall node and returns its node ref. */ + def mkMethodCall(receiver: Sym, method: Method, args: Seq[AnyRef], + neverInvoke: Boolean, isAdapterCall: Boolean, resultElem: Elem[_]): Sym = { + reifyObject(MethodCall(receiver, method, args, neverInvoke)(asElem[Any](resultElem), isAdapterCall)) + } + + /** Creates new NewObject node and returns its node ref. */ + def newObjEx[A](args: Any*)(implicit eA: Elem[A]): Ref[A] = { + reifyObject(NewObject[A](eA, args)) + } + + @tailrec + private def baseCause(e: Throwable): Throwable = e match { + case e: java.lang.reflect.UndeclaredThrowableException => baseCause(e.getCause) + case e: InvocationTargetException => baseCause(e.getCause) + case e: ExceptionInInitializerError => baseCause(e.getCause) + case e => e + } + + /** Used by Graphviz dot file generator to format text label of the graph node. */ + override protected def formatDef(d: Def[_])(implicit config: GraphVizConfig): String = d match { + case MethodCall(obj, method, args, _) => + val methodCallStr = + s"${ScalaNameUtil.cleanScalaName(method.getName)}(${args.mkString(", ")})" + if (obj.isCompanionType) { + s"$obj.$methodCallStr" + } else { + val className = ScalaNameUtil.cleanNestedClassName(method.getDeclaringClass.getName) + s"$obj.$className.$methodCallStr" + } + case NewObject(eA, args) => + val className = ScalaNameUtil.cleanNestedClassName(eA.sourceType.name) + s"new $className(${args.mkString(", ")})" + case _ => super.formatDef(d) + } + + /** This method is called for each MethodCall node which is about to be added to the graph. + * This means `mc` has been examined by all the rewrite rules, but has not need rewritten. + * Now, if this method returns null, then mc will be added to the graph. + * However, in this method, `mc` can be examined by a second set of RW rules + * (kind of lower priority rules). These rules kind of context dependent, because at this + * point we know that the first RW set didn't triggered any rewrite. */ + def rewriteNonInvokableMethodCall(mc: MethodCall): Ref[_] = null + + /** Create delegate instance suitable for method invocation. + * It is used when T is a class or a trait and the node referred by x doesn't conform to T. + * This method returns dynamically constructed instance, which conforms to T. + * Whenever a method of T is called on that instance, the call is intercepted and + * `DelegatedInterceptionHandler.invoke` method is called, then a new MethodCall can + * be constructed (which is befavior by default). + */ + protected def unrefDelegate[T <: AnyRef](x: Ref[T])(implicit ct: ClassTag[T]): T = { + val d = x.node + if (d.isInstanceOf[Const[_]]) + d.asInstanceOf[Const[T]@unchecked].x + else + !!!(s"Cannot do undefDelegate($x -> ${x.node})") + } + + /** Generic helper to call the given method on the given receiver node. */ + private[scalan] def invokeMethod[A](receiver: Sym, m: Method, args: Array[AnyRef], + onInvokeSuccess: AnyRef => A, + onInvokeException: Throwable => A, + onInvokeImpossible: => A): A = { + val d = receiver.node + if (canBeInvoked(d, m, args)) { + try { + val res = m.invoke(d, args: _*) + onInvokeSuccess(res) + } catch { + case e: Exception => onInvokeException(baseCause(e)) + } + } + else + onInvokeImpossible + } + + /** Method invocation enabler. + * @return true if the given method can be invoked on the given node. */ + def isInvokeEnabled(d: Def[_], m: Method) = true + + /** Method invocation checker. */ + protected def canBeInvoked(d: Def[_], m: Method, args: Array[AnyRef]) = { + m.getDeclaringClass.isAssignableFrom(d.getClass) && isInvokeEnabled(d, m) + } + + /** Result of MethodCall invocation. + * @see tryInvoke */ + sealed abstract class InvokeResult + /** Successful MethodCall invocation with the given result. */ + case class InvokeSuccess(result: Ref[_]) extends InvokeResult + /** Exception thrown during MethodCall invocation. */ + case class InvokeFailure(exception: Throwable) extends InvokeResult + /** Invocation is not possible, e.g. when receiver doesn't implemented the method. */ + case object InvokeImpossible extends InvokeResult + + def throwInvocationException(whatFailed: String, cause: Throwable, receiver: Sym, m: Method, args: Seq[Any]) = { + val buf = DBuffer.empty[Sym] + buf += receiver + Def.extractSyms(args, buf) + val deps = buf.toArray() + !!!(s"$whatFailed (${receiver.varNameWithType}).${m.getName}(${args.mkString(", ")}) failed", baseCause(cause), deps: _*) + } +} diff --git a/core/src/main/scala/scalan/Modules.scala b/core/src/main/scala/scalan/Modules.scala new file mode 100644 index 0000000000..989f2c524c --- /dev/null +++ b/core/src/main/scala/scalan/Modules.scala @@ -0,0 +1,14 @@ +package scalan + +trait Modules extends Base { self: Scalan => + + /** Whether staged modules should be registered when cake is constructed and initialized. */ + def okRegisterModules: Boolean = false + + /** Called once for each staged module during this cake initialization. */ + protected def registerModule(moduleInfo: ModuleInfo) = { + if (okRegisterModules) { + !!!(s"Cannot register module $moduleInfo: registerModule method is not overridden in IR cake $this. ") + } + } +} diff --git a/core/src/main/scala/scalan/Plugins.scala b/core/src/main/scala/scalan/Plugins.scala new file mode 100644 index 0000000000..a744df0958 --- /dev/null +++ b/core/src/main/scala/scalan/Plugins.scala @@ -0,0 +1,25 @@ +package scalan + +import java.io.File +import com.typesafe.config.ConfigFactory +import scalan.util.ClassLoaderUtil + +object Plugins { + val extraClassPathKey = "plugins.extraClassPath" + + lazy val config0 = ConfigFactory.load().getConfig("scalan") + lazy val pluginClassLoader = { + val thisClassLoader = getClass.getClassLoader + + config0.getString(extraClassPathKey) match { + case "" => + thisClassLoader + case path => + val files = path.split(File.pathSeparatorChar).map(new File(_)) + ClassLoaderUtil.URLClassLoader(files, thisClassLoader) + } + } + lazy val configWithPlugins = ConfigFactory.load(pluginClassLoader).getConfig("scalan") + + def loadClass(name: String) = pluginClassLoader.loadClass(name) +} diff --git a/core/src/main/scala/scalan/Scalan.scala b/core/src/main/scala/scalan/Scalan.scala new file mode 100644 index 0000000000..6b037ccea5 --- /dev/null +++ b/core/src/main/scala/scalan/Scalan.scala @@ -0,0 +1,38 @@ +package scalan + +import scalan.compilation.GraphVizExport +import scalan.primitives._ +import scalan.staged.{Transforming} + +/** Aggregate cake with all inter-dependent modules assembled together. + * Each instance of this class contains independent IR context, thus many + * instances can be created simultaneously. + * However, the inner types declared in the traits are path-dependant. + * This in particular means that ctx1.Ref[_] and ctx2.Ref[_] are different types. + * The typical usage is to create `val ctx = new Scalan` and then import inner + * declarations using `import ctx._`. + * This way the declaration will be directly available as if they were global + * declarations. + * At the same time cake design pattern allow to `override` many methods and values + * in classed derived from `Scalan`, this is significant benefit over + * *everything is global* design. + */ +class Scalan + extends TypeDescs + with MethodCalls + with Tuples + with NumericOps + with UnBinOps + with LogicalOps + with OrderingOps + with Equal + with UniversalOps + with Functions + with IfThenElse + with Transforming + with GraphVizExport + with Thunks + with Entities + with Modules + with DefRewriting + diff --git a/core/src/main/scala/scalan/TypeDescs.scala b/core/src/main/scala/scalan/TypeDescs.scala new file mode 100644 index 0000000000..9b669e3311 --- /dev/null +++ b/core/src/main/scala/scalan/TypeDescs.scala @@ -0,0 +1,477 @@ +package scalan + +import java.lang.reflect.{InvocationTargetException, Method} + +import scala.annotation.implicitNotFound +import scala.collection.immutable.ListMap +import scala.reflect.runtime.universe._ +import scala.reflect.{ClassTag} +import scalan.util._ +import scalan.RType._ +import scalan.util.ReflectionUtil.ClassOps +import spire.syntax.all._ +import scala.collection.mutable + +abstract class TypeDescs extends Base { self: Scalan => + + /** Helper type case method. */ + @inline final def asElem[T](d: TypeDesc): Elem[T] = d.asInstanceOf[Elem[T]] + + /** Type descriptor which is computed lazily on demand. */ + type LElem[A] = Lazy[Elem[A]] + + /** Immutable data environment used to assign data values to graph nodes. */ + type DataEnv = Map[Sym, AnyRef] + + /** State monad for symbols computed in a data environment. + * `DataEnv` is used as the state of the state monad. + */ + case class EnvRep[A](run: DataEnv => (DataEnv, Ref[A])) { + def flatMap[B](f: Ref[A] => EnvRep[B]): EnvRep[B] = EnvRep { env => + val (env1, x) = run(env) + val res = f(x).run(env1) + res + } + def map[B](f: Ref[A] => Ref[B]): EnvRep[B] = EnvRep { env => + val (env1, x) = run(env) + val y = f(x) + (env1, y) + } + } + object EnvRep { + def add[T](entry: (Ref[T], AnyRef)): EnvRep[T] = + EnvRep { env => val (sym, value) = entry; (env + (sym -> value), sym) } + + def lifted[ST, T](x: ST)(implicit lT: Liftables.Liftable[ST, T]): EnvRep[T] = EnvRep { env => + val xSym = lT.lift(x) + val resEnv = env + ((xSym, x.asInstanceOf[AnyRef])) + (resEnv, xSym) + } + } + + sealed abstract class MethodDesc { + def method: Method + } + case class RMethodDesc(method: Method) extends MethodDesc + case class WMethodDesc(wrapSpec: WrapSpec, method: Method) extends MethodDesc + +// TODO benchmark this version agains the version below +// def getSourceValues(dataEnv: DataEnv, forWrapper: Boolean, stagedValue: AnyRef, out: DBuffer[AnyRef]): Unit = { +// import OverloadHack._ +// stagedValue match { +// case s: Sym => +// out += dataEnv(s) +// case vec: Seq[AnyRef]@unchecked => +// val sub = DBuffer.ofSize[AnyRef](vec.length) +// getSourceValues(dataEnv, forWrapper, vec, sub) +// out += (sub.toArray: Seq[AnyRef]) +// case e: Elem[_] => +// val arg = +// if (forWrapper) e.sourceType.classTag // WrapSpec classes use ClassTag implicit arguments +// else e.sourceType +// out += arg +// case _: Overloaded => // filter out special arguments +// } +// } +// def getSourceValues(dataEnv: DataEnv, forWrapper: Boolean, stagedValues: Seq[AnyRef], out: DBuffer[AnyRef]): Unit = { +// val limit = stagedValues.length +// cfor(0)(_ < limit, _ + 1) { i => +// val v = stagedValues.apply(i) +// getSourceValues(dataEnv, forWrapper, v, out) +// } +// } + + // TODO optimize performance hot spot (45% of invokeUnlifted time) + final def getSourceValues(dataEnv: DataEnv, forWrapper: Boolean, stagedValues: AnyRef*): Seq[AnyRef] = { + import OverloadHack._ + val limit = stagedValues.length + val res = mutable.ArrayBuilder.make[AnyRef]() + res.sizeHint(limit) + cfor(0)(_ < limit, _ + 1) { i => + val v = stagedValues.apply(i) + v match { + case s: Sym => + res += dataEnv(s) + case vec: Seq[AnyRef]@unchecked => + res += getSourceValues(dataEnv, forWrapper, vec:_*) + case e: Elem[_] => + val arg = + if (forWrapper) e.sourceType.classTag // WrapSpec classes use ClassTag implicit arguments + else e.sourceType + res += arg + case _: Overloaded => // filter out special arguments + } + } + res.result() + } + + abstract class TypeDesc extends Serializable { + def getName(f: TypeDesc => String): String + lazy val name: String = getName(_.name) + + // <> to delimit because: [] is used inside name; {} looks bad with structs. + override def toString = s"${getClass.safeSimpleName}<$name>" + } + + /** Type descriptor of staged types, which correspond to source (unstaged) RTypes + * defined outside of IR cake. + * @tparam A the type represented by this descriptor + */ + @implicitNotFound(msg = "No Elem available for ${A}.") + abstract class Elem[A] extends TypeDesc { _: scala.Equals => + import Liftables._ + def buildTypeArgs: ListMap[String, (TypeDesc, Variance)] = EmptyTypeArgs + lazy val typeArgs: ListMap[String, (TypeDesc, Variance)] = buildTypeArgs + lazy val typeArgsDescs: Seq[TypeDesc] = { + val b = mutable.ArrayBuilder.make[TypeDesc]() + for (v <- typeArgs.valuesIterator) { + b += v._1 + } + b.result() + } + + override def getName(f: TypeDesc => String) = { + val className = this match { + case be: BaseElemLiftable[_] => + be.sourceType.name + case e => + val cl = e.getClass + val name = cl.safeSimpleName.stripSuffix("Elem") + name + } + if (typeArgs.isEmpty) + className + else { + val typeArgString = typeArgsDescs.map(f).mkString(", ") + s"$className[$typeArgString]" + } + } + + def liftable: Liftable[_, A] = + !!!(s"Cannot get Liftable instance for $this") + + final lazy val sourceType: RType[_] = liftable.sourceType + protected def collectMethods: Map[Method, MethodDesc] = Map() + protected lazy val methods: Map[Method, MethodDesc] = collectMethods + + // TODO benchamrk against the version below it + // def invokeUnlifted(mc: MethodCall, dataEnv: DataEnv): AnyRef = { + // val srcArgs = DBuffer.ofSize[AnyRef](mc.args.length + 10) // with some spare space to have only single allocation + // val res = methods.get(mc.method) match { + // case Some(WMethodDesc(wrapSpec, method)) => + // getSourceValues(dataEnv, true, mc.receiver, srcArgs) + // getSourceValues(dataEnv, true, mc.args, srcArgs) + // def msg = s"Cannot invoke method $method on object $wrapSpec with arguments $srcArgs" + // val res = + // try method.invoke(wrapSpec, srcArgs.toArray:_*) + // catch { + // case e: InvocationTargetException => !!!(msg, e.getTargetException) + // case t: Throwable => !!!(msg, t) + // } + // res + // case Some(RMethodDesc(method)) => + // getSourceValues(dataEnv, false, mc.receiver, srcArgs) + // val srcObj = srcArgs(0) + // srcArgs.pop() + // getSourceValues(dataEnv, false, mc.args, srcArgs) + // def msg = s"Cannot invoke method $method on object $srcObj with arguments ${srcArgs.toArray.toSeq}" + // val res = + // try method.invoke(srcObj, srcArgs.toArray:_*) + // catch { + // case e: InvocationTargetException => !!!(msg, e.getTargetException) + // case t: Throwable => !!!(msg, t) + // } + // res + // case None => + // !!!(s"Cannot perform unliftedInvoke of $mc") + // } + // // this if is required because res == null in case of Unit return type + // if (mc.selfType == UnitElement) ().asInstanceOf[AnyRef] else res + // } + + /** Invoke source type method corresponding to the given MethodCall node. + * The instance of receiver is obtained from `dataEnv` using mc.receiver symbol. + * The Method descriptor of the source class is taken from `this.methods` mapping. + * @param mc IR node representing method invocation + * @param dataEnv environment where each symbol of 'mc' has associated data value + * @return data value returned from invoked method + */ + def invokeUnlifted(mc: MethodCall, dataEnv: DataEnv): AnyRef = { + val res = methods.get(mc.method) match { + case Some(WMethodDesc(wrapSpec, method)) => + val srcArgs = getSourceValues(dataEnv, true, mc.receiver +: mc.args:_*) + def msg = s"Cannot invoke method $method on object $wrapSpec with arguments $srcArgs" + val res = + try method.invoke(wrapSpec, srcArgs:_*) + catch { + case e: InvocationTargetException => !!!(msg, e.getTargetException) + case t: Throwable => !!!(msg, t) + } + res + case Some(RMethodDesc(method)) => + val srcObj = getSourceValues(dataEnv, false, mc.receiver).head + val srcArgs = getSourceValues(dataEnv, false, mc.args:_*) + def msg = s"Cannot invoke method $method on object $srcObj with arguments $srcArgs" + val res = + try method.invoke(srcObj, srcArgs:_*) + catch { + case e: InvocationTargetException => !!!(msg, e.getTargetException) + case t: Throwable => !!!(msg, t) + } + res + case None => + !!!(s"Cannot perform unliftedInvoke of $mc") + } + // this if is required because res == null in case of Unit return type + if (mc.resultType == UnitElement) ().asInstanceOf[AnyRef] else res + } + + def <:<(e: Elem[_]) = e.getClass.isAssignableFrom(this.getClass) + } + + object Elem { + /** Map source type desciptor to stated type descriptor using liftable instance. */ + implicit def rtypeToElem[SA, A](tSA: RType[SA])(implicit lA: Liftables.Liftable[SA,A]): Elem[A] = lA.eW + + final def unapply[T, E <: Elem[T]](s: Ref[T]): Nullable[E] = Nullable(s.elem.asInstanceOf[E]) + + /** Get unique method name suitable to be used as HashMap key. */ + def methodKey(m: Method) = { + val ann = m.getDeclaredAnnotation(classOf[OverloadId]) + if (ann != null) + s"${m.getName}_${ann.value}" + else + m.getName + } + + /** Build a mapping between methods of staged class and the corresponding methods of source class. + * The methods are related using names. + * The computed mapping can be used to project MethodCalls IR nodes back to the corresponding + * methods of source classes and then making their invocation using Java Reflection (Method.invoke). + * @param cls staged class where `methodNames` should be looked up + * @param srcCls source class where `methodNames` should be looked up + * @param methodNames list of method names to lookup in both classes + * @return a sequence of pairs relating for each staged method the corresponding method from + * source classes. + */ + def declaredMethods(cls: Class[_], srcCls: Class[_], methodNames: Set[String]): Seq[(Method, MethodDesc)] = { + val rmethods = cls.getDeclaredMethods.filter(m => methodNames.contains(m.getName)) + val smethods = srcCls.getDeclaredMethods.filter(m => methodNames.contains(m.getName)) + val mapping = CollectionUtil.joinSeqs(rmethods, smethods)(methodKey, methodKey) + mapping.map { case (rm, sm) => + (rm, RMethodDesc(sm)) + }.to[Seq] + } + + /** Build a mapping between methods of staged wrapper and the corresponding methods of wrapper spec class. + * The methods are related using names. + * @param wrapSpec wrapper specification class where `methodNames` should be looked up + * @param wcls wrapper class where `methodNames` should be looked up + * @param methodNames list of method names to lookup in both classes + * @return a sequence of pairs relating for each wrapper method the corresponding method from + * source classes. + */ + def declaredWrapperMethods(wrapSpec: WrapSpec, wcls: Class[_], methodNames: Set[String]): Seq[(Method, MethodDesc)] = { + val specCls = wrapSpec.getClass + val wMethods = wcls.getDeclaredMethods.filter(m => methodNames.contains(m.getName)) + val specMethods = specCls.getDeclaredMethods.filter(m => methodNames.contains(m.getName)) + val mapping = CollectionUtil.joinSeqs(wMethods, specMethods)(methodKey, methodKey) + mapping.map { case (wm, sm) => + (wm, WMethodDesc(wrapSpec, sm)) + }.to[Seq] + } + + } + + /** Invoke source type method corresponding to the given MethodCall node. + * This method delegated the work to the given element instance. + * @param e type descriptor of receiver node + * @param mc IR node representing method invocation + * @param dataEnv environment where each symbol of 'mc' has associated data value + * @return data value returned from invoked method + */ + def invokeUnlifted(e: Elem[_], mc: MethodCall, dataEnv: DataEnv): AnyRef = + e.invokeUnlifted(mc, dataEnv) + + /** Get first (and the only) constructor of the `clazz`. */ + private[scalan] final def getConstructor(clazz: Class[_]) = { + val constructors = clazz.getDeclaredConstructors() + if (constructors.length != 1) + !!!(s"Element class $clazz has ${constructors.length} constructors, 1 expected") + else + constructors(0) + } + + /** Retrieve an instance of the given Elem class by either looking up in the cache + * or creating a new one. + * We assume that all Elem instances are uniquely defined by (clazz, args) + * @param args arguments of Elem class constructor + * @param clazz Elem class + */ + final def cachedElemByClass[E <: Elem[_]](args: AnyRef*)(implicit clazz: Class[E]) = { + cachedElem0(clazz, Nullable.None, args).asInstanceOf[E] + } + + /** Elements cache information for each Elem class. */ + class ElemCacheEntry( + /** Constructor of the class to create new instances. */ + val constructor: java.lang.reflect.Constructor[_], + /** Whether owner argument of constructor exists and of which kind. */ + val ownerType: OwnerKind, + /** Created instances of elements, one for each unique collection of args. */ + val elements: AVHashMap[Seq[AnyRef], AnyRef] + ) + + protected val elemCache = AVHashMap[Class[_], ElemCacheEntry](1000) + + private[scalan] final def cachedElem0(clazz: Class[_], optConstructor: Nullable[java.lang.reflect.Constructor[_]], args: Seq[AnyRef]) = { + val entry = elemCache.get(clazz) match { + case Nullable(entry) => entry + case _ => + val constructor = if (optConstructor.isEmpty) getConstructor(clazz) else optConstructor.get + val ownerType = getOwnerKind(constructor) + val entry = new ElemCacheEntry(constructor, ownerType, AVHashMap(10)) + elemCache.put(clazz, entry) + entry + } + val e = entry.elements.get(args) match { + case Nullable(e) => e + case _ => + val constructorArgs = addOwnerParameter(entry.ownerType, args) + val e = entry.constructor.newInstance(constructorArgs: _*).asInstanceOf[AnyRef] + entry.elements.put(args, e) + e + } + e.asInstanceOf[Elem[_]] + } + + final def element[A](implicit ea: Elem[A]): Elem[A] = ea + + abstract class BaseElem[A](defaultValue: A) extends Elem[A] with Serializable with scala.Equals + + /** Type descriptor for primitive types. + * There is implicit `val` declaration for each primitive type. */ + class BaseElemLiftable[A](defaultValue: A, val tA: RType[A]) extends BaseElem[A](defaultValue) { + override def buildTypeArgs = EmptyTypeArgs + override val liftable = new Liftables.BaseLiftable[A]()(this, tA) + override def canEqual(other: Any) = other.isInstanceOf[BaseElemLiftable[_]] + override def equals(other: Any) = (this eq other.asInstanceOf[AnyRef]) || (other match { + case other: BaseElemLiftable[_] => tA == other.tA + case _ => false + }) + override val hashCode = tA.hashCode + } + + /** Type descriptor for `(A, B)` type where descriptors for `A` and `B` are given as arguments. */ + case class PairElem[A, B](eFst: Elem[A], eSnd: Elem[B]) extends Elem[(A, B)] { + assert(eFst != null && eSnd != null) + override def getName(f: TypeDesc => String) = s"(${f(eFst)}, ${f(eSnd)})" + override def buildTypeArgs = ListMap("A" -> (eFst -> Covariant), "B" -> (eSnd -> Covariant)) + override def liftable: Liftables.Liftable[_, (A, B)] = + Liftables.asLiftable[(_,_), (A,B)](Liftables.PairIsLiftable(eFst.liftable, eSnd.liftable)) + } + + /** Type descriptor for `A | B` type where descriptors for `A` and `B` are given as arguments. */ + case class SumElem[A, B](eLeft: Elem[A], eRight: Elem[B]) extends Elem[A | B] { + override def getName(f: TypeDesc => String) = s"(${f(eLeft)} | ${f(eRight)})" + override def buildTypeArgs = ListMap("A" -> (eLeft -> Covariant), "B" -> (eRight -> Covariant)) + } + + /** Type descriptor for `A => B` type where descriptors for `A` and `B` are given as arguments. */ + case class FuncElem[A, B](eDom: Elem[A], eRange: Elem[B]) extends Elem[A => B] { + import Liftables._ + override def getName(f: TypeDesc => String) = s"${f(eDom)} => ${f(eRange)}" + override def buildTypeArgs = ListMap("A" -> (eDom -> Contravariant), "B" -> (eRange -> Covariant)) + override def liftable: Liftable[_, A => B] = + asLiftable[_ => _, A => B](FuncIsLiftable(eDom.liftable, eRange.liftable)) + } + + /** Type descriptor for `Any`, cannot be used implicitly. */ + val AnyElement: Elem[Any] = new BaseElemLiftable[Any](null, AnyType) + + /** Predefined Lazy value saved here to be used in hotspot code. */ + val LazyAnyElement = Lazy(AnyElement) + + /** Type descriptor for `AnyRef`, cannot be used implicitly. */ + val AnyRefElement: Elem[AnyRef] = new BaseElemLiftable[AnyRef](null, AnyRefType) + + // somewhat ugly casts, but they completely disappear after type erasure + // (so not present in Java bytecode) + val NothingElement: Elem[Nothing] = + asElem[Nothing](new BaseElemLiftable[Null]( + null, NothingType.asInstanceOf[RType[Null]] + )) + + implicit val BooleanElement: Elem[Boolean] = new BaseElemLiftable(false, BooleanType) + implicit val ByteElement: Elem[Byte] = new BaseElemLiftable(0.toByte, ByteType) + implicit val ShortElement: Elem[Short] = new BaseElemLiftable(0.toShort, ShortType) + implicit val IntElement: Elem[Int] = new BaseElemLiftable(0, IntType) + implicit val LongElement: Elem[Long] = new BaseElemLiftable(0L, LongType) + implicit val FloatElement: Elem[Float] = new BaseElemLiftable(0.0F, FloatType) + implicit val DoubleElement: Elem[Double] = new BaseElemLiftable(0.0, DoubleType) + implicit val UnitElement: Elem[Unit] = new BaseElemLiftable((), UnitType) + implicit val StringElement: Elem[String] = new BaseElemLiftable("", StringType) + implicit val CharElement: Elem[Char] = new BaseElemLiftable('\u0000', CharType) + + implicit final def pairElement[A, B](implicit ea: Elem[A], eb: Elem[B]): Elem[(A, B)] = + cachedElemByClass[PairElem[A, B]](ea, eb)(classOf[PairElem[A, B]]) + implicit final def sumElement[A, B](implicit ea: Elem[A], eb: Elem[B]): Elem[A | B] = + cachedElemByClass[SumElem[A, B]](ea, eb)(classOf[SumElem[A, B]]) + implicit final def funcElement[A, B](implicit ea: Elem[A], eb: Elem[B]): Elem[A => B] = + cachedElemByClass[FuncElem[A, B]](ea, eb)(classOf[FuncElem[A, B]]) + + implicit final def PairElemExtensions[A, B](eAB: Elem[(A, B)]): PairElem[A, B] = eAB.asInstanceOf[PairElem[A, B]] + implicit final def SumElemExtensions[A, B](eAB: Elem[A | B]): SumElem[A, B] = eAB.asInstanceOf[SumElem[A, B]] + implicit final def FuncElemExtensions[A, B](eAB: Elem[A => B]): FuncElem[A, B] = eAB.asInstanceOf[FuncElem[A, B]] + + implicit final def toLazyElem[A](implicit eA: Elem[A]): LElem[A] = Lazy(eA) + + /** Since ListMap is immutable this empty map can be shared by all other maps created from it. */ + val EmptyTypeArgs: ListMap[String, (TypeDesc, Variance)] = ListMap.empty + + final def TypeArgs(descs: (String, (TypeDesc, Variance))*): ListMap[String, (TypeDesc, Variance)] = ListMap(descs: _*) + + // can be removed and replaced with assert(value.elem == elem) after #72 + def assertElem(value: Ref[_], elem: Elem[_]): Unit = assertElem(value, elem, "") + def assertElem(value: Ref[_], elem: Elem[_], hint: => String): Unit = { + assert(value.elem == elem, + s"${value.varNameWithType} doesn't have type ${elem.name}" + (if (hint.isEmpty) "" else s"; $hint")) + } + def assertEqualElems[A](e1: Elem[A], e2: Elem[A], m: => String): Unit = + assert(e1 == e2, s"Element $e1 != $e2: $m") + + /** Descriptor of type constructor of `* -> *` kind. Type constructor is not a type, + * but rather a function from type to type. + * It contains methods which abstract relationship between types `T`, `F[T]` etc. + * @param F high-kind type costructor which is described by this descriptor*/ + @implicitNotFound(msg = "No Cont available for ${F}.") + abstract class Cont[F[_]] extends TypeDesc { + /** Given a descriptor of type `T` produced descriptor of type `F[T]`. */ + def lift[T](implicit eT: Elem[T]): Elem[F[T]] + + /** Given a descriptor of type `F[T]` extracts a descriptor of type `T`. */ + def unlift[T](implicit eFT: Elem[F[T]]): Elem[T] + + /** Recogniser of type descriptors constructed by this type costructor. + * This can be used in generic code, where F is not known, but this descriptor is available. */ + def unapply[T](e: Elem[_]): Option[Elem[F[T]]] + + /** Type string of this type constructor. */ + def getName(f: TypeDesc => String): String = { + val eFAny = lift(AnyElement) + val name = eFAny.getClass.getSimpleName.stripSuffix("Elem") + "[x] => " + name + "[x]" + } + + /** Whether the type constructor `F` is an instance of Functor type class. */ + final def isFunctor = this.isInstanceOf[Functor[F]] + } + + final def container[F[_]: Cont] = implicitly[Cont[F]] + + implicit final def containerElem[F[_]:Cont, A:Elem]: Elem[F[A]] = container[F].lift(element[A]) + + trait Functor[F[_]] extends Cont[F] { + def map[A,B](a: Ref[F[A]])(f: Ref[A] => Ref[B]): Ref[F[B]] + } +} diff --git a/core/src/main/scala/scalan/compilation/GraphVizExport.scala b/core/src/main/scala/scalan/compilation/GraphVizExport.scala new file mode 100644 index 0000000000..8c90f221b6 --- /dev/null +++ b/core/src/main/scala/scalan/compilation/GraphVizExport.scala @@ -0,0 +1,544 @@ +package scalan.compilation + +import java.awt.Desktop +import java.io.{PrintWriter, File} + +import configs.Configs +import configs.syntax._ +import com.typesafe.config.{ConfigUtil, Config} +import configs.Result.{Success, Failure} +import scalan.{Plugins, Scalan, Base} +import scalan.util.{ProcessUtil, FileUtil, StringUtil, ScalaNameUtil} +import scala.collection.immutable.StringOps + +// TODO implement this outside of the cake + +/** Implementation of Graphviz's dot file generator. */ +trait GraphVizExport extends Base { self: Scalan => + + case class GraphFile(file: File, fileType: String) { + def open() = { + Plugins.configWithPlugins.get[String](ConfigUtil.joinPath("graphviz", "viewer", fileType)) match { + case Failure(_) => + Desktop.getDesktop.open(file) + case Success(command) => + ProcessUtil.launch(Seq(command, file.getAbsolutePath)) + } + } + } + + // TODO it would be better to have nodeColor(elem: Elem[_], optDef: Option[Def[_]]) to + // avoid looking up definition, but this leads to ClassFormatError (likely Scala bug) + protected def nodeColor(td: TypeDesc, d: Def[_])(implicit config: GraphVizConfig): String = d match { + case _ => nodeColor(td) + } + + protected def nodeColor(td: TypeDesc): String = td match { + case _: ConcreteElem[_, _] => "green" + case _: FuncElem[_, _] => "magenta" + case _: CompanionElem[_] => "lightgray" + case _ => "gray" + } + + // ensures nice line wrapping + final protected def nodeLabel(parts: String*)(implicit config: GraphVizConfig) = { + config.nodeLabel(parts) + } + + private def emitNode0(x: Sym, d: Option[Def[_]], acc: GraphData)(implicit stream: PrintWriter, config: GraphVizConfig) = { + stream.println(StringUtil.quote(x) + " [") + val acc1 = acc.addNode(x, d) + val xElem = x.elem + val label = acc1.typeString(xElem) + val xAndD = d match { + case Some(rhs) => + val lhsStr = s"$x: $label =" + val rhsStr = formatDef(rhs) + val rhsElem = rhs.resultType + if (rhsElem != xElem) { + List(lhsStr, s"$rhsStr:", acc1.typeString(rhsElem)) + } else { + List(lhsStr, rhsStr) + } + case None => + List(s"$x: $label") + } + val metadata = if (config.emitMetadata) formatMetadata(x) else Nil + val allParts = xAndD ++ metadata + stream.println(nodeLabel(allParts: _*)) + + val (shape, color) = d match { + case Some(rhs) => + ("box", nodeColor(xElem, rhs)) + case None => + ("oval", nodeColor(xElem)) + } + // use full type name for the tooltip + stream.println(s"shape=$shape, color=$color, tooltip=${StringUtil.quote(x.varNameWithType)}, style=filled, fillcolor=white") + stream.println("]") + acc1 + } + + private def emitNode(sym: Sym, rhs: Def[_], acc: GraphData)(implicit stream: PrintWriter, config: GraphVizConfig) = { + val acc1 = rhs match { + case g: AstGraph => + g.boundVars.foldLeft(acc)((acc2, x) => emitNode0(x, None, acc2)) + case _ => + acc + } + emitNode0(sym, Some(rhs), acc1) + } + + protected def formatMetadata(s: Sym): List[String] = Nil + + protected def formatDef(d: Def[_])(implicit config: GraphVizConfig): String = d match { + case Const(x) => + val formattedX = formatConst(x) + s"Const($formattedX)" + case l: Lambda[_, _] => + val y = l.y + val bodyStr = y match { + case Def(b) => + val rhs = formatDef(b) + if (config.showLambdaReturnSym) + s"$y = $rhs" + else + rhs + case _ => y.toString + } + s"${l.x} => $bodyStr" + case Apply(f, arg, _) => s"$f($arg)" + case Tup(a, b) => s"($a, $b)" + case First(pair) => s"$pair._1" + case Second(pair) => s"$pair._2" + case ApplyBinOp(op, lhs, rhs) => s"$lhs ${op.opName} $rhs" + case ApplyUnOp(op, arg) => op match { + case NumericToFloat(_) => s"$arg.toFloat" + case NumericToDouble(_) => s"$arg.toDouble" + case NumericToInt(_) => s"$arg.toInt" + case ToString() => s"$arg.toString" + case HashCode() => s"$arg.hashCode" + case _ => s"${op.opName} $arg" + } + case _ => d.toString + } + + protected def formatConst(x: Any): String = x match { + case str: String => + val tripleQuote = "\"\"\"" + new StringOps(str).lines.toSeq match { + case Seq() => + "\"\"" + case Seq(line) => + if (line.contains("\"")) + tripleQuote + line + tripleQuote + else + StringUtil.quote(line) + case lines => + (tripleQuote +: lines :+ tripleQuote).mkString("\n") + } + case c: Char => s"'$c'" + case f: Float => s"${f}f" + case l: Long => s"${l}l" + case arr: Array[_] => s"Array(${arr.toSeq.map(formatConst).mkString(", ")})" + case seq: Seq[_] => + s"${seq.stringPrefix}(${seq.map(formatConst).mkString(", ")})" + case null => "null" + case _ => x.toString + } + + private def emitDepEdges(sym: Sym, rhs: Def[_])(implicit stream: PrintWriter, config: GraphVizConfig) = { + val (deps, lambdaVars) = rhs match { + case l: Lambda[_, _] => lambdaDeps(l) + case _ => (rhs.deps.toList, Nil) + } + emitEdges(lambdaVars, sym, "[style=dashed, color=lightgray, weight=0]") + emitEdges(deps, sym, "[style=solid]") + } + + private def emitEdges(list: Seq[Any], target: Any, params: String)(implicit stream: PrintWriter) = + list.foreach(emitEdge(_, target, params)) + + private def emitEdge(source: Any, target: Any, params: String)(implicit stream: PrintWriter): Unit = + stream.println(s"${StringUtil.quote(source)} -> ${StringUtil.quote(target)} $params") + + // can be overridden if desired + def defaultGraphVizConfig: GraphVizConfig = + GraphVizConfig.default + + def emitDepGraph(d: Def[_], directory: File, fileName: String)(implicit config: GraphVizConfig): Option[GraphFile] = + emitDepGraph(d.deps, directory, fileName)(config) + def emitDepGraph(start: Sym, directory: File, fileName: String)(implicit config: GraphVizConfig): Option[GraphFile] = + emitDepGraph(List(start), directory, fileName)(config) + def emitDepGraph(ss: Seq[Sym], directory: File, fileName: String)(implicit config: GraphVizConfig): Option[GraphFile] = + emitDepGraph(new PGraph(ss.toList), directory, fileName)(config) + def emitExceptionGraph(e: Throwable, directory: File, fileName: String)(implicit config: GraphVizConfig): Option[GraphFile] = + emitDepGraph(Left(e), directory, fileName) + def emitDepGraph(graph: AstGraph, directory: File, fileName: String)(implicit config: GraphVizConfig): Option[GraphFile] = + emitDepGraph(Right(graph), directory, fileName) + def emitDepGraph(exceptionOrGraph: Either[Throwable, AstGraph], directory: File, fileName: String)(implicit config: GraphVizConfig): Option[GraphFile] = + emitGraphFile(directory, fileName)(emitDepGraph(exceptionOrGraph, fileName)(_, config)) + + def emitDot(dotText: String, directory: File, fileName: String)(implicit config: GraphVizConfig): Option[GraphFile] = + emitGraphFile(directory, fileName)(_.println(dotText)) + + private def emitGraphFile(directory: File, fileName: String)(f: PrintWriter => Unit)(implicit config: GraphVizConfig): Option[GraphFile] = { + if (config.emitGraphs) { + val dotFileName = s"$fileName.dot" + val file = new File(directory, dotFileName) + FileUtil.withFile(file)(f) + + val dotFile = new File(directory, dotFileName) + val dotGraphFile = GraphFile(dotFile, "dot") + + Some(config.format match { + case "dot" => + dotGraphFile + case format => + val convertedFileName = FileUtil.replaceOrAppendExtension(dotFileName, format) + try { + ProcessUtil.launch(Seq("dot", s"-T$format", "-o", convertedFileName, dotFileName), directory) + GraphFile(new File(directory, convertedFileName), format) + } catch { + case e: Exception => + logWarn(s"Failed to convert ${dotFile.getAbsolutePath} to $format: ${e.getMessage}") + dotGraphFile + } + }) + } else None + } + + implicit class SeqExpExtensionsForEmitGraph(symbols: Seq[Sym]) { + // Not default argument to allow use from the debugger + def show(): Unit = show(defaultGraphVizConfig) + def show(config: GraphVizConfig): Unit = showGraphs(symbols: _*)(config) + } + + def showGraphs(roots: Sym*)(implicit config: GraphVizConfig): Unit = + showGraphs(new PGraph(roots.toList)) + + def showGraphs(graph: AstGraph)(implicit config: GraphVizConfig): Unit = { + val prefix = graph.roots.mkString("_") + val file = File.createTempFile(s"graph_${prefix}_", ".dot") + // unfortunately can end up deleting the file before the process reads it + // file.deleteOnExit() + val directory = file.getAbsoluteFile.getParentFile + val fileName = FileUtil.stripExtension(file.getName) + emitDepGraph(graph, directory, fileName)(config).foreach(_.open()) + } + + private def lambdaDeps(l: Lambda[_, _]): (List[Sym], List[Sym]) = l.y match { + case Def(l1: Lambda[_, _]) => + val (ds, vs) = lambdaDeps(l1) + (ds, l.x :: vs) + case _ => (l.y.node.deps.toList, List(l.x)) + } + + protected def clusterColor(g: AstGraph) = g match { + case _: ProgramGraph => None + case _: Lambda[_, _] => Some("#FFCCFF") + case _: ThunkDef[_] => Some("#FFCCCC") + case _ => Some("lightgray") + } + + protected def clusterSchedule(g: AstGraph) = g match { + case lam: Lambda[_, _] => lam.schedule.filter(_ != lam.y) + case _ => g.schedule + } + + protected def shouldEmitCluster(g: AstGraph) = g match { + case lam: Lambda[_, _] => !lam.isIdentity + case _ => true + } + + // This function accumulates all emitted nodes so that dependency edges are placed outside any clusters. + // Otherwise dot will incorrectly show nodes inside clusters they don't belong to. + private def emitCluster(g: AstGraph, acc: GraphData)(implicit stream: PrintWriter, config: GraphVizConfig): GraphData = { + val schedule = clusterSchedule(g) + + schedule.foldLeft(acc) { case (acc1, s) => + val d = s.node + d match { + case g: AstGraph if shouldEmitCluster(g) => + if (config.subgraphClusters) { + stream.println(s"subgraph cluster_$s {") + clusterColor(g).foreach { color => + stream.println(s"style=dashed; color=${StringUtil.quote(color)}") + } + } + val acc2 = emitNode(s, d, acc1) + // for lambdas, do we want lambdaDeps instead? + val sources = g.boundVars + if (config.subgraphClusters && sources.nonEmpty) { + stream.println(s"{rank=source; ${sources.mkString("; ")}}") + } + val acc3 = emitCluster(g, acc2) + if (config.subgraphClusters) { + stream.println(s"{rank=sink; $s}") + stream.println("}") + } + acc3 + case _ => + emitNode(s, d, acc1) + } + } + } + + private def emitExceptionCluster(e: Throwable, depth: Int, acc: GraphData)(implicit stream: PrintWriter, config: GraphVizConfig): GraphData = { + // edges appear before their end nodes but it shouldn't be a problem + val nodeName = exceptionNodeName(depth) + + val acc1 = e.getCause match { + case null => acc + case cause => + val causeDepth = depth + 1 + emitEdge(exceptionNodeName(causeDepth), nodeName, "[style=dashed, color=red]") + emitExceptionCluster(cause, causeDepth, acc) + } + + val acc2 = e match { + case e: StagingException if e.syms.nonEmpty => + val syms1 = e.syms + val depGraph = new PGraph(syms1.toList) + emitEdges(syms1, nodeName, "[color=red]") + emitCluster(depGraph, acc1) + case _ => + acc1 + } + emitExceptionNode(e, depth) + acc2 + } + + private def exceptionNodeName(depth: Int) = "e" + depth + + private def emitExceptionNode(e: Throwable, depth: Int)(implicit stream: PrintWriter, config: GraphVizConfig) = { + stream.println(StringUtil.quote(exceptionNodeName(depth)) + " [") + // complete stacks are huge; we'd like to put them into tooltip, but \l doesn't work there and xdot doesn't show + // the tooltip anyway + val firstUsefulStackTraceLine = e.getStackTrace.find { ste => + val methodName = ScalaNameUtil.cleanScalaName(ste.getMethodName) + // skip ???, !!!, throwInvocationException and other methods which just build and throw exceptions + !(methodName.endsWith("???") || methodName.endsWith("!!!") || methodName.startsWith("throw")) + }.map(ste => ScalaNameUtil.cleanScalaName(ste.toString)).toList + stream.println(config.nodeLabel(new StringOps(e.toString).lines.toList ++ firstUsefulStackTraceLine)) + stream.println(s"shape=note,color=red,style=filled,fillcolor=white") + stream.println("]") + } + + private sealed trait Label { + def label: String + } + private case class NoAlias(label: String) extends Label + private case class Alias(label: String, rhs: String, td: TypeDesc) extends Label + + private case class GraphData(nodes: Map[Sym, Option[Def[_]]], labels: Map[TypeDesc, Label], aliases: List[Alias], aliasCounter: Int)(implicit config: GraphVizConfig) { + def addNode(s: Sym, d: Option[Def[_]]): GraphData = { + val withType = config.maxTypeNameLength match { + case Some(maxLength) => + val elems = d.map(_.resultType).toSet + s.elem + elems.foldLeft(this)(_.registerType(_, maxLength)) + case None => + this + } + val nodes1 = withType.nodes + (s -> d) + withType.copy(nodes = nodes1) + } + + def typeString(td: TypeDesc) = { + def f(td1: TypeDesc, recurse: Boolean): String = + labels.get(td1) match { + case Some(l) => + l.label + case None => + if (recurse) { + td1.getName(f(_, false)) + } else { + // TODO this should never happen, but does with TypeWrappers + // !!!(s"$td1 is used in $td.getName, but isn't registered in $labels") + td1.name + } + } + + f(td, true) + } + + private def registerType(td: TypeDesc, maxLength: Int): GraphData = { + if (labels.contains(td)) + this + else { + val withTypeArgs = partsIterator(td).foldLeft(this)(_.registerType(_, maxLength)) + withTypeArgs.registerType0(td, maxLength) + } + } + + private def registerType0(td: TypeDesc, maxLength: Int): GraphData = { + val labelString0 = typeString(td) + + val (label, newAliases, newAliasCounter) = + if (labelString0.length > maxLength) { + val alias = Alias(s"T$aliasCounter", labelString0, td) + (alias, alias :: aliases, aliasCounter + 1) + } else + (NoAlias(labelString0), aliases, aliasCounter) + + val newLabels = labels + (td -> label) + copy(labels = newLabels, aliases = newAliases, aliasCounter = newAliasCounter) + } + + def finishGraph(implicit stream: PrintWriter) = { + nodes.foreach { + case (sym, Some(rhs)) => + emitDepEdges(sym, rhs) + case _ => + } + + def emitAliasEdge(node: Any, td: TypeDesc): Unit = + labels.get(td) match { + case Some(Alias(label1, _, _)) => + // dotted doesn't work in xdot + emitEdge(node, label1, """[style=dashed, color=turquoise]""") + case _ => + } + + if (aliasCounter > 0) { + stream.println(s"subgraph cluster_aliases {") + stream.println("""label="Type Aliases"""") + val orderedAliases = aliases.reverse + orderedAliases.foreach { + case Alias(label, rhs, td) => + stream.println(s"""$label [label="type $label = $rhs", shape=box, style=rounded, color=${nodeColor(td)}, fillcolor=white]""") + // Below code doesn't show the dependencies correctly +// if (config.typeAliasEdges) { +// partsIterator(td).foreach(emitAliasEdge(label, _)) +// } + } + if (aliases.length > 1) { + stream.println(orderedAliases.map(_.label).mkString(" -> ") + " [style=invis]") + } + stream.println("}") + if (config.typeAliasEdges) { + nodes.keysIterator.foreach { + s => emitAliasEdge(s, s.elem) + } + } + } + } + } + private object GraphData { + def empty(implicit config: GraphVizConfig) = GraphData(Map.empty, Map.empty, Nil, 0) + } + + protected def partsIterator(td: TypeDesc) = td match { + case e: Elem[_] => + e.typeArgsDescs + case _: Cont[_] => + Iterator.empty + } + + private def emitDepGraph(exceptionOrGraph: Either[Throwable, AstGraph], name: String)(implicit stream: PrintWriter, config: GraphVizConfig): Unit = { + stream.println(s"""digraph "$name" {""") + + stream.println("concentrate=true") + stream.println(s"node [style=filled, fillcolor=orangered]") + stream.println(config.orientationString) + + val finalData = exceptionOrGraph match { + case Left(e) => emitExceptionCluster(e, 0, GraphData.empty) + case Right(graph) => emitCluster(graph, GraphData.empty) + } + + finalData.finishGraph(stream) + stream.println("}") + stream.close() + } +} + +sealed trait Orientation +case object Portrait extends Orientation +case object Landscape extends Orientation + +object Orientation { + implicit val orientationC: Configs[Orientation] = Configs[Orientation] +} + +sealed trait ControlFlowStyle +case object ControlFlowWithBoxes extends ControlFlowStyle +case object ControlFlowWithArrows extends ControlFlowStyle + +// outside the cake to be usable from ItTestsUtil +case class GraphVizConfig(emitGraphs: Boolean, + format: String, + orientation: Orientation, + maxLabelLineLength: Int, + subgraphClusters: Boolean, + maxTypeNameLength: Option[Int], + typeAliasEdges: Boolean, + emitMetadata: Boolean, + showLambdaReturnSym: Boolean + ) { + + // ensures nice line wrapping + def nodeLabel(parts: Seq[String]): String = { + def escape(s: String) = s.replace("""\""", """\\""").replace("\"", """\"""") + val lineBreak = """\l""" + + var lineLength = 0 + val sb = new StringBuilder() + var isFirst = true + parts.foreach { part => + val lines = new StringOps(part).lines.toSeq + if (isFirst) { + isFirst = false + } else { + lines match { + case Seq() => + // do nothing + case Seq(line) => + val lineLengthIfNoNewLine = lineLength + 1 + line.length + lineLength = if (lineLengthIfNoNewLine <= maxLabelLineLength) { + sb.append(" ") + lineLengthIfNoNewLine + } else { + sb.append(lineBreak) + line.length + } + case _ => + sb.append(lineBreak) + lineLength = lines.last.length + } + } + sb.append(lines.map(escape).mkString(lineBreak)) + } + val label0 = sb.result() + // left-justify the last line if there are multiple lines + val label = if (label0.contains(lineBreak) && !label0.endsWith(lineBreak)) + label0 + lineBreak + else + label0 + s"label=${StringUtil.quote(label)}" + } + + def orientationString = if (orientation == Landscape) "rankdir=LR" else "" +} + +object GraphVizConfig { + lazy val config = Plugins.configWithPlugins.getConfig("graphviz") + // not made implicit because it would be too easy to use + // it accidentally instead of passing up + // For some reason, return type has to be given explicitly + val default: GraphVizConfig = GraphVizConfig( + emitGraphs = true, + format = "dot", + orientation = Portrait, + maxLabelLineLength = 50, + subgraphClusters = true, + maxTypeNameLength = None, + typeAliasEdges = false, + emitMetadata = false, + showLambdaReturnSym = false + ) //config.extract[GraphVizConfig] + + val none: GraphVizConfig = default.copy(emitGraphs = false) + + def from(config: Config): GraphVizConfig = config.withFallback(this.config).extract[GraphVizConfig].value +} diff --git a/core/src/main/scala/scalan/primitives/Equal.scala b/core/src/main/scala/scalan/primitives/Equal.scala new file mode 100644 index 0000000000..32dc525f89 --- /dev/null +++ b/core/src/main/scala/scalan/primitives/Equal.scala @@ -0,0 +1,24 @@ +package scalan.primitives + +import scalan.{Base, Scalan} + +trait Equal extends Base { self: Scalan => + /** Binary operation representing structural equality between arguments. */ + case class Equals[A: Elem]() extends BinOp[A, Boolean]("==", equalValues[A](_, _)) + + /** Binary operation representing structural inequality between arguments. */ + case class NotEquals[A: Elem]() extends BinOp[A, Boolean]("!=", !equalValues[A](_, _)) + + protected def equalValues[A](x: Any, y: Any)(implicit eA: Elem[A]) = x == y + + /** Extension methods to construct ApplyBinOp nodes */ + implicit class EqualOps[A](x: Ref[A]) { + implicit private val eA = x.elem + + /** Apply Equals binary operation and return Ref to ApplyBinOp node. */ + def ===(y: Ref[A]): Ref[Boolean] = Equals[A].apply(x, y) + + /** Apply NotEquals binary operation and return Ref to ApplyBinOp node. */ + def !==(y: Ref[A]): Ref[Boolean] = NotEquals[A].apply(x, y) + } +} diff --git a/core/src/main/scala/scalan/primitives/Functions.scala b/core/src/main/scala/scalan/primitives/Functions.scala new file mode 100644 index 0000000000..63f88f4a34 --- /dev/null +++ b/core/src/main/scala/scalan/primitives/Functions.scala @@ -0,0 +1,430 @@ +package scalan.primitives + +import java.util +import scalan.staged.ProgramGraphs +import scalan.util.GraphUtil +import scalan.{Lazy, Base, Nullable, Scalan} +import debox.{Buffer => DBuffer} +import scala.language.implicitConversions +import spire.syntax.all.cfor + +trait Functions extends Base with ProgramGraphs { self: Scalan => + + implicit class LambdaOps[A,B](f: Ref[A => B]) { + /** Apply given function symbol to the given argument symbol. + * @return symbol representing result of function application */ + final def apply(x: Ref[A]): Ref[B] = mkApply(f, x) + + /** Build new function which applies `f` and then `g`*/ + final def >>[C](g: Ref[B => C]): Ref[A => C] = compose(g, f) + + /** Build new function which applies `g` and then `f`*/ + final def <<[C](g: Ref[C => A]): Ref[C => B] = compose(f, g) + } + + /** Global lambda equality mode used by default. It is used in `fun` and `fun2` lambda builders. + * If this flag is `true` then Lambda nodes are equal if they are the same up to renaming of symbols. (see Lambda.equals()). + * Each Lambda node has independent equality mode flag which is setup in the constructor. */ + var useAlphaEquality: Boolean = true + + /** Global flag governing lambda reification in `fun` and `mkLambda`. + * If this flag is `true` then original `f: Ref[A] => Ref[B]` function is stored in Lambda node. + * As a consequence if `f` is not stored, then `unfoldLambda` is done by `mirrorLambda`. */ + var keepOriginalFunc: Boolean = true + + /** Turns on/off lambda unfolding using original function `f` stored in the Lambda node. + * If this flag is `false` then this function cannot be used even if it is present in the node. */ + var unfoldWithOriginalFunc: Boolean = true + + /** Executes given lambda to construct Lambda node. The function `f` can be called with any symbol + * and has an effect of growing a graph starting from the argument symbol. + * If a reference to `Variable` node is passed as argument, then the constructed graph nodes + * can be collected to Lambda node forming its body and schedule. + * @param f function which execution will create body nodes + * @param eA arguments type descriptor + */ + implicit final def fun[A,B](f: Ref[A] => Ref[B])(implicit eA: LElem[A]): Ref[A => B] = mkLambda(f, true, useAlphaEquality, keepOriginalFunc) + implicit final def fun2[A,B,C](f: (Ref[A], Ref[B]) => Ref[C])(implicit eA: LElem[A], eB: LElem[B]): Ref[((A,B))=>C] = mkLambda(f) + + /** Represent lambda expression as IR node. + * @param f optional function, which was used to compute `y` + * @param x lambda-bound variable + * @param y symbol representing result of lambda invocation + * @param mayInline whether this lambda can be inlined when applied + * @param alphaEquality whether to use alpha-equality in `equals` */ + class Lambda[A, B](val f: Nullable[Ref[A] => Ref[B]], val x: Ref[A], val y: Ref[B], val mayInline: Boolean, val alphaEquality: Boolean = true) + extends AstGraph with Def[A => B] { thisLambda => + def eA = x.elem + def eB = y.elem + + private var _resultType: Elem[A => B] = _ + def resultType: Elem[A => B] = { + if (_resultType != null) _resultType + else { + val res = funcElement(eA, eB) + if (!y.isPlaceholder) _resultType = res // memoize once y is assigned + res + } + } + + // ensure all lambdas of the same type have the same hashcode, + // so they are tested for alpha-equivalence using equals + private var _hashCode: Int = 0 + override def hashCode: Int = { + if (_hashCode == 0) { + _hashCode = if (alphaEquality) + 41 * (41 + x.elem.hashCode) + y.elem.hashCode + else + 41 * (41 + x.hashCode) + y.hashCode + } + _hashCode + } + + override def equals(other: Any) = (this eq other.asInstanceOf[AnyRef]) || + (other match { + case other: Lambda[_,_] => + if (alphaEquality) + matchLambdas(this, other, false, emptyMatchSubst).isDefined + else + other.x == this.x && other.y == this.y + case _ => false + }) + + override def toString = s"Lambda(${if (f.isDefined) "f is Some" else "f is None"}, $x => $y})" + def canEqual(other: Any) = other.isInstanceOf[Lambda[_,_]] + + // Product implementation + def productElement(n: Int): Any = n match { + case 0 => x + case 1 => y + case _ => throw new NoSuchElementException(s"Lambda.productElement($n) is undefined") + } + def productArity: Int = 2 + + // AstGraph implementation + val boundVars = Array(x) + val boundVarId = x.node._nodeId + val roots = Array(y) + + override lazy val rootIds: DBuffer[Int] = super.rootIds + + override lazy val freeVars = super.freeVars + + override def isIdentity: Boolean = x == y + + @inline override def isBoundVar(s: Sym) = s.node.nodeId == boundVarId + + override lazy val scheduleIds: DBuffer[Int] = { + val sch = if (isIdentity) + DBuffer.ofSize[Int](0) + else { + // graph g will contain all Defs reified as part of this Lambda, (due to `filterNode`) + // BUT not all of them depend on boundVars, thus we need to filter them out + // 1) we build g.schedule and then g.usageMap + // 2) collect set of nodes, which depend on `x` + val g = new PGraph(roots, filterNode = Nullable(s => s.node._nodeId >= boundVarId)) + val usages = new PGraphUsages(g) + val locals = GraphUtil.depthFirstSetFrom[Int](DBuffer(boundVarId))(usages) + val gschedule = g.schedule.toArray + val len = gschedule.length + val sch = DBuffer.ofSize[Int](len) + cfor(0)(_ < len, _ + 1) { i => + val sym = gschedule(i) + val id = sym.node.nodeId + if (locals(id) && !sym.isVar) + sch += id + } + val currSch = if (sch.isEmpty) g.rootIds else sch + currSch + } + if (debugModeSanityChecks) { + // check that every inner lambda depend on boundVars + cfor(0)(_ < sch.length, _ + 1) { i => + getSym(sch(i)).node match { + case l: Lambda[_,_] => + val varDeps = l.deps intersect(boundVars ++ sch.map(getSym(_)).toArray) + if (varDeps.isEmpty) { + // val cwd = new File("").getAbsoluteFile + // val dir = "test-out/errors" + // emitDepGraph(roots, FileUtil.file(cwd, dir), "nested_lambda")(defaultGraphVizConfig) + assert(false, s"Invalid nested lambda $l inside $this") + } + case op @ OpCost(_, _, args, opCost) => + if (args.contains(opCost)) { + !!!(s"Invalid OpCost($op)") + } + case _ => + } + } + } + sch + } + + override protected def getDeps: Array[Sym] = freeVars.toArray + + def isGlobalLambda: Boolean = { + freeVars.forall { x => + x.isConst || { + val xIsGlobalLambda = x.isLambda && { val lam = x.node.asInstanceOf[Lambda[_, _]]; lam.isGlobalLambda } + xIsGlobalLambda + } + } + } + } + + type LambdaData[A,B] = (Lambda[A,B], Nullable[Ref[A] => Ref[B]], Ref[A], Ref[B]) + object Lambda { + def unapply[A,B](lam: Lambda[A, B]): Nullable[LambdaData[A,B]] = { + val res: LambdaData[A,B] = + if (lam == null) null + else { + (lam, lam.f, lam.x, lam.y) + } + Nullable(res) + } + } + + /** + * Matcher for lambdas which don't depend on their arguments + * (but can close over other expressions, unlike VeryConstantLambda). + */ + object ConstantLambda { + // if lam.y depends on lam.x indirectly, lam.schedule must contain the dependency path + // and its length will be > 1 + def unapply[A,B](lam: Lambda[A, B]): Option[Ref[B]] = + if (lam.schedule.length <= 1 && !lam.y.node.deps.contains(lam.x) && lam.y != lam.x) + Some(lam.y) + else + None + } + + /** + * Matcher for lambdas which return staging-time constants. + * VeryConstantLambda(x) should be equivalent to ConstantLambda(Def(Const(x))) + */ + object VeryConstantLambda { + def unapply[A,B](lam: Lambda[A, B]): Option[B] = lam.y.node match { + case Const(y) => Some(y) + case _ => None + } + } + + // matcher version of Lambda.isIdentity + object IdentityLambda { + def unapply[A,B](lam: Lambda[A, B]): Boolean = lam.isIdentity + } + + case class Apply[A,B](f: Ref[A => B], arg: Ref[A], mayInline: Boolean = true) extends Def[B] { + def resultType = f.elem.eRange + override def transform(t: Transformer) = Apply(t(f), t(arg), mayInline) + } + + implicit class FuncExtensions[A, B](f: Ref[A=>B]) { + implicit def eA = f.elem.eDom + def getLambda: Lambda[A,B] = f.node match { + case lam: Lambda[_,_] => lam.asInstanceOf[Lambda[A,B]] + case _ => !!!(s"Expected symbol of Lambda node but was $f", f) + } + + def zip[C](g: Ref[A=>C]): Ref[A=>(B,C)] = { + implicit val eB = f.elem.eRange + implicit val eC = g.elem.eRange + fun { (x: Ref[A]) => Pair(f(x), g(x)) } + } + } + + type Subst = java.util.HashMap[Sym, Sym] + @inline def emptyMatchSubst: Subst = new util.HashMap[Sym,Sym]() + + def alphaEqual(s1: Sym, s2: Sym): Boolean = matchExps(s1, s2, false, emptyMatchSubst).isDefined + + def patternMatch(s1: Sym, s2: Sym): Nullable[Subst] = matchExps(s1, s2, true, emptyMatchSubst) + + protected def matchExps(s1: Sym, s2: Sym, allowInexactMatch: Boolean, subst: Subst): Nullable[Subst] = s1.node match { + case _ if s1 == s2 || subst.get(s1) == s2 || subst.get(s2) == s1 => + Nullable(subst) + case d1 if !d1.isInstanceOf[Variable[_]] => + val d2 = s2.node + val res = matchDefs(d1, d2, allowInexactMatch, subst) + if (res.isDefined) { + res.get.put(s1, s2) + } + res + case _ => + if (allowInexactMatch && !subst.containsKey(s1)) { + subst.put(s1, s2) + Nullable(subst) + } else { + Nullable.None + } + } + + @inline + private def matchLambdas(lam1: Lambda[_, _], lam2: Lambda[_, _], allowInexactMatch: Boolean, subst: Subst): Nullable[Subst] = + if (lam1.x.elem == lam2.x.elem) { + subst.put(lam1.x, lam2.x) + matchExps(lam1.y, lam2.y, allowInexactMatch, subst) + } + else + Nullable.None + + protected def matchDefs(d1: Def[_], d2: Def[_], allowInexactMatch: Boolean, subst: Subst): Nullable[Subst] = d1 match { + case lam1: Lambda[_, _] => d2 match { + case lam2: Lambda[_, _] => + matchLambdas(lam1, lam2, allowInexactMatch, subst) + case _ => Nullable.None + } + case _ => + if (d1.getClass == d2.getClass && d1.productArity == d2.productArity && d1.resultType.name == d2.resultType.name) { + matchIterators(d1.productIterator, d2.productIterator, allowInexactMatch, subst) + } else + Nullable.None + } + + // generalize to Seq or Iterable if we get nodes with deps of these types + protected def matchIterators(i1: Iterator[_], i2: Iterator[_], allowInexactMatch: Boolean, subst: Subst): Nullable[Subst] = + if (i1.hasNext) { + if (i2.hasNext) { + var res = matchAny(i1.next(), i2.next(), allowInexactMatch, subst) + if (res.isDefined) + res = matchIterators(i1, i2, allowInexactMatch, res.get) + res + } else Nullable.None + } else { + if (i2.hasNext) Nullable.None else Nullable(subst) + } + + protected def matchAny(a1: Any, a2: Any, allowInexactMatch: Boolean, subst: Subst): Nullable[Subst] = a1 match { + case s1: Sym => a2 match { + case s2: Sym => + matchExps(s1, s2, allowInexactMatch, subst) + case _ => Nullable.None + } + case l1: Iterable[_] => a2 match { + case l2: Iterable[_] => + matchIterators(l1.iterator, l2.iterator, allowInexactMatch, subst) + case _ => Nullable.None + } + case _ => if (a1 == a2) Nullable(subst) else Nullable.None + } + + //===================================================================================== + // Function application + + def mkApply[A,B](f: Ref[A => B], x: Ref[A]): Ref[B] = { + val d = f.node + if (d.isInstanceOf[Lambda[_, _]]) { + val lam = d.asInstanceOf[Lambda[A, B]] + if (lam.mayInline) { + return unfoldLambda(lam, x) + } + } + Apply(f, x, mayInline = false) + } + + def unfoldLambda[A,B](lam: Lambda[A,B], x: Ref[A]): Ref[B] = { + lam.f match { + case Nullable(g) if unfoldWithOriginalFunc => g(x) // unfold initial non-recursive function + case _ => mirrorApply(lam, x) // f is mirrored, unfold it by mirroring + } + } + + def unfoldLambda[A,B](f: Ref[A=>B], x: Ref[A]): Ref[B] = { + val lam = f.getLambda + unfoldLambda(lam, x) + } + + def mirrorApply[A,B](lam: Lambda[A, B], s: Ref[A]): Ref[B] = { + val body = lam.scheduleIds + val m = new java.util.HashMap[Sym, Sym](100) + m.put(lam.x, s) + val subst = new MapTransformer(m) + val t = DefaultMirror.mirrorSymbols(subst, NoRewriting, lam, body) + t(lam.y) + } + + //===================================================================================== + // Function reification + + def mkLambda[A,B](f: Ref[A] => Ref[B], + mayInline: Boolean, + alphaEquality: Boolean, + keepOriginalFunc: Boolean)(implicit eA: LElem[A]): Ref[A=>B] = { + val x = variable[A] + lambda(x)(f, mayInline, alphaEquality, keepOriginalFunc) + } + + def mkLambda[A,B,C](f: Ref[A]=>Ref[B]=>Ref[C]) + (implicit eA: LElem[A], eB: Elem[B]): Ref[A=>B=>C] = { + val y = variable[B] + mkLambda( + (a: Ref[A]) => lambda(y)((b:Ref[B]) => f(a)(b), mayInline = true, useAlphaEquality, keepOriginalFunc), + mayInline = true, + alphaEquality = useAlphaEquality, + keepOriginalFunc = keepOriginalFunc) + } + + def mkLambda[A,B,C](f: (Ref[A], Ref[B])=>Ref[C])(implicit eA: LElem[A], eB: LElem[B]): Ref[((A,B))=>C] = { + implicit val leAB = Lazy(pairElement(eA.value, eB.value)) + mkLambda({ (p: Ref[(A, B)]) => + val (x, y) = unzipPair(p) + f(x, y) + }, true, useAlphaEquality, keepOriginalFunc) + } + + var lambdaStack: List[Lambda[_,_]] = Nil + + private def lambda[A,B](x: Ref[A])(f: Ref[A] => Ref[B], + mayInline: Boolean, + alphaEquality: Boolean, + keepOriginalFunc: Boolean)(implicit leA: LElem[A]): Ref[A=>B] = { + // ySym will be assigned after f is executed + val ySym = placeholder(LazyAnyElement).asInstanceOf[Ref[B]] + + val orig = if (keepOriginalFunc) Nullable(f) else Nullable.None + val lam = new Lambda(orig, x, ySym, mayInline, alphaEquality) + val lamSym = lam.self + + val oldStack = lambdaStack + try { + lambdaStack = lam :: lambdaStack + val y = { // reifyEffects block + f(x) + } + ySym.assignDefFrom(y) + } + finally { + lambdaStack = oldStack + } + + findOrCreateDefinition(lam, lamSym) + } + + class LambdaStack { + var stack = List[Sym]() + def top: Option[Sym] = stack.isEmpty match { case true => None case _ => Some(stack.head) } + def push(e: Sym): this.type = { stack = e :: stack; this } + def pop: Sym = { + val res = stack.head; + stack = stack.tail; + res + } + } + + def identityFun[A](implicit e: Elem[A]) = fun[A, A](x => x) + + def upcastFun[A: Elem, B >: A]: Ref[A => B] = fun[A,B](x => x) + + def constFun[A, B](x: Ref[B])(implicit e: Elem[A]) = { + implicit val eB = x.elem + fun[A, B](_ => x) + } + + /** Composition of two functions (in mathematical notation), where first `g` is applied and them `f`. */ + def compose[A, B, C](f: Ref[B => C], g: Ref[A => B]): Ref[A => C] = { + implicit val eA = g.elem.eDom + implicit val eC = f.elem.eRange + fun { x => f(g(x)) } + } + +} diff --git a/core/src/main/scala/scalan/primitives/IfThenElse.scala b/core/src/main/scala/scalan/primitives/IfThenElse.scala new file mode 100644 index 0000000000..22fd2095d7 --- /dev/null +++ b/core/src/main/scala/scalan/primitives/IfThenElse.scala @@ -0,0 +1,55 @@ +package scalan.primitives + +import scalan.{Base, Scalan} + +trait IfThenElse extends Base { self: Scalan => + + /** If c then t else e construction with standard lazy evaluation of branches. + * The representation uses Thunk for each branch */ + def IF(cond: Ref[Boolean]): IfBranch = new IfBranch(cond) + + /** Defines syntax available after `IF (cond) ` */ + class IfBranch(cond: Ref[Boolean]) { + def apply[T](thenp: => Ref[T]) = THEN(thenp) + + def THEN[T](thenp: => Ref[T]) = new ThenIfBranch[T](cond, thenp) + } + + /** Defines syntax available after `IF (cond) THEN thenp ELSEIF (cond1) ` */ + class ElseIfBranch[T](cond: Ref[Boolean], outer: ThenIfBranch[T]) { + def apply(thenp: => Ref[T]) = THEN(thenp) + + def THEN(thenp: => Ref[T]) = new ThenIfBranch[T](cond, thenp) { + override def ELSE(elsep: => Ref[T]) = outer.elseIf(cond, thenp, elsep) + } + } + + /** Defines syntax available after `IF (cond) THEN thenp ` */ + class ThenIfBranch[T](cond: Ref[Boolean], thenp: => Ref[T]) { + def ELSE(elsep: => Ref[T]): Ref[T] = ifThenElseLazy(cond, thenp, elsep) + + def elseIf(cond1: => Ref[Boolean], thenp1: => Ref[T], elsep1: => Ref[T]) = + ELSE(ifThenElseLazy(cond1, thenp1, elsep1)) + + def ELSEIF(cond1: => Ref[Boolean]) = new ElseIfBranch[T](cond1, this) + } + + /** IR node to represent IF condition with lazy branches. */ + case class IfThenElseLazy[T](cond: Ref[Boolean], thenp: Ref[Thunk[T]], elsep: Ref[Thunk[T]]) extends Def[T] { + lazy val resultType = { + val eThen = thenp.elem.eItem + val eElse = elsep.elem.eItem + assert(eThen == eElse, s"Both branched of IfThenElseLazy should have the same type, but was $eThen and $eElse") + eThen + } + override def transform(t: Transformer) = IfThenElseLazy(t(cond), t(thenp), t(elsep)) + } + + /** Constructs IfThenElse node wrapping by-name args into ThunkDef nodes. */ + def ifThenElseLazy[T](cond: Ref[Boolean], thenp: => Ref[T], elsep: => Ref[T]): Ref[T] = { + val t = Thunk(thenp) + val e = Thunk(elsep) + IfThenElseLazy(cond, t, e) + } + +} diff --git a/core/src/main/scala/scalan/primitives/LogicalOps.scala b/core/src/main/scala/scalan/primitives/LogicalOps.scala new file mode 100644 index 0000000000..fd71800d95 --- /dev/null +++ b/core/src/main/scala/scalan/primitives/LogicalOps.scala @@ -0,0 +1,56 @@ +package scalan.primitives + +import scalan.{Base, Scalan} + +trait LogicalOps extends Base { self: Scalan => + val And = new EndoBinOp[Boolean]("&&", _ && _) + + val Or = new EndoBinOp[Boolean]("||", _ || _) + + val Not = new EndoUnOp[Boolean]("!", !_) + + val BinaryXorOp = new EndoBinOp[Boolean]("^", _ ^ _) + + val BooleanToInt = new UnOp[Boolean, Int]("ToInt", if (_) 1 else 0) + + implicit class RepBooleanOps(value: Ref[Boolean]) { + def &&(y: Ref[Boolean]): Ref[Boolean] = And(value, y) + def ||(y: Ref[Boolean]): Ref[Boolean] = Or(value, y) + def ^(y: Ref[Boolean]): Ref[Boolean] = BinaryXorOp(value, y) + + def lazy_&&(y: Ref[Thunk[Boolean]]): Ref[Boolean] = And.applyLazy(value, y) + def lazy_||(y: Ref[Thunk[Boolean]]): Ref[Boolean] = Or.applyLazy(value, y) + + def unary_!() : Ref[Boolean] = Not(value) + def toInt: Ref[Int] = BooleanToInt(value) + } + + + @inline + final def rewriteBoolConsts(lhs: Sym, rhs: Sym, ifTrue: Sym => Sym, ifFalse: Sym => Sym, ifEqual: Sym => Sym, ifNegated: Sym => Sym): Sym = + lhs match { + // op(x, x) + case `rhs` => + ifEqual(lhs) + + // op(!x, x) => ifNegated(!x) + case Def(ApplyUnOp(op, `rhs`)) if op == Not => + ifNegated(lhs) + + // op(true, x) => ifTrue(x) | op(false, x) => ifFalse(x) + case Def(Const(b: Boolean)) => + if (b) ifTrue(rhs) else ifFalse(rhs) + + case _ => + rhs.node match { + // op(x, true) => ifTrue(x) | op(false, x) => ifFalse(x) + case Const(b: Boolean) => + if (b) ifTrue(lhs) else ifFalse(lhs) + + // op(x, !x) => ifNegated(!x) + case ApplyUnOp(op, `lhs`) if op == Not => + ifNegated(rhs) + case _ => null + } + } +} diff --git a/core/src/main/scala/scalan/primitives/NumericOps.scala b/core/src/main/scala/scalan/primitives/NumericOps.scala new file mode 100644 index 0000000000..70216627d4 --- /dev/null +++ b/core/src/main/scala/scalan/primitives/NumericOps.scala @@ -0,0 +1,57 @@ +package scalan.primitives + +import scalan.{ExactNumeric, Base, Scalan, ExactIntegral} + +trait NumericOps extends Base { self: Scalan => + implicit class NumericOpsCls[T](x: Ref[T])(implicit val n: ExactNumeric[T]) { + def +(y: Ref[T]): Ref[T] = NumericPlus(n)(x.elem).apply(x, y) + def -(y: Ref[T]): Ref[T] = NumericMinus(n)(x.elem).apply(x, y) + def *(y: Ref[T]): Ref[T] = NumericTimes(n)(x.elem).apply(x, y) + def unary_- : Ref[T] = NumericNegate(n)(x.elem).apply(x) + def abs: Ref[T] = Abs(n)(x.elem).apply(x) + def toFloat: Ref[Float] = NumericToFloat(n).apply(x) + def toDouble: Ref[Double] = NumericToDouble(n).apply(x) + def toInt: Ref[Int] = NumericToInt(n).apply(x) + def toLong: Ref[Long] = NumericToLong(n).apply(x) + } + + implicit class IntegralOpsCls[T](x: Ref[T])(implicit i: ExactIntegral[T]) { + def div(y: Ref[T]): Ref[T] = IntegralDivide(i)(x.elem).apply(x, y) + def mod(y: Ref[T]): Ref[T] = IntegralMod(i)(x.elem).apply(x, y) + // avoid / due to conflicts + def /!(y: Ref[T]): Ref[T] = div(y) + def %(y: Ref[T]): Ref[T] = mod(y) + } + + def numeric[T:ExactNumeric]: ExactNumeric[T] = implicitly[ExactNumeric[T]] + def integral[T:ExactIntegral]: ExactIntegral[T] = implicitly[ExactIntegral[T]] + + case class NumericPlus[T: Elem](n: ExactNumeric[T]) extends EndoBinOp[T]("+", n.plus) + + case class NumericMinus[T: Elem](n: ExactNumeric[T]) extends EndoBinOp[T]("-", n.minus) + + case class NumericTimes[T: Elem](n: ExactNumeric[T]) extends EndoBinOp[T]("*", n.times) + + class DivOp[T: Elem](opName: String, applySeq: (T, T) => T, n: ExactIntegral[T]) extends EndoBinOp[T](opName, applySeq) { + override def shouldPropagate(lhs: T, rhs: T) = rhs != n.zero + } + + case class NumericNegate[T: Elem](n: ExactNumeric[T]) extends UnOp[T, T]("-", n.negate) + + case class NumericToDouble[T](n: ExactNumeric[T]) extends UnOp[T,Double]("ToDouble", n.toDouble) + + case class NumericToFloat[T](n: ExactNumeric[T]) extends UnOp[T, Float]("ToFloat", n.toFloat) + + case class NumericToInt[T](n: ExactNumeric[T]) extends UnOp[T,Int]("ToInt", n.toInt) + + case class NumericToLong[T](n: ExactNumeric[T]) extends UnOp[T,Long]("ToLong", n.toLong) + + case class Abs[T: Elem](n: ExactNumeric[T]) extends UnOp[T, T]("Abs", n.abs) + + case class IntegralDivide[T](i: ExactIntegral[T])(implicit elem: Elem[T]) extends DivOp[T]("/", i.quot, i) + + case class IntegralMod[T](i: ExactIntegral[T])(implicit elem: Elem[T]) extends DivOp[T]("%", i.rem, i) + + @inline final def isZero[T](x: T, n: ExactNumeric[T]) = x == n.zero + @inline final def isOne[T](x: T, n: ExactNumeric[T]) = x == n.fromInt(1) +} diff --git a/core/src/main/scala/scalan/primitives/OrderingOps.scala b/core/src/main/scala/scalan/primitives/OrderingOps.scala new file mode 100644 index 0000000000..19045be96a --- /dev/null +++ b/core/src/main/scala/scalan/primitives/OrderingOps.scala @@ -0,0 +1,32 @@ +package scalan.primitives + +import scalan.{Base, Scalan, ExactOrdering} + +trait OrderingOps extends Base { self: Scalan => + implicit def repOrderingToOrderingOps[T](x: Ref[T])(implicit n: ExactOrdering[T]) = new OrderingOpsCls(x) + implicit def OrderingToOrderingOps[T](x: T)(implicit n: ExactOrdering[T], et: Elem[T]) = new OrderingOpsCls(toRep(x)) + + class OrderingOpsCls[T](lhs: Ref[T])(implicit val n: ExactOrdering[T]) { + def <(rhs: Ref[T]) = OrderingLT(n).apply(lhs,rhs) + def <=(rhs: Ref[T]) = OrderingLTEQ(n).apply(lhs,rhs) + def >(rhs: Ref[T]) = OrderingGT(n).apply(lhs,rhs) + def >=(rhs: Ref[T]) = OrderingGTEQ(n).apply(lhs,rhs) + def max(rhs: Ref[T]): Ref[T] = OrderingMax(n)(lhs.elem).apply(lhs,rhs) + def min(rhs: Ref[T]): Ref[T] = OrderingMin(n)(lhs.elem).apply(lhs,rhs) + def compare(rhs: Ref[T]): Ref[Int] = OrderingCompare(n).apply(lhs,rhs) + } + + case class OrderingLT[T](ord: ExactOrdering[T]) extends BinOp[T, Boolean]("<", ord.lt) + + case class OrderingLTEQ[T](ord: ExactOrdering[T]) extends BinOp[T, Boolean]("<=", ord.lteq) + + case class OrderingGT[T](ord: ExactOrdering[T]) extends BinOp[T, Boolean](">", ord.gt) + + case class OrderingGTEQ[T](ord: ExactOrdering[T]) extends BinOp[T, Boolean](">=", ord.gteq) + + case class OrderingMax[T: Elem](ord: ExactOrdering[T]) extends BinOp[T, T]("max", ord.max) + + case class OrderingMin[T: Elem](ord: ExactOrdering[T]) extends BinOp[T, T]("min", ord.min) + + case class OrderingCompare[T](ord: ExactOrdering[T]) extends BinOp[T, Int]("compare", ord.compare) +} \ No newline at end of file diff --git a/core/src/main/scala/scalan/primitives/Thunks.scala b/core/src/main/scala/scalan/primitives/Thunks.scala new file mode 100644 index 0000000000..11eaf7162e --- /dev/null +++ b/core/src/main/scala/scalan/primitives/Thunks.scala @@ -0,0 +1,279 @@ +package scalan.primitives + +import scalan.compilation.{GraphVizConfig, GraphVizExport} +import scalan.{Liftable => _, _} +import debox.{Set => DSet, Buffer => DBuffer} +import spire.syntax.all.cfor + +import scala.reflect.runtime.universe._ +import scalan.util.{Covariant, GraphUtil} + +trait Thunks extends Functions with GraphVizExport { self: Scalan => + + type Th[+T] = Ref[Thunk[T]] + trait Thunk[+A] { def value: A } + class ThunkCompanion { + def apply[T](block: => Ref[T]) = thunk_create(block) + def forced[T](block: => Ref[T]) = thunk_create(block).force + } + val Thunk: ThunkCompanion = new ThunkCompanion + + implicit class RepThunkOps[T](t: Th[T]) { + def force() = thunk_force(t) + def map[R](f: Ref[T => R]): Th[R] = thunk_map(t, f) + def map[R](f: Ref[T] => Ref[R]): Th[R] = thunk_map1(t, f) + } + + implicit val thunkCont: Cont[Thunk] = new Cont[Thunk] { + def lift[T](implicit eT: Elem[T]) = element[Thunk[T]] + def unlift[T](implicit eFT: Elem[Thunk[T]]) = eFT.eItem + def unapply[T](e: Elem[_]) = e match { + case e: ThunkElem[_] => Some(asElem[Thunk[T]](e)) + case _ => None + } + } + + import Liftables._ + import scala.reflect.{ClassTag, classTag} + type SThunk[T] = () => T + + case class ThunkConst[ST, T](constValue: SThunk[ST], lT: Liftable[ST, T]) + extends BaseDef[Thunk[T]]()(thunkElement(lT.eW)) + with LiftedConst[SThunk[ST], Thunk[T]] { + val liftable: Liftable[SThunk[ST], Thunk[T]] = liftableThunk(lT) + } + + case class LiftableThunk[ST, T](lT: Liftable[ST, T]) extends Liftable[SThunk[ST], Thunk[T]] { + import RType._ + def eW: Elem[Thunk[T]] = thunkElement(lT.eW) + def sourceType: RType[SThunk[ST]] = { + implicit val tST = lT.sourceType + RType[SThunk[ST]] + } + def lift(x: SThunk[ST]): Ref[Thunk[T]] = ThunkConst(x, lT) + def unlift(w: Ref[Thunk[T]]): SThunk[ST] = w.node match { + case ThunkConst(x: SThunk[_], l) if l == lT => x.asInstanceOf[SThunk[ST]] + case _ => unliftError(w) + } + } + + implicit def liftableThunk[ST,T](implicit lT: Liftable[ST,T]): Liftable[SThunk[ST], Thunk[T]] = + LiftableThunk(lT) + + + case class ThunkElem[A](override val eItem: Elem[A]) + extends EntityElem1[A, Thunk[A], Thunk](eItem, container[Thunk]) { + override lazy val liftable = asLiftable[SThunk[_], Thunk[A]](liftableThunk(eItem.liftable)) + override lazy val typeArgs = TypeArgs("A" -> (eItem -> Covariant)) + } + + implicit def thunkElement[T](implicit eItem: Elem[T]): Elem[Thunk[T]] = + cachedElemByClass(eItem)(classOf[ThunkElem[T]]) + implicit def extendThunkElement[T](elem: Elem[Thunk[T]]): ThunkElem[T] = elem.asInstanceOf[ThunkElem[T]] + + class ThunkDef[A](val root: Ref[A], _scheduleIds: =>ScheduleIds) + extends AstGraph with Def[Thunk[A]] { + + implicit def eA: Elem[A] = root.elem + private var _selfType: Elem[Thunk[A]] = _ + def resultType: Elem[Thunk[A]] = + if (_selfType != null) _selfType + else { + val res = thunkElement(eA) + if (!root.isPlaceholder) _selfType = res // memoize once root is assigned + res + } + + override lazy val scheduleIds: ScheduleIds = _scheduleIds + + /** NOTE on structural equality implementation + * Every Def is assigned fresh nodeId in the constructor. As result this ThunkDef + * instance will have unique nodeId. Thus, different ThunkDef instances will have + * different nodeIds and hence they are NOT equal. + * */ + override lazy val hashCode: Int = _nodeId //41 * (41 + root.hashCode) + schedule.hashCode + def canEqual(other: Any) = other.isInstanceOf[ThunkDef[_]] + override def equals(other: Any) = + other match { + case that: ThunkDef[_] => _nodeId == that._nodeId + case _ => false + } + override def toString = s"Th($root, [${scheduleIds.toArray.mkString(",")}])" + + + // Product implementation + def productElement(n: Int): Any = n match { + case 0 => root + case _ => throw new NoSuchElementException(s"ThunkDef.productElement($n) is undefined") + } + def productArity: Int = 1 + + override def boundVars = Nil + override lazy val freeVars = if (schedule.isEmpty) Array(root) else super.freeVars + + override protected def getDeps: Array[Sym] = freeVars.toArray + + val roots = Array(root) + override lazy val rootIds: DBuffer[Int] = super.rootIds + override def isIdentity: Boolean = false + } + object ThunkDef { + def unapply(d: ThunkDef[_]): Option[(Ref[T], Schedule) forSome {type T}] = d match { + case th: ThunkDef[_] => Some((th.root, th.schedule)) + case _ => None + } + } + + class ThunkScope(val parent: ThunkScope, val thunkSym: Ref[Any]) { + private val bodyIds: DSet[Int] = DSet.ofSize(16) + private val bodyDefs: AVHashMap[Def[_], Def[_]] = AVHashMap(32) + + @inline final def isEmptyBody: Boolean = bodyIds.isEmpty + + def +=(sym: Sym): Unit = { + val d = sym.node + bodyIds += d.nodeId + bodyDefs.put(d, d) + } + + def scheduleForResult(root: Ref[Any]): DBuffer[Int] = { + val sch = GraphUtil.depthFirstOrderFrom( + DBuffer(root.node.nodeId), + { id: Int => + val deps = getSym(id).node.deps + val res = DBuffer.ofSize[Int](deps.length) + cfor(0)(_ < deps.length, _ + 1) { i => + val s = deps(i) + val id = s.node.nodeId + if (bodyIds(id) && !s.isVar) + res += id + } + res + } + ) + sch + } + + def findDef[T](d: Def[T]): Ref[T] = { + val existingOpt = bodyDefs.get(d) + if (existingOpt.isDefined) return existingOpt.get.self.asInstanceOf[Ref[T]] + if (parent == null) + findGlobalDefinition(d) + else + parent.findDef(d) + } + } + + class ThunkStack { + var stack = List[ThunkScope]() + @inline def top: Nullable[ThunkScope] = if (stack.isEmpty) Nullable.None else Nullable(stack.head) + def push(e: ThunkScope): this.type = { stack = e :: stack; this } + @inline def pop: ThunkScope = { + val res = stack.head + stack = stack.tail + res + } + def beginScope(thunkSym: Ref[Any]): ThunkScope = { + val parent = if (stack.isEmpty) null else stack.head + val scope = new ThunkScope(parent, thunkSym) + this.push(scope) + scope + } + @inline def endScope(): Unit = { this.pop } + } + protected val thunkStack = new ThunkStack + + implicit def repToThunk[A](block: Ref[A]): Ref[Thunk[A]] = thunk_create(block) + + def thunk_create[A](block: => Ref[A]): Ref[Thunk[A]] = { + var scheduleIds: ScheduleIds = null + val resPH = placeholder(Lazy(AnyElement)).asInstanceOf[Ref[A]] // will be known after block is evaluated + val newThunk = new ThunkDef(resPH, { assert(scheduleIds != null); scheduleIds }) + val newThunkSym = newThunk.self + + val newScope = thunkStack.beginScope(newThunkSym) + // execute block and add all new definitions to the top scope (see createDefinition) + // reify all the effects during block execution + val res = block + resPH.assignDefFrom(res) + scheduleIds = + if (res.isVar) DBuffer.ofSize(0) + else if (newScope.isEmptyBody) DBuffer.ofSize(0) + else newScope.scheduleForResult(res) + + val sh = newThunk.scheduleIds // force lazy value in newThunk (see ThunkDef._scheduleIds argument above) + thunkStack.endScope() + toExp(newThunk, newThunkSym) + } + + def thunk_map[A, B](t: Th[A], f: Ref[A => B]): Th[B] = { + Thunk { + f(thunk_force(t)) + } + } + def thunk_map1[A, B](t: Th[A], f: Ref[A] => Ref[B]): Th[B] = { + Thunk { + f(thunk_force(t)) + } + } + + var isInlineThunksOnForce = false + + def forceThunkByMirror[A](thunk: Th[A], subst: MapTransformer = MapTransformer.empty()): Ref[A] = { + val th = thunk.node.asInstanceOf[ThunkDef[A]] + forceThunkDefByMirror(th, subst) + } + def forceThunkDefByMirror[A](th: ThunkDef[A], subst: MapTransformer = MapTransformer.empty()): Ref[A] = { + val body = th.scheduleIds + val t = DefaultMirror.mirrorSymbols(subst, NoRewriting, th, body) + t(th.root) + } + + def thunk_force[A](t: Th[A]): Ref[A] = + if (isInlineThunksOnForce) + t.node match { + case th @ ThunkDef(_, _) => + forceThunkByMirror(t) + case _ => ThunkForce(t) + } + else + ThunkForce(t) + + case class ThunkForce[A](thunk: Ref[Thunk[A]]) extends Def[A] { + implicit def resultType = thunk.elem.eItem + override def transform(t: Transformer) = ThunkForce(t(thunk)) + } + + override protected def matchDefs(d1: Def[_], d2: Def[_], allowInexactMatch: Boolean, subst: Subst): Nullable[Subst] = d1 match { + case ThunkDef(root1, sch1) => d2 match { + case ThunkDef(root2, sch2) => + var res = matchIterators(sch1.iterator, sch2.iterator, allowInexactMatch, subst) + if (res.isDefined) + res = matchExps(root1, root2, allowInexactMatch, res.get) + res + case _ => Nullable.None + } + case _ => + super.matchDefs(d1, d2, allowInexactMatch, subst) + } + + object ConstantThunk { + def unapply(d: Def[_]): Option[Const[_]] = d match { + case ThunkDef(root @ Def(c @Const(_)), Seq(s1)) if root == s1 => Some(c) + case _ => None + } + def unapply(s: Sym): Option[Const[_]] = unapply(s.node) + } + + + override protected def formatDef(d: Def[_])(implicit config: GraphVizConfig): String = d match { + case ThunkDef(r, sch) => s"Thunk($r, [${sch.mkString(",")}])" + case _ => super.formatDef(d) + } + + override protected def nodeColor(td: TypeDesc, d: Def[_])(implicit config: GraphVizConfig) = td match { + case _: ThunkElem[_] => "red" + case _ => super.nodeColor(td, d) + } +} + diff --git a/core/src/main/scala/scalan/primitives/Tuples.scala b/core/src/main/scala/scalan/primitives/Tuples.scala new file mode 100644 index 0000000000..15cea7c133 --- /dev/null +++ b/core/src/main/scala/scalan/primitives/Tuples.scala @@ -0,0 +1,97 @@ +/** + * Author: Alexander Slesarenko + * Date: 7/25/12 + */ +package scalan.primitives + +import scalan.{Base, Scalan, AVHashMap} + +trait Tuples extends Base { self: Scalan => + object Pair { + def apply[A, B](a: Ref[A], b: Ref[B]) = zipPair[A, B]((a, b)) + def unapply[A, B](p: Ref[(A, B)]) = Some(unzipPair[A, B](p)) + } + + object IsPair { + def unapply[A,B](s: Sym): Option[Ref[(A,B)]] = s.elem match { + case pe: PairElem[_,_] => Some(s.asInstanceOf[Ref[(A,B)]]) + case _ => None + } + } + + implicit class ListOps[A, B](t: Ref[(A, B)]) { + def head: Ref[A] = { val Pair(x, _) = t; x } + def tail: Ref[B] = { val Pair(_, x) = t; x } + } + + implicit class TupleOps2[A, B](t: Ref[(A, B)]) { + def _1: Ref[A] = { val Pair(x, _) = t; x } + def _2: Ref[B] = { val Pair(_, x) = t; x } + } + + implicit class TupleOps3[A,B,C](t: Ref[(A,(B,C))]) { + def _1: Ref[A] = { val Pair(x, _) = t; x } + def _2: Ref[B] = { val Pair(_, Pair(x, _)) = t; x } + def _3: Ref[C] = { val Pair(_, Pair(_, x)) = t; x } + } + + implicit class TupleOps4[A,B,C,D](t: Ref[(A,(B,(C,D)))]) { + def _1: Ref[A] = { val Pair(x, _) = t; x } + def _2: Ref[B] = { val Pair(_, Pair(x, _)) = t; x } + def _3: Ref[C] = { val Pair(_, Pair(_, Pair(x, _))) = t; x } + def _4: Ref[D] = { val Pair(_, Pair(_, Pair(_, x))) = t; x } + } + + implicit class TupleOps5[A,B,C,D,E](t: Ref[(A,(B,(C,(D,E))))]) { + def _1: Ref[A] = { val Pair(x, _) = t; x } + def _2: Ref[B] = { val Pair(_, Pair(x, _)) = t; x } + def _3: Ref[C] = { val Pair(_, Pair(_, Pair(x, _))) = t; x } + def _4: Ref[D] = { val Pair(_, Pair(_, Pair(_, Pair(x, _)))) = t; x } + def _5: Ref[E] = { val Pair(_, Pair(_, Pair(_, Pair(_, x)))) = t; x } + } + + val tuplesCache = AVHashMap[Ref[_], (Ref[_], Ref[_])](1000) + + def unzipPair[A, B](p: Ref[(A, B)]): (Ref[A], Ref[B]) = p.node match { + case Tup(a, b) => (a, b) + case _ => p.elem match { + case pe: PairElem[_, _] => + implicit val eA = pe.eFst + implicit val eB = pe.eSnd + if (cachePairs) { + if (!tuplesCache.containsKey(p)) { + tuplesCache.put(p, (First(p), Second(p))) + } + tuplesCache(p).asInstanceOf[(Ref[A], Ref[B])] + } + else + (First(p), Second(p)) + case _ => + !!!(s"expected Tup[A,B] or Sym with type (A,B) but got ${p.toStringWithDefinition}", p) + } + } + + implicit def zipPair[A, B](p: (Ref[A], Ref[B])): Ref[(A, B)] = { + implicit val ea = p._1.elem + implicit val eb = p._2.elem + Tup(p._1, p._2) + } + + case class Tup[A, B](a: Ref[A], b: Ref[B]) extends Def[(A, B)] { + implicit val eA: Elem[A] = a.elem + implicit val eB: Elem[B] = b.elem + assert(null != eA && null != eB) + lazy val resultType = element[(A,B)] + override def transform(t: Transformer): Def[(A, B)] = Tup(t(a), t(b)) + } + + case class First[A, B](pair: Ref[(A, B)]) extends Def[A] { + val resultType: Elem[A] = pair.elem.eFst + override def transform(t: Transformer): Def[A] = First(t(pair)) + } + + case class Second[A, B](pair: Ref[(A, B)]) extends Def[B] { + val resultType: Elem[B] = pair.elem.eSnd + override def transform(t: Transformer): Def[B] = Second(t(pair)) + } +} diff --git a/core/src/main/scala/scalan/primitives/UnBinOps.scala b/core/src/main/scala/scalan/primitives/UnBinOps.scala new file mode 100644 index 0000000000..ed690e7aa6 --- /dev/null +++ b/core/src/main/scala/scalan/primitives/UnBinOps.scala @@ -0,0 +1,47 @@ +package scalan.primitives + +import scalan.{Scalan, Base} + +trait UnBinOps extends Base { self: Scalan => + + class UnOp[A, R](val opName: String, val applySeq: A => R)(implicit val eResult: Elem[R]) { + override def toString = opName + + def apply(arg: Ref[A]) = applyUnOp(this, arg) + + def shouldPropagate(arg: A) = true + } + + class BinOp[A, R](val opName: String, val applySeq: (A, A) => R)(implicit val eResult: Elem[R]) { + override def toString = opName + + def apply(lhs: Ref[A], rhs: Ref[A]) = applyBinOp(this, lhs, rhs) + def applyLazy(lhs: Ref[A], rhs: Ref[Thunk[A]]) = applyBinOpLazy(this, lhs, rhs) + + // ideally shouldn't be necessary, but + // we curently can't handle division by zero properly + def shouldPropagate(lhs: A, rhs: A) = true + } + + type EndoUnOp[A] = UnOp[A, A] + type EndoBinOp[A] = BinOp[A, A] + + case class ApplyUnOp[A, R](op: UnOp[A, R], arg: Ref[A]) extends BaseDef[R]()(op.eResult) { + override def toString = s"$op($arg)" + override def transform(t: Transformer): Def[R] = ApplyUnOp[A,R](op, t(arg)) + } + + case class ApplyBinOp[A, R](op: BinOp[A, R], lhs: Ref[A], rhs: Ref[A]) extends BaseDef[R]()(op.eResult) { + override def toString = s"$op($lhs, $rhs)" + override def transform(t: Transformer): Def[R] = ApplyBinOp[A,R](op, t(lhs), t(rhs)) + } + case class ApplyBinOpLazy[A, R](op: BinOp[A, R], lhs: Ref[A], rhs: Ref[Thunk[A]]) extends BaseDef[R]()(op.eResult) { + override def toString = s"$lhs $op { $rhs }" + override def transform(t: Transformer): Def[R] = ApplyBinOpLazy[A,R](op, t(lhs), t(rhs)) + } + + def applyUnOp[A, R](op: UnOp[A, R], arg: Ref[A]): Ref[R] = ApplyUnOp(op, arg) + + def applyBinOp[A, R](op: BinOp[A, R], lhs: Ref[A], rhs: Ref[A]): Ref[R] = ApplyBinOp(op, lhs, rhs) + def applyBinOpLazy[A, R](op: BinOp[A, R], lhs: Ref[A], rhs: Ref[Thunk[A]]): Ref[R] = ApplyBinOpLazy(op, lhs, rhs) +} \ No newline at end of file diff --git a/core/src/main/scala/scalan/primitives/UniversalOps.scala b/core/src/main/scala/scalan/primitives/UniversalOps.scala new file mode 100644 index 0000000000..30aeb28dae --- /dev/null +++ b/core/src/main/scala/scalan/primitives/UniversalOps.scala @@ -0,0 +1,88 @@ +package scalan.primitives + +import scalan.{Base, Scalan} + +trait UniversalOps extends Base { scalan: Scalan => + case class HashCode[A]() extends UnOp[A, Int]("hashCode", _.hashCode) + + case class ToString[A]() extends UnOp[A, String]("toString", _.toString) + + /** Represents calculation of size in bytes of the given value. + * The descriptor value.elem can be used to decompose value into components. + */ + case class SizeOf[T](value: Ref[T]) extends BaseDef[Long] { + override def transform(t: Transformer) = SizeOf(t(value)) + } + + def sizeOf[T](value: Ref[T]): Ref[Long] = SizeOf(value) + + /** Special graph node to represent accumulation of the operation costs. + * In general, due to node sharing it is incorrect to just sum up all the `args` costs + * and add `resCost` to that value. + * Example:
+ * + * val x = .. + * val y = op1(x) + * val z = op2(x) + * val res = op3(y, z) + * + * The naive summation will lead to the cost of x` is accumulated both into `cost of y` + * and into `cost of z`, so in the `cost of res` it is accumulated twice. + * To avoid this problem OpCost nodes require special handling in during evaluation. + * + * @param lambdaVar the variable of the lambda in which scope this node is created. + * This makes this node belong to the lambda body, even if it doesn't + * otherwise depend on lambda argument. + * @param costedValueId The id of the node for which this node represents cost + * @param args costs of the arguments, which are here represent dependency information. + * @param opCost operation cost, which should be added to the current scope accumulated cost + */ + case class OpCost(lambdaVar: Sym, costedValueId: Int, args: Seq[Ref[Int]], opCost: Ref[Int]) extends BaseDef[Int] { + /** When this node is mirrored (as part of mirrorLambda) we apply transformer t for all arguments + * with standard data flow semantics. + * However this is not correct to do for lambdaVar. + * Instead we use current lambda from the top of the stack, which is always points to the most nested + * lambda. + */ + override def transform(t: Transformer) = OpCost(lambdaStack.head.x, costedValueId, t(args), t(opCost)) + } + + def opCost(costedValue: Sym, args: Seq[Ref[Int]], opCost: Ref[Int]): Ref[Int] = { + val id = costedValue.node.nodeId + val lamVar = lambdaStack.head.x + OpCost(lamVar, id, args, opCost) + } + + def assertValueIdForOpCost[A,B](value: Ref[A], cost: Ref[B]): Unit = { + assert(if (cost.node.isInstanceOf[OpCost]) value.node.nodeId == cost.node.asInstanceOf[OpCost].costedValueId else true, + s"${value.node} value node id (${value.node.nodeId}) is not equal to OpCost.costedValueId (${cost.node.asInstanceOf[OpCost].costedValueId})") + } + + case class Downcast[From, To](input: Ref[From], eTo: Elem[To]) extends BaseDef[To]()(eTo) { + override def transform(t: Transformer) = Downcast(t(input), eTo) + } + case class Upcast[From, To](input: Ref[From], eTo: Elem[To]) extends BaseDef[To]()(eTo) { + override def transform(t: Transformer) = Upcast(t(input), eTo) + } + + def downcast[To:Elem](value: Ref[_]): Ref[To] = Downcast(value, element[To]) + def upcast[To:Elem](value: Ref[_]): Ref[To] = Upcast(value, element[To]) + + implicit class RepUniversalOps[A](x: Ref[A]) { + def hashCodeRep: Ref[Int] = HashCode[A]().apply(x) + def toStringRep = ToString[A]().apply(x) + } + + case class Convert[From,To](eFrom: Elem[From], eTo: Elem[To], x: Ref[Def[_]], conv: Ref[From => To]) + extends BaseDef[To]()(eTo) { + override def transform(t: Transformer) = Convert(eFrom, eTo, t(x), t(conv)) + } + + def tryConvert[From, To](eFrom: Elem[From], eTo: Elem[To], x: Ref[Def[_]], conv: Ref[From => To]): Ref[To] = { + if (x.elem <:< eFrom) + conv(asRep[From](x)) + else + Convert(eFrom, eTo, x, conv) + } + +} diff --git a/core/src/main/scala/scalan/staged/AstGraphs.scala b/core/src/main/scala/scalan/staged/AstGraphs.scala new file mode 100644 index 0000000000..a9967bf100 --- /dev/null +++ b/core/src/main/scala/scalan/staged/AstGraphs.scala @@ -0,0 +1,211 @@ +package scalan.staged + +import scala.collection._ +import scalan.Scalan +import scalan.compilation.GraphVizConfig +import spire.syntax.all.cfor +import debox.{Set => DSet, Buffer => DBuffer, Map => DMap} + + +trait AstGraphs extends Transforming { self: Scalan => + + /** GraphNode is created for each symbol of the AstGraph and represents graph linking structure */ + case class GraphNode( + sym: Sym, // this symbol + usages: DBuffer[Int]) { + def inputSyms: Seq[Sym] = sym.node.deps + def outSyms: DBuffer[Sym] = { + usages.map(getSym) + } + } + + /** Type synonim for graph schedules. */ + type Schedule = Seq[Sym] + + /** Alternative representation of schedules using node ids. */ + type ScheduleIds = DBuffer[Int] + + /** Base class for all compound nodes with schedule (e.g. Lambda, ThunkDef). + * The graph is directed acyclic (i.e. DAG) in which edges go from `boundVars` down to `roots`. + */ + abstract class AstGraph extends Node { thisGraph => + /** If this graph represent Lambda abstraction, the boundVars is lambda bound symbols. + * otherwise this is empty set. */ + def boundVars: Seq[Sym] + + /** Terminal nodes of the graph. There are incoming, but no outgoing edges. */ + def roots: Seq[Sym] + + /** Extract identifies out of `roots`. */ + def rootIds: DBuffer[Int] = { + val rs = roots.toArray + val len = rs.length + val res = new Array[Int](len) + cfor(0)(_ < len, _ + 1) { i => res(i) = rs(i).node.nodeId } + DBuffer.unsafe(res) + } + + /** Collect a set of symbols used in the graph but which are not part of its schedule. + * If the graph represents a compound definition (Lambda, Thunk etc), + * then each item in `freeVars` is used in the body, but not part of it. + * Intersection of free vars with bound vars is empty. + * @hotspot don't beautify the code + */ + def freeVars: Seq[Sym] = { + val sch = schedule.toArray + val len = sch.length + val resSet = DSet.ofSize[Int](len) + val resIds = DBuffer.ofSize[Int](len) + cfor(0)(_ < len, _ + 1) { i => + val sym = sch(i) + val deps = sym.node.deps + cfor(0)(_ < deps.length, _ + 1) { j => + val s = deps(j) + val sId = s.node.nodeId + if (!resSet(sId)) { + if (!(isLocalDefId(sId) || isBoundVar(s))) { + resSet += sId + resIds += sId + } + } + } + } + val res = new Array[Sym](resIds.length) + cfor(0)(_ < resIds.length, _ + 1) { i => + res(i) = getSym(resIds(i)) + } + res + } + + /** Schedule represents a body of compound definition - topologically ordered + * sequence of nodes of the graph. It is implemented differently depending + * on node type. + * @see Lambda, ThunkDef */ + def scheduleIds: DBuffer[Int] + + /** Sequence of node references forming a schedule. + * @hotspot don't beautify the code */ + lazy val schedule: Schedule = { + val len = scheduleIds.length + val res = new Array[Sym](len) + cfor(0)(_ < len, _ + 1) { i => + res(i) = getSym(scheduleIds(i)) + } + res + } + + /** Set of symbol ids in the schedule. Can be used to quickly recognize + * symbols belonging to the body of this definition. + */ + lazy val domain: DSet[Int] = { + val res = DSet.ofSize[Int](scheduleIds.length) + res ++= scheduleIds.toArray + res + } + + /** Whether this graph represents identity function. */ + @inline def isIdentity: Boolean + + /** Checks the symbol is lambda bound. */ + @inline def isBoundVar(s: Sym) = boundVars.contains(s) + + @inline final def isLocalDef(s: Sym): Boolean = domain(s.node.nodeId) + @inline final def isLocalDefId(id: Int): Boolean = domain(id) + + @inline final def isRoot(s: Sym): Boolean = roots.contains(s) + + /** Flatten the given schedule into single sequence of non-AstGraph definitions. + * All scope forming definitions like Lambda and ThunkDef are recursively unfolded in the given buffer `flatBuf`. + * NOTE: The symbols of AstGraph-like definitions are added to `flatBuf` AFTER the unfolded body. + */ + final def buildFlatSchedule(schedule: Schedule, flatBuf: DBuffer[Sym]): Unit = { + cfor(0)(_ < schedule.length, _ + 1) { i => + val sym = schedule(i) + if (sym.node.isInstanceOf[AstGraph]) { + val subSch = sym.node.asInstanceOf[AstGraph].flatSchedule.toArray + flatBuf ++= subSch + } + flatBuf += sym + } + } + + lazy val flatSchedule: Schedule = { + val flatBuf = DBuffer.ofSize[Sym](schedule.length) + buildFlatSchedule(schedule, flatBuf) + flatBuf.toArray + } + + /** Build usage information induced by the given schedule. + * For each symbol of the schedule a GraphNode is created and usages are collected. + * @hotspot don't beautify the code + */ + def buildUsageMap(schedule: Schedule, usingDeps: Boolean): DMap[Int, GraphNode] = { + val len = schedule.length + val nodeMap = DMap.ofSize[Int, GraphNode](len) + cfor(0)(_ < len, _ + 1) { i => + val sym = schedule(i) + val symId = sym.node.nodeId + nodeMap.update(symId, GraphNode(sym, DBuffer.empty[Int])) + } + cfor(0)(_ < len, _ + 1) { i => + val sym = schedule(i) + val symId = sym.node.nodeId + + val deps = if (usingDeps) sym.node.deps else sym.node.syms + cfor(0)(_ < deps.length, _ + 1) { j => + val us = deps(j) // used symbol + val usId = us.node.nodeId // used symbol id + var node = nodeMap.getOrElse(usId, null) + if (null == node) { + node = GraphNode(us, DBuffer.empty[Int]) + nodeMap.update(usId, node) + } + node.usages += symId + } + + } + nodeMap + } + + /** + * Symbol Usage information for this graph + */ + lazy val usageMap: DMap[Int, GraphNode] = { + buildUsageMap(schedule, usingDeps = true) + } + + lazy val allNodes: DMap[Int, GraphNode] = { + buildUsageMap(flatSchedule, usingDeps = false) // using rhs.syms instead of rhs.deps + } + + def globalUsagesOf(s: Sym): DBuffer[Sym] = allNodes.get(s.node.nodeId) match { + case Some(node) => node.outSyms + case None => DBuffer.empty[Sym] + } + + def hasManyUsagesGlobal(s: Sym): Boolean = globalUsagesOf(s).length > 1 + + /** This empty buffer is returned every time the usages are requested for the node + * that is not in usageMap. + * WARNING! Since it is mutable, special care should be taken to not change this buffer. + * @hotspot used havily in scheduling */ + private val NoUsages = DBuffer.unsafe(new Array[Int](0)) + + /** @hotspot for performance we return mutable structure, but it should never be changed. */ + def usagesOf(id: Int): DBuffer[Int] = { + val node = usageMap.getOrElse(id, null) + if (node == null) return NoUsages + node.usages + } + + def hasManyUsages(s: Sym): Boolean = usagesOf(s.node.nodeId).length > 1 + + def show(): Unit = show(defaultGraphVizConfig) + def show(emitMetadata: Boolean): Unit = show(defaultGraphVizConfig.copy(emitMetadata = emitMetadata)) + def show(config: GraphVizConfig): Unit = showGraphs(this)(config) + + } // AstGraph + + + +} diff --git a/core/src/main/scala/scalan/staged/ProgramGraphs.scala b/core/src/main/scala/scalan/staged/ProgramGraphs.scala new file mode 100644 index 0000000000..12b10624dd --- /dev/null +++ b/core/src/main/scala/scalan/staged/ProgramGraphs.scala @@ -0,0 +1,102 @@ +package scalan.staged + +import scalan.{DFunc, Nullable, Scalan} +import debox.{Buffer => DBuffer} +import scalan.util.GraphUtil +import spire.syntax.all.cfor + +import scala.collection.mutable + +trait ProgramGraphs extends AstGraphs { self: Scalan => + + type PGraph = ProgramGraph + + /** Deboxed function to obtain usages of a given node. + * Represents adjacency matrix of the reversed graph `g`. + * @param g original graph whose usages are computed */ + class PGraphUsages(g: AstGraph) extends DFunc[Int, DBuffer[Int]] { + override def apply(nodeId: Int) = { + val us = g.usagesOf(nodeId) + us + } + } + + /** Immutable graph collected from `roots` following Ref.node.deps links. */ + case class ProgramGraph(roots: Seq[Sym], mapping: Nullable[Transformer], filterNode: Nullable[Sym => Boolean]) + extends AstGraph { + def this(roots: Seq[Sym], filterNode: Nullable[Sym => Boolean] = Nullable.None) { this(roots, Nullable.None, filterNode) } + def this(root: Sym) { this(List(root)) } + + override lazy val rootIds: DBuffer[Int] = super.rootIds + + override def boundVars = Nil + override def isIdentity: Boolean = false + override def freeVars = mutable.WrappedArray.empty[Sym] + override lazy val scheduleIds = { + val neighbours: DFunc[Int, DBuffer[Int]] = filterNode match { + case Nullable(pred) => + { (id: Int) => + val deps = getSym(id).node.deps + val len = deps.length + val res = DBuffer.ofSize[Int](len) + cfor(0)(_ < len, _ + 1) { i => + val sym = deps(i) + if (pred(sym) && !sym.isVar) // TODO remove isVar condition here and below + res += sym.node.nodeId + } + res + } + case _ => + { (id: Int) => + val deps = getSym(id).node.deps + val len = deps.length + val res = DBuffer.ofSize[Int](len) + cfor(0)(_ < len, _ + 1) { i => + val sym = deps(i) + if (!sym.isVar) + res += sym.node.nodeId + } + res + } + } + val sch = GraphUtil.depthFirstOrderFrom(rootIds, neighbours) + sch + } + + /** Mirror all the nodes of this graph applying transformer and performing rewriting. + * @param m mirror instance to be used for mirroring of nodes + * @param rw rewriter to be tried for each new created mirrored node + * @param t transformer of symbols, to be used for substitution of symbols in the new nodes. + * @return new graph which is not necessary clone of this graph, but should be semantically + * equivalent to this graph (provided all rw rules preserve equivalence). + * If rw is identity, then the resulting graph is alpha-equivalent to this graph + * as long as t is bijection. + */ + def transform(m: Mirror, rw: Rewriter, t: Transformer): ProgramGraph = { + val t0 = mapping match { + case Nullable(mapping) => t merge mapping + case _ => t + } + val t1 = m.mirrorSymbols(t0, rw, this, scheduleIds) + val newRoots = roots map { t1(_) } + new ProgramGraph(newRoots, Nullable(t1), filterNode) + } + + /** Remove transformer component of the graph. */ + def withoutContext = ProgramGraph(roots, Nullable.None, filterNode) + + override def toString: String = { + val mappingStr = if (mapping.isEmpty) "None" else mapping.toString + val filterNodeStr = if (filterNode.isDefined) filterNode.toString else "None" + s"ProgramGraph($roots, $mappingStr, $filterNodeStr)" + } + } + + object ProgramGraph { + def transform[A](s: Ref[A], rw: Rewriter = NoRewriting, t: MapTransformer = MapTransformer.empty()): Ref[A] = { + val g = ProgramGraph(List(s), Nullable.None, Nullable.None) + val g1 = g.transform(DefaultMirror, rw, t) + g1.roots(0).asInstanceOf[Ref[A]] + } + } +} diff --git a/core/src/main/scala/scalan/staged/Transforming.scala b/core/src/main/scala/scalan/staged/Transforming.scala new file mode 100644 index 0000000000..436e5f69fc --- /dev/null +++ b/core/src/main/scala/scalan/staged/Transforming.scala @@ -0,0 +1,264 @@ +package scalan.staged + +import java.lang.reflect.Method +import java.util + +import scalan.{Nullable, DelayInvokeException, Lazy, Scalan, AVHashMap} +import debox.{Buffer => DBuffer} +import spire.syntax.all.cfor + +trait Transforming { self: Scalan => + + /** Descriptor of a current compiler pass. + * Compiler can be configured to perform one pass after another. + * Each pass has name, configuration parameters, finalizaton logic etc. + */ + abstract class Pass { + /** Unique name of the pass. */ + def name: String + /** Configuration parameters of this pass. */ + def config: PassConfig = Pass.defaultPassConfig + /** Called when this pass is being finalized. */ + def doFinalization(): Unit = {} + /** + * Pass specific optional decision. + * @param d receiver of the method + * @param m method to invoke + * @return Some(decision) if some this Pass defines some logic, None - then core behavior is used + */ + def isInvokeEnabled(d: Def[_], m: Method): Option[Boolean] = None + } + object Pass { + val defaultPassName = "default" + /** When this IR is used without a compiler this pass is used as current pass. */ + val defaultPass = new DefaultPass(defaultPassName) + val defaultPassConfig = defaultPass.config + } + + /** Configuration parameters of the Pass descriptor. */ + case class PassConfig( + /** Whether the pair type `(A,B)` should be specialized to `{_1: A, _2:B} struct type.`. + * This is used in structs flattening transformation and can also be used in other way. */ + shouldUnpackTuples: Boolean = false, + /** Turn on/off the RW rule to extract a value of the field if the value is known in the graph. */ + shouldExtractFields: Boolean = true, + /** Turn on/off constant propagation RW rules. */ + constantPropagation: Boolean = true, + /** Used in SlicingPass */ + shouldSlice: Boolean = false) + { + def withConstantPropagation(value: Boolean) = this.copy(constantPropagation = value) + } + + /** Default pass to be used when IR is used without special compiler configuration. */ + class DefaultPass(val name: String, override val config: PassConfig = PassConfig()) extends Pass + + //TODO Current design doesn't allow to run through passes in two Compilers in parallel + var _currentPass: Pass = Pass.defaultPass + + /** IR global current Pass, changes when the compier switches from one pass to the next one. + * Should remain constant during the whole pass execution. */ + def currentPass = _currentPass + + /** Called to setup IR before the new pass is executed. */ + def beginPass(pass: Pass): Unit = { + _currentPass = pass + } + /** Called to let this IR context to finalized the given pass. */ + def endPass(pass: Pass): Unit = { + _currentPass = Pass.defaultPass + } + + /** Concrete and default implementation of Transformer using underlying HashMap. + * @hotspot don't beatify the code */ + case class MapTransformer(private val subst: util.HashMap[Sym, Sym]) extends Transformer { + def this(substPairs: (Sym, Sym)*) { + this({ + val map = new util.HashMap[Sym, Sym](1000) + val len = substPairs.length + cfor(0)(_ < len, _ + 1) { i => + val kv = substPairs(i) + map.put(kv._1, kv._2) + } + map + }) + } + def apply[A](x: Ref[A]): Ref[A] = { + val y = subst.get(x) + if (y == null || y == x) return x + apply(y.asInstanceOf[Ref[A]]) // apply recursively to obtain transitive closure + } + def isDefinedAt(x: Ref[_]) = subst.containsKey(x) + def domain: Seq[Ref[_]] = subst.keySet.toArray(new Array[Sym](0)) + + def +[A](key: Sym, value: Sym): Transformer = { + subst.put(key, value) + this + } + def merge(other: Transformer): Transformer = + other.domain.foldLeft[Transformer](this) { + case (t, s: Sym) => t + (s, other(s)) + } + + override def toString = if (subst.isEmpty) "MapTransformer.Empty" else s"MapTransformer($subst)" + } + + object MapTransformer { + def empty(initialCapacity: Int = 100) = new MapTransformer(new util.HashMap[Sym, Sym](initialCapacity)) + } + + abstract class Rewriter { self => + def apply[T](x: Ref[T]): Ref[T] + + def orElse(other: Rewriter): Rewriter = new Rewriter { + def apply[T](x: Ref[T]) = { + val y = self(x) + (x == y) match { case true => other(x) case _ => y } + } + } + def andThen(other: Rewriter): Rewriter = new Rewriter { + def apply[T](x: Ref[T]) = { + val y = self(x) + val res = other(y) + res + } + } + + def |(other: Rewriter) = orElse(other) + def ~(other: Rewriter) = andThen(other) + } + + /** Turns partial function into rewriter (i.e. set of rewriting rules) */ + implicit class PartialRewriter(pf: PartialFunction[Sym, Sym]) extends Rewriter { + def apply[T](x: Ref[T]): Ref[T] = + if (pf.isDefinedAt(x)) + pf(x).asInstanceOf[Ref[T]] + else + x + } + + /** Identity rewriter, i.e. doesn't change the graph when applied. */ + val NoRewriting: Rewriter = new Rewriter { + def apply[T](x: Ref[T]) = x + } + + /** Base class for mirrors of graph nodes. Provides default implementations which can be + * overriden if special logic is required. + * @hotspot don't beautify the code */ + abstract class Mirror { + def apply[A](t: Transformer, rewriter: Rewriter, node: Ref[A], d: Def[A]): Sym = d.mirror(t) + + protected def mirrorElem(node: Sym): Elem[_] = node.elem + + // every mirrorXXX method should return a pair (t + (v -> v1), v1) + protected def mirrorVar[A](t: Transformer, rewriter: Rewriter, v: Ref[A]): Transformer = { + val newVar = variable(Lazy(mirrorElem(v))) + t + (v, newVar) + } + + protected def mirrorDef[A](t: Transformer, rewriter: Rewriter, node: Ref[A], d: Def[A]): Transformer = { + val res = apply(t, rewriter, node, d) + t + (node, res) + } + + protected def getMirroredLambdaSym[A, B](node: Ref[A => B]): Sym = placeholder(Lazy(mirrorElem(node))) + + // require: should be called after oldlam.schedule is mirrored + private def getMirroredLambdaDef(t: Transformer, oldLam: Lambda[_,_], newRoot: Sym): Lambda[_,_] = { + val newVar = t(oldLam.x) + val newLambdaDef = new Lambda(Nullable.None, newVar, newRoot, oldLam.mayInline, oldLam.alphaEquality) + newLambdaDef + } + + protected def mirrorLambda[A, B](t: Transformer, rewriter: Rewriter, node: Ref[A => B], lam: Lambda[A, B]): Transformer = { + var tRes: Transformer = t + val t1 = mirrorNode(t, rewriter, lam, lam.x) + + // original root + val originalRoot = lam.y + + // ySym will be assigned after f is executed + val ySym = placeholder(Lazy(lam.y.elem)) + val newLambdaCandidate = getMirroredLambdaDef(t1, lam, ySym) + val newLambdaSym = newLambdaCandidate.self + + // new effects may appear during body mirroring + // thus we need to forget original Reify node and create a new one +// val oldStack = lambdaStack + try { +// lambdaStack = newLambdaCandidate :: lambdaStack + val newRoot = { // reifyEffects block + val schedule = lam.scheduleIds + val t2 = mirrorSymbols(t1, rewriter, lam, schedule) + tRes = t2 + tRes(originalRoot) // this will be a new root + } + ySym.assignDefFrom(newRoot) + } + finally { +// lambdaStack = oldStack + } + + // we don't use toExp here to avoid rewriting pass for new Lambda + val resLam = findOrCreateDefinition(newLambdaCandidate, newLambdaSym) + + tRes + (node, resLam) + } + + protected def mirrorThunk[A](t: Transformer, rewriter: Rewriter, node: Ref[Thunk[A]], thunk: ThunkDef[A]): Transformer = { + var scheduleIdsPH: ScheduleIds = null + val newRootPH = placeholder(Lazy(node.elem.eItem)) + val newThunk = new ThunkDef(newRootPH, { assert(scheduleIdsPH != null); scheduleIdsPH }) + val newThunkSym = newThunk.self + + val newScope = thunkStack.beginScope(newThunkSym) + val schedule = thunk.scheduleIds + val t1 = mirrorSymbols(t, rewriter, thunk, schedule) + thunkStack.endScope() + + val newRoot = t1(thunk.root) + newRootPH.assignDefFrom(newRoot) + scheduleIdsPH = + if (newRoot.isVar) DBuffer.ofSize(0) + else if (newScope.isEmptyBody) DBuffer.ofSize(0) + else newScope.scheduleForResult(newRoot) + + createDefinition(thunkStack.top, newThunkSym, newThunk) + t1 + (node, newThunkSym) + } + + protected def isMirrored(t: Transformer, node: Sym): Boolean = t.isDefinedAt(node) + + def mirrorNode(t: Transformer, rewriter: Rewriter, g: AstGraph, node: Sym): Transformer = { + if (isMirrored(t, node)) t + else { + node.node match { + case v: Variable[_] => + mirrorVar(t, rewriter, node) + case lam: Lambda[a, b] => + mirrorLambda(t, rewriter, node.asInstanceOf[Ref[a => b]], lam) + case th: ThunkDef[a] => + mirrorThunk(t, rewriter, node.asInstanceOf[Ref[Thunk[a]]], th) + case d => + mirrorDef(t, rewriter, node, d) + } + } + } + + /** @hotspot */ + def mirrorSymbols(t0: Transformer, rewriter: Rewriter, g: AstGraph, nodes: DBuffer[Int]) = { + var t: Transformer = t0 + cfor(0)(_ < nodes.length, _ + 1) { i => + val n = nodes(i) + val s = getSym(n) + t = mirrorNode(t, rewriter, g, s) + } + t + } + } + + /** Default Mirror instance which is used in core IR methods. */ + val DefaultMirror = new Mirror {} + +} + diff --git a/core/src/test/scala/scalan/BaseLiftableTests.scala b/core/src/test/scala/scalan/BaseLiftableTests.scala new file mode 100644 index 0000000000..7e28b3528f --- /dev/null +++ b/core/src/test/scala/scalan/BaseLiftableTests.scala @@ -0,0 +1,24 @@ +package scalan + +import scala.collection.mutable + +trait BaseLiftableTests { self: BaseCtxTests => + + trait LiftableTestKit { scalan: Scalan => + import Liftables._ + + /** Check the MethodCall reified in f can be mapped to unlifted method which can be invoked.*/ + def check[ST, T](obj: ST, f: EnvRep[T] => EnvRep[_], expected: Any)(implicit lT: Liftable[ST,T]) = { + val objSym: Ref[T] = liftConst(obj) + val env = Map[Sym, AnyRef]() + val resEnvSym = f(EnvRep.add(objSym -> obj.asInstanceOf[AnyRef])) + val (resEnv, resSym) = resEnvSym.run(env) + resSym match { + case Def(mc: MethodCall) => + val res = invokeUnlifted(objSym.elem, mc, resEnv) + res shouldBe expected + } + } + } + +} diff --git a/core/src/test/scala/scalan/TestContexts.scala b/core/src/test/scala/scalan/TestContexts.scala new file mode 100644 index 0000000000..3d89f76c1a --- /dev/null +++ b/core/src/test/scala/scalan/TestContexts.scala @@ -0,0 +1,60 @@ +package scalan + +import java.lang.reflect.Method + +import scalan.compilation.GraphVizConfig +import scalan.util.FileUtil + +trait TestContexts extends TestUtils { + protected[this] def stage(scalan: Scalan)(testName: String, name: String, sfs: Seq[() => scalan.Sym]): Unit = { + val directory = FileUtil.file(prefix, testName) + implicit val graphVizConfig = scalan.defaultGraphVizConfig + try { + val ss = sfs.map(_.apply()) + scalan.emitDepGraph(ss, directory, name) + } catch { + case e: Exception => + val graphMsg = scalan.emitExceptionGraph(e, directory, name) match { + case Some(graphFile) => + s"See ${graphFile.file.getAbsolutePath} for exception graph." + case None => + s"No exception graph produced." + } + fail(s"Staging $name failed. $graphMsg", e) + } + } + + trait TestContextApi { scalan: Scalan => + def invokeAll: Boolean + def isInvokeEnabled(d: Def[_], m: Method): Boolean + def shouldUnpack(e: Elem[_]): Boolean + def testName: String + def emitF(name: String, sfs: (() => Sym)*): Unit + // def emit(name: String, s1: => Sym): Unit = emitF(name, () => s1) + def emit(name: String, ss: Sym*): Unit = { + emitF(name, ss.map((s: Ref[_]) => () => s): _*) + } + def emit(s1: => Sym): Unit = emitF(testName, () => s1) + def emit(s1: => Sym, s2: Sym*): Unit = { + emitF(testName, Seq(() => s1) ++ s2.map((s: Ref[_]) => () => s): _*) + } + } + abstract class TestContext(val testName: String) extends Scalan with TestContextApi { + def this() = this(currentTestNameAsFileName) + + override val invokeAll = true + override def isInvokeEnabled(d: Def[_], m: Method) = invokeAll + override def shouldUnpack(e: Elem[_]) = true + + // workaround for non-existence of by-name repeated parameters + def emitF(name: String, sfs: (() => Sym)*): Unit = stage(this)(testName, name, sfs) + } + + +} + +abstract class BaseCtxTests extends BaseTests with TestContexts + +abstract class BaseNestedCtxTests extends BaseNestedTests with TestContexts + +abstract class BaseShouldCtxTests extends BaseShouldTests with TestContexts \ No newline at end of file diff --git a/docs/Costing.md b/docs/Costing.md index f575aee410..a48b6d9b84 100644 --- a/docs/Costing.md +++ b/docs/Costing.md @@ -236,12 +236,12 @@ require special rewriting rule. See section [Rewrite Rules](#RewriteRules) Given an environment `envVals` and ErgoTree `tree` a Costed Graph can be obtained as [reified lambda](https://github.com/scalan/scalan.github.io/blob/master/idioms.md#Idiom4) of type -`Rep[Context => Costed[T#WrappedType]]` +`Ref[Context => Costed[T#WrappedType]]` This transformation is implemented as shown in the following `buildCostedGraph` method, which can be found in `RuntimeCosting.scala` file. ```scala -def buildCostedGraph[T <: SType](envVals: Map[Any, SValue], tree: Value[T]): Rep[Context => Costed[T#WrappedType]] = - fun { ctx: Rep[Context] => // here ctx represents data context +def buildCostedGraph[T <: SType](envVals: Map[Any, SValue], tree: Value[T]): Ref[Context => Costed[T#WrappedType]] = + fun { ctx: Ref[Context] => // here ctx represents data context val ctxC = RCCostedContext(ctx) // data context is wrapped into Costed value container val env = envVals.mapValues(v => evalNode(ctxC, Map(), v)) // do costing of environment val res = evalNode(ctxC, env, tree) // traverse tree recursively applying costing rules @@ -259,9 +259,9 @@ In order to build costed graph, the algorithm have to recursively traverse ErgoT For each node of ErgoTree, separate _costing rule_ is applied using `evalNode` method whose structure is show below. ```scala -type RCosted[A] = Rep[Costed[A]] +type RCosted[A] = Ref[Costed[A]] type CostingEnv = Map[Any, RCosted[_]] -def evalNode[T <: SType](ctx: Rep[CostedContext], env: CostingEnv, node: Value[T]): RCosted[T#WrappedType] = { +def evalNode[T <: SType](ctx: Ref[CostedContext], env: CostingEnv, node: Value[T]): RCosted[T#WrappedType] = { def eval[T <: SType](node: Value[T]) = evalNode(ctx, env, node) object In { def unapply(v: SValue): Nullable[RCosted[Any]] = Nullable(evalNode(ctx, env, v)) } ... @@ -275,15 +275,15 @@ def evalNode[T <: SType](ctx: Rep[CostedContext], env: CostingEnv, node: Value[T Here `In` is a helper extractor which recursively apply `evalNode` for each argument so that variables `arg1,...,argK` represent results of costing of the corresponding subtree. The right hand side of each rule (`rhs1,...rhsN`) contains operations with -[Rep types](https://github.com/scalan/scalan.github.io/blob/master/idioms.md#Idiom3), the effect of their +[Ref types](https://github.com/scalan/scalan.github.io/blob/master/idioms.md#Idiom3), the effect of their execution is creation of new graph nodes which become part of resulting costed graph. Following is an example of a simple costing rule to introduce basic concepts (it can be found in RuntimeCosting.scala file). ```scala case sigmastate.MultiplyGroup(In(_l), In(_r)) => - val l = asRep[Costed[WECPoint]](_l) // type cast to an expected Rep type - val r = asRep[Costed[WECPoint]](_r) + val l = asRep[Costed[GroupElement]](_l) // type cast to an expected Ref type + val r = asRep[Costed[GroupElement]](_r) val value = l.value.add(r.value) // value sub-rule val cost = l.cost + r.cost + costOf(node) // cost sub-rule val size = CryptoConstants.groupSize.toLong // size sub-rule @@ -312,7 +312,7 @@ explicit by using `eval` helper and also employ other idioms of staged evaluatio val xs = asRep[CostedColl[Any]](eval(input)) // recursively build subgraph for input argument implicit val eAny = xs.elem.asInstanceOf[CostedElem[Coll[Any],_]].eVal.eA assert(eIn == eAny, s"Types should be equal: but $eIn != $eAny") - val mapperC = fun { x: Rep[Costed[Any]] => // x argument is already costed + val mapperC = fun { x: Ref[Costed[Any]] => // x argument is already costed evalNode(ctx, env + (id -> x), mapper) // associate id in the tree with x node of the graph } val res = xs.mapCosted(mapperC) // call costed method of costed collection @@ -320,7 +320,7 @@ explicit by using `eval` helper and also employ other idioms of staged evaluatio ``` Observe that this rule basically translates mapping operation over collection into invocation of the method `mapCosted` on costed collection value `xs` with appropriately prepared argument `mapperC`. -Because `xs` has [Rep type](https://github.com/scalan/scalan.github.io/blob/master/idioms.md#Idiom3) +Because `xs` has [Ref type](https://github.com/scalan/scalan.github.io/blob/master/idioms.md#Idiom3) this invocation has an effect of adding new `MethodCall(xs, "mapCosted", Seq(mapperC))` node to the graph. This new node is immediately catched by the rewriting rule (see [Rewrite Rules](#RewriteRules) section) which further transforms it into final nodes of resulting costed graph. Such separation makes the whole algorithm more modular. @@ -334,11 +334,11 @@ operations of the Costed Graph from cost and data size computing operations. After building a Costed Graph ```scala -val graphC: Rep[Context => SType#WrappedValue] = buildCostedGraph(env, tree) +val graphC: Ref[Context => SType#WrappedValue] = buildCostedGraph(env, tree) ``` we can perform _splitting_ by using the function `split` to obtain `calcF` and `costF` functions ```scala -val Pair(calcF: Rep[Context => SType#WrappedValue], costF: Rep[Context => Int]) = split(graphC) +val Pair(calcF: Ref[Context => SType#WrappedValue], costF: Ref[Context => Int]) = split(graphC) ``` Both `calcF` and `costF` take `Context` as its argument and both represented as [reified lambdas](https://github.com/scalan/scalan.github.io/blob/master/idioms.md#Idiom4) of @@ -346,9 +346,9 @@ Scalan/Special IR. This _splitting_ function is generic and defined as shown below ```scala - def split[T,R](f: Rep[T => Costed[R]]): Rep[(T => R, T => Int)] = { - val calc = fun { x: Rep[T] => val y = f(x); val res = y.value; res } - val cost = fun { x: Rep[T] => f(x).cost } + def split[T,R](f: Ref[T => Costed[R]]): Ref[(T => R, T => Int)] = { + val calc = fun { x: Ref[T] => val y = f(x); val res = y.value; res } + val cost = fun { x: Ref[T] => f(x).cost } Pair(calc, cost) } ``` @@ -412,7 +412,7 @@ The following rule uses auto-generated extractor `mapCosted` which recognizes in `CostedColl.mapCosted` (Remember, this method was used in costing rule for `MapCollection` tree node). ```scala -override def rewriteDef[T](d: Def[T]): Rep[_] = { +override def rewriteDef[T](d: Def[T]): Ref[_] = { val CCM = CostedCollMethods d match { case CCM.mapCosted(xs: RCostedColl[a], _f: RCostedFunc[_, b]) => @@ -426,7 +426,7 @@ override def rewriteDef[T](d: Def[T]): Rep[_] = { val costs = mCostF.mDom match { case PairMarking(markA,_) if markA.isEmpty => - val slicedCostF = fun { in: Rep[(Int, Long)] => costF(Pair(variable[a], in)) } + val slicedCostF = fun { in: Ref[(Int, Long)] => costF(Pair(variable[a], in)) } xs.costs.zip(xs.sizes).map(slicedCostF) case _ => xs.values.zip(xs.costs.zip(xs.sizes)).map(costF) diff --git a/docs/spec/generated/Context_methods.tex b/docs/spec/generated/Context_methods.tex index 351e8df433..f80616a37f 100644 --- a/docs/spec/generated/Context_methods.tex +++ b/docs/spec/generated/Context_methods.tex @@ -9,13 +9,16 @@ \subsubsection{\lst{Context.dataInputs} method (Code 101.1)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: Context} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{Coll[Box]} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:PropertyCall]{\lst{PropertyCall}} \\ + \hline + \end{tabularx} @@ -30,13 +33,16 @@ \subsubsection{\lst{Context.headers} method (Code 101.2)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: Context} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{Coll[Header]} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:PropertyCall]{\lst{PropertyCall}} \\ + \hline + \end{tabularx} @@ -51,13 +57,16 @@ \subsubsection{\lst{Context.preHeader} method (Code 101.3)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: Context} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{PreHeader} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:PropertyCall]{\lst{PropertyCall}} \\ + \hline + \end{tabularx} @@ -72,13 +81,16 @@ \subsubsection{\lst{Context.INPUTS} method (Code 101.4)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: Context} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{Coll[Box]} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:Inputs]{\lst{Inputs}} \\ + \hline + \end{tabularx} @@ -93,13 +105,16 @@ \subsubsection{\lst{Context.OUTPUTS} method (Code 101.5)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: Context} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{Coll[Box]} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:Outputs]{\lst{Outputs}} \\ + \hline + \end{tabularx} @@ -114,13 +129,16 @@ \subsubsection{\lst{Context.HEIGHT} method (Code 101.6)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: Context} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{Int} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:Height]{\lst{Height}} \\ + \hline + \end{tabularx} @@ -135,13 +153,16 @@ \subsubsection{\lst{Context.SELF} method (Code 101.7)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: Context} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{Box} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:Self]{\lst{Self}} \\ + \hline + \end{tabularx} @@ -156,13 +177,16 @@ \subsubsection{\lst{Context.selfBoxIndex} method (Code 101.8)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: Context} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{Int} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:PropertyCall]{\lst{PropertyCall}} \\ + \hline + \end{tabularx} @@ -177,13 +201,16 @@ \subsubsection{\lst{Context.LastBlockUtxoRootHash} method (Code 101.9)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: Context} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{AvlTree} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:LastBlockUtxoRootHash]{\lst{LastBlockUtxoRootHash}} \\ + \hline + \end{tabularx} @@ -198,13 +225,16 @@ \subsubsection{\lst{Context.minerPubKey} method (Code 101.10)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: Context} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{Coll[Byte]} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:MinerPubkey]{\lst{MinerPubkey}} \\ + \hline + \end{tabularx} @@ -214,17 +244,19 @@ \subsubsection{\lst{Context.getVar} method (Code 101.11)} \noindent \begin{tabularx}{\textwidth}{| l | X |} \hline - \bf{Description} & \\ + \bf{Description} & Get context variable with given \lst{varId} and type. \\ \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: Context} & \text{// } \\ -\lst{arg1} & \lst{: Byte} & \text{// } \\ + \lst{varId} & \lst{: Byte} & \text{// \lst{Byte} identifier of context variable} \\ \end{array}\) \\ \hline \bf{Result} & \lst{Option[T]} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:GetVar]{\lst{GetVar}} \\ + \hline + \end{tabularx} diff --git a/docs/spec/generated/Header_methods.tex b/docs/spec/generated/Header_methods.tex index 5779748d8a..50a5e40149 100644 --- a/docs/spec/generated/Header_methods.tex +++ b/docs/spec/generated/Header_methods.tex @@ -9,13 +9,16 @@ \subsubsection{\lst{Header.id} method (Code 104.1)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: Header} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{Coll[Byte]} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:PropertyCall]{\lst{PropertyCall}} \\ + \hline + \end{tabularx} @@ -30,13 +33,16 @@ \subsubsection{\lst{Header.version} method (Code 104.2)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: Header} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{Byte} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:PropertyCall]{\lst{PropertyCall}} \\ + \hline + \end{tabularx} @@ -51,13 +57,16 @@ \subsubsection{\lst{Header.parentId} method (Code 104.3)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: Header} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{Coll[Byte]} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:PropertyCall]{\lst{PropertyCall}} \\ + \hline + \end{tabularx} @@ -72,13 +81,16 @@ \subsubsection{\lst{Header.ADProofsRoot} method (Code 104.4)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: Header} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{Coll[Byte]} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:PropertyCall]{\lst{PropertyCall}} \\ + \hline + \end{tabularx} @@ -93,13 +105,16 @@ \subsubsection{\lst{Header.stateRoot} method (Code 104.5)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: Header} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{AvlTree} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:PropertyCall]{\lst{PropertyCall}} \\ + \hline + \end{tabularx} @@ -114,13 +129,16 @@ \subsubsection{\lst{Header.transactionsRoot} method (Code 104.6)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: Header} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{Coll[Byte]} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:PropertyCall]{\lst{PropertyCall}} \\ + \hline + \end{tabularx} @@ -135,13 +153,16 @@ \subsubsection{\lst{Header.timestamp} method (Code 104.7)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: Header} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{Long} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:PropertyCall]{\lst{PropertyCall}} \\ + \hline + \end{tabularx} @@ -156,13 +177,16 @@ \subsubsection{\lst{Header.nBits} method (Code 104.8)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: Header} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{Long} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:PropertyCall]{\lst{PropertyCall}} \\ + \hline + \end{tabularx} @@ -177,13 +201,16 @@ \subsubsection{\lst{Header.height} method (Code 104.9)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: Header} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{Int} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:PropertyCall]{\lst{PropertyCall}} \\ + \hline + \end{tabularx} @@ -198,13 +225,16 @@ \subsubsection{\lst{Header.extensionRoot} method (Code 104.10)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: Header} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{Coll[Byte]} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:PropertyCall]{\lst{PropertyCall}} \\ + \hline + \end{tabularx} @@ -219,13 +249,16 @@ \subsubsection{\lst{Header.minerPk} method (Code 104.11)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: Header} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{GroupElement} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:PropertyCall]{\lst{PropertyCall}} \\ + \hline + \end{tabularx} @@ -240,13 +273,16 @@ \subsubsection{\lst{Header.powOnetimePk} method (Code 104.12)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: Header} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{GroupElement} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:PropertyCall]{\lst{PropertyCall}} \\ + \hline + \end{tabularx} @@ -261,13 +297,16 @@ \subsubsection{\lst{Header.powNonce} method (Code 104.13)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: Header} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{Coll[Byte]} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:PropertyCall]{\lst{PropertyCall}} \\ + \hline + \end{tabularx} @@ -282,13 +321,16 @@ \subsubsection{\lst{Header.powDistance} method (Code 104.14)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: Header} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{BigInt} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:PropertyCall]{\lst{PropertyCall}} \\ + \hline + \end{tabularx} @@ -303,11 +345,14 @@ \subsubsection{\lst{Header.votes} method (Code 104.15)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: Header} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{Coll[Byte]} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:PropertyCall]{\lst{PropertyCall}} \\ + \hline + \end{tabularx} diff --git a/docs/spec/generated/PreHeader_methods.tex b/docs/spec/generated/PreHeader_methods.tex index 8b8118840a..307229fb93 100644 --- a/docs/spec/generated/PreHeader_methods.tex +++ b/docs/spec/generated/PreHeader_methods.tex @@ -9,13 +9,16 @@ \subsubsection{\lst{PreHeader.version} method (Code 105.1)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: PreHeader} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{Byte} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:PropertyCall]{\lst{PropertyCall}} \\ + \hline + \end{tabularx} @@ -30,13 +33,16 @@ \subsubsection{\lst{PreHeader.parentId} method (Code 105.2)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: PreHeader} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{Coll[Byte]} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:PropertyCall]{\lst{PropertyCall}} \\ + \hline + \end{tabularx} @@ -51,13 +57,16 @@ \subsubsection{\lst{PreHeader.timestamp} method (Code 105.3)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: PreHeader} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{Long} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:PropertyCall]{\lst{PropertyCall}} \\ + \hline + \end{tabularx} @@ -72,13 +81,16 @@ \subsubsection{\lst{PreHeader.nBits} method (Code 105.4)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: PreHeader} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{Long} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:PropertyCall]{\lst{PropertyCall}} \\ + \hline + \end{tabularx} @@ -93,13 +105,16 @@ \subsubsection{\lst{PreHeader.height} method (Code 105.5)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: PreHeader} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{Int} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:PropertyCall]{\lst{PropertyCall}} \\ + \hline + \end{tabularx} @@ -114,13 +129,16 @@ \subsubsection{\lst{PreHeader.minerPk} method (Code 105.6)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: PreHeader} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{GroupElement} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:PropertyCall]{\lst{PropertyCall}} \\ + \hline + \end{tabularx} @@ -135,11 +153,14 @@ \subsubsection{\lst{PreHeader.votes} method (Code 105.7)} \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: PreHeader} & \text{// } \\ + \end{array}\) \\ \hline \bf{Result} & \lst{Coll[Byte]} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:PropertyCall]{\lst{PropertyCall}} \\ + \hline + \end{tabularx} diff --git a/docs/spec/generated/SigmaDslBuilder_methods.tex b/docs/spec/generated/SigmaDslBuilder_methods.tex index 611aeac9a6..32899f89fa 100644 --- a/docs/spec/generated/SigmaDslBuilder_methods.tex +++ b/docs/spec/generated/SigmaDslBuilder_methods.tex @@ -28,18 +28,20 @@ \subsubsection{\lst{SigmaDslBuilder.xor} method (Code 106.2)} \noindent \begin{tabularx}{\textwidth}{| l | X |} \hline - \bf{Description} & \\ + \bf{Description} & Byte-wise XOR of two collections of bytes \\ \hline \bf{Parameters} & \(\begin{array}{l l l} - \lst{arg0} & \lst{: SigmaDslBuilder} & \text{// } \\ -\lst{arg1} & \lst{: Coll[Byte]} & \text{// } \\ -\lst{arg2} & \lst{: Coll[Byte]} & \text{// } \\ + \lst{left} & \lst{: Coll[Byte]} & \text{// left operand} \\ +\lst{right} & \lst{: Coll[Byte]} & \text{// right operand} \\ \end{array}\) \\ \hline \bf{Result} & \lst{Coll[Byte]} \\ \hline + \bf{Serialized as} & \hyperref[sec:serialization:operation:Xor]{\lst{Xor}} \\ + \hline + \end{tabularx} diff --git a/library-api/src/main/resources/special/collection/Colls.scalan b/library-api/src/main/resources/special/collection/Colls.scalan new file mode 100644 index 0000000000..84db36b278 --- /dev/null +++ b/library-api/src/main/resources/special/collection/Colls.scalan @@ -0,0 +1,80 @@ +package special.collection { + import scalan._ + + trait Colls extends Base { self: CollsModule => + import Coll._; + import CollBuilder._; + import Monoid._; + import MonoidBuilder._; + import PairColl._; + import WOption._; + @ContainerType @FunctorType @Liftable @WithMethodCallRecognizers trait Coll[A] extends Def[Coll[A]] { + implicit def eA: Elem[A]; + def builder: Ref[CollBuilder]; + def length: Ref[Int]; + def size: Ref[Int] = this.length; + def isEmpty: Ref[Boolean]; + def nonEmpty: Ref[Boolean]; + def apply(i: Ref[Int]): Ref[A]; + def isDefinedAt(idx: Ref[Int]): Ref[Boolean]; + def getOrElse(index: Ref[Int], default: Ref[A]): Ref[A]; + def map[B](f: Ref[scala.Function1[A, B]]): Ref[Coll[B]]; + def zip[B](ys: Ref[Coll[B]]): Ref[Coll[scala.Tuple2[A, B]]]; + def exists(p: Ref[scala.Function1[A, Boolean]]): Ref[Boolean]; + def forall(p: Ref[scala.Function1[A, Boolean]]): Ref[Boolean]; + def filter(p: Ref[scala.Function1[A, Boolean]]): Ref[Coll[A]]; + def foldLeft[B](zero: Ref[B], op: Ref[scala.Function1[scala.Tuple2[B, A], B]]): Ref[B]; + def indices: Ref[Coll[Int]]; + def flatMap[B](f: Ref[scala.Function1[A, Coll[B]]]): Ref[Coll[B]]; + def segmentLength(p: Ref[scala.Function1[A, Boolean]], from: Ref[Int]): Ref[Int]; + @NeverInline def find(p: Ref[scala.Function1[A, Boolean]]): Ref[WOption[A]] = delayInvoke; + def indexWhere(p: Ref[scala.Function1[A, Boolean]], from: Ref[Int]): Ref[Int]; + @NeverInline def indexOf(elem: Ref[A], from: Ref[Int]): Ref[Int] = delayInvoke; + def lastIndexWhere(p: Ref[scala.Function1[A, Boolean]], end: Ref[Int]): Ref[Int]; + def take(n: Ref[Int]): Ref[Coll[A]]; + def partition(pred: Ref[scala.Function1[A, Boolean]]): Ref[scala.Tuple2[Coll[A], Coll[A]]]; + def patch(from: Ref[Int], patch: Ref[Coll[A]], replaced: Ref[Int]): Ref[Coll[A]]; + def updated(index: Ref[Int], elem: Ref[A]): Ref[Coll[A]]; + def updateMany(indexes: Ref[Coll[Int]], values: Ref[Coll[A]]): Ref[Coll[A]]; + def mapReduce[K, V](m: Ref[scala.Function1[A, scala.Tuple2[K, V]]], r: Ref[scala.Function1[scala.Tuple2[V, V], V]]): Ref[Coll[scala.Tuple2[K, V]]]; + @NeverInline def groupBy[K](key: Ref[scala.Function1[A, K]]): Ref[Coll[scala.Tuple2[K, Coll[A]]]] = delayInvoke; + @NeverInline def groupByProjecting[K, V](key: Ref[scala.Function1[A, K]], proj: Ref[scala.Function1[A, V]]): Ref[Coll[scala.Tuple2[K, Coll[V]]]] = delayInvoke; + def unionSet(that: Ref[Coll[A]]): Ref[Coll[A]]; + @NeverInline def diff(that: Ref[Coll[A]]): Ref[Coll[A]] = delayInvoke; + @NeverInline def intersect(that: Ref[Coll[A]]): Ref[Coll[A]] = delayInvoke; + def sum(m: Ref[Monoid[A]]): Ref[A]; + def slice(from: Ref[Int], until: Ref[Int]): Ref[Coll[A]]; + def append(other: Ref[Coll[A]]): Ref[Coll[A]]; + def reverse: Ref[Coll[A]] + }; + @WithMethodCallRecognizers trait PairColl[L, R] extends Coll[scala.Tuple2[L, R]] { + implicit def eL: Elem[L]; + implicit def eR: Elem[R]; + def ls: Ref[Coll[L]]; + def rs: Ref[Coll[R]]; + def mapFirst[T1](f: Ref[scala.Function1[L, T1]]): Ref[Coll[scala.Tuple2[T1, R]]]; + def mapSecond[T1](f: Ref[scala.Function1[R, T1]]): Ref[Coll[scala.Tuple2[L, T1]]] + }; + @Liftable @WithMethodCallRecognizers trait ReplColl[A] extends Coll[A] { + implicit def eA: Elem[A]; + def value: Ref[A]; + def length: Ref[Int]; + def append(other: Ref[Coll[A]]): Ref[Coll[A]] + }; + @Liftable @WithMethodCallRecognizers trait CollBuilder extends Def[CollBuilder] { + def Monoids: Ref[MonoidBuilder]; + def pairColl[A, B](as: Ref[Coll[A]], bs: Ref[Coll[B]]): Ref[PairColl[A, B]]; + @Reified(value = "T") def fromItems[T](items: Ref[T]*)(implicit cT: Elem[T]): Ref[Coll[T]]; + def unzip[A, B](xs: Ref[Coll[scala.Tuple2[A, B]]]): Ref[scala.Tuple2[Coll[A], Coll[B]]]; + def xor(left: Ref[Coll[Byte]], right: Ref[Coll[Byte]]): Ref[Coll[Byte]]; + def replicate[T](n: Ref[Int], v: Ref[T]): Ref[Coll[T]]; + def emptyColl[T](implicit tT: Elem[T]): Ref[Coll[T]]; + def outerJoin[K, L, R, O](left: Ref[Coll[scala.Tuple2[K, L]]], right: Ref[Coll[scala.Tuple2[K, R]]])(l: Ref[scala.Function1[scala.Tuple2[K, L], O]], r: Ref[scala.Function1[scala.Tuple2[K, R], O]], inner: Ref[scala.Function1[scala.Tuple2[K, scala.Tuple2[L, R]], O]]): Ref[Coll[scala.Tuple2[K, O]]]; + def flattenColl[A](coll: Ref[Coll[Coll[A]]]): Ref[Coll[A]] + }; + trait CollCompanion; + trait PairCollCompanion; + trait ReplCollCompanion; + trait CollBuilderCompanion + } +} \ No newline at end of file diff --git a/library-api/src/main/resources/special/collection/Costs.scalan b/library-api/src/main/resources/special/collection/Costs.scalan new file mode 100644 index 0000000000..e78dfa8f44 --- /dev/null +++ b/library-api/src/main/resources/special/collection/Costs.scalan @@ -0,0 +1,97 @@ +package special.collection { + import scalan._ + + trait Costs extends Base { self: CostsModule => + import Coll._; + import Costed._; + import CostedBuilder._; + import CostedColl._; + import CostedFunc._; + import CostedOption._; + import CostedPair._; + import CostedPrim._; + import MonoidBuilder._; + import Size._; + import SizeColl._; + import SizeFunc._; + import SizeOption._; + import SizePair._; + import SizePrim._; + import WOption._; + import WRType._; + @WithMethodCallRecognizers trait Costed[Val] extends Def[Costed[Val]] { + implicit def eVal: Elem[Val]; + def builder: Ref[CostedBuilder]; + def value: Ref[Val]; + def cost: Ref[Int]; + def size: Ref[Size[Val]] + }; + trait CostedPrim[Val] extends Costed[Val] { + implicit def eVal: Elem[Val]; + def value: Ref[Val]; + def cost: Ref[Int]; + def size: Ref[Size[Val]] + }; + trait CostedPair[L, R] extends Costed[scala.Tuple2[L, R]] { + implicit def eL: Elem[L]; + implicit def eR: Elem[R]; + def l: Ref[Costed[L]]; + def r: Ref[Costed[R]]; + def accCost: Ref[Int] + }; + trait CostedFunc[Env, Arg, Res] extends Costed[scala.Function1[Arg, Res]] { + implicit def eEnv: Elem[Env]; + implicit def eArg: Elem[Arg]; + implicit def eRes: Elem[Res]; + def envCosted: Ref[Costed[Env]]; + def func: Ref[scala.Function1[Costed[Arg], Costed[Res]]]; + def cost: Ref[Int]; + def sliceCalc: Ref[scala.Function1[Arg, Res]]; + def sliceCost: Ref[scala.Function1[scala.Tuple2[Int, Size[Arg]], Int]]; + def sliceCostEx: Ref[scala.Function1[scala.Tuple2[Arg, scala.Tuple2[Int, Size[Arg]]], Int]]; + def sliceSize: Ref[scala.Function1[Size[Arg], Size[Res]]] + }; + @WithMethodCallRecognizers trait CostedColl[Item] extends Costed[Coll[Item]] { + implicit def eItem: Elem[Item]; + def values: Ref[Coll[Item]]; + def costs: Ref[Coll[Int]]; + def sizes: Ref[Coll[Size[Item]]]; + def valuesCost: Ref[Int]; + def mapCosted[Res](f: Ref[scala.Function1[Costed[Item], Costed[Res]]]): Ref[CostedColl[Res]]; + def filterCosted(f: Ref[scala.Function1[Costed[Item], Costed[Boolean]]]): Ref[CostedColl[Item]]; + def foldCosted[B](zero: Ref[Costed[B]], op: Ref[scala.Function1[Costed[scala.Tuple2[B, Item]], Costed[B]]]): Ref[Costed[B]] + }; + trait CostedOption[T] extends Costed[WOption[T]] { + implicit def eT: Elem[T]; + def costOpt: Ref[WOption[Int]]; + def sizeOpt: Ref[WOption[Size[T]]]; + def accumulatedCost: Ref[Int] + }; + @WithMethodCallRecognizers trait CostedBuilder extends Def[CostedBuilder] { + def ConstructTupleCost: Ref[Int] = toRep(1.asInstanceOf[Int]); + def ConstructSumCost: Ref[Int] = toRep(1.asInstanceOf[Int]); + def SelectFieldCost: Ref[Int] = toRep(1.asInstanceOf[Int]); + def SumTagSize: Ref[Long] = toRep(1L.asInstanceOf[Long]); + def costedValue[T](x: Ref[T], optCost: Ref[WOption[Int]]): Ref[Costed[T]]; + def defaultValue[T](valueType: Ref[WRType[T]]): Ref[T]; + def monoidBuilder: Ref[MonoidBuilder]; + def mkSizePrim[T](dataSize: Ref[Long], tT: Ref[WRType[T]]): Ref[SizePrim[T]]; + def mkSizePair[L, R](l: Ref[Size[L]], r: Ref[Size[R]]): Ref[SizePair[L, R]]; + def mkSizeColl[T](sizes: Ref[Coll[Size[T]]]): Ref[SizeColl[T]]; + def mkSizeFunc[E, A, R](sizeEnv: Ref[Size[E]], sizeFunc: Ref[Long], tA: Ref[WRType[A]], tR: Ref[WRType[R]]): Ref[SizeFunc[E, A, R]]; + def mkSizeOption[T](sizeOpt: Ref[WOption[Size[T]]]): Ref[SizeOption[T]]; + def mkCostedPrim[T](value: Ref[T], cost: Ref[Int], size: Ref[Size[T]]): Ref[CostedPrim[T]]; + def mkCostedPair[L, R](first: Ref[Costed[L]], second: Ref[Costed[R]], accCost: Ref[Int]): Ref[CostedPair[L, R]]; + def mkCostedFunc[Env, Arg, Res](envCosted: Ref[Costed[Env]], func: Ref[scala.Function1[Costed[Arg], Costed[Res]]], cost: Ref[Int], size: Ref[Size[scala.Function1[Arg, Res]]]): Ref[CostedFunc[Env, Arg, Res]]; + def mkCostedColl[T](values: Ref[Coll[T]], costs: Ref[Coll[Int]], sizes: Ref[Coll[Size[T]]], valuesCost: Ref[Int]): Ref[CostedColl[T]]; + def mkCostedOption[T](value: Ref[WOption[T]], costOpt: Ref[WOption[Int]], sizeOpt: Ref[WOption[Size[T]]], accumulatedCost: Ref[Int]): Ref[CostedOption[T]] + }; + trait CostedCompanion; + trait CostedPrimCompanion; + trait CostedPairCompanion; + trait CostedFuncCompanion; + trait CostedCollCompanion; + trait CostedOptionCompanion; + trait CostedBuilderCompanion + } +} \ No newline at end of file diff --git a/library-api/src/main/resources/special/collection/Monoids.scalan b/library-api/src/main/resources/special/collection/Monoids.scalan new file mode 100644 index 0000000000..e265f60c9a --- /dev/null +++ b/library-api/src/main/resources/special/collection/Monoids.scalan @@ -0,0 +1,25 @@ +package special.collection { + import scalan._ + + trait Monoids extends Base { self: MonoidsModule => + import Monoid._; + import MonoidBuilder._; + trait Monoid[T] extends Def[Monoid[T]] { + implicit def eT: Elem[T]; + def zero: Ref[T]; + def plus(x: Ref[T], y: Ref[T]): Ref[T]; + def power(x: Ref[T], n: Ref[Int]): Ref[T] + }; + @WithMethodCallRecognizers trait MonoidBuilder extends Def[MonoidBuilder] { + def intPlusMonoid: Ref[Monoid[Int]]; + def intMaxMonoid: Ref[Monoid[Int]]; + def intMinMonoid: Ref[Monoid[Int]]; + def longPlusMonoid: Ref[Monoid[Long]]; + def longMaxMonoid: Ref[Monoid[Long]]; + def longMinMonoid: Ref[Monoid[Long]]; + def pairMonoid[A, B](m1: Ref[Monoid[A]], m2: Ref[Monoid[B]]): Ref[Monoid[scala.Tuple2[A, B]]] + }; + trait MonoidCompanion; + trait MonoidBuilderCompanion + } +} \ No newline at end of file diff --git a/library-api/src/main/resources/special/collection/Sizes.scalan b/library-api/src/main/resources/special/collection/Sizes.scalan new file mode 100644 index 0000000000..7e52ed77d8 --- /dev/null +++ b/library-api/src/main/resources/special/collection/Sizes.scalan @@ -0,0 +1,45 @@ +package special.collection { + import scalan._ + + trait Sizes extends Base { self: SizesModule => + import Coll._; + import Size._; + import WOption._; + import WRType._; + @Liftable @WithMethodCallRecognizers trait Size[Val] extends Def[Size[Val]] { + implicit def eVal: Elem[Val]; + def dataSize: Ref[Long] + }; + @Liftable trait SizePrim[Val] extends Size[Val] { + implicit def eVal: Elem[Val]; + def dataSize: Ref[Long]; + def tVal: Ref[WRType[Val]] + }; + @Liftable @WithMethodCallRecognizers trait SizePair[L, R] extends Size[scala.Tuple2[L, R]] { + implicit def eL: Elem[L]; + implicit def eR: Elem[R]; + def l: Ref[Size[L]]; + def r: Ref[Size[R]] + }; + @Liftable @WithMethodCallRecognizers trait SizeColl[Item] extends Size[Coll[Item]] { + implicit def eItem: Elem[Item]; + def sizes: Ref[Coll[Size[Item]]] + }; + @Liftable @WithMethodCallRecognizers trait SizeFunc[Env, Arg, Res] extends Size[scala.Function1[Arg, Res]] { + implicit def eEnv: Elem[Env]; + implicit def eArg: Elem[Arg]; + implicit def eRes: Elem[Res]; + def sizeEnv: Ref[Size[Env]] + }; + @Liftable @WithMethodCallRecognizers trait SizeOption[T] extends Size[WOption[T]] { + implicit def eT: Elem[T]; + def sizeOpt: Ref[WOption[Size[T]]] + }; + trait SizeCompanion; + trait SizePrimCompanion; + trait SizePairCompanion; + trait SizeCollCompanion; + trait SizeFuncCompanion; + trait SizeOptionCompanion + } +} \ No newline at end of file diff --git a/library-api/src/main/resources/special/wrappers/WrappersSpec.scalan b/library-api/src/main/resources/special/wrappers/WrappersSpec.scalan new file mode 100644 index 0000000000..faf83cbcd7 --- /dev/null +++ b/library-api/src/main/resources/special/wrappers/WrappersSpec.scalan @@ -0,0 +1,35 @@ +package special.wrappers { + import scalan._ + + trait WrappersSpec extends Base { self: WrappersSpecModule => + import WOption._; + import WRType._; + import WSpecialPredef._; + import WrapSpecBase._; + trait WrapSpecBase extends Def[WrapSpecBase] with WrapSpec; + trait OptionWrapSpec extends WrapSpecBase { + def get[A](xs: Ref[WOption[A]]): Ref[A] = xs.get; + @NeverInline def getOrElse[A](xs: Ref[WOption[A]], default: Ref[Thunk[A]]): Ref[A] = delayInvoke; + def map[A, B](xs: Ref[WOption[A]], f: Ref[scala.Function1[A, B]]): Ref[WOption[B]] = xs.map[B](f); + def flatMap[A, B](xs: Ref[WOption[A]], f: Ref[scala.Function1[A, WOption[B]]]): Ref[WOption[B]] = xs.flatMap[B](f); + def filter[A](xs: Ref[WOption[A]], f: Ref[scala.Function1[A, Boolean]]): Ref[WOption[A]] = xs.filter(f); + def isDefined[A](xs: Ref[WOption[A]]): Ref[Boolean] = xs.isDefined; + def isEmpty[A](xs: Ref[WOption[A]]): Ref[Boolean] = xs.isEmpty; + @NeverInline def fold[A, B](xs: Ref[WOption[A]], ifEmpty: Ref[Thunk[B]], f: Ref[scala.Function1[A, B]]): Ref[B] = delayInvoke + }; + trait SpecialPredefWrapSpec extends WrapSpecBase { + def loopUntil[A](s1: Ref[A], isMatch: Ref[scala.Function1[A, Boolean]], step: Ref[scala.Function1[A, A]]): Ref[A] = RWSpecialPredef.loopUntil[A](s1, isMatch, step); + def cast[A](v: Ref[Any])(implicit cA: Elem[A]): Ref[WOption[A]] = RWSpecialPredef.cast[A](v); + def some[A](x: Ref[A]): Ref[WOption[A]] = RWSpecialPredef.some[A](x); + def none[A](implicit cA: Elem[A]): Ref[WOption[A]] = RWSpecialPredef.none[A]; + def optionGetOrElse[A](opt: Ref[WOption[A]], default: Ref[A]): Ref[A] = RWSpecialPredef.optionGetOrElse[A](opt, default) + }; + trait RTypeWrapSpec extends WrapSpecBase { + def name[T](d: Ref[WRType[T]]): Ref[String] = d.name + }; + trait WrapSpecBaseCompanion; + trait OptionWrapSpecCompanion; + trait SpecialPredefWrapSpecCompanion; + trait RTypeWrapSpecCompanion + } +} \ No newline at end of file diff --git a/library-api/src/main/resources/wrappers/scala/WOptions.scalan b/library-api/src/main/resources/wrappers/scala/WOptions.scalan new file mode 100644 index 0000000000..374aa4e290 --- /dev/null +++ b/library-api/src/main/resources/wrappers/scala/WOptions.scalan @@ -0,0 +1,27 @@ +package wrappers.scala { + import scalan._ + + import impl._ + + import special.wrappers.WrappersModule + + import special.wrappers.OptionWrapSpec + + import scala.collection.mutable.WrappedArray + + trait WOptions extends Base { self: WrappersModule => + import WOption._; + @External("Option") @ContainerType @FunctorType @Liftable @WithMethodCallRecognizers trait WOption[A] extends Def[WOption[A]] { self => + implicit def eA: Elem[A]; + @External def fold[B](ifEmpty: Ref[Thunk[B]], f: Ref[scala.Function1[A, B]]): Ref[B]; + @External def isEmpty: Ref[Boolean]; + @External def isDefined: Ref[Boolean]; + @External def filter(p: Ref[scala.Function1[A, Boolean]]): Ref[WOption[A]]; + @External def flatMap[B](f: Ref[scala.Function1[A, WOption[B]]]): Ref[WOption[B]]; + @External def map[B](f: Ref[scala.Function1[A, B]]): Ref[WOption[B]]; + @External def getOrElse[B](default: Ref[Thunk[B]]): Ref[B]; + @External def get: Ref[A] + }; + trait WOptionCompanion + } +} \ No newline at end of file diff --git a/library-api/src/main/resources/wrappers/scalan/WRTypes.scalan b/library-api/src/main/resources/wrappers/scalan/WRTypes.scalan new file mode 100644 index 0000000000..6b8ef0427b --- /dev/null +++ b/library-api/src/main/resources/wrappers/scalan/WRTypes.scalan @@ -0,0 +1,22 @@ +package wrappers.scalan { + import scalan._ + + import impl._ + + import scalan.RType + + import special.wrappers.WrappersModule + + import special.wrappers.RTypeWrapSpec + + import scala.collection.mutable.WrappedArray + + trait WRTypes extends Base { self: WrappersModule => + import WRType._; + @External("RType") @Liftable @WithMethodCallRecognizers trait WRType[A] extends Def[WRType[A]] { self => + implicit def eA: Elem[A]; + @External def name: Ref[String] + }; + trait WRTypeCompanion + } +} \ No newline at end of file diff --git a/library-api/src/main/resources/wrappers/special/WSpecialPredefs.scalan b/library-api/src/main/resources/wrappers/special/WSpecialPredefs.scalan new file mode 100644 index 0000000000..0b2f0282f3 --- /dev/null +++ b/library-api/src/main/resources/wrappers/special/WSpecialPredefs.scalan @@ -0,0 +1,26 @@ +package wrappers.special { + import scalan._ + + import impl._ + + import special.wrappers.WrappersModule + + import special.wrappers.SpecialPredefWrapSpec + + import scala.collection.mutable.WrappedArray + + trait WSpecialPredefs extends Base { self: WrappersModule => + import WOption._; + import WSpecialPredef._; + @External("SpecialPredef") @WithMethodCallRecognizers trait WSpecialPredef extends Def[WSpecialPredef] { self => + + }; + trait WSpecialPredefCompanion { + @External def optionGetOrElse[A](opt: Ref[WOption[A]], default: Ref[A]): Ref[A]; + @External def none[@Reified A](implicit emA: Elem[A]): Ref[WOption[A]]; + @External def some[A](x: Ref[A]): Ref[WOption[A]]; + @External def cast[@Reified T](v: Ref[Any])(implicit emT: Elem[T]): Ref[WOption[T]]; + @External def loopUntil[A](s1: Ref[A], isMatch: Ref[scala.Function1[A, Boolean]], step: Ref[scala.Function1[A, A]]): Ref[A] + } + } +} \ No newline at end of file diff --git a/library-api/src/main/scala/special/SpecialPredef.scala b/library-api/src/main/scala/special/SpecialPredef.scala new file mode 100644 index 0000000000..9c0bbdca99 --- /dev/null +++ b/library-api/src/main/scala/special/SpecialPredef.scala @@ -0,0 +1,24 @@ +package special + +import scala.reflect.ClassTag +import scalan.{Reified, RType} + +object SpecialPredef { + def loopUntil[A](s1: A, isMatch: A => Boolean, step: A => A): A = { + var res = s1 + while (!isMatch(res)) + res = step(res) + res + } + + def cast[T:ClassTag](v: Any): Option[T] = v match { case _: T => Some(v.asInstanceOf[T]) case _ => None } + + def some[A](x: A): Option[A] = Some(x) + + @Reified("A") def none[A](implicit tA: RType[A]): Option[A] = Option.empty[A] + + def optionGetOrElse[A](opt: Option[A], default: A): A = opt.getOrElse(default) + + def rewritableMethod = + sys.error(s"Shouldn't be called, instead it should be either handled in rewrite rule, or overridden in derived class.") +} diff --git a/library-api/src/main/scala/special/Types.scala b/library-api/src/main/scala/special/Types.scala new file mode 100644 index 0000000000..5dd547704b --- /dev/null +++ b/library-api/src/main/scala/special/Types.scala @@ -0,0 +1,48 @@ +package special + +import scalan.RType +import scalan.util.CollectionUtil + +import scala.reflect.ClassTag +import scalan.RType.SomeType +import special.collection.Coll + +object Types { + + type StructData = Coll[Any] + + def structRType(names: Array[String], types: Array[SomeType]): RType[StructData] = StructType(names, types) + + case class StructType(fieldNames: Array[String], fieldTypes: Array[SomeType]) extends RType[StructData] { + val classTag: ClassTag[StructData] = scala.reflect.classTag[StructData] + override def isConstantSize: Boolean = fieldTypes.forall(_.isConstantSize) + override def hashCode(): Int = { + var h = CollectionUtil.deepHashCode(fieldNames) + h += h * 31 + CollectionUtil.deepHashCode(fieldTypes) + h + } + override def equals(obj: Any): Boolean = (this eq obj.asInstanceOf[AnyRef]) || (obj match { + case that: StructType => + java.util.Arrays.equals(fieldNames.asInstanceOf[Array[AnyRef]], that.fieldNames.asInstanceOf[Array[AnyRef]]) && + java.util.Arrays.equals(fieldTypes.asInstanceOf[Array[AnyRef]], that.fieldTypes.asInstanceOf[Array[AnyRef]]) + case _ => false + }) + } + + type TupleData = Coll[Any] + + def tupleRType(types: Array[SomeType]): RType[TupleData] = TupleType(types) + + case class TupleType(items: Array[SomeType]) extends RType[StructData] { + val classTag: ClassTag[TupleData] = scala.reflect.classTag[TupleData] + override def name: String = items.map(_.name).mkString("(", ", ", ")") + override def isConstantSize: Boolean = items.forall(_.isConstantSize) + override def hashCode(): Int = CollectionUtil.deepHashCode(items) + override def equals(obj: Any): Boolean = (this eq obj.asInstanceOf[AnyRef]) || (obj match { + case that: TupleType => java.util.Arrays.equals(items.asInstanceOf[Array[AnyRef]], that.items.asInstanceOf[Array[AnyRef]]) + case _ => false + }) + } + +} + diff --git a/library-api/src/main/scala/special/collection/Colls.scala b/library-api/src/main/scala/special/collection/Colls.scala new file mode 100644 index 0000000000..231e3fba71 --- /dev/null +++ b/library-api/src/main/scala/special/collection/Colls.scala @@ -0,0 +1,504 @@ +package special.collection + +import scala.reflect.ClassTag +import scalan._ + +import scala.collection.immutable + +/** Indexed (zero-based) collection of elements of type `A` + * @define Coll `Coll` + * @define coll collection + * @define colls collections + * @tparam A the collection element type + */ +@ContainerType +@FunctorType +@scalan.Liftable +@WithMethodCallRecognizers +trait Coll[@specialized A] { + def builder: CollBuilder + @Internal + def toArray: Array[A] + + /** The length of the collection. */ + def length: Int + + /** The size of the collection in elements. */ + def size: Int = this.length + + /** Tests whether the $coll is empty. + * @return `true` if the $coll contains no elements, `false` otherwise. + */ + def isEmpty: Boolean + + /** Tests whether the $coll is not empty. + * @return `true` if the $coll contains at least one element, `false` otherwise. + */ + def nonEmpty: Boolean + + /** Returns true if the index in the valid range. + * @param i index of an element of this collection */ + @Internal + final def isValidIndex(i: Int): Boolean = 0 <= i && i < this.length + + /** The element at given index. + * Indices start at `0`; `xs.apply(0)` is the first element of collection `xs`. + * Note the indexing syntax `xs(i)` is a shorthand for `xs.apply(i)`. + * + * @param i the index + * @return the element at the given index + * @throws ArrayIndexOutOfBoundsException if `i < 0` or `length <= i` + */ + def apply(i: Int): A + + /** Tests whether this $coll contains given index. + * + * The implementations of methods `apply` and `isDefinedAt` turn a `Coll[A]` into + * a `PartialFunction[Int, A]`. + * + * @param idx the index to test + * @return `true` if this $coll contains an element at position `idx`, `false` otherwise. + */ + def isDefinedAt(idx: Int): Boolean + + /** The elements at given indexes. + * Indices start at `0` so that `xs.apply(0)` is the first element of collection `xs`. + * Note the indexing syntax `xs(i)` is a shorthand for `xs.apply(i)`. + * + * @param indexes the indexes of the elements to extract from this collection + * @return the elements at the given indexes + * @throws ArrayIndexOutOfBoundsException if `i < 0` or `length <= i` + * for any `i` in `indexes` + */ +// def applyMany(indexes: Coll[Int]): Coll[A] + + /** The element of the collection or default value. + * If an index is out of bounds (`i < 0 || i >= length`) then `default` value is returned. + * @param i the index + * @return the element at the given index or default value if index is out or bounds + * @since 2.0 + */ + def getOrElse(index: Int, default: A): A + + /** Builds a new collection by applying a function to all elements of this collection. + * + * @param f the function to apply to each element. + * @tparam B the element type of the returned collection. + * @return a new collection of type `Coll[B]` resulting from applying the given function + * `f` to each element of this collection and collecting the results. + */ + def map[@specialized B: RType](f: A => B): Coll[B] + + /** For this collection (x0, ..., xN) and other collection (y0, ..., yM) + * produces a collection ((x0, y0), ..., (xK, yK)) where K = min(N, M) */ + def zip[@specialized B](ys: Coll[B]): Coll[(A, B)] + + /** Tests whether a predicate holds for at least one element of this collection. + * @param p the predicate used to test elements. + * @return `true` if the given predicate `p` is satisfied by at least one element of this collection, otherwise `false` + */ + def exists(p: A => Boolean): Boolean + + /** Tests whether a predicate holds for all elements of this collection. + * @param p the predicate used to test elements. + * @return `true` if this collection is empty or the given predicate `p` + * holds for all elements of this collection, otherwise `false`. + */ + def forall(p: A => Boolean): Boolean + + /** Selects all elements of this collection which satisfy a predicate. + * @param p the predicate used to test elements. + * @return a new collection consisting of all elements of this collection that satisfy the given + * predicate `p`. The order of the elements is preserved. + * @since 2.0 + */ + def filter(p: A => Boolean): Coll[A] + + /** Applies a binary operator to a start value and all elements of this collection, + * going left to right. + * + * @param z the start value. + * @param op the binary operator. + * @tparam B the result type of the binary operator. + * @return the result of inserting `op` between consecutive elements of this collection, + * going left to right with the start value `z` on the left: + * {{{ + * op(...op(z, x_1), x_2, ..., x_n) + * }}} + * where `x,,1,,, ..., x,,n,,` are the elements of this collection. + * Returns `z` if this collection is empty. + */ + def foldLeft[B](zero: B, op: ((B, A)) => B): B + + /** Produces the range of all indices of this collection as a new collection + * containing [0 .. length-1] values. + * @since 2.0 + */ + def indices: Coll[Int] + + /** + * Builds a new collection by applying a function to all elements of this $coll + * and using the elements of the resulting collections. + * + * Function `f` is constrained to be of the form `x => x.someProperty`, otherwise + * it is illegal. + * + * @param f the function to apply to each element. + * @tparam B the element type of the returned collection. + * @return a new collection of type `Coll[B]` resulting from applying the given collection-valued function + * `f` to each element of this $coll and concatenating the results. + * @since 2.0 + */ + def flatMap[B: RType](f: A => Coll[B]): Coll[B] + + /** Computes length of longest segment whose elements all satisfy some predicate. + * + * @param p the predicate used to test elements. + * @param from the index where the search starts. + * @return the length of the longest segment of this $coll starting from index `from` + * such that every element of the segment satisfies the predicate `p`. + * @since 2.0 + */ + def segmentLength(p: A => Boolean, from: Int): Int + + /** Finds the first element of the $coll satisfying a predicate, if any. + * + * @param p the predicate used to test elements. + * @return an option value containing the first element in the $coll + * that satisfies `p`, or `None` if none exists. + * @since 2.0 + */ + @NeverInline + def find(p: A => Boolean): Option[A] = { + val i = segmentLength(!p(_), 0) + if (i < length) Some(this(i)) else None + } + + /** Finds index of the first element satisfying some predicate after or at some start index. + * + * @param p the predicate used to test elements. + * @param from the start index + * @return the index `>= from` of the first element of this $coll that satisfies the predicate `p`, + * or `-1`, if none exists. + * @since 2.0 + */ + def indexWhere(p: A => Boolean, from: Int): Int + + /** Finds index of first occurrence of some value in this $coll after or at some start index. + * + * @param elem the element value to search for. + * @param from the start index + * @return the index `>= from` of the first element of this $coll that is equal (as determined by `==`) + * to `elem`, or `-1`, if none exists. + * @since 2.0 + */ + @NeverInline + def indexOf(elem: A, from: Int): Int = this.indexWhere(x => elem == x, from) + + /** Finds index of last element satisfying some predicate before or at given end index. + * + * @param p the predicate used to test elements. + * @return the index `<= end` of the last element of this $coll that satisfies the predicate `p`, + * or `-1`, if none exists. + * @since 2.0 + */ + def lastIndexWhere(p: A => Boolean, end: Int): Int + + /** Selects first ''n'' elements. + * @param n the number of elements to take from this $coll. + * @return a $coll consisting only of the first `n` elements of this $coll, + * or else the whole $coll, if it has less than `n` elements. + * If `n` is negative, returns an empty $coll. + */ + def take(n: Int): Coll[A] + + /** Partitions this $coll in two $colls according to a predicate. + * + * @param pred the predicate on which to partition. + * @return a pair of $colls: the first $coll consists of all elements that + * satisfy the predicate `p` and the second $coll consists of all elements + * that don't. The relative order of the elements in the resulting ${coll}s + * will BE preserved (this is different from Scala's version of this method). + * @since 2.0 + */ + def partition(pred: A => Boolean): (Coll[A], Coll[A]) + + /** Produces a new $coll where a slice of elements in this $coll is replaced by another sequence. + * + * @param from the index of the first replaced element + * @param patch the replacement sequence + * @param replaced the number of elements to drop in the original $coll + * @return a new $coll consisting of all elements of this $coll + * except that `replaced` elements starting from `from` are replaced by `patch`. + * @since 2.0 + */ + def patch(from: Int, patch: Coll[A], replaced: Int): Coll[A] + + /** A copy of this $coll with one single replaced element. + * @param index the position of the replacement + * @param elem the replacing element + * @return a new $coll which is a copy of this $coll with the element at position `index` replaced by `elem`. + * @throws IndexOutOfBoundsException if `index` does not satisfy `0 <= index < length`. + * @since 2.0 + */ + def updated(index: Int, elem: A): Coll[A] + + /** Returns a copy of this collection where elements at `indexes` are replaced with `values`. + * @since 2.0 + */ + def updateMany(indexes: Coll[Int], values: Coll[A]): Coll[A] + + /** Apply m for each element of this collection, group by key and reduce each group using r. + * @returns one item for each group in a new collection of (K,V) pairs. + * @since 2.0 + */ + def mapReduce[K: RType, V: RType](m: A => (K,V), r: ((V,V)) => V): Coll[(K,V)] + + /** Partitions this $coll into a map of ${coll}s according to some discriminator function. + * + * @param key the discriminator function. + * @tparam K the type of keys returned by the discriminator function. + * @return A map from keys to ${coll}s such that the following invariant holds: + * {{{ + * (xs groupBy key)(k) = xs filter (x => key(x) == k) + * }}} + * That is, every key `k` is bound to a $coll of those elements `x` + * for which `key(x)` equals `k`. + * @since 2.0 + */ + @NeverInline + def groupBy[K: RType](key: A => K): Coll[(K, Coll[A])] = { + val res = toArray.groupBy(key).mapValues(builder.fromArray(_)) + builder.fromMap(res) + } + + /** Partitions this $coll into a map of ${coll}s according to some discriminator function. + * Additionally projecting each element to a new value. + * + * @param key the discriminator function. + * @param proj projection function to produce new value for each element of this $coll + * @tparam K the type of keys returned by the discriminator function. + * @tparam V the type of values returned by the projection function. + * @return A map from keys to ${coll}s such that the following invariant holds: + * {{{ + * (xs groupByProjecting (key, proj))(k) = xs filter (x => key(x) == k).map(proj) + * }}} + * That is, every key `k` is bound to projections of those elements `x` + * for which `key(x)` equals `k`. + * @since 2.0 + */ + @NeverInline + def groupByProjecting[K: RType, V: RType](key: A => K, proj: A => V): Coll[(K, Coll[V])] = { + implicit val ctV: ClassTag[V] = RType[V].classTag + val res = toArray.groupBy(key).mapValues(arr => builder.fromArray(arr.map(proj))) + builder.fromMap(res) + } + + /** Produces a new collection which contains all distinct elements of this $coll and also all elements of + * a given collection that are not in this collection. + * This is order preserving operation considering only first occurrences of each distinct elements. + * Any collection `xs` can be transformed to a sequence with distinct elements by using xs.unionSet(Col()). + * + * NOTE: Use append if you don't need set semantics. + * + * @param that the collection to add. + * @since 2.0 + */ + def unionSet(that: Coll[A]): Coll[A] + + /** Computes the multiset difference between this $coll and another sequence. + * + * @param that the sequence of elements to remove + * @tparam B the element type of the returned $coll. + * @return a new collection which contains all elements of this $coll + * except some of occurrences of elements that also appear in `that`. + * If an element value `x` appears + * ''n'' times in `that`, then the first ''n'' occurrences of `x` will not form + * part of the result, but any following occurrences will. + * @since 2.0 + */ + @NeverInline + def diff(that: Coll[A]): Coll[A] = { + val res = toArray.diff(that.toArray) + builder.fromArray(res) + } + + /** Computes the multiset intersection between this $coll and another sequence. + * + * @param that the sequence of elements to intersect with. + * @return a new collection which contains all elements of this $coll + * which also appear in `that`. + * If an element value `x` appears + * ''n'' times in `that`, then the first ''n'' occurrences of `x` will be retained + * in the result, but any following occurrences will be omitted. + * @since 2.0 + */ + @NeverInline + def intersect(that: Coll[A]): Coll[A] = { + val res = toArray.intersect(that.toArray) + builder.fromArray(res) + } + + /** Folding through all elements of this $coll starting from m.zero and applying m.plus to accumulate + * resulting value. + * + * @param m monoid object to use for summation + * @return result of the following operations (m.zero `m.plus` x1 `m.plus` x2 `m.plus` ... xN) + * @since 2.0 + */ + def sum(m: Monoid[A]): A + + /** Selects an interval of elements. The returned collection is made up + * of all elements `x` which satisfy the invariant: + * {{{ + * from <= indexOf(x) < until + * }}} + * @param from the lowest index to include from this $coll. + * @param until the lowest index to EXCLUDE from this $coll. + */ + def slice(from: Int, until: Int): Coll[A] + + /** Puts the elements of other collection after the elements of this collection (concatenation of 2 collections) */ + def append(other: Coll[A]): Coll[A] + + /** Returns new $coll with elements in reversed order. + * + * @return A new $coll with all elements of this $coll in reversed order. + */ + def reverse: Coll[A] + + @Internal + private[collection] def isReplArray(len: Int, value: A): Boolean + + @Internal + private def trim[T](arr: Array[T]) = arr.take(arr.length min 100) + @Internal + override def toString = s"Coll(${trim(toArray).mkString(",")})" + + @Internal + implicit def tItem: RType[A] + + @Internal + def toMap[T, U](implicit ev: A <:< (T, U)): immutable.Map[T, U] = { + var b = immutable.Map.empty[T,U] + var i = 0 + val len = length + while (i < len) { + val kv = this(i) + if (b.contains(kv._1)) + throw new IllegalArgumentException(s"Cannot transform collection $this to Map: duplicate key in entry $kv") + b = b + kv + i += 1 + } + b + } + + @Internal + def distinctByKey[T, U](implicit ev: A <:< (T, U)): Coll[A] = { + unionSetByKey(builder.emptyColl[A](tItem)) + } + + + @Internal + def unionSetByKey[T, U](that: Coll[A])(implicit ev: A <:< (T, U)): Coll[A] = { + import scalan.util.CollectionUtil._ + // TODO optimize representation-wise + val res = append(that).toArray.toIterable.distinctBy(_._1) + builder.fromArray(res.toArray(tItem.classTag)) + } +} + +@WithMethodCallRecognizers +trait PairColl[@specialized L, @specialized R] extends Coll[(L,R)] { + def ls: Coll[L] + def rs: Coll[R] + def mapFirst[T1: RType](f: L => T1): Coll[(T1, R)] + def mapSecond[T1: RType](f: R => T1): Coll[(L, T1)] +} + +@Liftable +@WithMethodCallRecognizers +trait ReplColl[@specialized A] extends Coll[A] { + def value: A + def length: Int + def append(other: Coll[A]): Coll[A] +} + +@scalan.Liftable +@WithMethodCallRecognizers +trait CollBuilder { + def Monoids: MonoidBuilder + def pairColl[@specialized A, @specialized B](as: Coll[A], bs: Coll[B]): PairColl[A,B] + + @Internal + def pairCollFromArrays[A: RType, B: RType](as: Array[A], bs: Array[B]): PairColl[A,B] = + pairColl(fromArray(as), fromArray(bs)) + + /** Construct a collection of (K,V) pairs using PairColl representation, + * in which keys and values are stored as separate unboxed arrays. */ + @Internal + def fromMap[K: RType, V: RType](m: Map[K,V]): Coll[(K,V)] + + /** Construct a new collection from the given list of arguments. + * The arguments should be of the same type for which there should be + * an implicit type descriptor at the call site. */ + @Reified("T") def fromItems[T](items: T*)(implicit cT: RType[T]): Coll[T] + + /** Deconstruct collection of (A,B) pairs into pair of collections. + * If `xs` is represented as PairColl, then this is O(1) operation (no data is touched). */ + def unzip[@specialized A, @specialized B](xs: Coll[(A,B)]): (Coll[A], Coll[B]) + + /** Element-wise xor of two collections. */ + def xor(left: Coll[Byte], right: Coll[Byte]): Coll[Byte] + + /** Wrap array into collection. */ + @Internal + def fromArray[@specialized T: RType](arr: Array[T]): Coll[T] + + /** Creates a new collection by replicating value `v`. + * @param n how many times to replicate value `v` + * @param v value to replicate + * @return collection of the form (v, v, v, ... v) of n elements.*/ + def replicate[@specialized T: RType](n: Int, v: T): Coll[T] + + /** Create a new collection in which every item is executed lazily + * form the corresponding item of the `source` collection. + * @param source collection which is used as the source of items + * @param f function to compute each item of this collection from the source item + * This is O(1) operation, all executions of `f` are delayed until the corresponding + * item of this collection is needed in some operation. + */ + @Internal + def makeView[@specialized A, @specialized B: RType](source: Coll[A], f: A => B): Coll[B] + + @Internal + def makePartialView[@specialized A, @specialized B: RType](source: Coll[A], f: A => B, calculated: Array[Boolean], calculatedItems: Array[B]): Coll[B] + + /** Create an empty collection with items of the given type. + * Even though there are no items, the type of them is specified. */ + def emptyColl[T](implicit tT: RType[T]): Coll[T] + + /** Performs outer join operation between left and right collections. + * This is a restricted version of relational join operation. + * It expects `left` and `right` collections have distinct K values in pairs (otherwise exception is thrown). + * Under this condition resulting collection has size <= left.size + right.size. + * @param l projection function executed for each element of `left` + * @param r projection function executed for each element of `right` + * @param inner projection function which is executed for matching items (K, L) and (K, R) with the same K + * @return collection of (K, O) pairs, where each key comes form either left or right collection and values are produced by projections + * @since 2.0 + */ + def outerJoin[K: RType, L, R, O: RType] + (left: Coll[(K, L)], right: Coll[(K, R)]) + (l: ((K,L)) => O, r: ((K,R)) => O, inner: ((K,(L,R))) => O): Coll[(K,O)] + + /** Flattens a two-dimensional array by concatenating all its rows + * into a single array. + * + * @tparam U Type of row elements. + * @param asTrav A function that converts elements of this array to rows - arrays of type `U`. + * @return An array obtained by concatenating rows of this array. + */ + def flattenColl[A:RType](coll: Coll[Coll[A]]): Coll[A] +} + diff --git a/library-api/src/main/scala/special/collection/Costs.scala b/library-api/src/main/scala/special/collection/Costs.scala new file mode 100644 index 0000000000..60c0cbf974 --- /dev/null +++ b/library-api/src/main/scala/special/collection/Costs.scala @@ -0,0 +1,76 @@ +package special.collection + +import scalan._ + +@WithMethodCallRecognizers +trait Costed[Val] { + def builder: CostedBuilder + def value: Val + def cost: Int + def size: Size[Val] +} + +trait CostedPrim[Val] extends Costed[Val] { + def value: Val + def cost: Int + def size: Size[Val] +} + +trait CostedPair[L,R] extends Costed[(L,R)] { + def l: Costed[L] + def r: Costed[R] + def accCost: Int +} + +trait CostedFunc[Env,Arg,Res] extends Costed[Arg => Res] { + def envCosted: Costed[Env] + def func: Costed[Arg] => Costed[Res] + def cost: Int + def sliceCalc: Arg => Res + def sliceCost: ((Int,Size[Arg])) => Int + def sliceCostEx: ((Arg, (Int,Size[Arg]))) => Int + def sliceSize: Size[Arg] => Size[Res] +} + +@WithMethodCallRecognizers +trait CostedColl[Item] extends Costed[Coll[Item]] { + def values: Coll[Item] + def costs: Coll[Int] + def sizes: Coll[Size[Item]] + def valuesCost: Int + def mapCosted[Res](f: Costed[Item] => Costed[Res]): CostedColl[Res] + def filterCosted(f: Costed[Item] => Costed[Boolean]): CostedColl[Item] + def foldCosted[B](zero: Costed[B], op: Costed[(B, Item)] => Costed[B]): Costed[B] +} + +/** NOTE: Option is a special case of Either, such that Option[T] is isomorphic to Either[Unit, T]. + * Keeping this in mind, we however define constructions for Option separately. */ +trait CostedOption[T] extends Costed[Option[T]] { + def costOpt: Option[Int] + def sizeOpt: Option[Size[T]] + def accumulatedCost: Int +} + +@WithMethodCallRecognizers +trait CostedBuilder { + def ConstructTupleCost: Int = 1 + def ConstructSumCost: Int = 1 + def SelectFieldCost: Int = 1 + def SumTagSize: Long = 1 + def costedValue[T](x: T, optCost: Option[Int])(implicit cT: RType[T]): Costed[T] + def defaultValue[T](valueType: RType[T]): T + def monoidBuilder: MonoidBuilder + def mkSizePrim[T](dataSize: Long, tT: RType[T]): SizePrim[T] + def mkSizePair[L,R](l: Size[L], r: Size[R]): SizePair[L,R] + def mkSizeColl[T](sizes: Coll[Size[T]]): SizeColl[T] + def mkSizeFunc[E,A,R](sizeEnv: Size[E], sizeFunc: Long, tA: RType[A], tR: RType[R]): SizeFunc[E,A,R] + def mkSizeOption[T](sizeOpt: Option[Size[T]]): SizeOption[T] + + def mkCostedPrim[T](value: T, cost: Int, size: Size[T]): CostedPrim[T] + def mkCostedPair[L,R](first: Costed[L], second: Costed[R], accCost: Int): CostedPair[L,R] + def mkCostedFunc[Env,Arg,Res](envCosted: Costed[Env], func: Costed[Arg] => Costed[Res], cost: Int, size: Size[Arg=>Res]): CostedFunc[Env, Arg, Res] + def mkCostedColl[T](values: Coll[T], costs: Coll[Int], sizes: Coll[Size[T]], valuesCost: Int): CostedColl[T] + def mkCostedOption[T](value: Option[T], costOpt: Option[Int], sizeOpt: Option[Size[T]], accumulatedCost: Int): CostedOption[T] +} + + diff --git a/library-api/src/main/scala/special/collection/Monoids.scala b/library-api/src/main/scala/special/collection/Monoids.scala new file mode 100644 index 0000000000..3e21bc25a9 --- /dev/null +++ b/library-api/src/main/scala/special/collection/Monoids.scala @@ -0,0 +1,29 @@ +package special.collection + +import scalan.{WithMethodCallRecognizers, Internal} + +trait Monoid[@specialized(Int, Long) T] { + def zero: T + def plus(x: T, y: T): T + def power(x: T, n: Int): T +} + +@WithMethodCallRecognizers +trait MonoidBuilder { + def intPlusMonoid: Monoid[Int] + @Internal + def intMaxMonoid: Monoid[Int] + @Internal + def intMinMonoid: Monoid[Int] + + def longPlusMonoid: Monoid[Long] + @Internal + def longMaxMonoid: Monoid[Long] + @Internal + def longMinMonoid: Monoid[Long] + + @Internal + def pairMonoid[@specialized(Int, Long) A, @specialized(Int, Long) B](m1: Monoid[A], m2: Monoid[B]): Monoid[(A,B)] +} + + diff --git a/library-api/src/main/scala/special/collection/Sizes.scala b/library-api/src/main/scala/special/collection/Sizes.scala new file mode 100644 index 0000000000..79f5b477d4 --- /dev/null +++ b/library-api/src/main/scala/special/collection/Sizes.scala @@ -0,0 +1,41 @@ +package special.collection + +import scalan.{RType, WithMethodCallRecognizers} + +@scalan.Liftable +@WithMethodCallRecognizers +trait Size[Val] { + def dataSize: Long +} + +@scalan.Liftable +trait SizePrim[Val] extends Size[Val] { + def dataSize: Long + def tVal: RType[Val] +} + +@scalan.Liftable +@WithMethodCallRecognizers +trait SizePair[L,R] extends Size[(L,R)] { + def l: Size[L] + def r: Size[R] +} + +@scalan.Liftable +@WithMethodCallRecognizers +trait SizeColl[Item] extends Size[Coll[Item]] { + def sizes: Coll[Size[Item]] +} + +@scalan.Liftable +@WithMethodCallRecognizers +trait SizeFunc[Env, Arg, Res] extends Size[Arg => Res] { + def sizeEnv: Size[Env] +} + +@scalan.Liftable +@WithMethodCallRecognizers +trait SizeOption[T] extends Size[Option[T]] { + def sizeOpt: Option[Size[T]] +} + diff --git a/library-api/src/main/scala/special/collection/package.scala b/library-api/src/main/scala/special/collection/package.scala new file mode 100644 index 0000000000..e0d13337a0 --- /dev/null +++ b/library-api/src/main/scala/special/collection/package.scala @@ -0,0 +1,76 @@ +package special + +import scalan.RType +import scala.reflect.{ClassTag, classTag} + +package collection { + case class CollType[A](tItem: RType[A]) extends RType[Coll[A]] { + val classTag: ClassTag[Coll[A]] = ClassTag[Coll[A]](classOf[Coll[A]]) + override def name: String = s"Coll[${tItem.name}]" + override def isConstantSize: Boolean = false + } + case class ReplCollType[A](tItem: RType[A]) extends RType[ReplColl[A]] { + val classTag: ClassTag[ReplColl[A]] = ClassTag[ReplColl[A]](classOf[ReplColl[A]]) + override def name: String = s"ReplColl[${tItem.name}]" + override def isConstantSize: Boolean = false + } + + case class SizeType[A](tVal: RType[A]) extends RType[Size[A]] { + val classTag: ClassTag[Size[A]] = ClassTag[Size[A]](classOf[Size[A]]) + override def name: String = s"Size[${tVal.name}]" + override def isConstantSize: Boolean = tVal.isConstantSize + } + case class SizePrimType[A](tVal: RType[A]) extends RType[SizePrim[A]] { + val classTag: ClassTag[SizePrim[A]] = ClassTag[SizePrim[A]](classOf[SizePrim[A]]) + override def name: String = s"SizePrim[${tVal.name}]" + override def isConstantSize: Boolean = tVal.isConstantSize + } + case class SizePairType[A,B](tFst: RType[A], tSnd: RType[B]) extends RType[SizePair[A, B]] { + val classTag: ClassTag[SizePair[A, B]] = ClassTag[SizePair[A, B]](classOf[SizePair[A, B]]) + override def name: String = s"SizePair[${tFst.name},${tSnd.name}]" + override def isConstantSize: Boolean = tFst.isConstantSize && tSnd.isConstantSize + } + case class SizeCollType[A](tItem: RType[A]) extends RType[SizeColl[A]] { + val classTag: ClassTag[SizeColl[A]] = ClassTag[SizeColl[A]](classOf[SizeColl[A]]) + override def name: String = s"SizeColl[${tItem.name}]" + override def isConstantSize: Boolean = tItem.isConstantSize + } + case class SizeFuncType[E,A,B](tEnv: RType[E], tDom: RType[A], tRange: RType[B]) extends RType[SizeFunc[E, A, B]] { + val classTag: ClassTag[SizeFunc[E, A, B]] = ClassTag[SizeFunc[E, A, B]](classOf[SizeFunc[E, A, B]]) + override def name: String = s"SizeFunc[${tEnv.name},${tDom.name},${tRange.name}]" + override def isConstantSize: Boolean = false + } + case class SizeOptionType[A](tItem: RType[A]) extends RType[SizeOption[A]] { + val classTag: ClassTag[SizeOption[A]] = ClassTag[SizeOption[A]](classOf[SizeOption[A]]) + override def name: String = s"SizeOption[${tItem.name}]" + override def isConstantSize: Boolean = tItem.isConstantSize + } +} + +package object collection { + implicit def collRType[A](implicit tA: RType[A]): RType[Coll[A]] = CollType[A](tA) + implicit def extendCollType[A](ct: RType[Coll[A]]): CollType[A] = ct.asInstanceOf[CollType[A]] + + implicit def replCollRType[A](implicit tA: RType[A]): RType[ReplColl[A]] = ReplCollType[A](tA) + + implicit val collBuilderRType: RType[CollBuilder] = RType.fromClassTag(classTag[CollBuilder]) + + implicit def sizeRType[A](implicit tA: RType[A]): RType[Size[A]] = SizeType[A](tA) + implicit def extendSizeType[A](ct: RType[Size[A]]): SizeType[A] = ct.asInstanceOf[SizeType[A]] + + implicit def sizePrimRType[A](implicit tA: RType[A]): RType[SizePrim[A]] = SizePrimType[A](tA) + implicit def extendSizePrimType[A](ct: RType[SizePrim[A]]): SizePrimType[A] = ct.asInstanceOf[SizePrimType[A]] + + implicit def sizePairRType[A, B](implicit tA: RType[A], tB: RType[B]): RType[SizePair[A, B]] = SizePairType[A, B](tA, tB) + implicit def extendSizePairType[A, B](ct: RType[SizePair[A,B]]): SizePairType[A, B] = ct.asInstanceOf[SizePairType[A, B]] + + implicit def sizeCollRType[A](implicit tA: RType[A]): RType[SizeColl[A]] = SizeCollType[A](tA) + implicit def extendSizeCollType[A](ct: RType[SizeColl[A]]): SizeCollType[A] = ct.asInstanceOf[SizeCollType[A]] + + implicit def sizeFuncType[E, A, B](implicit tE: RType[E], tA: RType[A], tB: RType[B]): RType[SizeFunc[E, A, B]] = SizeFuncType[E, A, B](tE, tA, tB) + implicit def extendSizeFuncType[E, A, B](ct: RType[SizeFunc[E,A,B]]): SizeFuncType[E, A, B] = ct.asInstanceOf[SizeFuncType[E, A, B]] + + implicit def sizeOptionRType[A](implicit tA: RType[A]): RType[SizeOption[A]] = SizeOptionType[A](tA) + implicit def extendSizeOptionType[A](ct: RType[SizeOption[A]]): SizeOptionType[A] = ct.asInstanceOf[SizeOptionType[A]] + +} diff --git a/library-api/src/main/scala/special/wrappers/WrappersSpec.scala b/library-api/src/main/scala/special/wrappers/WrappersSpec.scala new file mode 100644 index 0000000000..87f63d1429 --- /dev/null +++ b/library-api/src/main/scala/special/wrappers/WrappersSpec.scala @@ -0,0 +1,34 @@ +package special.wrappers + +import scala.reflect.ClassTag +import special.SpecialPredef +import scalan.{NeverInline, RType, WrapSpec} + +trait WrapSpecBase extends WrapSpec { +} + +/** Wrappers spec for Option */ +trait OptionWrapSpec extends WrapSpecBase { + def get[A](xs: Option[A]): A = xs.get + @NeverInline // TODO codegen: convertion to Thunk is required + def getOrElse[A](xs: Option[A], default: => A): A = xs.getOrElse(default) + def map[A,B](xs: Option[A], f: A => B): Option[B] = xs.map(f) + def flatMap[A,B](xs: Option[A], f: A => Option[B]): Option[B] = xs.flatMap(f) + def filter[A](xs: Option[A], f: A => Boolean): Option[A] = xs.filter(f) + def isDefined[A](xs: Option[A]): Boolean = xs.isDefined + def isEmpty[A](xs: Option[A]): Boolean = xs.isEmpty + @NeverInline // TODO codegen: fold should have single section, and convertion to Thunk is required + def fold[A,B](xs: Option[A], ifEmpty: =>B, f: A => B): B = xs.fold(ifEmpty)(f) +}; + +trait SpecialPredefWrapSpec extends WrapSpecBase { + def loopUntil[A](s1: A, isMatch: A => Boolean, step: A => A): A = SpecialPredef.loopUntil(s1, isMatch, step) + def cast[A](v: Any)(implicit cA: ClassTag[A]): Option[A] = SpecialPredef.cast[A](v) + def some[A](x: A): Option[A] = SpecialPredef.some(x) + def none[A](implicit cA: RType[A]): Option[A] = SpecialPredef.none[A] + def optionGetOrElse[A](opt: Option[A], default: A): A = SpecialPredef.optionGetOrElse(opt, default) +} + +trait RTypeWrapSpec extends WrapSpecBase { + def name[T](d: RType[T]): String = d.name +} diff --git a/library-api/src/test/scala/special/TypesTests.scala b/library-api/src/test/scala/special/TypesTests.scala new file mode 100644 index 0000000000..aaa9e35847 --- /dev/null +++ b/library-api/src/test/scala/special/TypesTests.scala @@ -0,0 +1,38 @@ +package special + +import scalan.{BaseTests, RType} +import RType._ +import Types._ + +class TypesTests extends BaseTests { + + test("RType has name") { + def test[A](t: RType[A], n: String) = { + t.name shouldBe n + } + test(tupleRType(Array(IntType, LongType, RType[(String, Double)], RType[Option[Boolean]])), + "(Int, Long, (String, Double), Option[Boolean])") + } + + test("RType implements equality") { + def test[A: RType, B: RType] = { + val x = RType[A]; val y = RType[B] + assert(x == y) + } + + def tuple = tupleRType(Array(RType[Int], RType[Long])) + assert(tuple == tuple, "compare two different but equal instances") + + def tuple2 = tupleRType(Array(RType[Long], RType[Int])) + assert(tuple != tuple2, "compare two different types") + + def struct = structRType(Array("x", "y"), Array(RType[Int], RType[Long])) + assert(struct == struct, "compare two different but equal instances") + + def struct2 = structRType(Array("x", "y2"), Array(RType[Int], RType[Long])) + assert(struct != struct2, "changed single field name") + + def struct3 = structRType(Array("x", "y"), Array(RType[Int], RType[Int])) + assert(struct != struct3, "changed single field type") + } +} diff --git a/library-impl/src/main/resources/special/collection/ConcreteCosts.scalan b/library-impl/src/main/resources/special/collection/ConcreteCosts.scalan new file mode 100644 index 0000000000..ab2a45cec2 --- /dev/null +++ b/library-impl/src/main/resources/special/collection/ConcreteCosts.scalan @@ -0,0 +1,82 @@ +package special.collection { + import scalan._ + + trait ConcreteCosts extends Base { self: ConcreteCostsModule => + import CCostedBuilder._; + import CCostedColl._; + import CCostedFunc._; + import CCostedOption._; + import CCostedPair._; + import CCostedPrim._; + import CSizeColl._; + import CSizeFunc._; + import CSizeOption._; + import CSizePair._; + import CSizePrim._; + import Coll._; + import Costed._; + import CostedBuilder._; + import CostedColl._; + import CostedFunc._; + import CostedOption._; + import CostedPair._; + import CostedPrim._; + import MonoidBuilder._; + import MonoidBuilderInst._; + import Size._; + import SizeColl._; + import SizeFunc._; + import SizeOption._; + import SizePair._; + import SizePrim._; + import WOption._; + import WRType._; + import WSpecialPredef._; + abstract class CCostedPrim[Val](val value: Ref[Val], val cost: Ref[Int], val size: Ref[Size[Val]]) extends CostedPrim[Val] { + def builder: Ref[CostedBuilder] = RCCostedBuilder() + }; + abstract class CCostedPair[L, R](val l: Ref[Costed[L]], val r: Ref[Costed[R]], val accCost: Ref[Int]) extends CostedPair[L, R] { + def builder: Ref[CostedBuilder] = RCCostedBuilder(); + def value: Ref[scala.Tuple2[L, R]] = Pair(CCostedPair.this.l.value, CCostedPair.this.r.value); + @NeverInline def cost: Ref[Int] = delayInvoke; + def size: Ref[Size[scala.Tuple2[L, R]]] = CCostedPair.this.builder.mkSizePair[L, R](CCostedPair.this.l.size, CCostedPair.this.r.size) + }; + abstract class CCostedFunc[Env, Arg, Res](val envCosted: Ref[Costed[Env]], val func: Ref[scala.Function1[Costed[Arg], Costed[Res]]], val cost: Ref[Int], val size: Ref[Size[scala.Function1[Arg, Res]]]) extends CostedFunc[Env, Arg, Res] { + def builder: Ref[CostedBuilder] = RCCostedBuilder(); + @NeverInline def value: Ref[scala.Function1[Arg, Res]] = delayInvoke; + override def sliceCalc: Ref[scala.Function1[Arg, Res]] = RWSpecialPredef.rewritableMethod; + override def sliceCost: Ref[scala.Function1[scala.Tuple2[Int, Size[Arg]], Int]] = RWSpecialPredef.rewritableMethod; + override def sliceCostEx: Ref[scala.Function1[scala.Tuple2[Arg, scala.Tuple2[Int, Size[Arg]]], Int]] = RWSpecialPredef.rewritableMethod; + override def sliceSize: Ref[scala.Function1[Size[Arg], Size[Res]]] = RWSpecialPredef.rewritableMethod + }; + abstract class CCostedColl[Item](val values: Ref[Coll[Item]], val costs: Ref[Coll[Int]], val sizes: Ref[Coll[Size[Item]]], val valuesCost: Ref[Int]) extends CostedColl[Item] { + def builder: Ref[CostedBuilder] = RCCostedBuilder(); + def value: Ref[Coll[Item]] = CCostedColl.this.values; + @NeverInline def cost: Ref[Int] = delayInvoke; + def size: Ref[Size[Coll[Item]]] = CCostedColl.this.builder.mkSizeColl[Item](CCostedColl.this.sizes); + @NeverInline def mapCosted[Res](f: Ref[scala.Function1[Costed[Item], Costed[Res]]]): Ref[CostedColl[Res]] = delayInvoke; + @NeverInline def filterCosted(f: Ref[scala.Function1[Costed[Item], Costed[Boolean]]]): Ref[CostedColl[Item]] = delayInvoke; + @NeverInline def foldCosted[B](zero: Ref[Costed[B]], op: Ref[scala.Function1[Costed[scala.Tuple2[B, Item]], Costed[B]]]): Ref[Costed[B]] = delayInvoke + }; + abstract class CCostedBuilder extends CostedBuilder { + def monoidBuilder: Ref[MonoidBuilder] = RMonoidBuilderInst(); + @NeverInline def costedValue[T](x: Ref[T], optCost: Ref[WOption[Int]]): Ref[Costed[T]] = delayInvoke; + @NeverInline def defaultValue[T](valueType: Ref[WRType[T]]): Ref[T] = delayInvoke; + def mkSizePrim[T](dataSize: Ref[Long], tT: Ref[WRType[T]]): Ref[SizePrim[T]] = RCSizePrim(dataSize, tT); + def mkSizePair[L, R](l: Ref[Size[L]], r: Ref[Size[R]]): Ref[SizePair[L, R]] = RCSizePair(l, r); + def mkSizeColl[T](sizes: Ref[Coll[Size[T]]]): Ref[SizeColl[T]] = RCSizeColl(sizes); + def mkSizeFunc[E, A, R](sizeEnv: Ref[Size[E]], sizeFunc: Ref[Long], tA: Ref[WRType[A]], tR: Ref[WRType[R]]): Ref[SizeFunc[E, A, R]] = RCSizeFunc(sizeEnv, sizeFunc, tA, tR); + def mkSizeOption[T](sizeOpt: Ref[WOption[Size[T]]]): Ref[SizeOption[T]] = RCSizeOption(sizeOpt); + def mkCostedPrim[T](value: Ref[T], cost: Ref[Int], size: Ref[Size[T]]): Ref[CostedPrim[T]] = RCCostedPrim(value, cost, size); + def mkCostedPair[L, R](first: Ref[Costed[L]], second: Ref[Costed[R]], accCost: Ref[Int]): Ref[CostedPair[L, R]] = RCCostedPair(first, second, accCost); + def mkCostedFunc[Env, Arg, Res](envCosted: Ref[Costed[Env]], func: Ref[scala.Function1[Costed[Arg], Costed[Res]]], cost: Ref[Int], size: Ref[Size[scala.Function1[Arg, Res]]]): Ref[CostedFunc[Env, Arg, Res]] = RCCostedFunc(envCosted, func, cost, size); + def mkCostedColl[T](values: Ref[Coll[T]], costs: Ref[Coll[Int]], sizes: Ref[Coll[Size[T]]], valuesCost: Ref[Int]): Ref[CostedColl[T]] = RCCostedColl(values, costs, sizes, valuesCost); + def mkCostedOption[T](value: Ref[WOption[T]], costOpt: Ref[WOption[Int]], sizeOpt: Ref[WOption[Size[T]]], accumulatedCost: Ref[Int]): Ref[CostedOption[T]] = RCCostedOption(value, costOpt, sizeOpt, accumulatedCost) + }; + trait CCostedPrimCompanion; + trait CCostedPairCompanion; + trait CCostedFuncCompanion; + trait CCostedCollCompanion; + trait CCostedBuilderCompanion + } +} \ No newline at end of file diff --git a/library-impl/src/main/resources/special/collection/ConcreteSizes.scalan b/library-impl/src/main/resources/special/collection/ConcreteSizes.scalan new file mode 100644 index 0000000000..cf4c73a47b --- /dev/null +++ b/library-impl/src/main/resources/special/collection/ConcreteSizes.scalan @@ -0,0 +1,29 @@ +package special.collection { + import scalan._ + + trait ConcreteSizes extends Base { self: ConcreteSizesModule => + import SizeColl._; + import SizeFunc._; + import SizeOption._; + import SizePair._; + import SizePrim._; + abstract class CSizePrim[Val](val dataSize: Ref[Long], val tVal: Ref[WRType[Val]]) extends SizePrim[Val]; + abstract class CSizePair[L, R](val l: Ref[Size[L]], val r: Ref[Size[R]]) extends SizePair[L, R] { + @NeverInline def dataSize: Ref[Long] = delayInvoke + }; + abstract class CSizeColl[Item](val sizes: Ref[Coll[Size[Item]]]) extends SizeColl[Item] { + @NeverInline def dataSize: Ref[Long] = delayInvoke + }; + abstract class CSizeFunc[Env, Arg, Res](val sizeEnv: Ref[Size[Env]], val sizeFunc: Ref[Long], val tArg: Ref[WRType[Arg]], val tRes: Ref[WRType[Res]]) extends SizeFunc[Env, Arg, Res] { + @NeverInline def dataSize: Ref[Long] = delayInvoke + }; + abstract class CSizeOption[Item](val sizeOpt: Ref[WOption[Size[Item]]]) extends SizeOption[Item] { + @NeverInline def dataSize: Ref[Long] = delayInvoke + }; + trait CSizePrimCompanion; + trait CSizePairCompanion; + trait CSizeCollCompanion; + trait CSizeFuncCompanion; + trait CSizeOptionCompanion + } +} \ No newline at end of file diff --git a/library-impl/src/main/resources/special/collection/CostedOptions.scalan b/library-impl/src/main/resources/special/collection/CostedOptions.scalan new file mode 100644 index 0000000000..7fbf623a49 --- /dev/null +++ b/library-impl/src/main/resources/special/collection/CostedOptions.scalan @@ -0,0 +1,18 @@ +package special.collection { + import scalan._ + + trait CostedOptions extends Base { self: CostedOptionsModule => + import CCostedBuilder._; + import CostedBuilder._; + import CostedOption._; + import Size._; + import SizeOption._; + import WOption._; + abstract class CCostedOption[T](val value: Ref[WOption[T]], val costOpt: Ref[WOption[Int]], val sizeOpt: Ref[WOption[Size[T]]], val accumulatedCost: Ref[Int]) extends CostedOption[T] { + def builder: Ref[CostedBuilder] = RCCostedBuilder(); + @NeverInline def cost: Ref[Int] = delayInvoke; + def size: Ref[Size[WOption[T]]] = CCostedOption.this.builder.mkSizeOption[T](CCostedOption.this.sizeOpt) + }; + trait CCostedOptionCompanion + } +} \ No newline at end of file diff --git a/library-impl/src/main/resources/special/collection/MonoidInstances.scalan b/library-impl/src/main/resources/special/collection/MonoidInstances.scalan new file mode 100644 index 0000000000..1fbf7e6b7a --- /dev/null +++ b/library-impl/src/main/resources/special/collection/MonoidInstances.scalan @@ -0,0 +1,27 @@ +package special.collection { + import scalan._ + + trait MonoidInstances extends Base { self: MonoidInstancesModule => + import IntPlusMonoid._; + import LongPlusMonoid._; + import Monoid._; + import MonoidBuilder._; + abstract class MonoidBuilderInst extends MonoidBuilder { + val `intPlusMonoid `: Ref[IntPlusMonoid] = RIntPlusMonoid(toRep(0.asInstanceOf[Int])); + def intPlusMonoid: Ref[IntPlusMonoid] = MonoidBuilderInst.this.`intPlusMonoid `; + val `longPlusMonoid `: Ref[LongPlusMonoid] = RLongPlusMonoid(toRep(0L.asInstanceOf[Long])); + def longPlusMonoid: Ref[LongPlusMonoid] = MonoidBuilderInst.this.`longPlusMonoid `; + }; + abstract class IntPlusMonoid(val zero: Ref[Int]) extends Monoid[Int] { + def plus(x: Ref[Int], y: Ref[Int]): Ref[Int] = java.lang.Math.addExact(x, y); + def power(x: Ref[Int], n: Ref[Int]): Ref[Int] = java.lang.Math.multiplyExact(x, n) + }; + abstract class LongPlusMonoid(val zero: Ref[Long]) extends Monoid[Long] { + def plus(x: Ref[Long], y: Ref[Long]): Ref[Long] = java.lang.Math.addExact(x, y); + def power(x: Ref[Long], n: Ref[Int]): Ref[Long] = java.lang.Math.multiplyExact(x, n.toLong) + }; + trait MonoidBuilderInstCompanion; + trait IntPlusMonoidCompanion; + trait LongPlusMonoidCompanion; + } +} \ No newline at end of file diff --git a/library-impl/src/main/scala/special/collection/Builder.scala b/library-impl/src/main/scala/special/collection/Builder.scala new file mode 100644 index 0000000000..41a1e193b5 --- /dev/null +++ b/library-impl/src/main/scala/special/collection/Builder.scala @@ -0,0 +1,5 @@ +package special.collection + +object Builder { + val DefaultCollBuilder = new CollOverArrayBuilder +} diff --git a/library-impl/src/main/scala/special/collection/CollsOverArrays.scala b/library-impl/src/main/scala/special/collection/CollsOverArrays.scala new file mode 100644 index 0000000000..51640b2aad --- /dev/null +++ b/library-impl/src/main/scala/special/collection/CollsOverArrays.scala @@ -0,0 +1,784 @@ +package special.collection + +import java.util +import java.util.Objects + +import special.SpecialPredef + +import scala.reflect.ClassTag +import scalan._ +import scalan.util.CollectionUtil +import scalan.{Internal, NeverInline, Reified, RType} +import Helpers._ +import debox.Buffer +import scalan.RType._ +import spire.syntax.all._ + +import scala.runtime.RichInt + +class CollOverArray[@specialized A](val toArray: Array[A])(implicit tA: RType[A]) extends Coll[A] { + @Internal + override def tItem: RType[A] = tA + def builder: CollBuilder = new CollOverArrayBuilder + @inline def length: Int = toArray.length + @inline def apply(i: Int): A = toArray.apply(i) + + @NeverInline + override def isEmpty: Boolean = length == 0 + + @NeverInline + override def nonEmpty: Boolean = length > 0 + + @NeverInline + override def isDefinedAt(idx: Int): Boolean = (idx >= 0) && (idx < length) + + @NeverInline + def getOrElse(i: Int, default: A): A = if (i >= 0 && i < toArray.length) toArray(i) else default + + @NeverInline + def map[@specialized B: RType](f: A => B): Coll[B] = { + implicit val ctB = RType[B].classTag + builder.fromArray(toArray.map(f)) + } + + def foreach(f: A => Unit): Unit = toArray.foreach(f) + def exists(p: A => Boolean): Boolean = toArray.exists(p) + def forall(p: A => Boolean): Boolean = toArray.forall(p) + def filter(p: A => Boolean): Coll[A] = builder.fromArray(toArray.filter(p)) + + @NeverInline + def foldLeft[B](zero: B, op: ((B, A)) => B): B = toArray.foldLeft(zero)((b, a) => op((b, a))) + + def slice(from: Int, until: Int): Coll[A] = builder.fromArray(toArray.slice(from, until)) + def sum(m: Monoid[A]): A = toArray.foldLeft(m.zero)((b, a) => m.plus(b, a)) + @inline def zip[@specialized B](ys: Coll[B]): PairColl[A, B] = builder.pairColl(this, ys) + + @NeverInline + def append(other: Coll[A]): Coll[A] = { + if (toArray.length <= 0) return other + val result = CollectionUtil.concatArrays(toArray, other.toArray) + builder.fromArray(result) + } + + @NeverInline + def reverse: Coll[A] = { + val limit = length + val res = new Array[A](limit) + cfor(0)(_ < limit, _ + 1) { i => + res(i) = toArray(limit - i - 1) + } + builder.fromArray(res) + } + + @NeverInline + def indices: Coll[Int] = builder.fromArray(toArray.indices.toArray) + + @NeverInline + override def flatMap[B: RType](f: A => Coll[B]): Coll[B] = { + implicit val ctB = RType[B].classTag + builder.fromArray(toArray.flatMap(x => f(x).toArray)) + } + + @NeverInline + override def segmentLength(p: A => Boolean, from: Int): Int = toArray.segmentLength(p, from) + + @NeverInline + override def indexWhere(p: A => Boolean, from: Int): Int = toArray.indexWhere(p, from) + + @NeverInline + override def lastIndexWhere(p: A => Boolean, end: Int): Int = toArray.lastIndexWhere(p, end) + + @NeverInline + override def take(n: Int): Coll[A] = { + if (n <= 0) builder.emptyColl + else if (n >= length) this + else { + val res = Array.ofDim[A](n) + Array.copy(toArray, 0, res, 0, n) + builder.fromArray(res) + } + } + + @NeverInline + override def partition(pred: A => Boolean): (Coll[A], Coll[A]) = { + val (ls, rs) = toArray.partition(pred) + (builder.fromArray(ls), builder.fromArray(rs)) + } + + @NeverInline + override def patch(from: Int, patch: Coll[A], replaced: Int): Coll[A] = { + // TODO optimize: avoid using `patch` as it do boxing + val res = toArray.patch(from, patch.toArray, replaced).toArray + builder.fromArray(res) + } + + @NeverInline + override def updated(index: Int, elem: A): Coll[A] = { + // TODO optimize: avoid using `updated` as it do boxing + val res = toArray.updated(index, elem) + builder.fromArray(res) + } + + @NeverInline + override def updateMany(indexes: Coll[Int], values: Coll[A]): Coll[A] = { + requireSameLength(indexes, values) + val resArr = toArray.clone() + var i = 0 + while (i < indexes.length) { + val pos = indexes(i) + if (pos < 0 || pos >= toArray.length) throw new IndexOutOfBoundsException(pos.toString) + resArr(pos) = values(i) + i += 1 + } + builder.fromArray(resArr) + } + + @NeverInline + override def mapReduce[K: RType, V: RType](m: A => (K, V), r: ((V, V)) => V): Coll[(K, V)] = { + val (keys, values) = Helpers.mapReduce(toArray, m, r) + builder.pairCollFromArrays(keys, values) + } + + @NeverInline + override def unionSet(that: Coll[A]): Coll[A] = { + val set = debox.Set.ofSize[A](this.length) + val res = Buffer.ofSize[A](this.length) + @inline def addItemToSet(x: A) = { + if (!set(x)) { + set.add(x) + res += x + } + } + def addToSet(arr: Array[A]) = { + val limit = arr.length + cfor(0)(_ < limit, _ + 1) { i => + val x = arr(i) + addItemToSet(x) + } + } + addToSet(this.toArray) + + that match { + case repl: ReplColl[A@unchecked] if repl.length > 0 => // optimization + addItemToSet(repl.value) + case _ => + addToSet(that.toArray) + } + builder.fromArray(res.toArray()) + } + + @Internal + protected def isAllPrimValue(value: A): Boolean = { + cfor(0)(_ < length, _ + 1) { i => + if (this(i) != value) return false + } + true + } + + @Internal + protected def isAllDeepEquals(value: Any): Boolean = { + cfor(0)(_ < length, _ + 1) { i => + if (!Objects.deepEquals(this(i), value)) return false + } + true + } + + @Internal + def isReplArray(len: Int, value: A): Boolean = { + length == len && { + if (tItem.classTag.runtimeClass.isPrimitive) { + isAllPrimValue(value) + } else { + isAllDeepEquals(value) + } + } + } + + @Internal + override def equals(obj: scala.Any): Boolean = obj match { + case obj: CollOverArray[_] if obj.tItem == this.tItem => + util.Objects.deepEquals(obj.toArray, toArray) + case repl: CReplColl[A]@unchecked if repl.tItem == this.tItem => + isReplArray(repl.length, repl.value) + case _ => false + } + + @Internal + override def hashCode() = CollectionUtil.deepHashCode(toArray) +} + +class CollOverArrayBuilder extends CollBuilder { + override def Monoids: MonoidBuilder = new MonoidBuilderInst + + @inline def pairColl[@specialized A, @specialized B](as: Coll[A], bs: Coll[B]): PairColl[A, B] = new PairOfCols(as, bs) + + @Internal + override def fromMap[K: RType, V: RType](m: Map[K, V]): Coll[(K, V)] = { + val (ks, vs) = Helpers.mapToArrays(m) + pairCollFromArrays(ks, vs) + } + + @Internal + private def fromBoxedPairs[A, B](seq: Seq[(A, B)])(implicit tA: RType[A], tB: RType[B]): PairColl[A,B] = { + val len = seq.length + val resA = Array.ofDim[A](len)(tA.classTag) + val resB = Array.ofDim[B](len)(tB.classTag) + cfor(0)(_ < len, _ + 1) { i => + val item = seq.apply(i).asInstanceOf[(A,B)] + resA(i) = item._1 + resB(i) = item._2 + } + pairCollFromArrays(resA, resB)(tA, tB) + } + + @NeverInline + @Reified("T") + def fromItems[T](items: T*)(implicit cT: RType[T]): Coll[T] = cT match { + case pt: PairType[a,b] => + val tA = pt.tFst + val tB = pt.tSnd + fromBoxedPairs(items)(tA, tB) + case _ => + new CollOverArray(items.toArray(cT.classTag)) + } + + @NeverInline + def fromArray[@specialized T: RType](arr: Array[T]): Coll[T] = RType[T] match { + case pt: PairType[a,b] => + val tA = pt.tFst + val tB = pt.tSnd + fromBoxedPairs[a,b](arr.asInstanceOf[Array[(a,b)]])(tA, tB) + case _ => + new CollOverArray(arr) + } + + @NeverInline + def replicate[@specialized T: RType](n: Int, v: T): Coll[T] = RType[T] match { + case pt: PairType[a,b] => + val tA = pt.tFst + val tB = pt.tSnd + val tuple = v.asInstanceOf[(a, b)] + new PairOfCols(replicate(n, tuple._1)(tA), replicate(n, tuple._2)(tB)) + case _ => + new CReplColl(v, n) + } + + @NeverInline + def makeView[@specialized A, @specialized B: RType](source: Coll[A], f: A => B): Coll[B] = new CViewColl(source, f) + + @NeverInline + def makePartialView[@specialized A, @specialized B: RType](source: Coll[A], f: A => B, calculated: Array[Boolean], calculatedItems: Array[B]): Coll[B] = { + new CViewColl(source, f).fromPartialCalculation(calculated, calculatedItems) + } + + @NeverInline + def unzip[@specialized A, @specialized B](xs: Coll[(A,B)]): (Coll[A], Coll[B]) = xs match { + case pa: PairColl[_,_] => (pa.ls, pa.rs) + case _ => + val limit = xs.length + implicit val tA = xs.tItem.tFst + implicit val tB = xs.tItem.tSnd + val ls = Array.ofDim[A](limit) + val rs = Array.ofDim[B](limit) + cfor(0)(_ < limit, _ + 1) { i => + val p = xs(i) + ls(i) = p._1 + rs(i) = p._2 + } + (fromArray(ls), fromArray(rs)) + } + + @NeverInline + def xor(left: Coll[Byte], right: Coll[Byte]): Coll[Byte] = left.zip(right).map { case (l, r) => (l ^ r).toByte } + + @NeverInline + override def emptyColl[T](implicit cT: RType[T]): Coll[T] = cT match { + case pt: PairType[a,b] => + val ls = emptyColl(pt.tFst) + val rs = emptyColl(pt.tSnd) + asColl[T](pairColl(ls, rs)) + case _ => + new CollOverArray[T](Array[T]()) + } + + @NeverInline + override def outerJoin[K: RType, L, R, O: RType] + (left: Coll[(K, L)], right: Coll[(K, R)]) + (l: ((K, L)) => O, r: ((K, R)) => O, inner: ((K, (L, R))) => O): Coll[(K, O)] = { + val res = CollectionUtil.outerJoin[K,L,R,O](left.toMap, right.toMap)( + (k,lv) => l((k,lv)), + (k,rv) => r((k,rv)), + (k, lv, rv) => inner((k, (lv, rv)))) + fromMap(res) + } + + @NeverInline + override def flattenColl[A: RType](coll: Coll[Coll[A]]): Coll[A] = { + implicit val ctA = RType[A].classTag + val res = coll.map(xs => xs.toArray).toArray.flatten + fromArray(res) + } +} + +class PairOfCols[@specialized L, @specialized R](val ls: Coll[L], val rs: Coll[R]) extends PairColl[L,R] { + @Internal + override private[collection] def isReplArray(len: Int, value: (L, R)): Boolean = { + ls.isReplArray(len, value._1) && rs.isReplArray(len, value._2) + } + + @Internal + override def equals(that: scala.Any) = (this eq that.asInstanceOf[AnyRef]) || (that match { + case that: PairColl[_,_] if that.tItem == this.tItem => ls == that.ls && rs == that.rs + case that: ReplColl[(L,R)]@unchecked if that.tItem == this.tItem => + ls.isReplArray(that.length, that.value._1) && + rs.isReplArray(that.length, that.value._2) + case _ => false + }) + @Internal + override def hashCode() = ls.hashCode() * 41 + rs.hashCode() + @Internal @inline + implicit def tL = ls.tItem + @Internal @inline + implicit def tR = rs.tItem + + @Internal + override lazy val tItem: RType[(L, R)] = { + RType.pairRType(tL, tR) + } + + override def builder: CollBuilder = new CollOverArrayBuilder + override def toArray: Array[(L, R)] = ls.toArray.zip(rs.toArray) + @inline override def length: Int = if (ls.length <= rs.length) ls.length else rs.length + @inline override def apply(i: Int): (L, R) = (ls(i), rs(i)) + + @NeverInline + override def isEmpty: Boolean = length == 0 + + @NeverInline + override def nonEmpty: Boolean = length > 0 + + @NeverInline + override def isDefinedAt(idx: Int): Boolean = ls.isDefinedAt(idx) && rs.isDefinedAt(idx) + + @NeverInline + override def getOrElse(i: Int, default: (L, R)): (L, R) = + if (i >= 0 && i < this.length) + this.apply(i) + else { + val d = default // force thunk + (d._1, d._2) + } + + @NeverInline + override def map[@specialized V: RType](f: ((L, R)) => V): Coll[V] = { + val limit = ls.length + val res = new Array[V](limit) + cfor(0)(_ < limit, _ + 1) { i => + res(i) = f((ls(i), rs(i))) + } + new CollOverArray(res) + } + + @NeverInline + override def exists(p: ((L, R)) => Boolean): Boolean = { + val len = ls.length + var i = 0 + while (i < len) { + val found = p((ls(i), rs(i))) + if (found) return true + i += 1 + } + false + } + + @NeverInline + override def forall(p: ((L, R)) => Boolean): Boolean = { + val len = ls.length + var i = 0 + while (i < len) { + val ok = p((ls(i), rs(i))) + if (!ok) return false + i += 1 + } + true + } + @NeverInline + override def filter(p: ((L, R)) => Boolean): Coll[(L,R)] = { + val len = ls.length + val resL: Buffer[L] = Buffer.empty[L](ls.tItem.classTag) + val resR: Buffer[R] = Buffer.empty[R](rs.tItem.classTag) + var i = 0 + while (i < len) { + val l = ls.apply(i) + val r = rs.apply(i) + val ok = p((l, r)) + if (ok) { + resL += l + resR += r + } + i += 1 + } + builder.pairCollFromArrays(resL.toArray(), resR.toArray()) + } + + @NeverInline + override def foldLeft[B](zero: B, op: ((B, (L, R))) => B): B = { + val limit = length + var state = zero + cfor(0)(_ < limit, _ + 1) { i => + val l = ls.apply(i) + val r = rs.apply(i) + state = op((state, (l, r))) + } + state + } + + override def slice(from: Int, until: Int): PairColl[L,R] = builder.pairColl(ls.slice(from, until), rs.slice(from, until)) + + def append(other: Coll[(L, R)]): Coll[(L,R)] = { + val arrs = builder.unzip(other) + builder.pairColl(ls.append(arrs._1), rs.append(arrs._2)) + } + + override def reverse: Coll[(L, R)] = { + val lLen = ls.length + val rLen = rs.length + if (lLen == rLen) { + builder.pairColl(ls.reverse, rs.reverse) + } else if (lLen < rLen) { + builder.pairColl(ls.reverse, rs.slice(0, lLen).reverse) + } else { + builder.pairColl(ls.slice(0, rLen).reverse, rs.reverse) + } + } + + @NeverInline + override def sum(m: Monoid[(L, R)]): (L, R) = { + val limit = length + var state = m.zero + cfor(0)(_ < limit, _ + 1) { i => + val l = ls.apply(i) + val r = rs.apply(i) + state = m.plus(state, (l, r)) + } + state + } + + def zip[@specialized B](ys: Coll[B]): PairColl[(L,R), B] = builder.pairColl(this, ys) + + override def indices: Coll[Int] = if (ls.length <= rs.length) ls.indices else rs.indices + + @NeverInline + override def flatMap[B: RType](f: ((L, R)) => Coll[B]): Coll[B] = + builder.fromArray(toArray.flatMap(p => f(p).toArray)) + + @NeverInline + override def segmentLength(p: ((L, R)) => Boolean, from: Int): Int = { + toArray.segmentLength(p, from) + } + + @NeverInline + override def indexWhere(p: ((L, R)) => Boolean, from: Int): Int = toArray.indexWhere(p, from) + + @NeverInline + override def lastIndexWhere(p: ((L, R)) => Boolean, end: Int): Int = toArray.lastIndexWhere(p, end) + + @NeverInline + override def take(n: Int): Coll[(L, R)] = builder.pairColl(ls.take(n), rs.take(n)) + + @NeverInline + override def partition(pred: ((L, R)) => Boolean): (Coll[(L, R)], Coll[(L, R)]) = { + val (ls, rs) = toArray.partition(pred) + (builder.fromArray(ls), builder.fromArray(rs)) + } + + @NeverInline + override def patch(from: Int, patch: Coll[(L, R)], replaced: Int): Coll[(L, R)] = { + val (lsPatch, rsPatch) = builder.unzip(patch) + val lp = ls.patch(from, lsPatch, replaced) + val rp = rs.patch(from, rsPatch, replaced) + builder.pairColl(lp, rp) + } + + @NeverInline + override def updated(index: Int, elem: (L, R)): Coll[(L, R)] = { + val lu = ls.updated(index, elem._1) + val ru = rs.updated(index, elem._2) + builder.pairColl(lu, ru) + } + + @NeverInline + override def updateMany(indexes: Coll[Int], values: Coll[(L, R)]): Coll[(L, R)] = { + requireSameLength(indexes, values) + val resL = ls.toArray.clone() + val resR = rs.toArray.clone() + var i = 0 + while (i < indexes.length) { + val pos = indexes(i) + if (pos < 0 || pos >= length) throw new IndexOutOfBoundsException(pos.toString) + resL(pos) = values(i)._1 + resR(pos) = values(i)._2 + i += 1 + } + builder.pairColl(builder.fromArray(resL), builder.fromArray(resR)) + } + + @NeverInline + override def mapReduce[K: RType, V: RType](m: ((L, R)) => (K, V), r: ((V, V)) => V): Coll[(K, V)] = { + // TODO optimize: don't reify arr + val (keys, values) = Helpers.mapReduce(toArray, m, r) + builder.pairCollFromArrays(keys, values) + } + + @NeverInline + override def unionSet(that: Coll[(L, R)]): Coll[(L, R)] = { + val set = new util.HashSet[(L,R)](32) + implicit val ctL = ls.tItem.classTag + implicit val ctR = rs.tItem.classTag + val resL = Buffer.empty[L] + val resR = Buffer.empty[R] + def addToSet(item: (L,R)) = { + if (!set.contains(item)) { + set.add(item) + resL += item._1 + resR += item._2 + } + } + var i = 0 + val thisLen = math.min(ls.length, rs.length) + while (i < thisLen) { + addToSet((ls(i), rs(i))) + i += 1 + } + i = 0 + val thatLen = that.length + while (i < thatLen) { + addToSet(that(i)) + i += 1 + } + builder.pairCollFromArrays(resL.toArray, resR.toArray) + } + + @NeverInline + override def mapFirst[T1: RType](f: L => T1): Coll[(T1, R)] = { + builder.pairColl(ls.map(f), rs) + } + + @NeverInline + override def mapSecond[T1: RType](f: R => T1): Coll[(L, T1)] = { + builder.pairColl(ls, rs.map(f)) + } +} + +class CReplColl[@specialized A](val value: A, val length: Int)(implicit tA: RType[A]) extends ReplColl[A] { + @Internal + override def tItem: RType[A] = tA + + def builder: CollBuilder = new CollOverArrayBuilder + + @Internal + lazy val _toArray: Array[A] = { + implicit val cT: ClassTag[A] = tA.classTag + val res = new Array[A](length) + val v = value + cfor(0)(_ < length, _ + 1) { i => res(i) = v } + res + } + @NeverInline + def toArray = _toArray + + @NeverInline + @inline def apply(i: Int): A = if (i >= 0 && i < this.length) value else throw new IndexOutOfBoundsException(i.toString) + + @NeverInline + override def isEmpty: Boolean = length == 0 + + @NeverInline + override def nonEmpty: Boolean = length > 0 + + @NeverInline + override def isDefinedAt(idx: Int): Boolean = (idx >= 0 && idx < this.length) + + @NeverInline + def getOrElse(i: Int, default: A): A = if (i >= 0 && i < this.length) value else default + def map[@specialized B: RType](f: A => B): Coll[B] = new CReplColl(f(value), length) + @NeverInline + def foreach(f: A => Unit): Unit = (0 until length).foreach(_ => f(value)) + @NeverInline + def exists(p: A => Boolean): Boolean = if (length == 0) false else p(value) + @NeverInline + def forall(p: A => Boolean): Boolean = if (length == 0) true else p(value) + @NeverInline + def filter(p: A => Boolean): Coll[A] = + if (length == 0) this + else + if (p(value)) this + else new CReplColl(value, 0) + + @NeverInline + def foldLeft[B](zero: B, op: ((B, A)) => B): B = + SpecialPredef.loopUntil[(B, Int)]((zero,0), + p => p._2 >= length, + p => (op((p._1, value)), p._2 + 1) + )._1 + + def zip[@specialized B](ys: Coll[B]): PairColl[A, B] = builder.pairColl(this, ys) + + @NeverInline + def slice(from: Int, until: Int): Coll[A] = { + val lo = math.max(from, 0) + val hi = math.min(math.max(until, 0), length) + val size = math.max(hi - lo, 0) + new CReplColl(value, size) + } + + @NeverInline + def append(other: Coll[A]): Coll[A] = other match { + case repl: ReplColl[A@unchecked] if this.value == repl.value => + new CReplColl(value, this.length + repl.length) + case _ => + builder.fromArray(toArray).append(builder.fromArray(other.toArray)) + } + + override def reverse: Coll[A] = this + + def sum(m: Monoid[A]): A = m.power(value, length) + + @NeverInline + override def indices: Coll[Int] = builder.fromArray((0 until length).toArray) + + @NeverInline + override def flatMap[B: RType](f: A => Coll[B]): Coll[B] = { + val seg = f(value).toArray + val xs = Range(0, length).flatMap(_ => seg).toArray + builder.fromArray(xs) + } + + @NeverInline + override def segmentLength(p: A => Boolean, from: Int): Int = { + if (from >= length) 0 + else + if (p(value)) length - from + else 0 + } + + @NeverInline + override def indexWhere(p: A => Boolean, from: Int): Int = { + if (from >= length) -1 + else + if (p(value)) math.max(from, 0) + else -1 + } + + @NeverInline + override def lastIndexWhere(p: A => Boolean, end: Int): Int = { + var i = math.min(end, length - 1) + if (i < 0) i + else if (p(value)) i + else -1 + } + + @NeverInline + override def take(n: Int): Coll[A] = + if (n <= 0) builder.emptyColl + else { + val m = new RichInt(n).min(length) + new CReplColl(value, m) + } + + @NeverInline + override def partition(pred: A => Boolean): (Coll[A], Coll[A]) = { + if (pred(value)) (this, builder.emptyColl[A]) + else (builder.emptyColl, this) + } + + @NeverInline + override def patch(from: Int, patch: Coll[A], replaced: Int): Coll[A] = { + builder.fromArray(toArray.patch(from, patch.toArray, replaced)) + } + + @NeverInline + override def updated(index: Int, elem: A): Coll[A] = { + if (elem == value) this + else { + // TODO optimize: avoid using `updated` as it do boxing + val res = toArray.updated(index, elem) + builder.fromArray(res) + } + } + + @NeverInline + override def updateMany(indexes: Coll[Int], values: Coll[A]): Coll[A] = { + requireSameLength(indexes, values) + val resArr = toArray.clone() + var i = 0 + while (i < indexes.length) { + val pos = indexes(i) + if (pos < 0 || pos >= length) throw new IndexOutOfBoundsException(pos.toString) + resArr(pos) = values(i) + i += 1 + } + builder.fromArray(resArr) + } + + @NeverInline + override def mapReduce[K: RType, V: RType](m: A => (K, V), r: ((V, V)) => V): Coll[(K, V)] = { + if (length <= 0) return builder.pairColl(builder.emptyColl[K], builder.emptyColl[V]) + val (k, v) = m(value) + var reducedV = v + var i = 1 + while (i < length) { + reducedV = r((reducedV, v)) + i += 1 + } + builder.pairColl(builder.fromItems(k), builder.fromItems(reducedV)) + } + + @NeverInline + override def unionSet(that: Coll[A]): Coll[A] = that match { + case repl: ReplColl[A@unchecked] => + if (this.length > 0) { + if (repl.length > 0) { + if (value == repl.value) { + // both replications have the same element `value`, just return it in a singleton set + new CReplColl(value, 1) + } + else { + builder.fromItems(value, repl.value) + } + } + else + new CReplColl(value, 1) + } else { + if (repl.length > 0) { + new CReplColl(repl.value, 1) + } else + new CReplColl(value, 0) // empty set + } + case _ => + if (this.length > 0) + builder.fromItems(value).unionSet(that) + else + builder.emptyColl[A].unionSet(that) + } + + @Internal + override private[collection] def isReplArray(len: Int, value: A): Boolean = { + this.length == len && this.value == value + } + + @Internal + override def equals(obj: scala.Any): Boolean = obj != null && (obj match { + case repl: CReplColl[A]@unchecked if repl.tItem == this.tItem => + this.length == repl.length && this.value == repl.value + case obj: Coll[A] if obj.tItem == this.tItem => + obj.isReplArray(this.length, this.value) + case _ => false + }) + + @Internal + override def hashCode() = CollectionUtil.deepHashCode(toArray) + + @Internal + override def toString = s"ReplColl($value, $length)" +} diff --git a/library-impl/src/main/scala/special/collection/ConcreteCosts.scala b/library-impl/src/main/scala/special/collection/ConcreteCosts.scala new file mode 100644 index 0000000000..dcd17f96c1 --- /dev/null +++ b/library-impl/src/main/scala/special/collection/ConcreteCosts.scala @@ -0,0 +1,97 @@ +package special.collection + +import scalan._ +import special.SpecialPredef._ + +class CCostedPrim[Val](val value: Val, val cost: Int, val size: Size[Val]) extends CostedPrim[Val] { + def builder: CostedBuilder = new CCostedBuilder +} + +class CCostedPair[L,R](val l: Costed[L], val r: Costed[R], val accCost: Int) extends CostedPair[L,R] { + def builder: CostedBuilder = new CCostedBuilder + def value: (L,R) = (l.value, r.value) + @NeverInline + def cost: Int = rewritableMethod // implementation is only expressible in staged code (see RW rule) + def size: Size[(L,R)] = builder.mkSizePair(l.size, r.size) +} + +/** @param cost Cost of creating the closure object of this function, doesn't include the cost of creating environment + * @param dataSize Size of memory necessary to store the closure object, doesn't include the dataSize of storing environment + * */ +class CCostedFunc[Env,Arg,Res]( + val envCosted: Costed[Env], + val func: Costed[Arg] => Costed[Res], + val cost: Int, + val size: Size[Arg => Res]) extends CostedFunc[Env, Arg, Res] +{ + def builder: CostedBuilder = new CCostedBuilder + @NeverInline def value: Arg => Res = rewritableMethod + override def sliceCalc: Arg => Res = rewritableMethod + override def sliceCost: ((Int, Size[Arg])) => Int = rewritableMethod + override def sliceCostEx: ((Arg, (Int, Size[Arg]))) => Int = rewritableMethod + override def sliceSize: Size[Arg] => Size[Res] = rewritableMethod +} + +class CCostedColl[Item]( + val values: Coll[Item], + val costs: Coll[Int], + val sizes: Coll[Size[Item]], + val valuesCost: Int) extends CostedColl[Item] +{ + def builder: CostedBuilder = new CCostedBuilder + def value: Coll[Item] = values + @NeverInline + def cost: Int = rewritableMethod // implementation is only expressible in staged code (see RW rule) + def size: Size[Coll[Item]] = builder.mkSizeColl(sizes) + @NeverInline + def mapCosted[Res](f: Costed[Item] => Costed[Res]): CostedColl[Res] = rewritableMethod + @NeverInline + def filterCosted(f: Costed[Item] => Costed[Boolean]): CostedColl[Item] = rewritableMethod + @NeverInline + def foldCosted[B](zero: Costed[B], op: Costed[(B, Item)] => Costed[B]): Costed[B] = rewritableMethod +} + +class CCostedBuilder extends CostedBuilder { + def monoidBuilder: MonoidBuilder = new MonoidBuilderInst + + @NeverInline + def costedValue[T](x: T, optCost: Option[Int])(implicit cT: RType[T]): Costed[T] = rewritableMethod + + @NeverInline + def defaultValue[T](valueType: RType[T]): T = rewritableMethod + + def mkSizePrim[T](dataSize: Long, tT: RType[T]): SizePrim[T] = + new CSizePrim[T](dataSize, tT) + + def mkSizePair[L, R](l: Size[L], r: Size[R]): SizePair[L, R] = + new CSizePair(l, r) + + def mkSizeColl[T](sizes: Coll[Size[T]]): SizeColl[T] = + new CSizeColl[T](sizes) + + def mkSizeFunc[E, A, R](sizeEnv: Size[E], sizeFunc: Long, tA: RType[A], tR: RType[R]): SizeFunc[E, A, R] = + new CSizeFunc[E, A, R](sizeEnv, sizeFunc, tA, tR) + + def mkSizeOption[T](sizeOpt: Option[Size[T]]): SizeOption[T] = + new CSizeOption[T](sizeOpt) + + def mkCostedPrim[T](value: T, cost: Int, size: Size[T]): CostedPrim[T] = + new CCostedPrim[T](value, cost, size) + + def mkCostedPair[L,R](first: Costed[L], second: Costed[R], accCost: Int): CostedPair[L,R] = + new CCostedPair(first, second, accCost) + + def mkCostedFunc[Env,Arg,Res]( + envCosted: Costed[Env], + func: Costed[Arg] => Costed[Res], + cost: Int, size: Size[Arg=>Res]): CostedFunc[Env, Arg, Res] + = new CCostedFunc(envCosted, func, cost, size) + + def mkCostedColl[T](values: Coll[T], costs: Coll[Int], sizes: Coll[Size[T]], valuesCost: Int): CostedColl[T] = + new CCostedColl[T](values, costs, sizes, valuesCost) + + def mkCostedOption[T](value: Option[T], costOpt: Option[Int], sizeOpt: Option[Size[T]], accumulatedCost: Int): CostedOption[T] = + new CCostedOption[T](value, costOpt, sizeOpt, accumulatedCost) +} + + diff --git a/library-impl/src/main/scala/special/collection/ConcreteSizes.scala b/library-impl/src/main/scala/special/collection/ConcreteSizes.scala new file mode 100644 index 0000000000..50a773a60e --- /dev/null +++ b/library-impl/src/main/scala/special/collection/ConcreteSizes.scala @@ -0,0 +1,29 @@ +package special.collection + +import scalan._ + +class CSizePrim[Val](val dataSize: Long, val tVal: RType[Val]) extends SizePrim[Val] { +} + +class CSizePair[L,R](val l: Size[L], val r: Size[R]) extends SizePair[L, R] { + @NeverInline + def dataSize: Long = l.dataSize + r.dataSize +} + +class CSizeColl[Item](val sizes: Coll[Size[Item]]) extends SizeColl[Item] { + @Internal + def builder: CostedBuilder = new CCostedBuilder + + @NeverInline + def dataSize: Long = sizes.map(_.dataSize).sum(builder.monoidBuilder.longPlusMonoid) +} + +class CSizeFunc[Env, Arg, Res](val sizeEnv: Size[Env], val sizeFunc: Long, val tArg: RType[Arg], val tRes: RType[Res]) extends SizeFunc[Env, Arg, Res] { + @NeverInline + def dataSize: Long = sizeEnv.dataSize + sizeFunc +} + +class CSizeOption[Item](val sizeOpt: Option[Size[Item]]) extends SizeOption[Item] { + @NeverInline + def dataSize: Long = sizeOpt.map(_.dataSize).getOrElse(0L) +} diff --git a/library-impl/src/main/scala/special/collection/CostedOptions.scala b/library-impl/src/main/scala/special/collection/CostedOptions.scala new file mode 100644 index 0000000000..a6f99770f7 --- /dev/null +++ b/library-impl/src/main/scala/special/collection/CostedOptions.scala @@ -0,0 +1,24 @@ +package special.collection + +import special.SpecialPredef +import special.SpecialPredef._ +import scalan.{NeverInline, RType} + +/** CostedOption is represented similar to CostedCol, because option can be represented as collection of 0 or 1 elements. + * @param value optional value + * @param costOpt optional cost of producing the optional value + * @param sizeOpt optional size of the optional value + * @param accumulatedCost accumulated cost to produce this option object (but not the cost of producing the value it may cost) */ +class CCostedOption[T]( + val value: Option[T], + val costOpt: Option[Int], + val sizeOpt: Option[Size[T]], + val accumulatedCost: Int + ) extends CostedOption[T] +{ + def builder: CostedBuilder = new CCostedBuilder + @NeverInline + def cost: Int = rewritableMethod + def size: Size[Option[T]] = builder.mkSizeOption(sizeOpt) +} + diff --git a/library-impl/src/main/scala/special/collection/ExtensionMethods.scala b/library-impl/src/main/scala/special/collection/ExtensionMethods.scala new file mode 100644 index 0000000000..4a1185a8b4 --- /dev/null +++ b/library-impl/src/main/scala/special/collection/ExtensionMethods.scala @@ -0,0 +1,146 @@ +package special.collection + +import scalan.RType + +object ExtensionMethods { + + implicit class CollOps[A](val source: Coll[A]) extends AnyVal { + + /** Tests whether every element of this $coll relates to the + * corresponding element of another sequence by satisfying a test predicate. + * + * @param that the other sequence + * @param p the test predicate, which relates elements from both sequences + * @tparam B the type of the elements of `that` + * @return `true` if both sequences have the same length and + * `p(x, y)` is `true` for all corresponding elements `x` of this $coll + * and `y` of `that`, otherwise `false`. + */ + def corresponds[B](that: Coll[B])(p: ((A, B)) => Boolean): Boolean = + source.zip(that).forall(p) + +// /** Returns the length of the longest prefix whose elements all satisfy some predicate. +// * +// * $mayNotTerminateInf +// * +// * @param p the predicate used to test elements. +// * @return the length of the longest prefix of this $coll +// * such that every element of the segment satisfies the predicate `p`. +// */ +// def prefixLength(p: A => Boolean): Int = xs.segmentLength(p, 0) +// +// /** Finds index of first occurrence of some value in this $coll after or at some start index. +// * +// * @param elem the element value to search for. +// * @param from the start index +// * @return the index `>= from` of the first element of this $coll that is equal (as determined by `==`) +// * to `elem`, or `-1`, if none exists. +// */ +// def indexOf(elem: A, from: Int): Int = xs.indexWhere(elem == _, from) +// +// /** Finds index of last occurrence of some value in this $coll before or at a given end index. +// * +// * @param elem the element value to search for. +// * @param end the end index. +// * @return the index `<= end` of the last element of this $coll that is equal (as determined by `==`) +// * to `elem`, or `-1`, if none exists. +// */ +// def lastIndexOf(elem: A, end: Int): Int = xs.lastIndexWhere(elem == _, end) +// +// /** Finds index of last element satisfying some predicate. +// * +// * @param p the predicate used to test elements. +// * @return the index of the last element of this $coll that satisfies the predicate `p`, +// * or `-1`, if none exists. +// */ +// def lastIndexWhere(p: A => Boolean): Int = xs.lastIndexWhere(p, xs.length - 1) +// + + /** Builds a new $coll from this $coll without any duplicate elements. + * + * @return A new $coll which contains the first occurrence of every element of this $coll. + */ + def distinct: Coll[A] = { + implicit val tA = source.tItem + source.unionSet(source.builder.emptyColl[A]) + } +// +// /** Tests whether this $coll starts with the given sequence. +// * +// * @param that the sequence to test +// * @return `true` if this collection has `that` as a prefix, `false` otherwise. +// */ +//// def startsWith[B](that: Coll[B]): Boolean = startsWith(that, 0) +// +// /** Tests whether this $coll contains the given sequence at a given index. +// * +// * '''Note''': If the both the receiver object `this` and the argument +// * `that` are infinite sequences this method may not terminate. +// * +// * @param that the sequence to test +// * @param offset the index where the sequence is searched. +// * @return `true` if the sequence `that` is contained in this $coll at +// * index `offset`, otherwise `false`. +// */ +//// def startsWith[B](that: Coll[B], offset: Int): Boolean = +// +// /** Tests whether this $coll ends with the given collection. +// * @param that the collection to test +// * @return `true` if this $coll has `that` as a suffix, `false` otherwise. +// */ +//// def endsWith(that: Coll[A]): Boolean +// +// /** A copy of this $coll with an element value appended until a given target length is reached. +// * +// * @param len the target length +// * @param elem the padding value +// * @return a new collection consisting of all elements of this $coll followed by the minimal +// * number of occurrences of `elem` so that the resulting collection has a length of at least `len`. +// */ +// def padTo(len: Int, elem: A): Coll[A] = { +// if (len <= xs.length) xs +// else +// xs.append(xs.builder.replicate(len - xs.length, elem)) +// } + + } + + implicit class PairCollOps[A,B](val source: Coll[(A,B)]) extends AnyVal { + import RType._ + @inline implicit def tA = source.tItem.tFst + @inline implicit def tB = source.tItem.tSnd + + // TODO optimize + def unionSetByKey(that: Coll[(A,B)]): Coll[(A,B)] = { + source.unionSetByKey(that) + } + + def reduceByKey(r: ((B,B)) => B): Coll[(A,B)] = { + source.mapReduce(identity, r) + } + + def sumByKey(implicit m: Monoid[B]): Coll[(A,B)] = + reduceByKey(r => m.plus(r._1, r._2)) + + def groupByKey: Coll[(A, Coll[B])] = source.groupByProjecting(_._1, _._2) + + @inline def mapFirst[A1: RType](f: A => A1): Coll[(A1, B)] = source.asInstanceOf[PairColl[A,B]].mapFirst(f) + @inline def mapSecond[B1: RType](f: B => B1): Coll[(A, B1)] = source.asInstanceOf[PairColl[A,B]].mapSecond(f) + } + + implicit class NestedCollOps[A](val source: Coll[Coll[A]]) extends AnyVal { + @inline implicit def tA = source.tItem.tItem + + def flatten: Coll[A] = source.builder.flattenColl(source) + } + + implicit class OptionOps[A](val source: Option[A]) extends AnyVal { + /** Returns a singleton collection containing the $option's value + * if it is nonempty, or the empty collection if the $option is empty. + * @since 2.0 + */ + def toColl(implicit tA: RType[A]): Coll[A] = + if (source.isEmpty) Builder.DefaultCollBuilder.emptyColl[A] + else Builder.DefaultCollBuilder.fromItems(source.get) + } +} diff --git a/library-impl/src/main/scala/special/collection/Helpers.scala b/library-impl/src/main/scala/special/collection/Helpers.scala new file mode 100644 index 0000000000..9f131b3f54 --- /dev/null +++ b/library-impl/src/main/scala/special/collection/Helpers.scala @@ -0,0 +1,56 @@ +package special.collection + +import scala.reflect.ClassTag +import scala.collection.mutable +import scalan.Internal +import spire.syntax.all._ + +object Helpers { + private def sameLengthErrorMsg[A,B](xs: Coll[A], ys: Coll[B]) = + s"Collections should have same length but was ${xs.length} and ${ys.length}:\n xs=$xs;\n ys=$ys" + + def assertSameLength[A,B](xs: Coll[A], ys: Coll[B]) = { + assert(xs.length == ys.length, sameLengthErrorMsg(xs, ys)) + } + + def requireSameLength[A,B](xs: Coll[A], ys: Coll[B]) = { + require(xs.length == ys.length, sameLengthErrorMsg(xs, ys)) + } + + @inline def asColl[T](coll: Coll[_]): Coll[T] = coll.asInstanceOf[Coll[T]] + + def mapReduce[A, K: ClassTag, V: ClassTag](arr: Array[A], m: A => (K, V), r: ((V, V)) => V): (Array[K], Array[V]) = { + val keyPositions = new java.util.HashMap[K, Int](32) + val keys = mutable.ArrayBuilder.make[K] + val values = Array.ofDim[V](arr.length) + var i = 0 + var nValues = 0 + while (i < arr.length) { + val (key, value) = m(arr(i)) + val pos = keyPositions.getOrDefault(key, 0) + if (pos == 0) { + keyPositions.put(key, nValues + 1) + keys += key + values(nValues) = value + nValues += 1 + } else { + values(pos - 1) = r((values(pos - 1), value)) + } + i += 1 + } + val resValues = Array.ofDim[V](nValues) + Array.copy(values, 0, resValues, 0, nValues) + (keys.result(), resValues) + } + + def mapToArrays[K: ClassTag, V: ClassTag](m: Map[K,V]): (Array[K], Array[V]) = { + val keys = mutable.ArrayBuilder.make[K] + val values = mutable.ArrayBuilder.make[V] + for ((k,v) <- m) { + keys += k + values += v + } + (keys.result, values.result) + } + +} diff --git a/library-impl/src/main/scala/special/collection/MonoidInstances.scala b/library-impl/src/main/scala/special/collection/MonoidInstances.scala new file mode 100644 index 0000000000..1183b9378e --- /dev/null +++ b/library-impl/src/main/scala/special/collection/MonoidInstances.scala @@ -0,0 +1,70 @@ +package special.collection + +import scalan.{NeverInline, Internal} + +class MonoidBuilderInst extends MonoidBuilder { + val intPlusMonoid = new IntPlusMonoid(0) + val longPlusMonoid = new LongPlusMonoid(0L) + + @Internal + val intMaxMonoid = new IntMaxMonoid(0x80000000) // Int.MinValue cannot be used due to virtualization + @Internal + val intMinMonoid = new IntMinMonoid(0x7fffffff) // Int.MinValue cannot be used due to virtualization + @Internal + val longMaxMonoid = new LongMaxMonoid(0x8000000000000000L) // Long.MinValue cannot be used due to virtualization + @Internal + val longMinMonoid = new LongMinMonoid(0x7fffffffffffffffL) // Int.MinValue cannot be used due to virtualization + + @Internal + override def pairMonoid[@specialized(Int, Long) A, @specialized(Int, Long) B](m1: Monoid[A], m2: Monoid[B]): Monoid[(A, B)] = + new PairMonoid(m1, m2) +} + +class IntPlusMonoid(val zero: Int) extends Monoid[Int] { + def plus(x: Int, y: Int): Int = Math.addExact(x, y) + def power(x: Int, n: Int): Int = Math.multiplyExact(x, n) +} + +@Internal +class IntMaxMonoid(val zero: Int) extends Monoid[Int] { + @NeverInline + def plus(x: Int, y: Int): Int = x max y + @NeverInline + def power(x: Int, n: Int): Int = x // x max x max .... x (n times) +} + +@Internal +class IntMinMonoid(val zero: Int) extends Monoid[Int] { + @NeverInline + def plus(x: Int, y: Int): Int = x min y + @NeverInline + def power(x: Int, n: Int): Int = x // x max x max .... x (n times) +} + +class LongPlusMonoid(val zero: Long) extends Monoid[Long] { + def plus(x: Long, y: Long): Long = Math.addExact(x, y) + def power(x: Long, n: Int): Long = Math.multiplyExact(x, n.toLong) +} + +@Internal +class LongMaxMonoid(val zero: Long) extends Monoid[Long] { + @NeverInline + def plus(x: Long, y: Long): Long = x max y + @NeverInline + def power(x: Long, n: Int): Long = x // x max x max .... x (n times) +} + +@Internal +class LongMinMonoid(val zero: Long) extends Monoid[Long] { + @NeverInline + def plus(x: Long, y: Long): Long = x min y + @NeverInline + def power(x: Long, n: Int): Long = x // x max x max .... x (n times) +} + +@Internal +class PairMonoid[@specialized(Int, Long) A, @specialized(Int, Long) B](val m1: Monoid[A], m2: Monoid[B]) extends Monoid[(A,B)] { + override def zero: (A, B) = (m1.zero, m2.zero) + override def plus(x: (A, B), y: (A, B)): (A, B) = (m1.plus(x._1, y._1), m2.plus(x._2, y._2)) + override def power(x: (A, B), n: Int): (A, B) = (m1.power(x._1, n), m2.power(x._2, n)) +} diff --git a/library-impl/src/main/scala/special/collection/ViewColls.scala b/library-impl/src/main/scala/special/collection/ViewColls.scala new file mode 100644 index 0000000000..4b4a3397fc --- /dev/null +++ b/library-impl/src/main/scala/special/collection/ViewColls.scala @@ -0,0 +1,268 @@ +package special.collection + +import scalan.{NeverInline, RType} +import spire.syntax.all.cfor + + +class CViewColl[@specialized A, @specialized B](val source: Coll[A], val f: A => B)(implicit val tItem: RType[B]) extends Coll[B] { + + private var isCalculated: Array[Boolean] = Array.ofDim[Boolean](source.length)(RType.BooleanType.classTag) + private var items: Array[B] = Array.ofDim[B](source.length)(tItem.classTag) + private var calculatedCount = 0 + + def fromPartialCalculation(calculated: Array[Boolean], calculatedItems: Array[B]): CViewColl[A, B] = { + if (calculated.length != source.length || calculatedItems.length != source.length) + throw new RuntimeException("Can't make partial collection: calculated items dimension != source dimension") + isCalculated = calculated + items = calculatedItems + calculatedCount = 0 + cfor(0)(_ < isCalculated.length, _ + 1) { i => + if (isCalculated(i)) { + calculatedCount += 1 + } + } + + this + } + + private def isAllItemsCalculated(): Boolean = calculatedCount == length + + private def calculateItem(index: Int): Unit = { + items(index) = f(source(index)) + isCalculated(index) = true + } + + private def ensureItemNoCalcCountChange(index: Int): Unit = { + if (!isCalculated(index)) { + calculateItem(index) + } + } + + private def ensureItem(index: Int): Unit = { + if (!isCalculated(index)) { + calculateItem(index) + calculatedCount += 1 + } + } + + @inline private def ensureAndGetItem(index: Int): B = { + ensureItem(index) + items(index) + } + + override def builder: CollBuilder = new CollOverArrayBuilder + + @NeverInline + override def toArray: Array[B] = { + if (!isAllItemsCalculated()) { + cfor(0)(_ < length, _ + 1) { i => + ensureItemNoCalcCountChange(i) + } + calculatedCount = length + } + items + } + + @NeverInline + override def length: Int = source.length + + @NeverInline + override def isEmpty: Boolean = source.isEmpty + + @NeverInline + override def nonEmpty: Boolean = !isEmpty + + @NeverInline + override def apply(i: Int): B = { + if (!isDefinedAt(i)) + throw new ArrayIndexOutOfBoundsException() + + ensureAndGetItem(i) + } + + @NeverInline + override def isDefinedAt(idx: Int): Boolean = (idx >= 0) && (idx < length) + + @NeverInline + override def getOrElse(index: Int, default: B): B = if (isDefinedAt(index)) ensureAndGetItem(index) else default + + @NeverInline + override def map[@specialized C: RType](g: B => C): Coll[C] = builder.makeView(this, g) + + @NeverInline + override def zip[@specialized C](ys: Coll[C]): Coll[(B, C)] = builder.pairColl(this, ys) + + @NeverInline + override def exists(p: B => Boolean): Boolean = { + cfor(0)(_ < length, _ + 1) { i => + val found = p(ensureAndGetItem(i)) + if (found) return true + } + false + } + + @NeverInline + override def forall(p: B => Boolean): Boolean = toArray.forall(p) + + @NeverInline + override def filter(p: B => Boolean): Coll[B] = builder.fromArray(toArray)(tItem).filter(p) + + @NeverInline + override def foldLeft[C](zero: C, op: ((C, B)) => C): C = toArray.foldLeft(zero)((item1, item2) => op((item1, item2))) + + @NeverInline + override def indices: Coll[Int] = builder.fromArray((0 until source.length).toArray) + + @NeverInline + override def flatMap[C: RType](g: B => Coll[C]): Coll[C] = builder.fromArray(toArray)(tItem).flatMap(g) + + @NeverInline + override def segmentLength(p: B => Boolean, from: Int): Int = { + val trueFrom = math.max(0, from) + cfor(trueFrom)(_ < length, _ + 1) { i => + val checkResult = p(ensureAndGetItem(i)) + if (!checkResult) { + return i - trueFrom + } + } + length - trueFrom + } + + @NeverInline + override def indexWhere(p: B => Boolean, from: Int): Int = { + val trueFrom = math.max(0, from) + cfor(trueFrom)(_ < length, _ + 1) { i => + val found = p(ensureAndGetItem(i)) + if (found) return i + } + -1 + } + + @NeverInline + override def lastIndexWhere(p: B => Boolean, end: Int): Int = toArray.lastIndexWhere(p, end) + + @NeverInline + override def take(n: Int): Coll[B] = { + if (n <= 0) + return builder.emptyColl(tItem) + if (n > length) + return this + slice(0, n) + } + + @NeverInline + override def partition(pred: B => Boolean): (Coll[B], Coll[B]) = builder.fromArray(toArray)(tItem).partition(pred) + + @NeverInline + override def patch(from: Int, + patch: Coll[B], + replaced: Int): Coll[B] = { + if (length > 0) { + val start = math.max(0, from) // check if from is non-negative + val trueReplace = math.max(replaced, 0) // check if replace is non-negative + /* + * According to patch specification new length is the old length + patch length - replacedCount. + * replacedCount is min(trueReplace, length - start) since it can turn out that trueReplace is greater than + * the rest length of array + */ + val newLength = patch.length + length - math.min(trueReplace, length - start) + + // At first we copy all items at [0, start), since they are kept unchanged + var itemsCopy = Array.ofDim[B](newLength)(tItem.classTag) + Array.copy(items, 0, itemsCopy, 0, start) + // There we put patch items after unchanged items from [0, start) + Array.copy(patch.toArray, 0, itemsCopy, start, patch.length) + // If there are any elements left in the rest of items and not all of them should be replaced, then we finally + // copy them to the end of new items + if (start + trueReplace < length) + Array.copy(items, start + trueReplace, itemsCopy, start + patch.length, length - start - trueReplace) + + // Here's the same procedure as was with items + var calcCopy = Array.ofDim[Boolean](newLength)(RType.BooleanType.classTag) + Array.copy(isCalculated, 0, calcCopy, 0, start) + if (start + trueReplace < length) + Array.copy(isCalculated, start + trueReplace, calcCopy, start + patch.length, length - start - trueReplace) + + // mark patched items as calculated + cfor(start)(_ < start + patch.length, _ + 1) { i => + calcCopy(i) = true + } + + /* + * patchColl solves problem with the absence of source elements in patch collection: it tries to copy the first + * element as source for all elements of patch. If there's no any source elements (collection is empty) then + * current collection is converted to CollOverArray and patch of CollOverArray is called (else branch below) + */ + val patchColl = new CReplColl(source(0), patch.length)(source.tItem) + builder.makePartialView(source.patch(start, patchColl, replaced), f, calcCopy, itemsCopy)(tItem) + } else { + builder.fromArray(toArray).patch(from, patch, replaced) + } + } + + @NeverInline + override def updated(index: Int, elem: B): Coll[B] = { + if (!isDefinedAt(index)) + throw new IndexOutOfBoundsException() + + var itemsCopy = items.clone() + var calcCopy = isCalculated.clone() + + calcCopy(index) = true + itemsCopy(index) = elem + builder.makePartialView(source, f, calcCopy, itemsCopy) + } + + @NeverInline + override def updateMany(indexes: Coll[Int], + values: Coll[B]): Coll[B] = { + // here we copy items and information about which items have been calculated already + var itemsCopy = items.clone() + var calcCopy = isCalculated.clone() + + // here we update items with new ones from values at indexes from indexes collection + cfor(0)(_ < indexes.length, _ + 1) { i => + itemsCopy(indexes(i)) = values(i) + calcCopy(indexes(i)) = true // updated elements should be surely marked as calculated + } + builder.makePartialView(source, f, calcCopy, itemsCopy)(tItem) + } + + @NeverInline + override def mapReduce[K: RType, V: RType](m: B => (K, V), + r: ((V, V)) => V): Coll[(K, V)] = builder.fromArray(toArray)(tItem).mapReduce(m, r) + + @NeverInline + override def unionSet(that: Coll[B]): Coll[B] = builder.fromArray(toArray)(tItem).unionSet(that) + + @NeverInline + override def sum(m: Monoid[B]): B = toArray.foldLeft(m.zero)((b, a) => m.plus(b, a)) + + @NeverInline + override def slice(from: Int, until: Int): Coll[B] = { + if (until <= 0 || until - from <= 0) + return builder.emptyColl(tItem) + + val start = math.max(0, from) + val end = math.min(until, length) + val sliceLength = end - start + + val itemsCopy = Array.ofDim[B](sliceLength)(tItem.classTag) + Array.copy(items, start, itemsCopy, 0, sliceLength) + + val calcCopy = Array.ofDim[Boolean](sliceLength)(RType.BooleanType.classTag) + Array.copy(isCalculated, start, calcCopy, 0, sliceLength) + + builder.makePartialView(source.slice(from, until), f, calcCopy, itemsCopy) + } + + @NeverInline + override def append(other: Coll[B]): Coll[B] = builder.fromArray(toArray)(tItem).append(other) + + @NeverInline + override def reverse: Coll[B] = { + builder.makePartialView(source.reverse, f, isCalculated.reverse, items.reverse)(tItem) + } + + override private[collection] def isReplArray(len: Int, value: B) = ??? +} diff --git a/library/src/main/scala/scalan/Enforcer.scala b/library/src/main/scala/scalan/Enforcer.scala new file mode 100644 index 0000000000..d596930908 --- /dev/null +++ b/library/src/main/scala/scalan/Enforcer.scala @@ -0,0 +1,8 @@ +package scalan + +/** + * This file is necessary to make this module non-empty. + * Otherwise, the compilation doesn't happen and TargetModulePipeline is not executed. + */ +class Enforcer { +} diff --git a/library/src/main/scala/scalan/Library.scala b/library/src/main/scala/scalan/Library.scala new file mode 100644 index 0000000000..a47b8ea407 --- /dev/null +++ b/library/src/main/scala/scalan/Library.scala @@ -0,0 +1,171 @@ +package scalan + +import special.collection._ +import special.wrappers.{WrappersSpecModule, WrappersModule} +import scalan.util.{MemoizedFunc} +import scalan.ExactNumeric._ + +trait Library extends Scalan + with WrappersModule + with WrappersSpecModule + with CollsModule + with SizesModule + with CostsModule + with ConcreteSizesModule + with ConcreteCostsModule + with MonoidsModule + with MonoidInstancesModule + with CostedOptionsModule { + import WOption._ + import WRType._ + import Coll._; import CollBuilder._; + import Size._ + import Costed._; import CostedBuilder._ + import CostedFunc._; + import WSpecialPredef._ + + type RSize[Val] = Ref[Size[Val]] + type RCosted[A] = Ref[Costed[A]] + type LazyRep[T] = MutableLazy[Ref[T]] + + private val _liftElemMemo = new MemoizedFunc({ + case eT: Elem[t] => + val lT = Liftables.asLiftable[Any, t](eT.liftable) + liftableRType(lT).lift(eT.sourceType.asInstanceOf[RType[Any]]) + }) + implicit def liftElem[T](eT: Elem[T]): Ref[WRType[T]] = { + _liftElemMemo(eT).asInstanceOf[Ref[WRType[T]]] // asRep cannot be used for AnyRef + } + + private val _specialPredef: LazyRep[WSpecialPredefCompanionCtor] = MutableLazy(RWSpecialPredef.value) + def specialPredef: Ref[WSpecialPredefCompanionCtor] = _specialPredef.value + + override protected def onReset(): Unit = { + _specialPredef.reset() + _liftElemMemo.reset() + super.onReset() + } + + def zeroSize[V](eVal: Elem[V]): RSize[V] = asRep[Size[V]](eVal match { + case pe: PairElem[a,b] => costedBuilder.mkSizePair(zeroSize[a](pe.eFst), zeroSize[b](pe.eSnd)) + case ce: CollElem[_,_] => + implicit val eItem = ce.eItem + costedBuilder.mkSizeColl(colBuilder.fromItems(zeroSize(eItem))) + case oe: WOptionElem[_,_] => costedBuilder.mkSizeOption(specialPredef.some(zeroSize(oe.eItem))) + case _: BaseElem[_] | _: EntityElem[_] => costedBuilder.mkSizePrim(0L, eVal) + case _ => !!!(s"Cannot create zeroSize($eVal)") + }) + + val CM = CollMethods + private val CBM = CollBuilderMethods + private val WOptionM = WOptionMethods + private val SPCM = WSpecialPredefCompanionMethods + + def colBuilder: Ref[CollBuilder] + def costedBuilder: Ref[CostedBuilder] + def intPlusMonoid: Ref[Monoid[Int]] + def longPlusMonoid: Ref[Monoid[Long]] + + val intPlusMonoidValue = new special.collection.MonoidBuilderInst().intPlusMonoid + val longPlusMonoidValue = new special.collection.MonoidBuilderInst().longPlusMonoid + + object IsNumericToInt { + def unapply(d: Def[_]): Nullable[Ref[A] forSome {type A}] = d match { + case ApplyUnOp(_: NumericToInt[_], x) => Nullable(x.asInstanceOf[Ref[A] forSome {type A}]) + case _ => Nullable.None + } + } + object IsNumericToLong { + def unapply(d: Def[_]): Nullable[Ref[A] forSome {type A}] = d match { + case ApplyUnOp(_: NumericToLong[_], x) => Nullable(x.asInstanceOf[Ref[A] forSome {type A}]) + case _ => Nullable.None + } + } + + override def rewriteDef[T](d: Def[T]) = d match { + case CM.length(ys) => ys.node match { + // Rule: xs.map(f).length ==> xs.length + case CM.map(xs, _) => + xs.length + // Rule: replicate(len, v).length => len + case CBM.replicate(_, len, _) => + len + // Rule: Const[Coll[T]](coll).length => + case CollConst(coll, _) => + coll.length + // Rule: Coll(items @ Seq(x1, x2, x3)).length => items.length + case CBM.fromItems(_, items, _) => + items.length + case _ => super.rewriteDef(d) + } + + case IsNumericToLong(Def(IsNumericToInt(x))) if x.elem == LongElement => x + + // Rule: replicate(l, x).zip(replicate(l, y)) ==> replicate(l, (x,y)) + case CM.zip(CBM.replicate(b1, l1, v1), CBM.replicate(b2, l2, v2)) if b1 == b2 && l1 == l2 => + b1.replicate(l1, Pair(v1, v2)) + + case CM.map(xs, _f) => _f.node match { + case IdentityLambda() => xs + case _ => xs.node match { + // Rule: replicate(l, v).map(f) ==> replicate(l, f(v)) + case CBM.replicate(b, l, v: Ref[a]) => + val f = asRep[a => Any](_f) + b.replicate(l, Apply(f, v, false)) + + // Rule: xs.map(f).map(g) ==> xs.map(x => g(f(x))) + case CM.map(_xs, f: RFunc[a, b]) => + implicit val ea = f.elem.eDom + val xs = asRep[Coll[a]](_xs) + val g = asRep[b => Any](_f) + xs.map[Any](fun { x: Ref[a] => g(f(x)) }) + + case _ => super.rewriteDef(d) + } + } + + + case CM.sum(xs, m) => m.node match { + case _: IntPlusMonoid => xs.node match { + case CollConst(coll, lA) if lA.eW == IntElement => + coll.asInstanceOf[SColl[Int]].sum(intPlusMonoidValue) + case CBM.replicate(_, n, x: Ref[Int] @unchecked) => + x * n + case _ => super.rewriteDef(d) + } + case _: LongPlusMonoid => xs.node match { + case CollConst(coll, lA) if lA.eW == LongElement => + coll.asInstanceOf[SColl[Long]].sum(longPlusMonoidValue) + case CBM.replicate(_, n, x: Ref[Long] @unchecked) => + x * n.toLong + case _ => super.rewriteDef(d) + } + case _ => super.rewriteDef(d) + } + + // Rule: opt.fold(None, x => Some(x)) ==> opt + case WOptionM.fold(opt, Def(ThunkDef(SPCM.none(_), _)), Def(Lambda(_, _, x, SPCM.some(y)))) if x == y => opt + + case WOptionM.getOrElse(opt, _) => opt.node match { + // Rule: Some(x).getOrElse(_) ==> x + case SPCM.some(x) => x + case WOptionConst(Some(x), lA) => lA.lift(x) + case _ => super.rewriteDef(d) + } + + case _ => super.rewriteDef(d) + } + + override def invokeUnlifted(e: Elem[_], mc: MethodCall, dataEnv: DataEnv): AnyRef = e match { + case _: CollElem[_,_] => mc match { + case CollMethods.map(xs, f) => + val newMC = mc.copy(args = mc.args :+ f.elem.eRange)(mc.resultType, mc.isAdapterCall) + super.invokeUnlifted(e, newMC, dataEnv) + case _ => + super.invokeUnlifted(e, mc, dataEnv) + } + case _ => + super.invokeUnlifted(e, mc, dataEnv) + } + +} diff --git a/library/src/main/scala/special/collection/CollsUnit.scala b/library/src/main/scala/special/collection/CollsUnit.scala new file mode 100644 index 0000000000..3790012d1c --- /dev/null +++ b/library/src/main/scala/special/collection/CollsUnit.scala @@ -0,0 +1,80 @@ +package special.collection { + import scalan._ + + trait Colls extends Base { self: Library => + import Coll._; + import CollBuilder._; + import Monoid._; + import MonoidBuilder._; + import PairColl._; + import WOption._; + @ContainerType @FunctorType @Liftable @WithMethodCallRecognizers trait Coll[A] extends Def[Coll[A]] { + implicit def eA: Elem[A]; + def builder: Ref[CollBuilder]; + def length: Ref[Int]; + def size: Ref[Int] = this.length; + def isEmpty: Ref[Boolean]; + def nonEmpty: Ref[Boolean]; + def apply(i: Ref[Int]): Ref[A]; + def isDefinedAt(idx: Ref[Int]): Ref[Boolean]; + def getOrElse(index: Ref[Int], default: Ref[A]): Ref[A]; + def map[B](f: Ref[scala.Function1[A, B]]): Ref[Coll[B]]; + def zip[B](ys: Ref[Coll[B]]): Ref[Coll[scala.Tuple2[A, B]]]; + def exists(p: Ref[scala.Function1[A, Boolean]]): Ref[Boolean]; + def forall(p: Ref[scala.Function1[A, Boolean]]): Ref[Boolean]; + def filter(p: Ref[scala.Function1[A, Boolean]]): Ref[Coll[A]]; + def foldLeft[B](zero: Ref[B], op: Ref[scala.Function1[scala.Tuple2[B, A], B]]): Ref[B]; + def indices: Ref[Coll[Int]]; + def flatMap[B](f: Ref[scala.Function1[A, Coll[B]]]): Ref[Coll[B]]; + def segmentLength(p: Ref[scala.Function1[A, Boolean]], from: Ref[Int]): Ref[Int]; + @NeverInline def find(p: Ref[scala.Function1[A, Boolean]]): Ref[WOption[A]] = delayInvoke; + def indexWhere(p: Ref[scala.Function1[A, Boolean]], from: Ref[Int]): Ref[Int]; + @NeverInline def indexOf(elem: Ref[A], from: Ref[Int]): Ref[Int] = delayInvoke; + def lastIndexWhere(p: Ref[scala.Function1[A, Boolean]], end: Ref[Int]): Ref[Int]; + def take(n: Ref[Int]): Ref[Coll[A]]; + def partition(pred: Ref[scala.Function1[A, Boolean]]): Ref[scala.Tuple2[Coll[A], Coll[A]]]; + def patch(from: Ref[Int], patch: Ref[Coll[A]], replaced: Ref[Int]): Ref[Coll[A]]; + def updated(index: Ref[Int], elem: Ref[A]): Ref[Coll[A]]; + def updateMany(indexes: Ref[Coll[Int]], values: Ref[Coll[A]]): Ref[Coll[A]]; + def mapReduce[K, V](m: Ref[scala.Function1[A, scala.Tuple2[K, V]]], r: Ref[scala.Function1[scala.Tuple2[V, V], V]]): Ref[Coll[scala.Tuple2[K, V]]]; + @NeverInline def groupBy[K](key: Ref[scala.Function1[A, K]]): Ref[Coll[scala.Tuple2[K, Coll[A]]]] = delayInvoke; + @NeverInline def groupByProjecting[K, V](key: Ref[scala.Function1[A, K]], proj: Ref[scala.Function1[A, V]]): Ref[Coll[scala.Tuple2[K, Coll[V]]]] = delayInvoke; + def unionSet(that: Ref[Coll[A]]): Ref[Coll[A]]; + @NeverInline def diff(that: Ref[Coll[A]]): Ref[Coll[A]] = delayInvoke; + @NeverInline def intersect(that: Ref[Coll[A]]): Ref[Coll[A]] = delayInvoke; + def sum(m: Ref[Monoid[A]]): Ref[A]; + def slice(from: Ref[Int], until: Ref[Int]): Ref[Coll[A]]; + def append(other: Ref[Coll[A]]): Ref[Coll[A]]; + def reverse: Ref[Coll[A]] + }; + @WithMethodCallRecognizers trait PairColl[L, R] extends Coll[scala.Tuple2[L, R]] { + implicit def eL: Elem[L]; + implicit def eR: Elem[R]; + def ls: Ref[Coll[L]]; + def rs: Ref[Coll[R]]; + def mapFirst[T1](f: Ref[scala.Function1[L, T1]]): Ref[Coll[scala.Tuple2[T1, R]]]; + def mapSecond[T1](f: Ref[scala.Function1[R, T1]]): Ref[Coll[scala.Tuple2[L, T1]]] + }; + @Liftable @WithMethodCallRecognizers trait ReplColl[A] extends Coll[A] { + implicit def eA: Elem[A]; + def value: Ref[A]; + def length: Ref[Int]; + def append(other: Ref[Coll[A]]): Ref[Coll[A]] + }; + @Liftable @WithMethodCallRecognizers trait CollBuilder extends Def[CollBuilder] { + def Monoids: Ref[MonoidBuilder]; + def pairColl[A, B](as: Ref[Coll[A]], bs: Ref[Coll[B]]): Ref[PairColl[A, B]]; + @Reified(value = "T") def fromItems[T](items: Ref[T]*)(implicit cT: Elem[T]): Ref[Coll[T]]; + def unzip[A, B](xs: Ref[Coll[scala.Tuple2[A, B]]]): Ref[scala.Tuple2[Coll[A], Coll[B]]]; + def xor(left: Ref[Coll[Byte]], right: Ref[Coll[Byte]]): Ref[Coll[Byte]]; + def replicate[T](n: Ref[Int], v: Ref[T]): Ref[Coll[T]]; + def emptyColl[T](implicit tT: Elem[T]): Ref[Coll[T]]; + def outerJoin[K, L, R, O](left: Ref[Coll[scala.Tuple2[K, L]]], right: Ref[Coll[scala.Tuple2[K, R]]])(l: Ref[scala.Function1[scala.Tuple2[K, L], O]], r: Ref[scala.Function1[scala.Tuple2[K, R], O]], inner: Ref[scala.Function1[scala.Tuple2[K, scala.Tuple2[L, R]], O]]): Ref[Coll[scala.Tuple2[K, O]]]; + def flattenColl[A](coll: Ref[Coll[Coll[A]]]): Ref[Coll[A]] + }; + trait CollCompanion; + trait PairCollCompanion; + trait ReplCollCompanion; + trait CollBuilderCompanion + } +} \ No newline at end of file diff --git a/library/src/main/scala/special/collection/ConcreteCostsUnit.scala b/library/src/main/scala/special/collection/ConcreteCostsUnit.scala new file mode 100644 index 0000000000..72573b0e57 --- /dev/null +++ b/library/src/main/scala/special/collection/ConcreteCostsUnit.scala @@ -0,0 +1,100 @@ +package special.collection { + import scalan._ + + trait ConcreteCosts extends Base { self: Library => + import CCostedBuilder._; + import CCostedColl._; + import CCostedFunc._; + import CCostedOption._; + import CCostedPair._; + import CCostedPrim._; + import CSizeColl._; + import CSizeFunc._; + import CSizeOption._; + import CSizePair._; + import CSizePrim._; + import Coll._; + import Costed._; + import CostedBuilder._; + import CostedColl._; + import CostedFunc._; + import CostedOption._; + import CostedPair._; + import CostedPrim._; + import MonoidBuilder._; + import MonoidBuilderInst._; + import Size._; + import SizeColl._; + import SizeFunc._; + import SizeOption._; + import SizePair._; + import SizePrim._; + import WOption._; + import WRType._; + import WSpecialPredef._; + abstract class CCostedPrim[Val](val value: Ref[Val], val cost: Ref[Int], val size: Ref[Size[Val]]) extends CostedPrim[Val] { + def builder: Ref[CostedBuilder] = RCCostedBuilder() + }; + abstract class CCostedPair[L, R](val l: Ref[Costed[L]], val r: Ref[Costed[R]], val accCost: Ref[Int]) extends CostedPair[L, R] { + def builder: Ref[CostedBuilder] = RCCostedBuilder(); + def value: Ref[scala.Tuple2[L, R]] = Pair(CCostedPair.this.l.value, CCostedPair.this.r.value); + @NeverInline def cost: Ref[Int] = delayInvoke; + def size: Ref[Size[scala.Tuple2[L, R]]] = CCostedPair.this.builder.mkSizePair[L, R](CCostedPair.this.l.size, CCostedPair.this.r.size) + }; + abstract class CCostedFunc[Env, Arg, Res](val envCosted: Ref[Costed[Env]], val func: Ref[scala.Function1[Costed[Arg], Costed[Res]]], val cost: Ref[Int], val size: Ref[Size[scala.Function1[Arg, Res]]]) extends CostedFunc[Env, Arg, Res] { + def builder: Ref[CostedBuilder] = RCCostedBuilder(); + @NeverInline def value: Ref[scala.Function1[Arg, Res]] = delayInvoke + + // manual fix + lazy val sliceCalc: Ref[Arg => Res] = fun { x: Ref[Arg] => func(RCCostedPrim(x, 0, zeroSize(x.elem))).value } + + // manual fix + lazy val sliceCost: Ref[((Int,Size[Arg])) => Int] = fun { in: Ref[(Int, Size[Arg])] => + val Pair(c, s) = in + func(RCCostedPrim(placeholder[Arg], c, s)).cost + } + + // manual fix + lazy val sliceCostEx: Ref[((Arg, (Int,Size[Arg]))) => Int] = fun { in: Ref[(Arg, (Int, Size[Arg]))] => + val Pair(ctx, Pair(c, s)) = in + func(RCCostedPrim(ctx, c, s)).cost + } + + // manual fix + lazy val sliceSize: Ref[Size[Arg] => Size[Res]] = fun { in: Ref[Size[Arg]] => + val s = in + val arg = RCCostedPrim(placeholder[Arg], 0, s) + func(arg).size + } + }; + abstract class CCostedColl[Item](val values: Ref[Coll[Item]], val costs: Ref[Coll[Int]], val sizes: Ref[Coll[Size[Item]]], val valuesCost: Ref[Int]) extends CostedColl[Item] { + def builder: Ref[CostedBuilder] = RCCostedBuilder(); + def value: Ref[Coll[Item]] = CCostedColl.this.values; + @NeverInline def cost: Ref[Int] = delayInvoke; + def size: Ref[Size[Coll[Item]]] = CCostedColl.this.builder.mkSizeColl[Item](CCostedColl.this.sizes); + @NeverInline def mapCosted[Res](f: Ref[scala.Function1[Costed[Item], Costed[Res]]]): Ref[CostedColl[Res]] = delayInvoke; + @NeverInline def filterCosted(f: Ref[scala.Function1[Costed[Item], Costed[Boolean]]]): Ref[CostedColl[Item]] = delayInvoke; + @NeverInline def foldCosted[B](zero: Ref[Costed[B]], op: Ref[scala.Function1[Costed[scala.Tuple2[B, Item]], Costed[B]]]): Ref[Costed[B]] = delayInvoke + }; + abstract class CCostedBuilder extends CostedBuilder { + def monoidBuilder: Ref[MonoidBuilder] = RMonoidBuilderInst(); + @NeverInline def costedValue[T](x: Ref[T], optCost: Ref[WOption[Int]]): Ref[Costed[T]] = delayInvoke; + @NeverInline def defaultValue[T](valueType: Ref[WRType[T]]): Ref[T] = delayInvoke; + def mkSizePrim[T](dataSize: Ref[Long], tT: Ref[WRType[T]]): Ref[SizePrim[T]] = RCSizePrim(dataSize, tT); + def mkSizePair[L, R](l: Ref[Size[L]], r: Ref[Size[R]]): Ref[SizePair[L, R]] = RCSizePair(l, r); + def mkSizeColl[T](sizes: Ref[Coll[Size[T]]]): Ref[SizeColl[T]] = RCSizeColl(sizes); + def mkSizeFunc[E, A, R](sizeEnv: Ref[Size[E]], sizeFunc: Ref[Long], tA: Ref[WRType[A]], tR: Ref[WRType[R]]): Ref[SizeFunc[E, A, R]] = RCSizeFunc(sizeEnv, sizeFunc, tA, tR); + def mkSizeOption[T](sizeOpt: Ref[WOption[Size[T]]]): Ref[SizeOption[T]] = RCSizeOption(sizeOpt); + def mkCostedPrim[T](value: Ref[T], cost: Ref[Int], size: Ref[Size[T]]): Ref[CostedPrim[T]] = RCCostedPrim(value, cost, size); + def mkCostedPair[L, R](first: Ref[Costed[L]], second: Ref[Costed[R]], accCost: Ref[Int]): Ref[CostedPair[L, R]] = RCCostedPair(first, second, accCost); + def mkCostedFunc[Env, Arg, Res](envCosted: Ref[Costed[Env]], func: Ref[scala.Function1[Costed[Arg], Costed[Res]]], cost: Ref[Int], size: Ref[Size[scala.Function1[Arg, Res]]]): Ref[CostedFunc[Env, Arg, Res]] = RCCostedFunc(envCosted, func, cost, size); + def mkCostedColl[T](values: Ref[Coll[T]], costs: Ref[Coll[Int]], sizes: Ref[Coll[Size[T]]], valuesCost: Ref[Int]): Ref[CostedColl[T]] = RCCostedColl(values, costs, sizes, valuesCost); + def mkCostedOption[T](value: Ref[WOption[T]], costOpt: Ref[WOption[Int]], sizeOpt: Ref[WOption[Size[T]]], accumulatedCost: Ref[Int]): Ref[CostedOption[T]] = RCCostedOption(value, costOpt, sizeOpt, accumulatedCost) + }; + trait CCostedPrimCompanion; + trait CCostedPairCompanion; + trait CCostedFuncCompanion; + trait CCostedCollCompanion; + trait CCostedBuilderCompanion + } +} \ No newline at end of file diff --git a/library/src/main/scala/special/collection/ConcreteSizesUnit.scala b/library/src/main/scala/special/collection/ConcreteSizesUnit.scala new file mode 100644 index 0000000000..51a8c42da8 --- /dev/null +++ b/library/src/main/scala/special/collection/ConcreteSizesUnit.scala @@ -0,0 +1,29 @@ +package special.collection { + import scalan._ + + trait ConcreteSizes extends Base { self: Library => + import SizeColl._; + import SizeFunc._; + import SizeOption._; + import SizePair._; + import SizePrim._; + abstract class CSizePrim[Val](val dataSize: Ref[Long], val tVal: Ref[WRType[Val]]) extends SizePrim[Val]; + abstract class CSizePair[L, R](val l: Ref[Size[L]], val r: Ref[Size[R]]) extends SizePair[L, R] { + @NeverInline def dataSize: Ref[Long] = delayInvoke + }; + abstract class CSizeColl[Item](val sizes: Ref[Coll[Size[Item]]]) extends SizeColl[Item] { + @NeverInline def dataSize: Ref[Long] = delayInvoke + }; + abstract class CSizeFunc[Env, Arg, Res](val sizeEnv: Ref[Size[Env]], val sizeFunc: Ref[Long], val tArg: Ref[WRType[Arg]], val tRes: Ref[WRType[Res]]) extends SizeFunc[Env, Arg, Res] { + @NeverInline def dataSize: Ref[Long] = delayInvoke + }; + abstract class CSizeOption[Item](val sizeOpt: Ref[WOption[Size[Item]]]) extends SizeOption[Item] { + @NeverInline def dataSize: Ref[Long] = delayInvoke + }; + trait CSizePrimCompanion; + trait CSizePairCompanion; + trait CSizeCollCompanion; + trait CSizeFuncCompanion; + trait CSizeOptionCompanion + } +} \ No newline at end of file diff --git a/library/src/main/scala/special/collection/CostedOptionsUnit.scala b/library/src/main/scala/special/collection/CostedOptionsUnit.scala new file mode 100644 index 0000000000..09b79625cb --- /dev/null +++ b/library/src/main/scala/special/collection/CostedOptionsUnit.scala @@ -0,0 +1,18 @@ +package special.collection { + import scalan._ + + trait CostedOptions extends Base { self: Library => + import CCostedBuilder._; + import CostedBuilder._; + import CostedOption._; + import Size._; + import SizeOption._; + import WOption._; + abstract class CCostedOption[T](val value: Ref[WOption[T]], val costOpt: Ref[WOption[Int]], val sizeOpt: Ref[WOption[Size[T]]], val accumulatedCost: Ref[Int]) extends CostedOption[T] { + def builder: Ref[CostedBuilder] = RCCostedBuilder(); + @NeverInline def cost: Ref[Int] = delayInvoke; + def size: Ref[Size[WOption[T]]] = CCostedOption.this.builder.mkSizeOption[T](CCostedOption.this.sizeOpt) + }; + trait CCostedOptionCompanion + } +} \ No newline at end of file diff --git a/library/src/main/scala/special/collection/CostsUnit.scala b/library/src/main/scala/special/collection/CostsUnit.scala new file mode 100644 index 0000000000..1aafb601a7 --- /dev/null +++ b/library/src/main/scala/special/collection/CostsUnit.scala @@ -0,0 +1,97 @@ +package special.collection { + import scalan._ + + trait Costs extends Base { self: Library => + import Coll._; + import Costed._; + import CostedBuilder._; + import CostedColl._; + import CostedFunc._; + import CostedOption._; + import CostedPair._; + import CostedPrim._; + import MonoidBuilder._; + import Size._; + import SizeColl._; + import SizeFunc._; + import SizeOption._; + import SizePair._; + import SizePrim._; + import WOption._; + import WRType._; + @WithMethodCallRecognizers trait Costed[Val] extends Def[Costed[Val]] { + implicit def eVal: Elem[Val]; + def builder: Ref[CostedBuilder]; + def value: Ref[Val]; + def cost: Ref[Int]; + def size: Ref[Size[Val]] + }; + trait CostedPrim[Val] extends Costed[Val] { + implicit def eVal: Elem[Val]; + def value: Ref[Val]; + def cost: Ref[Int]; + def size: Ref[Size[Val]] + }; + trait CostedPair[L, R] extends Costed[scala.Tuple2[L, R]] { + implicit def eL: Elem[L]; + implicit def eR: Elem[R]; + def l: Ref[Costed[L]]; + def r: Ref[Costed[R]]; + def accCost: Ref[Int] + }; + trait CostedFunc[Env, Arg, Res] extends Costed[scala.Function1[Arg, Res]] { + implicit def eEnv: Elem[Env]; + implicit def eArg: Elem[Arg]; + implicit def eRes: Elem[Res]; + def envCosted: Ref[Costed[Env]]; + def func: Ref[scala.Function1[Costed[Arg], Costed[Res]]]; + def cost: Ref[Int]; + def sliceCalc: Ref[scala.Function1[Arg, Res]]; + def sliceCost: Ref[scala.Function1[scala.Tuple2[Int, Size[Arg]], Int]]; + def sliceCostEx: Ref[scala.Function1[scala.Tuple2[Arg, scala.Tuple2[Int, Size[Arg]]], Int]]; + def sliceSize: Ref[scala.Function1[Size[Arg], Size[Res]]] + }; + @WithMethodCallRecognizers trait CostedColl[Item] extends Costed[Coll[Item]] { + implicit def eItem: Elem[Item]; + def values: Ref[Coll[Item]]; + def costs: Ref[Coll[Int]]; + def sizes: Ref[Coll[Size[Item]]]; + def valuesCost: Ref[Int]; + def mapCosted[Res](f: Ref[scala.Function1[Costed[Item], Costed[Res]]]): Ref[CostedColl[Res]]; + def filterCosted(f: Ref[scala.Function1[Costed[Item], Costed[Boolean]]]): Ref[CostedColl[Item]]; + def foldCosted[B](zero: Ref[Costed[B]], op: Ref[scala.Function1[Costed[scala.Tuple2[B, Item]], Costed[B]]]): Ref[Costed[B]] + }; + trait CostedOption[T] extends Costed[WOption[T]] { + implicit def eT: Elem[T]; + def costOpt: Ref[WOption[Int]]; + def sizeOpt: Ref[WOption[Size[T]]]; + def accumulatedCost: Ref[Int] + }; + @WithMethodCallRecognizers trait CostedBuilder extends Def[CostedBuilder] { + def ConstructTupleCost: Ref[Int] = toRep(1.asInstanceOf[Int]); + def ConstructSumCost: Ref[Int] = toRep(1.asInstanceOf[Int]); + def SelectFieldCost: Ref[Int] = toRep(1.asInstanceOf[Int]); + def SumTagSize: Ref[Long] = toRep(1L.asInstanceOf[Long]); + def costedValue[T](x: Ref[T], optCost: Ref[WOption[Int]]): Ref[Costed[T]]; + def defaultValue[T](valueType: Ref[WRType[T]]): Ref[T]; + def monoidBuilder: Ref[MonoidBuilder]; + def mkSizePrim[T](dataSize: Ref[Long], tT: Ref[WRType[T]]): Ref[SizePrim[T]]; + def mkSizePair[L, R](l: Ref[Size[L]], r: Ref[Size[R]]): Ref[SizePair[L, R]]; + def mkSizeColl[T](sizes: Ref[Coll[Size[T]]]): Ref[SizeColl[T]]; + def mkSizeFunc[E, A, R](sizeEnv: Ref[Size[E]], sizeFunc: Ref[Long], tA: Ref[WRType[A]], tR: Ref[WRType[R]]): Ref[SizeFunc[E, A, R]]; + def mkSizeOption[T](sizeOpt: Ref[WOption[Size[T]]]): Ref[SizeOption[T]]; + def mkCostedPrim[T](value: Ref[T], cost: Ref[Int], size: Ref[Size[T]]): Ref[CostedPrim[T]]; + def mkCostedPair[L, R](first: Ref[Costed[L]], second: Ref[Costed[R]], accCost: Ref[Int]): Ref[CostedPair[L, R]]; + def mkCostedFunc[Env, Arg, Res](envCosted: Ref[Costed[Env]], func: Ref[scala.Function1[Costed[Arg], Costed[Res]]], cost: Ref[Int], size: Ref[Size[scala.Function1[Arg, Res]]]): Ref[CostedFunc[Env, Arg, Res]]; + def mkCostedColl[T](values: Ref[Coll[T]], costs: Ref[Coll[Int]], sizes: Ref[Coll[Size[T]]], valuesCost: Ref[Int]): Ref[CostedColl[T]]; + def mkCostedOption[T](value: Ref[WOption[T]], costOpt: Ref[WOption[Int]], sizeOpt: Ref[WOption[Size[T]]], accumulatedCost: Ref[Int]): Ref[CostedOption[T]] + }; + trait CostedCompanion; + trait CostedPrimCompanion; + trait CostedPairCompanion; + trait CostedFuncCompanion; + trait CostedCollCompanion; + trait CostedOptionCompanion; + trait CostedBuilderCompanion + } +} \ No newline at end of file diff --git a/library/src/main/scala/special/collection/MonoidInstancesUnit.scala b/library/src/main/scala/special/collection/MonoidInstancesUnit.scala new file mode 100644 index 0000000000..e083ac4a2f --- /dev/null +++ b/library/src/main/scala/special/collection/MonoidInstancesUnit.scala @@ -0,0 +1,27 @@ +package special.collection { + import scalan._ + + trait MonoidInstances extends Base { self: Library => + import IntPlusMonoid._; + import LongPlusMonoid._; + import Monoid._; + import MonoidBuilder._; + abstract class MonoidBuilderInst extends MonoidBuilder { + val `intPlusMonoid ` : Ref[IntPlusMonoid] = RIntPlusMonoid(toRep(0.asInstanceOf[Int])); + def intPlusMonoid: Ref[IntPlusMonoid] = MonoidBuilderInst.this.`intPlusMonoid `; + val `longPlusMonoid ` : Ref[LongPlusMonoid] = RLongPlusMonoid(toRep(0L.asInstanceOf[Long])); + def longPlusMonoid: Ref[LongPlusMonoid] = MonoidBuilderInst.this.`longPlusMonoid `; + }; + abstract class IntPlusMonoid(val zero: Ref[Int]) extends Monoid[Int] { + def plus(x: Ref[Int], y: Ref[Int]): Ref[Int] = x.+(y); + def power(x: Ref[Int], n: Ref[Int]): Ref[Int] = x.*(n) + }; + abstract class LongPlusMonoid(val zero: Ref[Long]) extends Monoid[Long] { + def plus(x: Ref[Long], y: Ref[Long]): Ref[Long] = x.+(y); + def power(x: Ref[Long], n: Ref[Int]): Ref[Long] = x.*(n.toLong) + }; + trait MonoidBuilderInstCompanion; + trait IntPlusMonoidCompanion; + trait LongPlusMonoidCompanion; + } +} \ No newline at end of file diff --git a/library/src/main/scala/special/collection/MonoidsUnit.scala b/library/src/main/scala/special/collection/MonoidsUnit.scala new file mode 100644 index 0000000000..02b02bd57b --- /dev/null +++ b/library/src/main/scala/special/collection/MonoidsUnit.scala @@ -0,0 +1,20 @@ +package special.collection { + import scalan._ + + trait Monoids extends Base { self: Library => + import Monoid._; + import MonoidBuilder._; + trait Monoid[T] extends Def[Monoid[T]] { + implicit def eT: Elem[T]; + def zero: Ref[T]; + def plus(x: Ref[T], y: Ref[T]): Ref[T]; + def power(x: Ref[T], n: Ref[Int]): Ref[T] + }; + @WithMethodCallRecognizers trait MonoidBuilder extends Def[MonoidBuilder] { + def intPlusMonoid: Ref[Monoid[Int]]; + def longPlusMonoid: Ref[Monoid[Long]]; + }; + trait MonoidCompanion; + trait MonoidBuilderCompanion + } +} \ No newline at end of file diff --git a/library/src/main/scala/special/collection/SizesUnit.scala b/library/src/main/scala/special/collection/SizesUnit.scala new file mode 100644 index 0000000000..b1eecfb3af --- /dev/null +++ b/library/src/main/scala/special/collection/SizesUnit.scala @@ -0,0 +1,45 @@ +package special.collection { + import scalan._ + + trait Sizes extends Base { self: Library => + import Coll._; + import Size._; + import WOption._; + import WRType._; + @Liftable @WithMethodCallRecognizers trait Size[Val] extends Def[Size[Val]] { + implicit def eVal: Elem[Val]; + def dataSize: Ref[Long] + }; + @Liftable trait SizePrim[Val] extends Size[Val] { + implicit def eVal: Elem[Val]; + def dataSize: Ref[Long]; + def tVal: Ref[WRType[Val]] + }; + @Liftable @WithMethodCallRecognizers trait SizePair[L, R] extends Size[scala.Tuple2[L, R]] { + implicit def eL: Elem[L]; + implicit def eR: Elem[R]; + def l: Ref[Size[L]]; + def r: Ref[Size[R]] + }; + @Liftable @WithMethodCallRecognizers trait SizeColl[Item] extends Size[Coll[Item]] { + implicit def eItem: Elem[Item]; + def sizes: Ref[Coll[Size[Item]]] + }; + @Liftable @WithMethodCallRecognizers trait SizeFunc[Env, Arg, Res] extends Size[scala.Function1[Arg, Res]] { + implicit def eEnv: Elem[Env]; + implicit def eArg: Elem[Arg]; + implicit def eRes: Elem[Res]; + def sizeEnv: Ref[Size[Env]] + }; + @Liftable @WithMethodCallRecognizers trait SizeOption[T] extends Size[WOption[T]] { + implicit def eT: Elem[T]; + def sizeOpt: Ref[WOption[Size[T]]] + }; + trait SizeCompanion; + trait SizePrimCompanion; + trait SizePairCompanion; + trait SizeCollCompanion; + trait SizeFuncCompanion; + trait SizeOptionCompanion + } +} \ No newline at end of file diff --git a/library/src/main/scala/special/collection/impl/CollsImpl.scala b/library/src/main/scala/special/collection/impl/CollsImpl.scala new file mode 100644 index 0000000000..73c4e29bd1 --- /dev/null +++ b/library/src/main/scala/special/collection/impl/CollsImpl.scala @@ -0,0 +1,2138 @@ +package special.collection + +import scalan._ +import scala.reflect.runtime.universe._ +import scala.reflect._ +import scala.collection.mutable.WrappedArray + +package impl { +// Abs ----------------------------------- +trait CollsDefs extends scalan.Scalan with Colls { + self: Library => +import Coll._ +import CollBuilder._ +import Monoid._ +import MonoidBuilder._ +import PairColl._ +import WOption._ +import ReplColl._ + +object Coll extends EntityObject("Coll") { + // entityConst: single const for each entity + import Liftables._ + import scala.reflect.{ClassTag, classTag} + type SColl[A] = special.collection.Coll[A] + case class CollConst[SA, A]( + constValue: SColl[SA], + lA: Liftable[SA, A] + ) extends LiftedConst[SColl[SA], Coll[A]] with Coll[A] + with Def[Coll[A]] with CollConstMethods[A] { + implicit final def eA: Elem[A] = lA.eW + + val liftable: Liftable[SColl[SA], Coll[A]] = liftableColl(lA) + val resultType: Elem[Coll[A]] = liftable.eW + } + + trait CollConstMethods[A] extends Coll[A] { thisConst: Def[_] => + implicit def eA: Elem[A] + private val CollClass = classOf[Coll[A]] + + override def builder: Ref[CollBuilder] = { + asRep[CollBuilder](mkMethodCall(self, + CollClass.getMethod("builder"), + WrappedArray.empty, + true, false, element[CollBuilder])) + } + + override def length: Ref[Int] = { + asRep[Int](mkMethodCall(self, + CollClass.getMethod("length"), + WrappedArray.empty, + true, false, element[Int])) + } + + override def isEmpty: Ref[Boolean] = { + asRep[Boolean](mkMethodCall(self, + CollClass.getMethod("isEmpty"), + WrappedArray.empty, + true, false, element[Boolean])) + } + + override def nonEmpty: Ref[Boolean] = { + asRep[Boolean](mkMethodCall(self, + CollClass.getMethod("nonEmpty"), + WrappedArray.empty, + true, false, element[Boolean])) + } + + override def apply(i: Ref[Int]): Ref[A] = { + asRep[A](mkMethodCall(self, + CollClass.getMethod("apply", classOf[Sym]), + Array[AnyRef](i), + true, false, element[A])) + } + + override def isDefinedAt(idx: Ref[Int]): Ref[Boolean] = { + asRep[Boolean](mkMethodCall(self, + CollClass.getMethod("isDefinedAt", classOf[Sym]), + Array[AnyRef](idx), + true, false, element[Boolean])) + } + + override def getOrElse(index: Ref[Int], default: Ref[A]): Ref[A] = { + asRep[A](mkMethodCall(self, + CollClass.getMethod("getOrElse", classOf[Sym], classOf[Sym]), + Array[AnyRef](index, default), + true, false, element[A])) + } + + override def map[B](f: Ref[A => B]): Ref[Coll[B]] = { + implicit val eB = f.elem.eRange + asRep[Coll[B]](mkMethodCall(self, + CollClass.getMethod("map", classOf[Sym]), + Array[AnyRef](f), + true, false, element[Coll[B]])) + } + + override def zip[B](ys: Ref[Coll[B]]): Ref[Coll[(A, B)]] = { + implicit val eB = ys.eA + asRep[Coll[(A, B)]](mkMethodCall(self, + CollClass.getMethod("zip", classOf[Sym]), + Array[AnyRef](ys), + true, false, element[Coll[(A, B)]])) + } + + override def exists(p: Ref[A => Boolean]): Ref[Boolean] = { + asRep[Boolean](mkMethodCall(self, + CollClass.getMethod("exists", classOf[Sym]), + Array[AnyRef](p), + true, false, element[Boolean])) + } + + override def forall(p: Ref[A => Boolean]): Ref[Boolean] = { + asRep[Boolean](mkMethodCall(self, + CollClass.getMethod("forall", classOf[Sym]), + Array[AnyRef](p), + true, false, element[Boolean])) + } + + override def filter(p: Ref[A => Boolean]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(self, + CollClass.getMethod("filter", classOf[Sym]), + Array[AnyRef](p), + true, false, element[Coll[A]])) + } + + override def foldLeft[B](zero: Ref[B], op: Ref[((B, A)) => B]): Ref[B] = { + implicit val eB = zero.elem + asRep[B](mkMethodCall(self, + CollClass.getMethod("foldLeft", classOf[Sym], classOf[Sym]), + Array[AnyRef](zero, op), + true, false, element[B])) + } + + override def indices: Ref[Coll[Int]] = { + asRep[Coll[Int]](mkMethodCall(self, + CollClass.getMethod("indices"), + WrappedArray.empty, + true, false, element[Coll[Int]])) + } + + override def flatMap[B](f: Ref[A => Coll[B]]): Ref[Coll[B]] = { + implicit val eB = f.elem.eRange.typeArgs("A")._1.asInstanceOf[Elem[B]] + asRep[Coll[B]](mkMethodCall(self, + CollClass.getMethod("flatMap", classOf[Sym]), + Array[AnyRef](f), + true, false, element[Coll[B]])) + } + + override def segmentLength(p: Ref[A => Boolean], from: Ref[Int]): Ref[Int] = { + asRep[Int](mkMethodCall(self, + CollClass.getMethod("segmentLength", classOf[Sym], classOf[Sym]), + Array[AnyRef](p, from), + true, false, element[Int])) + } + + override def find(p: Ref[A => Boolean]): Ref[WOption[A]] = { + asRep[WOption[A]](mkMethodCall(self, + CollClass.getMethod("find", classOf[Sym]), + Array[AnyRef](p), + true, false, element[WOption[A]])) + } + + override def indexWhere(p: Ref[A => Boolean], from: Ref[Int]): Ref[Int] = { + asRep[Int](mkMethodCall(self, + CollClass.getMethod("indexWhere", classOf[Sym], classOf[Sym]), + Array[AnyRef](p, from), + true, false, element[Int])) + } + + override def indexOf(elem: Ref[A], from: Ref[Int]): Ref[Int] = { + asRep[Int](mkMethodCall(self, + CollClass.getMethod("indexOf", classOf[Sym], classOf[Sym]), + Array[AnyRef](elem, from), + true, false, element[Int])) + } + + override def lastIndexWhere(p: Ref[A => Boolean], end: Ref[Int]): Ref[Int] = { + asRep[Int](mkMethodCall(self, + CollClass.getMethod("lastIndexWhere", classOf[Sym], classOf[Sym]), + Array[AnyRef](p, end), + true, false, element[Int])) + } + + override def take(n: Ref[Int]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(self, + CollClass.getMethod("take", classOf[Sym]), + Array[AnyRef](n), + true, false, element[Coll[A]])) + } + + override def partition(pred: Ref[A => Boolean]): Ref[(Coll[A], Coll[A])] = { + asRep[(Coll[A], Coll[A])](mkMethodCall(self, + CollClass.getMethod("partition", classOf[Sym]), + Array[AnyRef](pred), + true, false, element[(Coll[A], Coll[A])])) + } + + override def patch(from: Ref[Int], patch: Ref[Coll[A]], replaced: Ref[Int]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(self, + CollClass.getMethod("patch", classOf[Sym], classOf[Sym], classOf[Sym]), + Array[AnyRef](from, patch, replaced), + true, false, element[Coll[A]])) + } + + override def updated(index: Ref[Int], elem: Ref[A]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(self, + CollClass.getMethod("updated", classOf[Sym], classOf[Sym]), + Array[AnyRef](index, elem), + true, false, element[Coll[A]])) + } + + override def updateMany(indexes: Ref[Coll[Int]], values: Ref[Coll[A]]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(self, + CollClass.getMethod("updateMany", classOf[Sym], classOf[Sym]), + Array[AnyRef](indexes, values), + true, false, element[Coll[A]])) + } + + override def mapReduce[K, V](m: Ref[A => (K, V)], r: Ref[((V, V)) => V]): Ref[Coll[(K, V)]] = { + implicit val eK = m.elem.eRange.eFst +implicit val eV = m.elem.eRange.eSnd + asRep[Coll[(K, V)]](mkMethodCall(self, + CollClass.getMethod("mapReduce", classOf[Sym], classOf[Sym]), + Array[AnyRef](m, r), + true, false, element[Coll[(K, V)]])) + } + + override def groupBy[K](key: Ref[A => K]): Ref[Coll[(K, Coll[A])]] = { + implicit val eK = key.elem.eRange + asRep[Coll[(K, Coll[A])]](mkMethodCall(self, + CollClass.getMethod("groupBy", classOf[Sym]), + Array[AnyRef](key), + true, false, element[Coll[(K, Coll[A])]])) + } + + override def groupByProjecting[K, V](key: Ref[A => K], proj: Ref[A => V]): Ref[Coll[(K, Coll[V])]] = { + implicit val eK = key.elem.eRange +implicit val eV = proj.elem.eRange + asRep[Coll[(K, Coll[V])]](mkMethodCall(self, + CollClass.getMethod("groupByProjecting", classOf[Sym], classOf[Sym]), + Array[AnyRef](key, proj), + true, false, element[Coll[(K, Coll[V])]])) + } + + override def unionSet(that: Ref[Coll[A]]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(self, + CollClass.getMethod("unionSet", classOf[Sym]), + Array[AnyRef](that), + true, false, element[Coll[A]])) + } + + override def diff(that: Ref[Coll[A]]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(self, + CollClass.getMethod("diff", classOf[Sym]), + Array[AnyRef](that), + true, false, element[Coll[A]])) + } + + override def intersect(that: Ref[Coll[A]]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(self, + CollClass.getMethod("intersect", classOf[Sym]), + Array[AnyRef](that), + true, false, element[Coll[A]])) + } + + override def sum(m: Ref[Monoid[A]]): Ref[A] = { + asRep[A](mkMethodCall(self, + CollClass.getMethod("sum", classOf[Sym]), + Array[AnyRef](m), + true, false, element[A])) + } + + override def slice(from: Ref[Int], until: Ref[Int]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(self, + CollClass.getMethod("slice", classOf[Sym], classOf[Sym]), + Array[AnyRef](from, until), + true, false, element[Coll[A]])) + } + + override def append(other: Ref[Coll[A]]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(self, + CollClass.getMethod("append", classOf[Sym]), + Array[AnyRef](other), + true, false, element[Coll[A]])) + } + + override def reverse: Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(self, + CollClass.getMethod("reverse"), + WrappedArray.empty, + true, false, element[Coll[A]])) + } + } + + case class LiftableColl[SA, A](lA: Liftable[SA, A]) + extends Liftable[SColl[SA], Coll[A]] { + lazy val eW: Elem[Coll[A]] = collElement(lA.eW) + lazy val sourceType: RType[SColl[SA]] = { + implicit val tagSA = lA.sourceType.asInstanceOf[RType[SA]] + RType[SColl[SA]] + } + def lift(x: SColl[SA]): Ref[Coll[A]] = CollConst(x, lA) + def unlift(w: Ref[Coll[A]]): SColl[SA] = w match { + case Def(CollConst(x: SColl[_], _lA)) + if _lA == lA => x.asInstanceOf[SColl[SA]] + case _ => unliftError(w) + } + } + implicit final def liftableColl[SA, A](implicit lA: Liftable[SA,A]): Liftable[SColl[SA], Coll[A]] = + LiftableColl(lA) + + private val CollClass = classOf[Coll[_]] + + // entityAdapter for Coll trait + case class CollAdapter[A](source: Ref[Coll[A]]) + extends Node with Coll[A] + with Def[Coll[A]] { + implicit lazy val eA = source.elem.typeArgs("A")._1.asInstanceOf[Elem[A]] + + val resultType: Elem[Coll[A]] = element[Coll[A]] + override def transform(t: Transformer) = CollAdapter[A](t(source)) + + def builder: Ref[CollBuilder] = { + asRep[CollBuilder](mkMethodCall(source, + CollClass.getMethod("builder"), + WrappedArray.empty, + true, true, element[CollBuilder])) + } + + def length: Ref[Int] = { + asRep[Int](mkMethodCall(source, + CollClass.getMethod("length"), + WrappedArray.empty, + true, true, element[Int])) + } + + def isEmpty: Ref[Boolean] = { + asRep[Boolean](mkMethodCall(source, + CollClass.getMethod("isEmpty"), + WrappedArray.empty, + true, true, element[Boolean])) + } + + def nonEmpty: Ref[Boolean] = { + asRep[Boolean](mkMethodCall(source, + CollClass.getMethod("nonEmpty"), + WrappedArray.empty, + true, true, element[Boolean])) + } + + def apply(i: Ref[Int]): Ref[A] = { + asRep[A](mkMethodCall(source, + CollClass.getMethod("apply", classOf[Sym]), + Array[AnyRef](i), + true, true, element[A])) + } + + def isDefinedAt(idx: Ref[Int]): Ref[Boolean] = { + asRep[Boolean](mkMethodCall(source, + CollClass.getMethod("isDefinedAt", classOf[Sym]), + Array[AnyRef](idx), + true, true, element[Boolean])) + } + + def getOrElse(index: Ref[Int], default: Ref[A]): Ref[A] = { + asRep[A](mkMethodCall(source, + CollClass.getMethod("getOrElse", classOf[Sym], classOf[Sym]), + Array[AnyRef](index, default), + true, true, element[A])) + } + + def map[B](f: Ref[A => B]): Ref[Coll[B]] = { + implicit val eB = f.elem.eRange + asRep[Coll[B]](mkMethodCall(source, + CollClass.getMethod("map", classOf[Sym]), + Array[AnyRef](f), + true, true, element[Coll[B]])) + } + + def zip[B](ys: Ref[Coll[B]]): Ref[Coll[(A, B)]] = { + implicit val eB = ys.eA + asRep[Coll[(A, B)]](mkMethodCall(source, + CollClass.getMethod("zip", classOf[Sym]), + Array[AnyRef](ys), + true, true, element[Coll[(A, B)]])) + } + + def exists(p: Ref[A => Boolean]): Ref[Boolean] = { + asRep[Boolean](mkMethodCall(source, + CollClass.getMethod("exists", classOf[Sym]), + Array[AnyRef](p), + true, true, element[Boolean])) + } + + def forall(p: Ref[A => Boolean]): Ref[Boolean] = { + asRep[Boolean](mkMethodCall(source, + CollClass.getMethod("forall", classOf[Sym]), + Array[AnyRef](p), + true, true, element[Boolean])) + } + + def filter(p: Ref[A => Boolean]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(source, + CollClass.getMethod("filter", classOf[Sym]), + Array[AnyRef](p), + true, true, element[Coll[A]])) + } + + def foldLeft[B](zero: Ref[B], op: Ref[((B, A)) => B]): Ref[B] = { + implicit val eB = zero.elem + asRep[B](mkMethodCall(source, + CollClass.getMethod("foldLeft", classOf[Sym], classOf[Sym]), + Array[AnyRef](zero, op), + true, true, element[B])) + } + + def indices: Ref[Coll[Int]] = { + asRep[Coll[Int]](mkMethodCall(source, + CollClass.getMethod("indices"), + WrappedArray.empty, + true, true, element[Coll[Int]])) + } + + def flatMap[B](f: Ref[A => Coll[B]]): Ref[Coll[B]] = { + implicit val eB = f.elem.eRange.typeArgs("A")._1.asInstanceOf[Elem[B]] + asRep[Coll[B]](mkMethodCall(source, + CollClass.getMethod("flatMap", classOf[Sym]), + Array[AnyRef](f), + true, true, element[Coll[B]])) + } + + def segmentLength(p: Ref[A => Boolean], from: Ref[Int]): Ref[Int] = { + asRep[Int](mkMethodCall(source, + CollClass.getMethod("segmentLength", classOf[Sym], classOf[Sym]), + Array[AnyRef](p, from), + true, true, element[Int])) + } + + override def find(p: Ref[A => Boolean]): Ref[WOption[A]] = { + asRep[WOption[A]](mkMethodCall(source, + CollClass.getMethod("find", classOf[Sym]), + Array[AnyRef](p), + true, true, element[WOption[A]])) + } + + def indexWhere(p: Ref[A => Boolean], from: Ref[Int]): Ref[Int] = { + asRep[Int](mkMethodCall(source, + CollClass.getMethod("indexWhere", classOf[Sym], classOf[Sym]), + Array[AnyRef](p, from), + true, true, element[Int])) + } + + override def indexOf(elem: Ref[A], from: Ref[Int]): Ref[Int] = { + asRep[Int](mkMethodCall(source, + CollClass.getMethod("indexOf", classOf[Sym], classOf[Sym]), + Array[AnyRef](elem, from), + true, true, element[Int])) + } + + def lastIndexWhere(p: Ref[A => Boolean], end: Ref[Int]): Ref[Int] = { + asRep[Int](mkMethodCall(source, + CollClass.getMethod("lastIndexWhere", classOf[Sym], classOf[Sym]), + Array[AnyRef](p, end), + true, true, element[Int])) + } + + def take(n: Ref[Int]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(source, + CollClass.getMethod("take", classOf[Sym]), + Array[AnyRef](n), + true, true, element[Coll[A]])) + } + + def partition(pred: Ref[A => Boolean]): Ref[(Coll[A], Coll[A])] = { + asRep[(Coll[A], Coll[A])](mkMethodCall(source, + CollClass.getMethod("partition", classOf[Sym]), + Array[AnyRef](pred), + true, true, element[(Coll[A], Coll[A])])) + } + + def patch(from: Ref[Int], patch: Ref[Coll[A]], replaced: Ref[Int]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(source, + CollClass.getMethod("patch", classOf[Sym], classOf[Sym], classOf[Sym]), + Array[AnyRef](from, patch, replaced), + true, true, element[Coll[A]])) + } + + def updated(index: Ref[Int], elem: Ref[A]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(source, + CollClass.getMethod("updated", classOf[Sym], classOf[Sym]), + Array[AnyRef](index, elem), + true, true, element[Coll[A]])) + } + + def updateMany(indexes: Ref[Coll[Int]], values: Ref[Coll[A]]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(source, + CollClass.getMethod("updateMany", classOf[Sym], classOf[Sym]), + Array[AnyRef](indexes, values), + true, true, element[Coll[A]])) + } + + def mapReduce[K, V](m: Ref[A => (K, V)], r: Ref[((V, V)) => V]): Ref[Coll[(K, V)]] = { + implicit val eK = m.elem.eRange.eFst +implicit val eV = m.elem.eRange.eSnd + asRep[Coll[(K, V)]](mkMethodCall(source, + CollClass.getMethod("mapReduce", classOf[Sym], classOf[Sym]), + Array[AnyRef](m, r), + true, true, element[Coll[(K, V)]])) + } + + override def groupBy[K](key: Ref[A => K]): Ref[Coll[(K, Coll[A])]] = { + implicit val eK = key.elem.eRange + asRep[Coll[(K, Coll[A])]](mkMethodCall(source, + CollClass.getMethod("groupBy", classOf[Sym]), + Array[AnyRef](key), + true, true, element[Coll[(K, Coll[A])]])) + } + + override def groupByProjecting[K, V](key: Ref[A => K], proj: Ref[A => V]): Ref[Coll[(K, Coll[V])]] = { + implicit val eK = key.elem.eRange +implicit val eV = proj.elem.eRange + asRep[Coll[(K, Coll[V])]](mkMethodCall(source, + CollClass.getMethod("groupByProjecting", classOf[Sym], classOf[Sym]), + Array[AnyRef](key, proj), + true, true, element[Coll[(K, Coll[V])]])) + } + + def unionSet(that: Ref[Coll[A]]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(source, + CollClass.getMethod("unionSet", classOf[Sym]), + Array[AnyRef](that), + true, true, element[Coll[A]])) + } + + override def diff(that: Ref[Coll[A]]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(source, + CollClass.getMethod("diff", classOf[Sym]), + Array[AnyRef](that), + true, true, element[Coll[A]])) + } + + override def intersect(that: Ref[Coll[A]]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(source, + CollClass.getMethod("intersect", classOf[Sym]), + Array[AnyRef](that), + true, true, element[Coll[A]])) + } + + def sum(m: Ref[Monoid[A]]): Ref[A] = { + asRep[A](mkMethodCall(source, + CollClass.getMethod("sum", classOf[Sym]), + Array[AnyRef](m), + true, true, element[A])) + } + + def slice(from: Ref[Int], until: Ref[Int]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(source, + CollClass.getMethod("slice", classOf[Sym], classOf[Sym]), + Array[AnyRef](from, until), + true, true, element[Coll[A]])) + } + + def append(other: Ref[Coll[A]]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(source, + CollClass.getMethod("append", classOf[Sym]), + Array[AnyRef](other), + true, true, element[Coll[A]])) + } + + def reverse: Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(source, + CollClass.getMethod("reverse"), + WrappedArray.empty, + true, true, element[Coll[A]])) + } + } + + // entityUnref: single unref method for each type family + val createCollAdapter: Ref[Coll[Any]] => Coll[Any] = x => CollAdapter(x) + + implicit final def unrefColl[A](p: Ref[Coll[A]]): Coll[A] = { + val sym = p.asInstanceOf[SingleRef[Coll[A]]] + sym.getAdapter( + p.node.isInstanceOf[Coll[A]@unchecked], + createCollAdapter.asInstanceOf[Ref[Coll[A]] => Coll[A]]) + } + + implicit final def castCollElement[A](elem: Elem[Coll[A]]): CollElem[A, Coll[A]] = + elem.asInstanceOf[CollElem[A, Coll[A]]] + + implicit lazy val containerColl: Functor[Coll] = new Functor[Coll] { + def lift[A](implicit evA: Elem[A]) = element[Coll[A]] + def unlift[A](implicit eFT: Elem[Coll[A]]) = + castCollElement(eFT).eA + def unapply[T](e: Elem[_]) = e match { + case e: CollElem[_,_] => Some(asElem[Coll[T]](e)) + case _ => None + } + def map[A,B](xs: Ref[Coll[A]])(f: Ref[A] => Ref[B]) = { implicit val eA = unlift(xs.elem); xs.map(fun(f))} + } + + // manual fix: CollIso, collIso + + // familyElem + class CollElem[A, To <: Coll[A]](implicit _eA: Elem[A]) + extends EntityElem1[A, To, Coll](_eA, container[Coll]) { + def eA = _eA + + override val liftable: Liftables.Liftable[_, To] = asLiftable[SColl[_], To](liftableColl(_eA.liftable)) + + override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { + super.collectMethods ++ + Elem.declaredMethods(classOf[Coll[A]], classOf[SColl[_]], Set( + "builder", "length", "size", "isEmpty", "nonEmpty", "apply", "isDefinedAt", "getOrElse", "map", "zip", "exists", "forall", "filter", "foldLeft", "indices", "flatMap", "segmentLength", "find", "indexWhere", "indexOf", "lastIndexWhere", "take", "partition", "patch", "updated", "updateMany", "mapReduce", "groupBy", "groupByProjecting", "unionSet", "diff", "intersect", "sum", "slice", "append", "reverse" + )) + } + + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("A" -> (eA -> scalan.util.Invariant)) + } + + implicit final def collElement[A](implicit eA: Elem[A]): Elem[Coll[A]] = + cachedElemByClass(eA)(classOf[CollElem[A, Coll[A]]]) + + implicit case object CollCompanionElem extends CompanionElem[CollCompanionCtor] + + abstract class CollCompanionCtor extends CompanionDef[CollCompanionCtor] with CollCompanion { + def resultType = CollCompanionElem + override def toString = "Coll" + } + implicit final def unrefCollCompanionCtor(p: Ref[CollCompanionCtor]): CollCompanionCtor = + p.node.asInstanceOf[CollCompanionCtor] + + lazy val RColl: MutableLazy[CollCompanionCtor] = MutableLazy(new CollCompanionCtor { + private val thisClass = classOf[CollCompanion] + }) + + // manual fix: ViewColl + + object CollMethods { + object builder { + def unapply(d: Def[_]): Nullable[Ref[Coll[A]] forSome {type A}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "builder" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[Coll[A]] forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[Coll[A]] forSome {type A}] = unapply(exp.node) + } + + object length { + def unapply(d: Def[_]): Nullable[Ref[Coll[A]] forSome {type A}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "length" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[Coll[A]] forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[Coll[A]] forSome {type A}] = unapply(exp.node) + } + + object size { + def unapply(d: Def[_]): Nullable[Ref[Coll[A]] forSome {type A}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "size" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[Coll[A]] forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[Coll[A]] forSome {type A}] = unapply(exp.node) + } + + object isEmpty { + def unapply(d: Def[_]): Nullable[Ref[Coll[A]] forSome {type A}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "isEmpty" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[Coll[A]] forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[Coll[A]] forSome {type A}] = unapply(exp.node) + } + + object nonEmpty { + def unapply(d: Def[_]): Nullable[Ref[Coll[A]] forSome {type A}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "nonEmpty" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[Coll[A]] forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[Coll[A]] forSome {type A}] = unapply(exp.node) + } + + object apply { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[Int]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "apply" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[Int]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[Int]) forSome {type A}] = unapply(exp.node) + } + + object isDefinedAt { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[Int]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "isDefinedAt" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[Int]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[Int]) forSome {type A}] = unapply(exp.node) + } + + object getOrElse { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[Int], Ref[A]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "getOrElse" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0), args(1)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[Int], Ref[A]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[Int], Ref[A]) forSome {type A}] = unapply(exp.node) + } + + object map { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[A => B]) forSome {type A; type B}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "map" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[A => B]) forSome {type A; type B}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[A => B]) forSome {type A; type B}] = unapply(exp.node) + } + + object zip { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[Coll[B]]) forSome {type A; type B}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "zip" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[Coll[B]]) forSome {type A; type B}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[Coll[B]]) forSome {type A; type B}] = unapply(exp.node) + } + + object exists { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[A => Boolean]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "exists" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[A => Boolean]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[A => Boolean]) forSome {type A}] = unapply(exp.node) + } + + object forall { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[A => Boolean]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "forall" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[A => Boolean]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[A => Boolean]) forSome {type A}] = unapply(exp.node) + } + + object filter { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[A => Boolean]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "filter" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[A => Boolean]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[A => Boolean]) forSome {type A}] = unapply(exp.node) + } + + object foldLeft { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[B], Ref[((B, A)) => B]) forSome {type A; type B}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "foldLeft" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0), args(1)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[B], Ref[((B, A)) => B]) forSome {type A; type B}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[B], Ref[((B, A)) => B]) forSome {type A; type B}] = unapply(exp.node) + } + + object indices { + def unapply(d: Def[_]): Nullable[Ref[Coll[A]] forSome {type A}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "indices" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[Coll[A]] forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[Coll[A]] forSome {type A}] = unapply(exp.node) + } + + object flatMap { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[A => Coll[B]]) forSome {type A; type B}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "flatMap" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[A => Coll[B]]) forSome {type A; type B}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[A => Coll[B]]) forSome {type A; type B}] = unapply(exp.node) + } + + object segmentLength { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[A => Boolean], Ref[Int]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "segmentLength" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0), args(1)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[A => Boolean], Ref[Int]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[A => Boolean], Ref[Int]) forSome {type A}] = unapply(exp.node) + } + + object find { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[A => Boolean]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "find" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[A => Boolean]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[A => Boolean]) forSome {type A}] = unapply(exp.node) + } + + object indexWhere { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[A => Boolean], Ref[Int]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "indexWhere" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0), args(1)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[A => Boolean], Ref[Int]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[A => Boolean], Ref[Int]) forSome {type A}] = unapply(exp.node) + } + + object indexOf { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[A], Ref[Int]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "indexOf" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0), args(1)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[A], Ref[Int]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[A], Ref[Int]) forSome {type A}] = unapply(exp.node) + } + + object lastIndexWhere { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[A => Boolean], Ref[Int]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "lastIndexWhere" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0), args(1)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[A => Boolean], Ref[Int]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[A => Boolean], Ref[Int]) forSome {type A}] = unapply(exp.node) + } + + object take { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[Int]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "take" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[Int]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[Int]) forSome {type A}] = unapply(exp.node) + } + + object partition { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[A => Boolean]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "partition" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[A => Boolean]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[A => Boolean]) forSome {type A}] = unapply(exp.node) + } + + object patch { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[Int], Ref[Coll[A]], Ref[Int]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "patch" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0), args(1), args(2)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[Int], Ref[Coll[A]], Ref[Int]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[Int], Ref[Coll[A]], Ref[Int]) forSome {type A}] = unapply(exp.node) + } + + object updated { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[Int], Ref[A]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "updated" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0), args(1)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[Int], Ref[A]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[Int], Ref[A]) forSome {type A}] = unapply(exp.node) + } + + object updateMany { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[Coll[Int]], Ref[Coll[A]]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "updateMany" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0), args(1)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[Coll[Int]], Ref[Coll[A]]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[Coll[Int]], Ref[Coll[A]]) forSome {type A}] = unapply(exp.node) + } + + object mapReduce { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[A => (K, V)], Ref[((V, V)) => V]) forSome {type A; type K; type V}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "mapReduce" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0), args(1)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[A => (K, V)], Ref[((V, V)) => V]) forSome {type A; type K; type V}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[A => (K, V)], Ref[((V, V)) => V]) forSome {type A; type K; type V}] = unapply(exp.node) + } + + object groupBy { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[A => K]) forSome {type A; type K}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "groupBy" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[A => K]) forSome {type A; type K}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[A => K]) forSome {type A; type K}] = unapply(exp.node) + } + + object groupByProjecting { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[A => K], Ref[A => V]) forSome {type A; type K; type V}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "groupByProjecting" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0), args(1)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[A => K], Ref[A => V]) forSome {type A; type K; type V}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[A => K], Ref[A => V]) forSome {type A; type K; type V}] = unapply(exp.node) + } + + object unionSet { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[Coll[A]]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "unionSet" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[Coll[A]]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[Coll[A]]) forSome {type A}] = unapply(exp.node) + } + + object diff { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[Coll[A]]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "diff" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[Coll[A]]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[Coll[A]]) forSome {type A}] = unapply(exp.node) + } + + object intersect { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[Coll[A]]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "intersect" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[Coll[A]]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[Coll[A]]) forSome {type A}] = unapply(exp.node) + } + + object sum { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[Monoid[A]]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "sum" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[Monoid[A]]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[Monoid[A]]) forSome {type A}] = unapply(exp.node) + } + + object slice { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[Int], Ref[Int]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "slice" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0), args(1)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[Int], Ref[Int]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[Int], Ref[Int]) forSome {type A}] = unapply(exp.node) + } + + object append { + def unapply(d: Def[_]): Nullable[(Ref[Coll[A]], Ref[Coll[A]]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "append" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[Coll[A]], Ref[Coll[A]]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Coll[A]], Ref[Coll[A]]) forSome {type A}] = unapply(exp.node) + } + + object reverse { + def unapply(d: Def[_]): Nullable[Ref[Coll[A]] forSome {type A}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "reverse" && receiver.elem.isInstanceOf[CollElem[_, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[Coll[A]] forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[Coll[A]] forSome {type A}] = unapply(exp.node) + } + } + + object CollCompanionMethods { + } +} // of object Coll + registerEntityObject("Coll", Coll) + + // manual fix: UserTypeColl removed + // manual fix: unapplyViews removed + // manual fix: RepColl removed + // manual fix: rewriteDef removed + +object PairColl extends EntityObject("PairColl") { + private val PairCollClass = classOf[PairColl[_, _]] + + // entityAdapter for PairColl trait + case class PairCollAdapter[L, R](source: Ref[PairColl[L, R]]) + extends Node with PairColl[L, R] + with Def[PairColl[L, R]] { + implicit lazy val eL = source.elem.typeArgs("L")._1.asInstanceOf[Elem[L]]; +implicit lazy val eR = source.elem.typeArgs("R")._1.asInstanceOf[Elem[R]] + override lazy val eA: Elem[(L, R)] = implicitly[Elem[(L, R)]] + val resultType: Elem[PairColl[L, R]] = element[PairColl[L, R]] + override def transform(t: Transformer) = PairCollAdapter[L, R](t(source)) + + def ls: Ref[Coll[L]] = { + asRep[Coll[L]](mkMethodCall(source, + PairCollClass.getMethod("ls"), + WrappedArray.empty, + true, true, element[Coll[L]])) + } + + def rs: Ref[Coll[R]] = { + asRep[Coll[R]](mkMethodCall(source, + PairCollClass.getMethod("rs"), + WrappedArray.empty, + true, true, element[Coll[R]])) + } + + def mapFirst[T1](f: Ref[L => T1]): Ref[Coll[(T1, R)]] = { + implicit val eT1 = f.elem.eRange + asRep[Coll[(T1, R)]](mkMethodCall(source, + PairCollClass.getMethod("mapFirst", classOf[Sym]), + Array[AnyRef](f), + true, true, element[Coll[(T1, R)]])) + } + + def mapSecond[T1](f: Ref[R => T1]): Ref[Coll[(L, T1)]] = { + implicit val eT1 = f.elem.eRange + asRep[Coll[(L, T1)]](mkMethodCall(source, + PairCollClass.getMethod("mapSecond", classOf[Sym]), + Array[AnyRef](f), + true, true, element[Coll[(L, T1)]])) + } + + def builder: Ref[CollBuilder] = { + asRep[CollBuilder](mkMethodCall(source, + PairCollClass.getMethod("builder"), + WrappedArray.empty, + true, true, element[CollBuilder])) + } + + def length: Ref[Int] = { + asRep[Int](mkMethodCall(source, + PairCollClass.getMethod("length"), + WrappedArray.empty, + true, true, element[Int])) + } + + def isEmpty: Ref[Boolean] = { + asRep[Boolean](mkMethodCall(source, + PairCollClass.getMethod("isEmpty"), + WrappedArray.empty, + true, true, element[Boolean])) + } + + def nonEmpty: Ref[Boolean] = { + asRep[Boolean](mkMethodCall(source, + PairCollClass.getMethod("nonEmpty"), + WrappedArray.empty, + true, true, element[Boolean])) + } + + def apply(i: Ref[Int]): Ref[(L, R)] = { + asRep[(L, R)](mkMethodCall(source, + PairCollClass.getMethod("apply", classOf[Sym]), + Array[AnyRef](i), + true, true, element[(L, R)])) + } + + def isDefinedAt(idx: Ref[Int]): Ref[Boolean] = { + asRep[Boolean](mkMethodCall(source, + PairCollClass.getMethod("isDefinedAt", classOf[Sym]), + Array[AnyRef](idx), + true, true, element[Boolean])) + } + + def getOrElse(index: Ref[Int], default: Ref[(L, R)]): Ref[(L, R)] = { + asRep[(L, R)](mkMethodCall(source, + PairCollClass.getMethod("getOrElse", classOf[Sym], classOf[Sym]), + Array[AnyRef](index, default), + true, true, element[(L, R)])) + } + + def map[B](f: Ref[((L, R)) => B]): Ref[Coll[B]] = { + implicit val eB = f.elem.eRange + asRep[Coll[B]](mkMethodCall(source, + PairCollClass.getMethod("map", classOf[Sym]), + Array[AnyRef](f), + true, true, element[Coll[B]])) + } + + // manual fix + def zip[B](ys: Ref[Coll[B]]): Ref[Coll[((L, R), B)]] = { + implicit val eB = ys.eA + asRep[Coll[((L, R), B)]](mkMethodCall(source, + PairCollClass.getMethod("zip", classOf[Sym]), + Array[AnyRef](ys), + true, true, element[Coll[((L, R), B)]](collElement(pairElement(pairElement(eL, eR), eB))))) + } + + def exists(p: Ref[((L, R)) => Boolean]): Ref[Boolean] = { + asRep[Boolean](mkMethodCall(source, + PairCollClass.getMethod("exists", classOf[Sym]), + Array[AnyRef](p), + true, true, element[Boolean])) + } + + def forall(p: Ref[((L, R)) => Boolean]): Ref[Boolean] = { + asRep[Boolean](mkMethodCall(source, + PairCollClass.getMethod("forall", classOf[Sym]), + Array[AnyRef](p), + true, true, element[Boolean])) + } + + def filter(p: Ref[((L, R)) => Boolean]): Ref[Coll[(L, R)]] = { + asRep[Coll[(L, R)]](mkMethodCall(source, + PairCollClass.getMethod("filter", classOf[Sym]), + Array[AnyRef](p), + true, true, element[Coll[(L, R)]])) + } + + def foldLeft[B](zero: Ref[B], op: Ref[((B, (L, R))) => B]): Ref[B] = { + implicit val eB = zero.elem + asRep[B](mkMethodCall(source, + PairCollClass.getMethod("foldLeft", classOf[Sym], classOf[Sym]), + Array[AnyRef](zero, op), + true, true, element[B])) + } + + def indices: Ref[Coll[Int]] = { + asRep[Coll[Int]](mkMethodCall(source, + PairCollClass.getMethod("indices"), + WrappedArray.empty, + true, true, element[Coll[Int]])) + } + + def flatMap[B](f: Ref[((L, R)) => Coll[B]]): Ref[Coll[B]] = { + implicit val eB = f.elem.eRange.typeArgs("A")._1.asInstanceOf[Elem[B]] + asRep[Coll[B]](mkMethodCall(source, + PairCollClass.getMethod("flatMap", classOf[Sym]), + Array[AnyRef](f), + true, true, element[Coll[B]])) + } + + def segmentLength(p: Ref[((L, R)) => Boolean], from: Ref[Int]): Ref[Int] = { + asRep[Int](mkMethodCall(source, + PairCollClass.getMethod("segmentLength", classOf[Sym], classOf[Sym]), + Array[AnyRef](p, from), + true, true, element[Int])) + } + + override def find(p: Ref[((L, R)) => Boolean]): Ref[WOption[(L, R)]] = { + asRep[WOption[(L, R)]](mkMethodCall(source, + PairCollClass.getMethod("find", classOf[Sym]), + Array[AnyRef](p), + true, true, element[WOption[(L, R)]])) + } + + def indexWhere(p: Ref[((L, R)) => Boolean], from: Ref[Int]): Ref[Int] = { + asRep[Int](mkMethodCall(source, + PairCollClass.getMethod("indexWhere", classOf[Sym], classOf[Sym]), + Array[AnyRef](p, from), + true, true, element[Int])) + } + + override def indexOf(elem: Ref[(L, R)], from: Ref[Int]): Ref[Int] = { + asRep[Int](mkMethodCall(source, + PairCollClass.getMethod("indexOf", classOf[Sym], classOf[Sym]), + Array[AnyRef](elem, from), + true, true, element[Int])) + } + + def lastIndexWhere(p: Ref[((L, R)) => Boolean], end: Ref[Int]): Ref[Int] = { + asRep[Int](mkMethodCall(source, + PairCollClass.getMethod("lastIndexWhere", classOf[Sym], classOf[Sym]), + Array[AnyRef](p, end), + true, true, element[Int])) + } + + def take(n: Ref[Int]): Ref[Coll[(L, R)]] = { + asRep[Coll[(L, R)]](mkMethodCall(source, + PairCollClass.getMethod("take", classOf[Sym]), + Array[AnyRef](n), + true, true, element[Coll[(L, R)]])) + } + + // manual fix + def partition(pred: Ref[((L, R)) => Boolean]): Ref[(Coll[(L, R)], Coll[(L, R)])] = { + asRep[(Coll[(L, R)], Coll[(L, R)])](mkMethodCall(source, + PairCollClass.getMethod("partition", classOf[Sym]), + Array[AnyRef](pred), + true, true, element[(Coll[(L, R)], Coll[(L, R)])](pairElement(collElement(pairElement(eL,eR)), collElement(pairElement(eL,eR)))))) + } + + def patch(from: Ref[Int], patch: Ref[Coll[(L, R)]], replaced: Ref[Int]): Ref[Coll[(L, R)]] = { + asRep[Coll[(L, R)]](mkMethodCall(source, + PairCollClass.getMethod("patch", classOf[Sym], classOf[Sym], classOf[Sym]), + Array[AnyRef](from, patch, replaced), + true, true, element[Coll[(L, R)]])) + } + + def updated(index: Ref[Int], elem: Ref[(L, R)]): Ref[Coll[(L, R)]] = { + asRep[Coll[(L, R)]](mkMethodCall(source, + PairCollClass.getMethod("updated", classOf[Sym], classOf[Sym]), + Array[AnyRef](index, elem), + true, true, element[Coll[(L, R)]])) + } + + def updateMany(indexes: Ref[Coll[Int]], values: Ref[Coll[(L, R)]]): Ref[Coll[(L, R)]] = { + asRep[Coll[(L, R)]](mkMethodCall(source, + PairCollClass.getMethod("updateMany", classOf[Sym], classOf[Sym]), + Array[AnyRef](indexes, values), + true, true, element[Coll[(L, R)]])) + } + + def mapReduce[K, V](m: Ref[((L, R)) => (K, V)], r: Ref[((V, V)) => V]): Ref[Coll[(K, V)]] = { + implicit val eK = m.elem.eRange.eFst +implicit val eV = m.elem.eRange.eSnd + asRep[Coll[(K, V)]](mkMethodCall(source, + PairCollClass.getMethod("mapReduce", classOf[Sym], classOf[Sym]), + Array[AnyRef](m, r), + true, true, element[Coll[(K, V)]])) + } + + // manual fix + override def groupBy[K](key: Ref[((L, R)) => K]): Ref[Coll[(K, Coll[(L, R)])]] = { + implicit val eK = key.elem.eRange + asRep[Coll[(K, Coll[(L, R)])]](mkMethodCall(source, + PairCollClass.getMethod("groupBy", classOf[Sym]), + Array[AnyRef](key), + true, true, element[Coll[(K, Coll[(L, R)])]](collElement(pairElement(eK, collElement(pairElement(eL, eR))))))) + } + + override def groupByProjecting[K, V](key: Ref[((L, R)) => K], proj: Ref[((L, R)) => V]): Ref[Coll[(K, Coll[V])]] = { + implicit val eK = key.elem.eRange +implicit val eV = proj.elem.eRange + asRep[Coll[(K, Coll[V])]](mkMethodCall(source, + PairCollClass.getMethod("groupByProjecting", classOf[Sym], classOf[Sym]), + Array[AnyRef](key, proj), + true, true, element[Coll[(K, Coll[V])]])) + } + + def unionSet(that: Ref[Coll[(L, R)]]): Ref[Coll[(L, R)]] = { + asRep[Coll[(L, R)]](mkMethodCall(source, + PairCollClass.getMethod("unionSet", classOf[Sym]), + Array[AnyRef](that), + true, true, element[Coll[(L, R)]])) + } + + override def diff(that: Ref[Coll[(L, R)]]): Ref[Coll[(L, R)]] = { + asRep[Coll[(L, R)]](mkMethodCall(source, + PairCollClass.getMethod("diff", classOf[Sym]), + Array[AnyRef](that), + true, true, element[Coll[(L, R)]])) + } + + override def intersect(that: Ref[Coll[(L, R)]]): Ref[Coll[(L, R)]] = { + asRep[Coll[(L, R)]](mkMethodCall(source, + PairCollClass.getMethod("intersect", classOf[Sym]), + Array[AnyRef](that), + true, true, element[Coll[(L, R)]])) + } + + def sum(m: Ref[Monoid[(L, R)]]): Ref[(L, R)] = { + asRep[(L, R)](mkMethodCall(source, + PairCollClass.getMethod("sum", classOf[Sym]), + Array[AnyRef](m), + true, true, element[(L, R)])) + } + + def slice(from: Ref[Int], until: Ref[Int]): Ref[Coll[(L, R)]] = { + asRep[Coll[(L, R)]](mkMethodCall(source, + PairCollClass.getMethod("slice", classOf[Sym], classOf[Sym]), + Array[AnyRef](from, until), + true, true, element[Coll[(L, R)]])) + } + + def append(other: Ref[Coll[(L, R)]]): Ref[Coll[(L, R)]] = { + asRep[Coll[(L, R)]](mkMethodCall(source, + PairCollClass.getMethod("append", classOf[Sym]), + Array[AnyRef](other), + true, true, element[Coll[(L, R)]])) + } + + def reverse: Ref[Coll[(L, R)]] = { + asRep[Coll[(L, R)]](mkMethodCall(source, + PairCollClass.getMethod("reverse"), + WrappedArray.empty, + true, true, element[Coll[(L, R)]])) + } + } + + // entityUnref: single unref method for each type family + implicit final def unrefPairColl[L, R](p: Ref[PairColl[L, R]]): PairColl[L, R] = { + if (p.node.isInstanceOf[PairColl[L, R]@unchecked]) p.node.asInstanceOf[PairColl[L, R]] + else + PairCollAdapter(p) + } + + // familyElem + class PairCollElem[L, R, To <: PairColl[L, R]](implicit _eL: Elem[L], _eR: Elem[R]) + extends CollElem[(L, R), To] { + def eL = _eL + def eR = _eR + + override lazy val parent: Option[Elem[_]] = Some(collElement(pairElement(element[L],element[R]))) + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("L" -> (eL -> scalan.util.Invariant), "R" -> (eR -> scalan.util.Invariant)) + } + + implicit final def pairCollElement[L, R](implicit eL: Elem[L], eR: Elem[R]): Elem[PairColl[L, R]] = + cachedElemByClass(eL, eR)(classOf[PairCollElem[L, R, PairColl[L, R]]]) + + implicit case object PairCollCompanionElem extends CompanionElem[PairCollCompanionCtor] + + abstract class PairCollCompanionCtor extends CompanionDef[PairCollCompanionCtor] with PairCollCompanion { + def resultType = PairCollCompanionElem + override def toString = "PairColl" + } + implicit final def unrefPairCollCompanionCtor(p: Ref[PairCollCompanionCtor]): PairCollCompanionCtor = + p.node.asInstanceOf[PairCollCompanionCtor] + + lazy val RPairColl: MutableLazy[PairCollCompanionCtor] = MutableLazy(new PairCollCompanionCtor { + private val thisClass = classOf[PairCollCompanion] + }) + + object PairCollMethods { + object ls { + def unapply(d: Def[_]): Nullable[Ref[PairColl[L, R]] forSome {type L; type R}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "ls" && receiver.elem.isInstanceOf[PairCollElem[_, _, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[PairColl[L, R]] forSome {type L; type R}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[PairColl[L, R]] forSome {type L; type R}] = unapply(exp.node) + } + + object rs { + def unapply(d: Def[_]): Nullable[Ref[PairColl[L, R]] forSome {type L; type R}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "rs" && receiver.elem.isInstanceOf[PairCollElem[_, _, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[PairColl[L, R]] forSome {type L; type R}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[PairColl[L, R]] forSome {type L; type R}] = unapply(exp.node) + } + + object mapFirst { + def unapply(d: Def[_]): Nullable[(Ref[PairColl[L, R]], Ref[L => T1]) forSome {type L; type R; type T1}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "mapFirst" && receiver.elem.isInstanceOf[PairCollElem[_, _, _]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[PairColl[L, R]], Ref[L => T1]) forSome {type L; type R; type T1}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[PairColl[L, R]], Ref[L => T1]) forSome {type L; type R; type T1}] = unapply(exp.node) + } + + object mapSecond { + def unapply(d: Def[_]): Nullable[(Ref[PairColl[L, R]], Ref[R => T1]) forSome {type L; type R; type T1}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "mapSecond" && receiver.elem.isInstanceOf[PairCollElem[_, _, _]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[PairColl[L, R]], Ref[R => T1]) forSome {type L; type R; type T1}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[PairColl[L, R]], Ref[R => T1]) forSome {type L; type R; type T1}] = unapply(exp.node) + } + } + + object PairCollCompanionMethods { + } +} // of object PairColl + registerEntityObject("PairColl", PairColl) + +object ReplColl extends EntityObject("ReplColl") { + // entityConst: single const for each entity + import Liftables._ + import scala.reflect.{ClassTag, classTag} + type SReplColl[A] = special.collection.ReplColl[A] + case class ReplCollConst[SA, A]( + constValue: SReplColl[SA], + lA: Liftable[SA, A] + ) extends LiftedConst[SReplColl[SA], ReplColl[A]] with ReplColl[A] + with Def[ReplColl[A]] with ReplCollConstMethods[A] { + implicit final def eA: Elem[A] = lA.eW + + val liftable: Liftable[SReplColl[SA], ReplColl[A]] = liftableReplColl(lA) + val resultType: Elem[ReplColl[A]] = liftable.eW + } + + trait ReplCollConstMethods[A] extends ReplColl[A] with CollConstMethods[A] { thisConst: Def[_] => + implicit def eA: Elem[A] + private val ReplCollClass = classOf[ReplColl[A]] + + override def value: Ref[A] = { + asRep[A](mkMethodCall(self, + ReplCollClass.getMethod("value"), + WrappedArray.empty, + true, false, element[A])) + } + + override def length: Ref[Int] = { + asRep[Int](mkMethodCall(self, + ReplCollClass.getMethod("length"), + WrappedArray.empty, + true, false, element[Int])) + } + + override def append(other: Ref[Coll[A]]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(self, + ReplCollClass.getMethod("append", classOf[Sym]), + Array[AnyRef](other), + true, false, element[Coll[A]])) + } + } + + case class LiftableReplColl[SA, A](lA: Liftable[SA, A]) + extends Liftable[SReplColl[SA], ReplColl[A]] { + lazy val eW: Elem[ReplColl[A]] = replCollElement(lA.eW) + lazy val sourceType: RType[SReplColl[SA]] = { + implicit val tagSA = lA.sourceType.asInstanceOf[RType[SA]] + RType[SReplColl[SA]] + } + def lift(x: SReplColl[SA]): Ref[ReplColl[A]] = ReplCollConst(x, lA) + def unlift(w: Ref[ReplColl[A]]): SReplColl[SA] = w match { + case Def(ReplCollConst(x: SReplColl[_], _lA)) + if _lA == lA => x.asInstanceOf[SReplColl[SA]] + case _ => unliftError(w) + } + } + implicit final def liftableReplColl[SA, A](implicit lA: Liftable[SA,A]): Liftable[SReplColl[SA], ReplColl[A]] = + LiftableReplColl(lA) + + private val ReplCollClass = classOf[ReplColl[_]] + + // entityAdapter for ReplColl trait + case class ReplCollAdapter[A](source: Ref[ReplColl[A]]) + extends Node with ReplColl[A] + with Def[ReplColl[A]] { + implicit lazy val eA = source.elem.typeArgs("A")._1.asInstanceOf[Elem[A]] + + val resultType: Elem[ReplColl[A]] = element[ReplColl[A]] + override def transform(t: Transformer) = ReplCollAdapter[A](t(source)) + + def value: Ref[A] = { + asRep[A](mkMethodCall(source, + ReplCollClass.getMethod("value"), + WrappedArray.empty, + true, true, element[A])) + } + + def length: Ref[Int] = { + asRep[Int](mkMethodCall(source, + ReplCollClass.getMethod("length"), + WrappedArray.empty, + true, true, element[Int])) + } + + def append(other: Ref[Coll[A]]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(source, + ReplCollClass.getMethod("append", classOf[Sym]), + Array[AnyRef](other), + true, true, element[Coll[A]])) + } + + def builder: Ref[CollBuilder] = { + asRep[CollBuilder](mkMethodCall(source, + ReplCollClass.getMethod("builder"), + WrappedArray.empty, + true, true, element[CollBuilder])) + } + + def isEmpty: Ref[Boolean] = { + asRep[Boolean](mkMethodCall(source, + ReplCollClass.getMethod("isEmpty"), + WrappedArray.empty, + true, true, element[Boolean])) + } + + def nonEmpty: Ref[Boolean] = { + asRep[Boolean](mkMethodCall(source, + ReplCollClass.getMethod("nonEmpty"), + WrappedArray.empty, + true, true, element[Boolean])) + } + + def apply(i: Ref[Int]): Ref[A] = { + asRep[A](mkMethodCall(source, + ReplCollClass.getMethod("apply", classOf[Sym]), + Array[AnyRef](i), + true, true, element[A])) + } + + def isDefinedAt(idx: Ref[Int]): Ref[Boolean] = { + asRep[Boolean](mkMethodCall(source, + ReplCollClass.getMethod("isDefinedAt", classOf[Sym]), + Array[AnyRef](idx), + true, true, element[Boolean])) + } + + def getOrElse(index: Ref[Int], default: Ref[A]): Ref[A] = { + asRep[A](mkMethodCall(source, + ReplCollClass.getMethod("getOrElse", classOf[Sym], classOf[Sym]), + Array[AnyRef](index, default), + true, true, element[A])) + } + + def map[B](f: Ref[A => B]): Ref[Coll[B]] = { + implicit val eB = f.elem.eRange + asRep[Coll[B]](mkMethodCall(source, + ReplCollClass.getMethod("map", classOf[Sym]), + Array[AnyRef](f), + true, true, element[Coll[B]])) + } + + def zip[B](ys: Ref[Coll[B]]): Ref[Coll[(A, B)]] = { + implicit val eB = ys.eA + asRep[Coll[(A, B)]](mkMethodCall(source, + ReplCollClass.getMethod("zip", classOf[Sym]), + Array[AnyRef](ys), + true, true, element[Coll[(A, B)]])) + } + + def exists(p: Ref[A => Boolean]): Ref[Boolean] = { + asRep[Boolean](mkMethodCall(source, + ReplCollClass.getMethod("exists", classOf[Sym]), + Array[AnyRef](p), + true, true, element[Boolean])) + } + + def forall(p: Ref[A => Boolean]): Ref[Boolean] = { + asRep[Boolean](mkMethodCall(source, + ReplCollClass.getMethod("forall", classOf[Sym]), + Array[AnyRef](p), + true, true, element[Boolean])) + } + + def filter(p: Ref[A => Boolean]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(source, + ReplCollClass.getMethod("filter", classOf[Sym]), + Array[AnyRef](p), + true, true, element[Coll[A]])) + } + + def foldLeft[B](zero: Ref[B], op: Ref[((B, A)) => B]): Ref[B] = { + implicit val eB = zero.elem + asRep[B](mkMethodCall(source, + ReplCollClass.getMethod("foldLeft", classOf[Sym], classOf[Sym]), + Array[AnyRef](zero, op), + true, true, element[B])) + } + + def indices: Ref[Coll[Int]] = { + asRep[Coll[Int]](mkMethodCall(source, + ReplCollClass.getMethod("indices"), + WrappedArray.empty, + true, true, element[Coll[Int]])) + } + + def flatMap[B](f: Ref[A => Coll[B]]): Ref[Coll[B]] = { + implicit val eB = f.elem.eRange.typeArgs("A")._1.asInstanceOf[Elem[B]] + asRep[Coll[B]](mkMethodCall(source, + ReplCollClass.getMethod("flatMap", classOf[Sym]), + Array[AnyRef](f), + true, true, element[Coll[B]])) + } + + def segmentLength(p: Ref[A => Boolean], from: Ref[Int]): Ref[Int] = { + asRep[Int](mkMethodCall(source, + ReplCollClass.getMethod("segmentLength", classOf[Sym], classOf[Sym]), + Array[AnyRef](p, from), + true, true, element[Int])) + } + + override def find(p: Ref[A => Boolean]): Ref[WOption[A]] = { + asRep[WOption[A]](mkMethodCall(source, + ReplCollClass.getMethod("find", classOf[Sym]), + Array[AnyRef](p), + true, true, element[WOption[A]])) + } + + def indexWhere(p: Ref[A => Boolean], from: Ref[Int]): Ref[Int] = { + asRep[Int](mkMethodCall(source, + ReplCollClass.getMethod("indexWhere", classOf[Sym], classOf[Sym]), + Array[AnyRef](p, from), + true, true, element[Int])) + } + + override def indexOf(elem: Ref[A], from: Ref[Int]): Ref[Int] = { + asRep[Int](mkMethodCall(source, + ReplCollClass.getMethod("indexOf", classOf[Sym], classOf[Sym]), + Array[AnyRef](elem, from), + true, true, element[Int])) + } + + def lastIndexWhere(p: Ref[A => Boolean], end: Ref[Int]): Ref[Int] = { + asRep[Int](mkMethodCall(source, + ReplCollClass.getMethod("lastIndexWhere", classOf[Sym], classOf[Sym]), + Array[AnyRef](p, end), + true, true, element[Int])) + } + + def take(n: Ref[Int]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(source, + ReplCollClass.getMethod("take", classOf[Sym]), + Array[AnyRef](n), + true, true, element[Coll[A]])) + } + + def partition(pred: Ref[A => Boolean]): Ref[(Coll[A], Coll[A])] = { + asRep[(Coll[A], Coll[A])](mkMethodCall(source, + ReplCollClass.getMethod("partition", classOf[Sym]), + Array[AnyRef](pred), + true, true, element[(Coll[A], Coll[A])])) + } + + def patch(from: Ref[Int], patch: Ref[Coll[A]], replaced: Ref[Int]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(source, + ReplCollClass.getMethod("patch", classOf[Sym], classOf[Sym], classOf[Sym]), + Array[AnyRef](from, patch, replaced), + true, true, element[Coll[A]])) + } + + def updated(index: Ref[Int], elem: Ref[A]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(source, + ReplCollClass.getMethod("updated", classOf[Sym], classOf[Sym]), + Array[AnyRef](index, elem), + true, true, element[Coll[A]])) + } + + def updateMany(indexes: Ref[Coll[Int]], values: Ref[Coll[A]]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(source, + ReplCollClass.getMethod("updateMany", classOf[Sym], classOf[Sym]), + Array[AnyRef](indexes, values), + true, true, element[Coll[A]])) + } + + def mapReduce[K, V](m: Ref[A => (K, V)], r: Ref[((V, V)) => V]): Ref[Coll[(K, V)]] = { + implicit val eK = m.elem.eRange.eFst +implicit val eV = m.elem.eRange.eSnd + asRep[Coll[(K, V)]](mkMethodCall(source, + ReplCollClass.getMethod("mapReduce", classOf[Sym], classOf[Sym]), + Array[AnyRef](m, r), + true, true, element[Coll[(K, V)]])) + } + + override def groupBy[K](key: Ref[A => K]): Ref[Coll[(K, Coll[A])]] = { + implicit val eK = key.elem.eRange + asRep[Coll[(K, Coll[A])]](mkMethodCall(source, + ReplCollClass.getMethod("groupBy", classOf[Sym]), + Array[AnyRef](key), + true, true, element[Coll[(K, Coll[A])]])) + } + + override def groupByProjecting[K, V](key: Ref[A => K], proj: Ref[A => V]): Ref[Coll[(K, Coll[V])]] = { + implicit val eK = key.elem.eRange +implicit val eV = proj.elem.eRange + asRep[Coll[(K, Coll[V])]](mkMethodCall(source, + ReplCollClass.getMethod("groupByProjecting", classOf[Sym], classOf[Sym]), + Array[AnyRef](key, proj), + true, true, element[Coll[(K, Coll[V])]])) + } + + def unionSet(that: Ref[Coll[A]]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(source, + ReplCollClass.getMethod("unionSet", classOf[Sym]), + Array[AnyRef](that), + true, true, element[Coll[A]])) + } + + override def diff(that: Ref[Coll[A]]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(source, + ReplCollClass.getMethod("diff", classOf[Sym]), + Array[AnyRef](that), + true, true, element[Coll[A]])) + } + + override def intersect(that: Ref[Coll[A]]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(source, + ReplCollClass.getMethod("intersect", classOf[Sym]), + Array[AnyRef](that), + true, true, element[Coll[A]])) + } + + def sum(m: Ref[Monoid[A]]): Ref[A] = { + asRep[A](mkMethodCall(source, + ReplCollClass.getMethod("sum", classOf[Sym]), + Array[AnyRef](m), + true, true, element[A])) + } + + def slice(from: Ref[Int], until: Ref[Int]): Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(source, + ReplCollClass.getMethod("slice", classOf[Sym], classOf[Sym]), + Array[AnyRef](from, until), + true, true, element[Coll[A]])) + } + + def reverse: Ref[Coll[A]] = { + asRep[Coll[A]](mkMethodCall(source, + ReplCollClass.getMethod("reverse"), + WrappedArray.empty, + true, true, element[Coll[A]])) + } + } + + // entityUnref: single unref method for each type family + implicit final def unrefReplColl[A](p: Ref[ReplColl[A]]): ReplColl[A] = { + if (p.node.isInstanceOf[ReplColl[A]@unchecked]) p.node.asInstanceOf[ReplColl[A]] + else + ReplCollAdapter(p) + } + + // familyElem + class ReplCollElem[A, To <: ReplColl[A]](implicit _eA: Elem[A]) + extends CollElem[A, To] { + override def eA = _eA + + override val liftable: Liftables.Liftable[_, To] = asLiftable[SReplColl[_], To](liftableReplColl(_eA.liftable)) + + override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { + super.collectMethods ++ + Elem.declaredMethods(classOf[ReplColl[A]], classOf[SReplColl[_]], Set( + "value", "length", "append" + )) + } + + override lazy val parent: Option[Elem[_]] = Some(collElement(element[A])) + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("A" -> (eA -> scalan.util.Invariant)) + } + + implicit final def replCollElement[A](implicit eA: Elem[A]): Elem[ReplColl[A]] = + cachedElemByClass(eA)(classOf[ReplCollElem[A, ReplColl[A]]]) + + implicit case object ReplCollCompanionElem extends CompanionElem[ReplCollCompanionCtor] + + abstract class ReplCollCompanionCtor extends CompanionDef[ReplCollCompanionCtor] with ReplCollCompanion { + def resultType = ReplCollCompanionElem + override def toString = "ReplColl" + } + implicit final def unrefReplCollCompanionCtor(p: Ref[ReplCollCompanionCtor]): ReplCollCompanionCtor = + p.node.asInstanceOf[ReplCollCompanionCtor] + + lazy val RReplColl: MutableLazy[ReplCollCompanionCtor] = MutableLazy(new ReplCollCompanionCtor { + private val thisClass = classOf[ReplCollCompanion] + }) + + object ReplCollMethods { + object value { + def unapply(d: Def[_]): Nullable[Ref[ReplColl[A]] forSome {type A}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "value" && receiver.elem.isInstanceOf[ReplCollElem[_, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[ReplColl[A]] forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[ReplColl[A]] forSome {type A}] = unapply(exp.node) + } + + object length { + def unapply(d: Def[_]): Nullable[Ref[ReplColl[A]] forSome {type A}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "length" && receiver.elem.isInstanceOf[ReplCollElem[_, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[ReplColl[A]] forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[ReplColl[A]] forSome {type A}] = unapply(exp.node) + } + + object append { + def unapply(d: Def[_]): Nullable[(Ref[ReplColl[A]], Ref[Coll[A]]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "append" && receiver.elem.isInstanceOf[ReplCollElem[_, _]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[ReplColl[A]], Ref[Coll[A]]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[ReplColl[A]], Ref[Coll[A]]) forSome {type A}] = unapply(exp.node) + } + } + + object ReplCollCompanionMethods { + } +} // of object ReplColl + registerEntityObject("ReplColl", ReplColl) + +object CollBuilder extends EntityObject("CollBuilder") { + // entityConst: single const for each entity + import Liftables._ + import scala.reflect.{ClassTag, classTag} + type SCollBuilder = special.collection.CollBuilder + case class CollBuilderConst( + constValue: SCollBuilder + ) extends LiftedConst[SCollBuilder, CollBuilder] with CollBuilder + with Def[CollBuilder] with CollBuilderConstMethods { + val liftable: Liftable[SCollBuilder, CollBuilder] = LiftableCollBuilder + val resultType: Elem[CollBuilder] = liftable.eW + } + + trait CollBuilderConstMethods extends CollBuilder { thisConst: Def[_] => + + private val CollBuilderClass = classOf[CollBuilder] + + override def Monoids: Ref[MonoidBuilder] = { + asRep[MonoidBuilder](mkMethodCall(self, + CollBuilderClass.getMethod("Monoids"), + WrappedArray.empty, + true, false, element[MonoidBuilder])) + } + + override def pairColl[A, B](as: Ref[Coll[A]], bs: Ref[Coll[B]]): Ref[PairColl[A, B]] = { + implicit val eA = as.eA +implicit val eB = bs.eA + asRep[PairColl[A, B]](mkMethodCall(self, + CollBuilderClass.getMethod("pairColl", classOf[Sym], classOf[Sym]), + Array[AnyRef](as, bs), + true, false, element[PairColl[A, B]])) + } + + override def fromItems[T](items: Ref[T]*)(implicit cT: Elem[T]): Ref[Coll[T]] = { + asRep[Coll[T]](mkMethodCall(self, + CollBuilderClass.getMethod("fromItems", classOf[Seq[_]], classOf[Elem[_]]), + Array[AnyRef](items, cT), + true, false, element[Coll[T]])) + } + + override def unzip[A, B](xs: Ref[Coll[(A, B)]]): Ref[(Coll[A], Coll[B])] = { + implicit val eA = xs.eA.eFst +implicit val eB = xs.eA.eSnd + asRep[(Coll[A], Coll[B])](mkMethodCall(self, + CollBuilderClass.getMethod("unzip", classOf[Sym]), + Array[AnyRef](xs), + true, false, element[(Coll[A], Coll[B])])) + } + + override def xor(left: Ref[Coll[Byte]], right: Ref[Coll[Byte]]): Ref[Coll[Byte]] = { + asRep[Coll[Byte]](mkMethodCall(self, + CollBuilderClass.getMethod("xor", classOf[Sym], classOf[Sym]), + Array[AnyRef](left, right), + true, false, element[Coll[Byte]])) + } + + override def replicate[T](n: Ref[Int], v: Ref[T]): Ref[Coll[T]] = { + implicit val eT = v.elem + asRep[Coll[T]](mkMethodCall(self, + CollBuilderClass.getMethod("replicate", classOf[Sym], classOf[Sym]), + Array[AnyRef](n, v), + true, false, element[Coll[T]])) + } + + override def emptyColl[T](implicit tT: Elem[T]): Ref[Coll[T]] = { + asRep[Coll[T]](mkMethodCall(self, + CollBuilderClass.getMethod("emptyColl", classOf[Elem[_]]), + Array[AnyRef](tT), + true, false, element[Coll[T]])) + } + + override def outerJoin[K, L, R, O](left: Ref[Coll[(K, L)]], right: Ref[Coll[(K, R)]])(l: Ref[((K, L)) => O], r: Ref[((K, R)) => O], inner: Ref[((K, (L, R))) => O]): Ref[Coll[(K, O)]] = { + implicit val eK = left.eA.eFst +implicit val eL = left.eA.eSnd +implicit val eR = right.eA.eSnd +implicit val eO = l.elem.eRange + asRep[Coll[(K, O)]](mkMethodCall(self, + CollBuilderClass.getMethod("outerJoin", classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym]), + Array[AnyRef](left, right, l, r, inner), + true, false, element[Coll[(K, O)]])) + } + + override def flattenColl[A](coll: Ref[Coll[Coll[A]]]): Ref[Coll[A]] = { + implicit val eA = coll.eA.typeArgs("A")._1.asInstanceOf[Elem[A]] + asRep[Coll[A]](mkMethodCall(self, + CollBuilderClass.getMethod("flattenColl", classOf[Sym]), + Array[AnyRef](coll), + true, false, element[Coll[A]])) + } + } + + implicit object LiftableCollBuilder + extends Liftable[SCollBuilder, CollBuilder] { + lazy val eW: Elem[CollBuilder] = collBuilderElement + lazy val sourceType: RType[SCollBuilder] = { + RType[SCollBuilder] + } + def lift(x: SCollBuilder): Ref[CollBuilder] = CollBuilderConst(x) + def unlift(w: Ref[CollBuilder]): SCollBuilder = w match { + case Def(CollBuilderConst(x: SCollBuilder)) + => x.asInstanceOf[SCollBuilder] + case _ => unliftError(w) + } + } + + private val CollBuilderClass = classOf[CollBuilder] + + // entityAdapter for CollBuilder trait + case class CollBuilderAdapter(source: Ref[CollBuilder]) + extends Node with CollBuilder + with Def[CollBuilder] { + val resultType: Elem[CollBuilder] = element[CollBuilder] + override def transform(t: Transformer) = CollBuilderAdapter(t(source)) + + def Monoids: Ref[MonoidBuilder] = { + asRep[MonoidBuilder](mkMethodCall(source, + CollBuilderClass.getMethod("Monoids"), + WrappedArray.empty, + true, true, element[MonoidBuilder])) + } + + def pairColl[A, B](as: Ref[Coll[A]], bs: Ref[Coll[B]]): Ref[PairColl[A, B]] = { + implicit val eA = as.eA +implicit val eB = bs.eA + asRep[PairColl[A, B]](mkMethodCall(source, + CollBuilderClass.getMethod("pairColl", classOf[Sym], classOf[Sym]), + Array[AnyRef](as, bs), + true, true, element[PairColl[A, B]])) + } + + def fromItems[T](items: Ref[T]*)(implicit cT: Elem[T]): Ref[Coll[T]] = { + asRep[Coll[T]](mkMethodCall(source, + CollBuilderClass.getMethod("fromItems", classOf[Seq[_]], classOf[Elem[_]]), + Array[AnyRef](items, cT), + true, true, element[Coll[T]])) + } + + def unzip[A, B](xs: Ref[Coll[(A, B)]]): Ref[(Coll[A], Coll[B])] = { + implicit val eA = xs.eA.eFst +implicit val eB = xs.eA.eSnd + asRep[(Coll[A], Coll[B])](mkMethodCall(source, + CollBuilderClass.getMethod("unzip", classOf[Sym]), + Array[AnyRef](xs), + true, true, element[(Coll[A], Coll[B])])) + } + + def xor(left: Ref[Coll[Byte]], right: Ref[Coll[Byte]]): Ref[Coll[Byte]] = { + asRep[Coll[Byte]](mkMethodCall(source, + CollBuilderClass.getMethod("xor", classOf[Sym], classOf[Sym]), + Array[AnyRef](left, right), + true, true, element[Coll[Byte]])) + } + + def replicate[T](n: Ref[Int], v: Ref[T]): Ref[Coll[T]] = { + implicit val eT = v.elem + asRep[Coll[T]](mkMethodCall(source, + CollBuilderClass.getMethod("replicate", classOf[Sym], classOf[Sym]), + Array[AnyRef](n, v), + true, true, element[Coll[T]])) + } + + def emptyColl[T](implicit tT: Elem[T]): Ref[Coll[T]] = { + asRep[Coll[T]](mkMethodCall(source, + CollBuilderClass.getMethod("emptyColl", classOf[Elem[_]]), + Array[AnyRef](tT), + true, true, element[Coll[T]])) + } + + def outerJoin[K, L, R, O](left: Ref[Coll[(K, L)]], right: Ref[Coll[(K, R)]])(l: Ref[((K, L)) => O], r: Ref[((K, R)) => O], inner: Ref[((K, (L, R))) => O]): Ref[Coll[(K, O)]] = { + implicit val eK = left.eA.eFst +implicit val eL = left.eA.eSnd +implicit val eR = right.eA.eSnd +implicit val eO = l.elem.eRange + asRep[Coll[(K, O)]](mkMethodCall(source, + CollBuilderClass.getMethod("outerJoin", classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym]), + Array[AnyRef](left, right, l, r, inner), + true, true, element[Coll[(K, O)]])) + } + + def flattenColl[A](coll: Ref[Coll[Coll[A]]]): Ref[Coll[A]] = { + implicit val eA = coll.eA.typeArgs("A")._1.asInstanceOf[Elem[A]] + asRep[Coll[A]](mkMethodCall(source, + CollBuilderClass.getMethod("flattenColl", classOf[Sym]), + Array[AnyRef](coll), + true, true, element[Coll[A]])) + } + } + + // entityUnref: single unref method for each type family + val createCollBuilderAdapter: Ref[CollBuilder] => CollBuilder = x => CollBuilderAdapter(x) + + implicit final def unrefCollBuilder(p: Ref[CollBuilder]): CollBuilder = + p.asInstanceOf[SingleRef[CollBuilder]].getAdapter( + p.node.isInstanceOf[CollBuilder], + createCollBuilderAdapter.asInstanceOf[Ref[CollBuilder] => CollBuilder]) + + // familyElem + class CollBuilderElem[To <: CollBuilder] + extends EntityElem[To] { + override val liftable: Liftables.Liftable[_, To] = asLiftable[SCollBuilder, To](LiftableCollBuilder) + + override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { + super.collectMethods ++ + Elem.declaredMethods(classOf[CollBuilder], classOf[SCollBuilder], Set( + "Monoids", "pairColl", "fromItems", "unzip", "xor", "replicate", "emptyColl", "outerJoin", "flattenColl" + )) + } + } + + implicit lazy val collBuilderElement: Elem[CollBuilder] = + new CollBuilderElem[CollBuilder] + + implicit case object CollBuilderCompanionElem extends CompanionElem[CollBuilderCompanionCtor] + + abstract class CollBuilderCompanionCtor extends CompanionDef[CollBuilderCompanionCtor] with CollBuilderCompanion { + def resultType = CollBuilderCompanionElem + override def toString = "CollBuilder" + } + implicit final def unrefCollBuilderCompanionCtor(p: Ref[CollBuilderCompanionCtor]): CollBuilderCompanionCtor = + p.node.asInstanceOf[CollBuilderCompanionCtor] + + lazy val RCollBuilder: MutableLazy[CollBuilderCompanionCtor] = MutableLazy(new CollBuilderCompanionCtor { + private val thisClass = classOf[CollBuilderCompanion] + }) + + object CollBuilderMethods { + object Monoids { + def unapply(d: Def[_]): Nullable[Ref[CollBuilder]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "Monoids" && receiver.elem.isInstanceOf[CollBuilderElem[_]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[CollBuilder]]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[CollBuilder]] = unapply(exp.node) + } + + object pairColl { + def unapply(d: Def[_]): Nullable[(Ref[CollBuilder], Ref[Coll[A]], Ref[Coll[B]]) forSome {type A; type B}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "pairColl" && receiver.elem.isInstanceOf[CollBuilderElem[_]] => + val res = (receiver, args(0), args(1)) + Nullable(res).asInstanceOf[Nullable[(Ref[CollBuilder], Ref[Coll[A]], Ref[Coll[B]]) forSome {type A; type B}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[CollBuilder], Ref[Coll[A]], Ref[Coll[B]]) forSome {type A; type B}] = unapply(exp.node) + } + + object fromItems { + def unapply(d: Def[_]): Nullable[(Ref[CollBuilder], Seq[Ref[T]], Elem[T]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "fromItems" && receiver.elem.isInstanceOf[CollBuilderElem[_]] => + val res = (receiver, args(0), args(1)) + Nullable(res).asInstanceOf[Nullable[(Ref[CollBuilder], Seq[Ref[T]], Elem[T]) forSome {type T}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[CollBuilder], Seq[Ref[T]], Elem[T]) forSome {type T}] = unapply(exp.node) + } + + object unzip { + def unapply(d: Def[_]): Nullable[(Ref[CollBuilder], Ref[Coll[(A, B)]]) forSome {type A; type B}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "unzip" && receiver.elem.isInstanceOf[CollBuilderElem[_]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[CollBuilder], Ref[Coll[(A, B)]]) forSome {type A; type B}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[CollBuilder], Ref[Coll[(A, B)]]) forSome {type A; type B}] = unapply(exp.node) + } + + object xor { + def unapply(d: Def[_]): Nullable[(Ref[CollBuilder], Ref[Coll[Byte]], Ref[Coll[Byte]])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "xor" && receiver.elem.isInstanceOf[CollBuilderElem[_]] => + val res = (receiver, args(0), args(1)) + Nullable(res).asInstanceOf[Nullable[(Ref[CollBuilder], Ref[Coll[Byte]], Ref[Coll[Byte]])]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[CollBuilder], Ref[Coll[Byte]], Ref[Coll[Byte]])] = unapply(exp.node) + } + + object replicate { + def unapply(d: Def[_]): Nullable[(Ref[CollBuilder], Ref[Int], Ref[T]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "replicate" && receiver.elem.isInstanceOf[CollBuilderElem[_]] => + val res = (receiver, args(0), args(1)) + Nullable(res).asInstanceOf[Nullable[(Ref[CollBuilder], Ref[Int], Ref[T]) forSome {type T}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[CollBuilder], Ref[Int], Ref[T]) forSome {type T}] = unapply(exp.node) + } + + object emptyColl { + def unapply(d: Def[_]): Nullable[(Ref[CollBuilder], Elem[T]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "emptyColl" && receiver.elem.isInstanceOf[CollBuilderElem[_]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[CollBuilder], Elem[T]) forSome {type T}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[CollBuilder], Elem[T]) forSome {type T}] = unapply(exp.node) + } + + object outerJoin { + def unapply(d: Def[_]): Nullable[(Ref[CollBuilder], Ref[Coll[(K, L)]], Ref[Coll[(K, R)]], Ref[((K, L)) => O], Ref[((K, R)) => O], Ref[((K, (L, R))) => O]) forSome {type K; type L; type R; type O}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "outerJoin" && receiver.elem.isInstanceOf[CollBuilderElem[_]] => + val res = (receiver, args(0), args(1), args(2), args(3), args(4)) + Nullable(res).asInstanceOf[Nullable[(Ref[CollBuilder], Ref[Coll[(K, L)]], Ref[Coll[(K, R)]], Ref[((K, L)) => O], Ref[((K, R)) => O], Ref[((K, (L, R))) => O]) forSome {type K; type L; type R; type O}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[CollBuilder], Ref[Coll[(K, L)]], Ref[Coll[(K, R)]], Ref[((K, L)) => O], Ref[((K, R)) => O], Ref[((K, (L, R))) => O]) forSome {type K; type L; type R; type O}] = unapply(exp.node) + } + + object flattenColl { + def unapply(d: Def[_]): Nullable[(Ref[CollBuilder], Ref[Coll[Coll[A]]]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "flattenColl" && receiver.elem.isInstanceOf[CollBuilderElem[_]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[CollBuilder], Ref[Coll[Coll[A]]]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[CollBuilder], Ref[Coll[Coll[A]]]) forSome {type A}] = unapply(exp.node) + } + } + + object CollBuilderCompanionMethods { + } +} // of object CollBuilder + registerEntityObject("CollBuilder", CollBuilder) + + override def resetContext(): Unit = { + super.resetContext() + RColl.reset() + RPairColl.reset() + RReplColl.reset() + RCollBuilder.reset() + } + + registerModule(CollsModule) +} + +object CollsModule extends scalan.ModuleInfo("special.collection", "Colls") +} + +trait CollsModule extends special.collection.impl.CollsDefs {self: Library =>} diff --git a/library/src/main/scala/special/collection/impl/ConcreteCostsImpl.scala b/library/src/main/scala/special/collection/impl/ConcreteCostsImpl.scala new file mode 100644 index 0000000000..4bf37c1cd2 --- /dev/null +++ b/library/src/main/scala/special/collection/impl/ConcreteCostsImpl.scala @@ -0,0 +1,488 @@ +package special.collection + +import scalan._ +import scala.reflect.runtime.universe._ +import scala.reflect._ +import scala.collection.mutable.WrappedArray + +package impl { +import scalan.util.MemoizedFunc // manual fix + +// Abs ----------------------------------- +trait ConcreteCostsDefs extends scalan.Scalan with ConcreteCosts { + self: Library => +import CCostedBuilder._ +import CCostedColl._ +import CCostedFunc._ +import CCostedOption._ +import CCostedPair._ +import CCostedPrim._ +import CSizeColl._ +import CSizeFunc._ +import CSizeOption._ +import CSizePair._ +import CSizePrim._ +import Coll._ +import Costed._ +import CostedBuilder._ +import CostedColl._ +import CostedFunc._ +import CostedOption._ +import CostedPair._ +import CostedPrim._ +import MonoidBuilder._ +import MonoidBuilderInst._ +import Size._ +import SizeColl._ +import SizeFunc._ +import SizeOption._ +import SizePair._ +import SizePrim._ +import WOption._ +import WRType._ +import WSpecialPredef._ + +object CCostedPrim extends EntityObject("CCostedPrim") { + case class CCostedPrimCtor[Val] + (override val value: Ref[Val], override val cost: Ref[Int], override val size: Ref[Size[Val]]) + extends CCostedPrim[Val](value, cost, size) with Def[CCostedPrim[Val]] { + implicit lazy val eVal = value.elem + + lazy val resultType = element[CCostedPrim[Val]] + override def transform(t: Transformer) = CCostedPrimCtor[Val](t(value), t(cost), t(size)) + } + + // state representation type + type CCostedPrimData[Val] = (Val, (Int, Size[Val])) + + // elem for concrete class + class CCostedPrimElem[Val](implicit override val eVal: Elem[Val]) + extends CostedPrimElem[Val, CCostedPrim[Val]] + with ConcreteElem[CCostedPrimData[Val], CCostedPrim[Val]] { + override lazy val parent: Option[Elem[_]] = Some(costedPrimElement(element[Val])) + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("Val" -> (eVal -> scalan.util.Invariant)) + } + + implicit final def cCostedPrimElement[Val](implicit eVal: Elem[Val]): Elem[CCostedPrim[Val]] = + cachedElemByClass(eVal)(classOf[CCostedPrimElem[Val]]) + + // 4) constructor and deconstructor + class CCostedPrimCompanionCtor extends CompanionDef[CCostedPrimCompanionCtor] with CCostedPrimCompanion { + def resultType = CCostedPrimCompanionElem + override def toString = "CCostedPrimCompanion" + @scalan.OverloadId("fromData") + def apply[Val](p: Ref[CCostedPrimData[Val]]): Ref[CCostedPrim[Val]] = { + implicit val eVal = p._1.elem + val Pair(value, Pair(cost, size)) = p + mkCCostedPrim(value, cost, size) + } + + // manual fix + @scalan.OverloadId("fromFields") + def apply[Val](value: Ref[Val], cost: Ref[Int], size: Ref[Size[Val]]): Ref[CCostedPrim[Val]] = { + assertValueIdForOpCost(value, cost) + mkCCostedPrim(value, cost, size) + } + + def unapply[Val](p: Ref[CostedPrim[Val]]) = unmkCCostedPrim(p) + } + lazy val RCCostedPrim: MutableLazy[CCostedPrimCompanionCtor] = MutableLazy(new CCostedPrimCompanionCtor) + implicit final def unrefCCostedPrimCompanion(p: Ref[CCostedPrimCompanionCtor]): CCostedPrimCompanionCtor = { + if (p.node.isInstanceOf[CCostedPrimCompanionCtor]) + p.node.asInstanceOf[CCostedPrimCompanionCtor] + else + unrefDelegate[CCostedPrimCompanionCtor](p) + } + + implicit case object CCostedPrimCompanionElem extends CompanionElem[CCostedPrimCompanionCtor] + + implicit final def unrefCCostedPrim[Val](p: Ref[CCostedPrim[Val]]): CCostedPrim[Val] = { + if (p.node.isInstanceOf[CCostedPrim[Val]@unchecked]) + p.node.asInstanceOf[CCostedPrim[Val]] + else + unrefDelegate[CCostedPrim[Val]](p) + } + + def mkCCostedPrim[Val] + (value: Ref[Val], cost: Ref[Int], size: Ref[Size[Val]]): Ref[CCostedPrim[Val]] = { + new CCostedPrimCtor[Val](value, cost, size) + } + def unmkCCostedPrim[Val](p: Ref[CostedPrim[Val]]) = p.elem.asInstanceOf[Elem[_]] match { + case _: CCostedPrimElem[Val] @unchecked => + Some((asRep[CCostedPrim[Val]](p).value, asRep[CCostedPrim[Val]](p).cost, asRep[CCostedPrim[Val]](p).size)) + case _ => + None + } +} // of object CCostedPrim + registerEntityObject("CCostedPrim", CCostedPrim) + +object CCostedPair extends EntityObject("CCostedPair") { + case class CCostedPairCtor[L, R] + (override val l: Ref[Costed[L]], override val r: Ref[Costed[R]], override val accCost: Ref[Int]) + extends CCostedPair[L, R](l, r, accCost) with Def[CCostedPair[L, R]] { + implicit lazy val eL = l.eVal; +implicit lazy val eR = r.eVal + override lazy val eVal: Elem[(L, R)] = implicitly[Elem[(L, R)]] + lazy val resultType = element[CCostedPair[L, R]] + override def transform(t: Transformer) = CCostedPairCtor[L, R](t(l), t(r), t(accCost)) + private val thisClass = classOf[CostedPair[_, _]] + + override def cost: Ref[Int] = { + asRep[Int](mkMethodCall(self, + thisClass.getMethod("cost"), + WrappedArray.empty, + true, false, element[Int])) + } + } + + // state representation type + type CCostedPairData[L, R] = (Costed[L], (Costed[R], Int)) + + // elem for concrete class + class CCostedPairElem[L, R](implicit override val eL: Elem[L], override val eR: Elem[R]) + extends CostedPairElem[L, R, CCostedPair[L, R]] + with ConcreteElem[CCostedPairData[L, R], CCostedPair[L, R]] { + override lazy val parent: Option[Elem[_]] = Some(costedPairElement(element[L], element[R])) + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("L" -> (eL -> scalan.util.Invariant), "R" -> (eR -> scalan.util.Invariant)) + } + + implicit final def cCostedPairElement[L, R](implicit eL: Elem[L], eR: Elem[R]): Elem[CCostedPair[L, R]] = + cachedElemByClass(eL, eR)(classOf[CCostedPairElem[L, R]]) + + // 4) constructor and deconstructor + class CCostedPairCompanionCtor extends CompanionDef[CCostedPairCompanionCtor] with CCostedPairCompanion { + def resultType = CCostedPairCompanionElem + override def toString = "CCostedPairCompanion" + @scalan.OverloadId("fromData") + def apply[L, R](p: Ref[CCostedPairData[L, R]]): Ref[CCostedPair[L, R]] = { + implicit val eL = p._1.eVal; +implicit val eR = p._2.eVal + val Pair(l, Pair(r, accCost)) = p + mkCCostedPair(l, r, accCost) + } + + // manual fix + @scalan.OverloadId("fromFields") + def apply[L, R](l: Ref[Costed[L]], r: Ref[Costed[R]], accCost: Ref[Int]): Ref[CCostedPair[L, R]] = { + assertValueIdForOpCost(Pair(l, r), accCost) + mkCCostedPair(l, r, accCost) + } + + def unapply[L, R](p: Ref[CostedPair[L, R]]) = unmkCCostedPair(p) + } + lazy val RCCostedPair: MutableLazy[CCostedPairCompanionCtor] = MutableLazy(new CCostedPairCompanionCtor) + implicit final def unrefCCostedPairCompanion(p: Ref[CCostedPairCompanionCtor]): CCostedPairCompanionCtor = { + if (p.node.isInstanceOf[CCostedPairCompanionCtor]) + p.node.asInstanceOf[CCostedPairCompanionCtor] + else + unrefDelegate[CCostedPairCompanionCtor](p) + } + + implicit case object CCostedPairCompanionElem extends CompanionElem[CCostedPairCompanionCtor] + + implicit final def unrefCCostedPair[L, R](p: Ref[CCostedPair[L, R]]): CCostedPair[L, R] = { + if (p.node.isInstanceOf[CCostedPair[L, R]@unchecked]) + p.node.asInstanceOf[CCostedPair[L, R]] + else + unrefDelegate[CCostedPair[L, R]](p) + } + + def mkCCostedPair[L, R] + (l: Ref[Costed[L]], r: Ref[Costed[R]], accCost: Ref[Int]): Ref[CCostedPair[L, R]] = { + new CCostedPairCtor[L, R](l, r, accCost) + } + def unmkCCostedPair[L, R](p: Ref[CostedPair[L, R]]) = p.elem.asInstanceOf[Elem[_]] match { + case _: CCostedPairElem[L, R] @unchecked => + Some((asRep[CCostedPair[L, R]](p).l, asRep[CCostedPair[L, R]](p).r, asRep[CCostedPair[L, R]](p).accCost)) + case _ => + None + } +} // of object CCostedPair + registerEntityObject("CCostedPair", CCostedPair) + +object CCostedFunc extends EntityObject("CCostedFunc") { + case class CCostedFuncCtor[Env, Arg, Res] + (override val envCosted: Ref[Costed[Env]], override val func: Ref[Costed[Arg] => Costed[Res]], override val cost: Ref[Int], override val size: Ref[Size[Arg => Res]]) + extends CCostedFunc[Env, Arg, Res](envCosted, func, cost, size) with Def[CCostedFunc[Env, Arg, Res]] { + implicit lazy val eEnv = envCosted.eVal; +implicit lazy val eArg = func.elem.eDom.typeArgs("Val")._1.asInstanceOf[Elem[Arg]]; +implicit lazy val eRes = func.elem.eRange.typeArgs("Val")._1.asInstanceOf[Elem[Res]] + override lazy val eVal: Elem[Arg => Res] = implicitly[Elem[Arg => Res]] + lazy val resultType = element[CCostedFunc[Env, Arg, Res]] + override def transform(t: Transformer) = CCostedFuncCtor[Env, Arg, Res](t(envCosted), t(func), t(cost), t(size)) + private val thisClass = classOf[CostedFunc[_, _, _]] + + override def value: Ref[Arg => Res] = { + asRep[Arg => Res](mkMethodCall(self, + thisClass.getMethod("value"), + WrappedArray.empty, + true, false, element[Arg => Res])) + } + } + + // state representation type + type CCostedFuncData[Env, Arg, Res] = (Costed[Env], (Costed[Arg] => Costed[Res], (Int, Size[Arg => Res]))) + + // elem for concrete class + class CCostedFuncElem[Env, Arg, Res](implicit override val eEnv: Elem[Env], override val eArg: Elem[Arg], override val eRes: Elem[Res]) + extends CostedFuncElem[Env, Arg, Res, CCostedFunc[Env, Arg, Res]] + with ConcreteElem[CCostedFuncData[Env, Arg, Res], CCostedFunc[Env, Arg, Res]] { + override lazy val parent: Option[Elem[_]] = Some(costedFuncElement(element[Env], element[Arg], element[Res])) + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("Env" -> (eEnv -> scalan.util.Invariant), "Arg" -> (eArg -> scalan.util.Invariant), "Res" -> (eRes -> scalan.util.Invariant)) + } + + implicit final def cCostedFuncElement[Env, Arg, Res](implicit eEnv: Elem[Env], eArg: Elem[Arg], eRes: Elem[Res]): Elem[CCostedFunc[Env, Arg, Res]] = + cachedElemByClass(eEnv, eArg, eRes)(classOf[CCostedFuncElem[Env, Arg, Res]]) + + // 4) constructor and deconstructor + class CCostedFuncCompanionCtor extends CompanionDef[CCostedFuncCompanionCtor] with CCostedFuncCompanion { + def resultType = CCostedFuncCompanionElem + override def toString = "CCostedFuncCompanion" + @scalan.OverloadId("fromData") + def apply[Env, Arg, Res](p: Ref[CCostedFuncData[Env, Arg, Res]]): Ref[CCostedFunc[Env, Arg, Res]] = { + implicit val eEnv = p._1.eVal; +implicit val eArg = p._2.elem.eDom.typeArgs("Val")._1.asInstanceOf[Elem[Arg]]; +implicit val eRes = p._2.elem.eRange.typeArgs("Val")._1.asInstanceOf[Elem[Res]] + val Pair(envCosted, Pair(func, Pair(cost, size))) = p + mkCCostedFunc(envCosted, func, cost, size) + } + + @scalan.OverloadId("fromFields") + def apply[Env, Arg, Res](envCosted: Ref[Costed[Env]], func: Ref[Costed[Arg] => Costed[Res]], cost: Ref[Int], size: Ref[Size[Arg => Res]]): Ref[CCostedFunc[Env, Arg, Res]] = + mkCCostedFunc(envCosted, func, cost, size) + + def unapply[Env, Arg, Res](p: Ref[CostedFunc[Env, Arg, Res]]) = unmkCCostedFunc(p) + } + lazy val RCCostedFunc: MutableLazy[CCostedFuncCompanionCtor] = MutableLazy(new CCostedFuncCompanionCtor) + implicit final def unrefCCostedFuncCompanion(p: Ref[CCostedFuncCompanionCtor]): CCostedFuncCompanionCtor = { + if (p.node.isInstanceOf[CCostedFuncCompanionCtor]) + p.node.asInstanceOf[CCostedFuncCompanionCtor] + else + unrefDelegate[CCostedFuncCompanionCtor](p) + } + + implicit case object CCostedFuncCompanionElem extends CompanionElem[CCostedFuncCompanionCtor] + + implicit final def unrefCCostedFunc[Env, Arg, Res](p: Ref[CCostedFunc[Env, Arg, Res]]): CCostedFunc[Env, Arg, Res] = { + if (p.node.isInstanceOf[CCostedFunc[Env, Arg, Res]@unchecked]) + p.node.asInstanceOf[CCostedFunc[Env, Arg, Res]] + else + unrefDelegate[CCostedFunc[Env, Arg, Res]](p) + } + + def mkCCostedFunc[Env, Arg, Res] + (envCosted: Ref[Costed[Env]], func: Ref[Costed[Arg] => Costed[Res]], cost: Ref[Int], size: Ref[Size[Arg => Res]]): Ref[CCostedFunc[Env, Arg, Res]] = { + new CCostedFuncCtor[Env, Arg, Res](envCosted, func, cost, size) + } + def unmkCCostedFunc[Env, Arg, Res](p: Ref[CostedFunc[Env, Arg, Res]]) = p.elem.asInstanceOf[Elem[_]] match { + case _: CCostedFuncElem[Env, Arg, Res] @unchecked => + Some((asRep[CCostedFunc[Env, Arg, Res]](p).envCosted, asRep[CCostedFunc[Env, Arg, Res]](p).func, asRep[CCostedFunc[Env, Arg, Res]](p).cost, asRep[CCostedFunc[Env, Arg, Res]](p).size)) + case _ => + None + } +} // of object CCostedFunc + registerEntityObject("CCostedFunc", CCostedFunc) + +object CCostedColl extends EntityObject("CCostedColl") { + case class CCostedCollCtor[Item] + (override val values: Ref[Coll[Item]], override val costs: Ref[Coll[Int]], override val sizes: Ref[Coll[Size[Item]]], override val valuesCost: Ref[Int]) + extends CCostedColl[Item](values, costs, sizes, valuesCost) with Def[CCostedColl[Item]] { + implicit lazy val eItem = values.eA + override lazy val eVal: Elem[Coll[Item]] = implicitly[Elem[Coll[Item]]] + lazy val resultType = element[CCostedColl[Item]] + override def transform(t: Transformer) = CCostedCollCtor[Item](t(values), t(costs), t(sizes), t(valuesCost)) + private val thisClass = classOf[CostedColl[_]] + + override def cost: Ref[Int] = { + asRep[Int](mkMethodCall(self, + thisClass.getMethod("cost"), + WrappedArray.empty, + true, false, element[Int])) + } + + override def mapCosted[Res](f: Ref[Costed[Item] => Costed[Res]]): Ref[CostedColl[Res]] = { + implicit val eRes = f.elem.eRange.typeArgs("Val")._1.asInstanceOf[Elem[Res]] + asRep[CostedColl[Res]](mkMethodCall(self, + thisClass.getMethod("mapCosted", classOf[Sym]), + Array[AnyRef](f), + true, false, element[CostedColl[Res]])) + } + + override def filterCosted(f: Ref[Costed[Item] => Costed[Boolean]]): Ref[CostedColl[Item]] = { + asRep[CostedColl[Item]](mkMethodCall(self, + thisClass.getMethod("filterCosted", classOf[Sym]), + Array[AnyRef](f), + true, false, element[CostedColl[Item]])) + } + + override def foldCosted[B](zero: Ref[Costed[B]], op: Ref[Costed[(B, Item)] => Costed[B]]): Ref[Costed[B]] = { + implicit val eB = zero.eVal + asRep[Costed[B]](mkMethodCall(self, + thisClass.getMethod("foldCosted", classOf[Sym], classOf[Sym]), + Array[AnyRef](zero, op), + true, false, element[Costed[B]])) + } + } + + // state representation type + type CCostedCollData[Item] = (Coll[Item], (Coll[Int], (Coll[Size[Item]], Int))) + + // elem for concrete class + class CCostedCollElem[Item](implicit override val eItem: Elem[Item]) + extends CostedCollElem[Item, CCostedColl[Item]] + with ConcreteElem[CCostedCollData[Item], CCostedColl[Item]] { + override lazy val parent: Option[Elem[_]] = Some(costedCollElement(element[Item])) + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("Item" -> (eItem -> scalan.util.Invariant)) + } + + implicit final def cCostedCollElement[Item](implicit eItem: Elem[Item]): Elem[CCostedColl[Item]] = + cachedElemByClass(eItem)(classOf[CCostedCollElem[Item]]) + + // 4) constructor and deconstructor + class CCostedCollCompanionCtor extends CompanionDef[CCostedCollCompanionCtor] with CCostedCollCompanion { + def resultType = CCostedCollCompanionElem + override def toString = "CCostedCollCompanion" + @scalan.OverloadId("fromData") + def apply[Item](p: Ref[CCostedCollData[Item]]): Ref[CCostedColl[Item]] = { + implicit val eItem = p._1.eA + val Pair(values, Pair(costs, Pair(sizes, valuesCost))) = p + mkCCostedColl(values, costs, sizes, valuesCost) + } + + @scalan.OverloadId("fromFields") + def apply[Item](values: Ref[Coll[Item]], costs: Ref[Coll[Int]], sizes: Ref[Coll[Size[Item]]], valuesCost: Ref[Int]): Ref[CCostedColl[Item]] = + mkCCostedColl(values, costs, sizes, valuesCost) + + def unapply[Item](p: Ref[CostedColl[Item]]) = unmkCCostedColl(p) + } + lazy val RCCostedColl: MutableLazy[CCostedCollCompanionCtor] = MutableLazy(new CCostedCollCompanionCtor) + implicit final def unrefCCostedCollCompanion(p: Ref[CCostedCollCompanionCtor]): CCostedCollCompanionCtor = { + if (p.node.isInstanceOf[CCostedCollCompanionCtor]) + p.node.asInstanceOf[CCostedCollCompanionCtor] + else + unrefDelegate[CCostedCollCompanionCtor](p) + } + + implicit case object CCostedCollCompanionElem extends CompanionElem[CCostedCollCompanionCtor] + + implicit final def unrefCCostedColl[Item](p: Ref[CCostedColl[Item]]): CCostedColl[Item] = { + if (p.node.isInstanceOf[CCostedColl[Item]@unchecked]) + p.node.asInstanceOf[CCostedColl[Item]] + else + unrefDelegate[CCostedColl[Item]](p) + } + + def mkCCostedColl[Item] + (values: Ref[Coll[Item]], costs: Ref[Coll[Int]], sizes: Ref[Coll[Size[Item]]], valuesCost: Ref[Int]): Ref[CCostedColl[Item]] = { + new CCostedCollCtor[Item](values, costs, sizes, valuesCost) + } + def unmkCCostedColl[Item](p: Ref[CostedColl[Item]]) = p.elem.asInstanceOf[Elem[_]] match { + case _: CCostedCollElem[Item] @unchecked => + Some((asRep[CCostedColl[Item]](p).values, asRep[CCostedColl[Item]](p).costs, asRep[CCostedColl[Item]](p).sizes, asRep[CCostedColl[Item]](p).valuesCost)) + case _ => + None + } +} // of object CCostedColl + registerEntityObject("CCostedColl", CCostedColl) + +object CCostedBuilder extends EntityObject("CCostedBuilder") { + case class CCostedBuilderCtor + () + extends CCostedBuilder() with Def[CCostedBuilder] { + lazy val resultType = element[CCostedBuilder] + override def transform(t: Transformer) = CCostedBuilderCtor() + private val thisClass = classOf[CostedBuilder] + + override def costedValue[T](x: Ref[T], optCost: Ref[WOption[Int]]): Ref[Costed[T]] = { + implicit val eT = x.elem + asRep[Costed[T]](mkMethodCall(self, + thisClass.getMethod("costedValue", classOf[Sym], classOf[Sym]), + Array[AnyRef](x, optCost), + true, false, element[Costed[T]])) + } + + override def defaultValue[T](valueType: Ref[WRType[T]]): Ref[T] = { + implicit val eT = valueType.eA + asRep[T](mkMethodCall(self, + thisClass.getMethod("defaultValue", classOf[Sym]), + Array[AnyRef](valueType), + true, false, element[T])) + } + } + + // state representation type + type CCostedBuilderData = Unit + + // elem for concrete class + class CCostedBuilderElem + extends CostedBuilderElem[CCostedBuilder] + with ConcreteElem[CCostedBuilderData, CCostedBuilder] { + override lazy val parent: Option[Elem[_]] = Some(costedBuilderElement) + } + + implicit lazy val cCostedBuilderElement: Elem[CCostedBuilder] = + new CCostedBuilderElem + + // 4) constructor and deconstructor + class CCostedBuilderCompanionCtor extends CompanionDef[CCostedBuilderCompanionCtor] with CCostedBuilderCompanion { + def resultType = CCostedBuilderCompanionElem + override def toString = "CCostedBuilderCompanion" + @scalan.OverloadId("fromData") + def apply(p: Ref[CCostedBuilderData]): Ref[CCostedBuilder] = { + val unit = p + mkCCostedBuilder() + } + + @scalan.OverloadId("fromFields") + def apply(): Ref[CCostedBuilder] = + mkCCostedBuilder() + + def unapply(p: Ref[CostedBuilder]) = unmkCCostedBuilder(p) + } + lazy val RCCostedBuilder: MutableLazy[CCostedBuilderCompanionCtor] = MutableLazy(new CCostedBuilderCompanionCtor) + implicit final def unrefCCostedBuilderCompanion(p: Ref[CCostedBuilderCompanionCtor]): CCostedBuilderCompanionCtor = { + if (p.node.isInstanceOf[CCostedBuilderCompanionCtor]) + p.node.asInstanceOf[CCostedBuilderCompanionCtor] + else + unrefDelegate[CCostedBuilderCompanionCtor](p) + } + + implicit case object CCostedBuilderCompanionElem extends CompanionElem[CCostedBuilderCompanionCtor] + + implicit final def unrefCCostedBuilder(p: Ref[CCostedBuilder]): CCostedBuilder = { + if (p.node.isInstanceOf[CCostedBuilder]) + p.node.asInstanceOf[CCostedBuilder] + else + unrefDelegate[CCostedBuilder](p) + } + + def mkCCostedBuilder + (): Ref[CCostedBuilder] = { + new CCostedBuilderCtor() + } + def unmkCCostedBuilder(p: Ref[CostedBuilder]) = p.elem.asInstanceOf[Elem[_]] match { + case _: CCostedBuilderElem @unchecked => + Some(()) + case _ => + None + } +} // of object CCostedBuilder + registerEntityObject("CCostedBuilder", CCostedBuilder) + + override def resetContext(): Unit = { + super.resetContext() + + RCCostedPrim.reset() + RCCostedPair.reset() + RCCostedFunc.reset() + RCCostedColl.reset() + RCCostedBuilder.reset() + } + + registerModule(ConcreteCostsModule) +} + +object ConcreteCostsModule extends scalan.ModuleInfo("special.collection", "ConcreteCosts") +} + +trait ConcreteCostsModule extends special.collection.impl.ConcreteCostsDefs {self: Library =>} diff --git a/library/src/main/scala/special/collection/impl/ConcreteSizesImpl.scala b/library/src/main/scala/special/collection/impl/ConcreteSizesImpl.scala new file mode 100644 index 0000000000..27994bbd78 --- /dev/null +++ b/library/src/main/scala/special/collection/impl/ConcreteSizesImpl.scala @@ -0,0 +1,427 @@ +package special.collection + +import scalan._ +import scala.reflect.runtime.universe._ +import scala.reflect._ +import scala.collection.mutable.WrappedArray + +package impl { + import scalan.util.MemoizedFunc // manual fix + + // Abs ----------------------------------- +trait ConcreteSizesDefs extends scalan.Scalan with ConcreteSizes { + self: Library => +import Size._ // manual fix +import Coll._ // manual fix +import WOption._ // manual fix +import SizeColl._ +import SizeFunc._ +import SizeOption._ +import SizePair._ +import SizePrim._ +import CSizeColl._ +import CSizeFunc._ +import CSizeOption._ +import CSizePair._ +import CSizePrim._ +import WRType._ // manual fix + +object CSizePrim extends EntityObject("CSizePrim") { + case class CSizePrimCtor[Val] + (override val dataSize: Ref[Long], override val tVal: Ref[WRType[Val]]) + extends CSizePrim[Val](dataSize, tVal) with Def[CSizePrim[Val]] { + implicit lazy val eVal = tVal.eA + + lazy val resultType = element[CSizePrim[Val]] + override def transform(t: Transformer) = CSizePrimCtor[Val](t(dataSize), t(tVal)) + } + + // state representation type + type CSizePrimData[Val] = (Long, WRType[Val]) + + // elem for concrete class + class CSizePrimElem[Val](implicit override val eVal: Elem[Val]) + extends SizePrimElem[Val, CSizePrim[Val]] + with ConcreteElem[CSizePrimData[Val], CSizePrim[Val]] { + override lazy val parent: Option[Elem[_]] = Some(sizePrimElement(element[Val])) + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("Val" -> (eVal -> scalan.util.Invariant)) + } + + implicit final def cSizePrimElement[Val](implicit eVal: Elem[Val]): Elem[CSizePrim[Val]] = + cachedElemByClass(eVal)(classOf[CSizePrimElem[Val]]) + + // 4) constructor and deconstructor + class CSizePrimCompanionCtor extends CompanionDef[CSizePrimCompanionCtor] with CSizePrimCompanion { + def resultType = CSizePrimCompanionElem + override def toString = "CSizePrimCompanion" + @scalan.OverloadId("fromData") + def apply[Val](p: Ref[CSizePrimData[Val]]): Ref[CSizePrim[Val]] = { + implicit val eVal = p._2.eA + val Pair(dataSize, tVal) = p + mkCSizePrim(dataSize, tVal) + } + + @scalan.OverloadId("fromFields") + def apply[Val](dataSize: Ref[Long], tVal: Ref[WRType[Val]]): Ref[CSizePrim[Val]] = + mkCSizePrim(dataSize, tVal) + + def unapply[Val](p: Ref[SizePrim[Val]]) = unmkCSizePrim(p) + } + lazy val RCSizePrim: MutableLazy[CSizePrimCompanionCtor] = MutableLazy(new CSizePrimCompanionCtor) + implicit final def unrefCSizePrimCompanion(p: Ref[CSizePrimCompanionCtor]): CSizePrimCompanionCtor = { + if (p.node.isInstanceOf[CSizePrimCompanionCtor]) + p.node.asInstanceOf[CSizePrimCompanionCtor] + else + unrefDelegate[CSizePrimCompanionCtor](p) + } + + implicit case object CSizePrimCompanionElem extends CompanionElem[CSizePrimCompanionCtor] + + implicit final def unrefCSizePrim[Val](p: Ref[CSizePrim[Val]]): CSizePrim[Val] = { + if (p.node.isInstanceOf[CSizePrim[Val]@unchecked]) + p.node.asInstanceOf[CSizePrim[Val]] + else + unrefDelegate[CSizePrim[Val]](p) + } + + def mkCSizePrim[Val] + (dataSize: Ref[Long], tVal: Ref[WRType[Val]]): Ref[CSizePrim[Val]] = { + new CSizePrimCtor[Val](dataSize, tVal) + } + def unmkCSizePrim[Val](p: Ref[SizePrim[Val]]) = p.elem.asInstanceOf[Elem[_]] match { + case _: CSizePrimElem[Val] @unchecked => + Some((asRep[CSizePrim[Val]](p).dataSize, asRep[CSizePrim[Val]](p).tVal)) + case _ => + None + } +} // of object CSizePrim + registerEntityObject("CSizePrim", CSizePrim) + +object CSizePair extends EntityObject("CSizePair") { + case class CSizePairCtor[L, R] + (override val l: Ref[Size[L]], override val r: Ref[Size[R]]) + extends CSizePair[L, R](l, r) with Def[CSizePair[L, R]] { + implicit lazy val eL = l.eVal; +implicit lazy val eR = r.eVal + override lazy val eVal: Elem[(L, R)] = implicitly[Elem[(L, R)]] + lazy val resultType = element[CSizePair[L, R]] + override def transform(t: Transformer) = CSizePairCtor[L, R](t(l), t(r)) + private val thisClass = classOf[SizePair[_, _]] + + override def dataSize: Ref[Long] = { + asRep[Long](mkMethodCall(self, + thisClass.getMethod("dataSize"), + WrappedArray.empty, + true, false, element[Long])) + } + } + + // state representation type + type CSizePairData[L, R] = (Size[L], Size[R]) + + // elem for concrete class + class CSizePairElem[L, R](implicit override val eL: Elem[L], override val eR: Elem[R]) + extends SizePairElem[L, R, CSizePair[L, R]] + with ConcreteElem[CSizePairData[L, R], CSizePair[L, R]] { + override lazy val parent: Option[Elem[_]] = Some(sizePairElement(element[L], element[R])) + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("L" -> (eL -> scalan.util.Invariant), "R" -> (eR -> scalan.util.Invariant)) + } + + implicit final def cSizePairElement[L, R](implicit eL: Elem[L], eR: Elem[R]): Elem[CSizePair[L, R]] = + cachedElemByClass(eL, eR)(classOf[CSizePairElem[L, R]]) + + // 4) constructor and deconstructor + class CSizePairCompanionCtor extends CompanionDef[CSizePairCompanionCtor] with CSizePairCompanion { + def resultType = CSizePairCompanionElem + override def toString = "CSizePairCompanion" + @scalan.OverloadId("fromData") + def apply[L, R](p: Ref[CSizePairData[L, R]]): Ref[CSizePair[L, R]] = { + implicit val eL = p._1.eVal; +implicit val eR = p._2.eVal + val Pair(l, r) = p + mkCSizePair(l, r) + } + + @scalan.OverloadId("fromFields") + def apply[L, R](l: Ref[Size[L]], r: Ref[Size[R]]): Ref[CSizePair[L, R]] = + mkCSizePair(l, r) + + def unapply[L, R](p: Ref[SizePair[L, R]]) = unmkCSizePair(p) + } + lazy val RCSizePair: MutableLazy[CSizePairCompanionCtor] = MutableLazy(new CSizePairCompanionCtor) + implicit final def unrefCSizePairCompanion(p: Ref[CSizePairCompanionCtor]): CSizePairCompanionCtor = { + if (p.node.isInstanceOf[CSizePairCompanionCtor]) + p.node.asInstanceOf[CSizePairCompanionCtor] + else + unrefDelegate[CSizePairCompanionCtor](p) + } + + implicit case object CSizePairCompanionElem extends CompanionElem[CSizePairCompanionCtor] + + implicit final def unrefCSizePair[L, R](p: Ref[CSizePair[L, R]]): CSizePair[L, R] = { + if (p.node.isInstanceOf[CSizePair[L, R]@unchecked]) + p.node.asInstanceOf[CSizePair[L, R]] + else + unrefDelegate[CSizePair[L, R]](p) + } + + def mkCSizePair[L, R] + (l: Ref[Size[L]], r: Ref[Size[R]]): Ref[CSizePair[L, R]] = { + new CSizePairCtor[L, R](l, r) + } + def unmkCSizePair[L, R](p: Ref[SizePair[L, R]]) = p.elem.asInstanceOf[Elem[_]] match { + case _: CSizePairElem[L, R] @unchecked => + Some((asRep[CSizePair[L, R]](p).l, asRep[CSizePair[L, R]](p).r)) + case _ => + None + } +} // of object CSizePair + registerEntityObject("CSizePair", CSizePair) + +object CSizeColl extends EntityObject("CSizeColl") { + case class CSizeCollCtor[Item] + (override val sizes: Ref[Coll[Size[Item]]]) + extends CSizeColl[Item](sizes) with Def[CSizeColl[Item]] { + implicit lazy val eItem = sizes.eA.typeArgs("Val")._1.asInstanceOf[Elem[Item]] + override lazy val eVal: Elem[Coll[Item]] = implicitly[Elem[Coll[Item]]] + lazy val resultType = element[CSizeColl[Item]] + override def transform(t: Transformer) = CSizeCollCtor[Item](t(sizes)) + private val thisClass = classOf[SizeColl[_]] + + override def dataSize: Ref[Long] = { + asRep[Long](mkMethodCall(self, + thisClass.getMethod("dataSize"), + WrappedArray.empty, + true, false, element[Long])) + } + } + + // state representation type + type CSizeCollData[Item] = Coll[Size[Item]] + + // elem for concrete class + class CSizeCollElem[Item](implicit override val eItem: Elem[Item]) + extends SizeCollElem[Item, CSizeColl[Item]] + with ConcreteElem[CSizeCollData[Item], CSizeColl[Item]] { + override lazy val parent: Option[Elem[_]] = Some(sizeCollElement(element[Item])) + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("Item" -> (eItem -> scalan.util.Invariant)) + } + + implicit final def cSizeCollElement[Item](implicit eItem: Elem[Item]): Elem[CSizeColl[Item]] = + cachedElemByClass(eItem)(classOf[CSizeCollElem[Item]]) + + // 4) constructor and deconstructor + class CSizeCollCompanionCtor extends CompanionDef[CSizeCollCompanionCtor] with CSizeCollCompanion { + def resultType = CSizeCollCompanionElem + override def toString = "CSizeCollCompanion" + + @scalan.OverloadId("fromFields") + def apply[Item](sizes: Ref[Coll[Size[Item]]]): Ref[CSizeColl[Item]] = + mkCSizeColl(sizes) + + def unapply[Item](p: Ref[SizeColl[Item]]) = unmkCSizeColl(p) + } + lazy val RCSizeColl: MutableLazy[CSizeCollCompanionCtor] = MutableLazy(new CSizeCollCompanionCtor) + implicit final def unrefCSizeCollCompanion(p: Ref[CSizeCollCompanionCtor]): CSizeCollCompanionCtor = { + if (p.node.isInstanceOf[CSizeCollCompanionCtor]) + p.node.asInstanceOf[CSizeCollCompanionCtor] + else + unrefDelegate[CSizeCollCompanionCtor](p) + } + + implicit case object CSizeCollCompanionElem extends CompanionElem[CSizeCollCompanionCtor] + + implicit final def unrefCSizeColl[Item](p: Ref[CSizeColl[Item]]): CSizeColl[Item] = { + if (p.node.isInstanceOf[CSizeColl[Item]@unchecked]) + p.node.asInstanceOf[CSizeColl[Item]] + else + unrefDelegate[CSizeColl[Item]](p) + } + + def mkCSizeColl[Item] + (sizes: Ref[Coll[Size[Item]]]): Ref[CSizeColl[Item]] = { + new CSizeCollCtor[Item](sizes) + } + def unmkCSizeColl[Item](p: Ref[SizeColl[Item]]) = p.elem.asInstanceOf[Elem[_]] match { + case _: CSizeCollElem[Item] @unchecked => + Some((asRep[CSizeColl[Item]](p).sizes)) + case _ => + None + } +} // of object CSizeColl + registerEntityObject("CSizeColl", CSizeColl) + +object CSizeFunc extends EntityObject("CSizeFunc") { + case class CSizeFuncCtor[Env, Arg, Res] + (override val sizeEnv: Ref[Size[Env]], override val sizeFunc: Ref[Long], override val tArg: Ref[WRType[Arg]], override val tRes: Ref[WRType[Res]]) + extends CSizeFunc[Env, Arg, Res](sizeEnv, sizeFunc, tArg, tRes) with Def[CSizeFunc[Env, Arg, Res]] { + implicit lazy val eEnv = sizeEnv.eVal; +implicit lazy val eArg = tArg.eA; +implicit lazy val eRes = tRes.eA + override lazy val eVal: Elem[Arg => Res] = implicitly[Elem[Arg => Res]] + lazy val resultType = element[CSizeFunc[Env, Arg, Res]] + override def transform(t: Transformer) = CSizeFuncCtor[Env, Arg, Res](t(sizeEnv), t(sizeFunc), t(tArg), t(tRes)) + private val thisClass = classOf[SizeFunc[_, _, _]] + + override def dataSize: Ref[Long] = { + asRep[Long](mkMethodCall(self, + thisClass.getMethod("dataSize"), + WrappedArray.empty, + true, false, element[Long])) + } + } + + // state representation type + type CSizeFuncData[Env, Arg, Res] = (Size[Env], (Long, (WRType[Arg], WRType[Res]))) + + // elem for concrete class + class CSizeFuncElem[Env, Arg, Res](implicit override val eEnv: Elem[Env], override val eArg: Elem[Arg], override val eRes: Elem[Res]) + extends SizeFuncElem[Env, Arg, Res, CSizeFunc[Env, Arg, Res]] + with ConcreteElem[CSizeFuncData[Env, Arg, Res], CSizeFunc[Env, Arg, Res]] { + override lazy val parent: Option[Elem[_]] = Some(sizeFuncElement(element[Env], element[Arg], element[Res])) + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("Env" -> (eEnv -> scalan.util.Invariant), "Arg" -> (eArg -> scalan.util.Invariant), "Res" -> (eRes -> scalan.util.Invariant)) + } + + implicit final def cSizeFuncElement[Env, Arg, Res](implicit eEnv: Elem[Env], eArg: Elem[Arg], eRes: Elem[Res]): Elem[CSizeFunc[Env, Arg, Res]] = + cachedElemByClass(eEnv, eArg, eRes)(classOf[CSizeFuncElem[Env, Arg, Res]]) + + // 4) constructor and deconstructor + class CSizeFuncCompanionCtor extends CompanionDef[CSizeFuncCompanionCtor] with CSizeFuncCompanion { + def resultType = CSizeFuncCompanionElem + override def toString = "CSizeFuncCompanion" + @scalan.OverloadId("fromData") + def apply[Env, Arg, Res](p: Ref[CSizeFuncData[Env, Arg, Res]]): Ref[CSizeFunc[Env, Arg, Res]] = { + implicit val eEnv = p._1.eVal; +implicit val eArg = p._3.eA; +implicit val eRes = p._4.eA + val Pair(sizeEnv, Pair(sizeFunc, Pair(tArg, tRes))) = p + mkCSizeFunc(sizeEnv, sizeFunc, tArg, tRes) + } + + @scalan.OverloadId("fromFields") + def apply[Env, Arg, Res](sizeEnv: Ref[Size[Env]], sizeFunc: Ref[Long], tArg: Ref[WRType[Arg]], tRes: Ref[WRType[Res]]): Ref[CSizeFunc[Env, Arg, Res]] = + mkCSizeFunc(sizeEnv, sizeFunc, tArg, tRes) + + def unapply[Env, Arg, Res](p: Ref[SizeFunc[Env, Arg, Res]]) = unmkCSizeFunc(p) + } + lazy val RCSizeFunc: MutableLazy[CSizeFuncCompanionCtor] = MutableLazy(new CSizeFuncCompanionCtor) + implicit final def unrefCSizeFuncCompanion(p: Ref[CSizeFuncCompanionCtor]): CSizeFuncCompanionCtor = { + if (p.node.isInstanceOf[CSizeFuncCompanionCtor]) + p.node.asInstanceOf[CSizeFuncCompanionCtor] + else + unrefDelegate[CSizeFuncCompanionCtor](p) + } + + implicit case object CSizeFuncCompanionElem extends CompanionElem[CSizeFuncCompanionCtor] + + implicit final def unrefCSizeFunc[Env, Arg, Res](p: Ref[CSizeFunc[Env, Arg, Res]]): CSizeFunc[Env, Arg, Res] = { + if (p.node.isInstanceOf[CSizeFunc[Env, Arg, Res]@unchecked]) + p.node.asInstanceOf[CSizeFunc[Env, Arg, Res]] + else + unrefDelegate[CSizeFunc[Env, Arg, Res]](p) + } + + def mkCSizeFunc[Env, Arg, Res] + (sizeEnv: Ref[Size[Env]], sizeFunc: Ref[Long], tArg: Ref[WRType[Arg]], tRes: Ref[WRType[Res]]): Ref[CSizeFunc[Env, Arg, Res]] = { + new CSizeFuncCtor[Env, Arg, Res](sizeEnv, sizeFunc, tArg, tRes) + } + def unmkCSizeFunc[Env, Arg, Res](p: Ref[SizeFunc[Env, Arg, Res]]) = p.elem.asInstanceOf[Elem[_]] match { + case _: CSizeFuncElem[Env, Arg, Res] @unchecked => + Some((asRep[CSizeFunc[Env, Arg, Res]](p).sizeEnv, asRep[CSizeFunc[Env, Arg, Res]](p).sizeFunc, asRep[CSizeFunc[Env, Arg, Res]](p).tArg, asRep[CSizeFunc[Env, Arg, Res]](p).tRes)) + case _ => + None + } +} // of object CSizeFunc + registerEntityObject("CSizeFunc", CSizeFunc) + +object CSizeOption extends EntityObject("CSizeOption") { + case class CSizeOptionCtor[Item] + (override val sizeOpt: Ref[WOption[Size[Item]]]) + extends CSizeOption[Item](sizeOpt) with Def[CSizeOption[Item]] { + implicit lazy val eItem = sizeOpt.eA.typeArgs("Val")._1.asInstanceOf[Elem[Item]] + override lazy val eT: Elem[Item] = eItem +override lazy val eVal: Elem[WOption[Item]] = implicitly[Elem[WOption[Item]]] + lazy val resultType = element[CSizeOption[Item]] + override def transform(t: Transformer) = CSizeOptionCtor[Item](t(sizeOpt)) + private val thisClass = classOf[SizeOption[_]] + + override def dataSize: Ref[Long] = { + asRep[Long](mkMethodCall(self, + thisClass.getMethod("dataSize"), + WrappedArray.empty, + true, false, element[Long])) + } + } + + // state representation type + type CSizeOptionData[Item] = WOption[Size[Item]] + + // elem for concrete class + class CSizeOptionElem[Item](implicit val eItem: Elem[Item]) + extends SizeOptionElem[Item, CSizeOption[Item]] + with ConcreteElem[CSizeOptionData[Item], CSizeOption[Item]] { + override lazy val parent: Option[Elem[_]] = Some(sizeOptionElement(element[Item])) + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("Item" -> (eItem -> scalan.util.Invariant)) + } + + implicit final def cSizeOptionElement[Item](implicit eItem: Elem[Item]): Elem[CSizeOption[Item]] = + cachedElemByClass(eItem)(classOf[CSizeOptionElem[Item]]) + + // 4) constructor and deconstructor + class CSizeOptionCompanionCtor extends CompanionDef[CSizeOptionCompanionCtor] with CSizeOptionCompanion { + def resultType = CSizeOptionCompanionElem + override def toString = "CSizeOptionCompanion" + + @scalan.OverloadId("fromFields") + def apply[Item](sizeOpt: Ref[WOption[Size[Item]]]): Ref[CSizeOption[Item]] = + mkCSizeOption(sizeOpt) + + def unapply[Item](p: Ref[SizeOption[Item]]) = unmkCSizeOption(p) + } + lazy val RCSizeOption: MutableLazy[CSizeOptionCompanionCtor] = MutableLazy(new CSizeOptionCompanionCtor) + implicit final def unrefCSizeOptionCompanion(p: Ref[CSizeOptionCompanionCtor]): CSizeOptionCompanionCtor = { + if (p.node.isInstanceOf[CSizeOptionCompanionCtor]) + p.node.asInstanceOf[CSizeOptionCompanionCtor] + else + unrefDelegate[CSizeOptionCompanionCtor](p) + } + + implicit case object CSizeOptionCompanionElem extends CompanionElem[CSizeOptionCompanionCtor] + + implicit final def unrefCSizeOption[Item](p: Ref[CSizeOption[Item]]): CSizeOption[Item] = { + if (p.node.isInstanceOf[CSizeOption[Item]@unchecked]) + p.node.asInstanceOf[CSizeOption[Item]] + else + unrefDelegate[CSizeOption[Item]](p) + } + + def mkCSizeOption[Item] + (sizeOpt: Ref[WOption[Size[Item]]]): Ref[CSizeOption[Item]] = { + new CSizeOptionCtor[Item](sizeOpt) + } + def unmkCSizeOption[Item](p: Ref[SizeOption[Item]]) = p.elem.asInstanceOf[Elem[_]] match { + case _: CSizeOptionElem[Item] @unchecked => + Some((asRep[CSizeOption[Item]](p).sizeOpt)) + case _ => + None + } +} // of object CSizeOption + registerEntityObject("CSizeOption", CSizeOption) + + override def resetContext(): Unit = { + super.resetContext() + + RCSizePrim.reset() + RCSizePair.reset() + RCSizeColl.reset() + RCSizeFunc.reset() + RCSizeOption.reset() + } + + registerModule(ConcreteSizesModule) +} + +object ConcreteSizesModule extends scalan.ModuleInfo("special.collection", "ConcreteSizes") +} + +trait ConcreteSizesModule extends special.collection.impl.ConcreteSizesDefs {self: Library =>} diff --git a/library/src/main/scala/special/collection/impl/CostedOptionsImpl.scala b/library/src/main/scala/special/collection/impl/CostedOptionsImpl.scala new file mode 100644 index 0000000000..1002a5cac2 --- /dev/null +++ b/library/src/main/scala/special/collection/impl/CostedOptionsImpl.scala @@ -0,0 +1,108 @@ +package special.collection + +import scalan._ +import scala.collection.mutable.WrappedArray + +package impl { +// Abs ----------------------------------- +trait CostedOptionsDefs extends scalan.Scalan with CostedOptions { + self: Library => +import CostedOption._ +import WOption._ +import CCostedOption._ + +object CCostedOption extends EntityObject("CCostedOption") { + case class CCostedOptionCtor[T] + (override val value: Ref[WOption[T]], override val costOpt: Ref[WOption[Int]], override val sizeOpt: Ref[WOption[Size[T]]], override val accumulatedCost: Ref[Int]) + extends CCostedOption[T](value, costOpt, sizeOpt, accumulatedCost) with Def[CCostedOption[T]] { + implicit lazy val eT = value.eA + override lazy val eVal: Elem[WOption[T]] = implicitly[Elem[WOption[T]]] + lazy val resultType = element[CCostedOption[T]] + override def transform(t: Transformer) = CCostedOptionCtor[T](t(value), t(costOpt), t(sizeOpt), t(accumulatedCost)) + private val thisClass = classOf[CostedOption[_]] + + override def cost: Ref[Int] = { + asRep[Int](mkMethodCall(self, + thisClass.getMethod("cost"), + WrappedArray.empty, + true, false, element[Int])) + } + } + + // state representation type + type CCostedOptionData[T] = (WOption[T], (WOption[Int], (WOption[Size[T]], Int))) + + // elem for concrete class + class CCostedOptionElem[T](implicit override val eT: Elem[T]) + extends CostedOptionElem[T, CCostedOption[T]] + with ConcreteElem[CCostedOptionData[T], CCostedOption[T]] { + override lazy val parent: Option[Elem[_]] = Some(costedOptionElement(element[T])) + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("T" -> (eT -> scalan.util.Invariant)) + } + + implicit final def cCostedOptionElement[T](implicit eT: Elem[T]): Elem[CCostedOption[T]] = + cachedElemByClass(eT)(classOf[CCostedOptionElem[T]]) + + // 4) constructor and deconstructor + class CCostedOptionCompanionCtor extends CompanionDef[CCostedOptionCompanionCtor] with CCostedOptionCompanion { + def resultType = CCostedOptionCompanionElem + override def toString = "CCostedOptionCompanion" + @scalan.OverloadId("fromData") + def apply[T](p: Ref[CCostedOptionData[T]]): Ref[CCostedOption[T]] = { + implicit val eT = p._1.eA + val Pair(value, Pair(costOpt, Pair(sizeOpt, accumulatedCost))) = p + mkCCostedOption(value, costOpt, sizeOpt, accumulatedCost) + } + + // manual fix + @scalan.OverloadId("fromFields") + def apply[T](value: Ref[WOption[T]], costOpt: Ref[WOption[Int]], sizeOpt: Ref[WOption[Size[T]]], accumulatedCost: Ref[Int]): Ref[CCostedOption[T]] = { + assertValueIdForOpCost(value, accumulatedCost) + mkCCostedOption(value, costOpt, sizeOpt, accumulatedCost) + } + + def unapply[T](p: Ref[CostedOption[T]]) = unmkCCostedOption(p) + } + lazy val RCCostedOption: MutableLazy[CCostedOptionCompanionCtor] = MutableLazy(new CCostedOptionCompanionCtor) + implicit final def unrefCCostedOptionCompanion(p: Ref[CCostedOptionCompanionCtor]): CCostedOptionCompanionCtor = { + if (p.node.isInstanceOf[CCostedOptionCompanionCtor]) + p.node.asInstanceOf[CCostedOptionCompanionCtor] + else + unrefDelegate[CCostedOptionCompanionCtor](p) + } + + implicit case object CCostedOptionCompanionElem extends CompanionElem[CCostedOptionCompanionCtor] + + implicit final def unrefCCostedOption[T](p: Ref[CCostedOption[T]]): CCostedOption[T] = { + if (p.node.isInstanceOf[CCostedOption[T]@unchecked]) + p.node.asInstanceOf[CCostedOption[T]] + else + unrefDelegate[CCostedOption[T]](p) + } + + def mkCCostedOption[T] + (value: Ref[WOption[T]], costOpt: Ref[WOption[Int]], sizeOpt: Ref[WOption[Size[T]]], accumulatedCost: Ref[Int]): Ref[CCostedOption[T]] = { + new CCostedOptionCtor[T](value, costOpt, sizeOpt, accumulatedCost) + } + def unmkCCostedOption[T](p: Ref[CostedOption[T]]) = p.elem.asInstanceOf[Elem[_]] match { + case _: CCostedOptionElem[T] @unchecked => + Some((asRep[CCostedOption[T]](p).value, asRep[CCostedOption[T]](p).costOpt, asRep[CCostedOption[T]](p).sizeOpt, asRep[CCostedOption[T]](p).accumulatedCost)) + case _ => + None + } +} // of object CCostedOption + registerEntityObject("CCostedOption", CCostedOption) + + override def resetContext(): Unit = { + super.resetContext() + + RCCostedOption.reset() + } + + registerModule(CostedOptionsModule) +} + +object CostedOptionsModule extends scalan.ModuleInfo("special.collection", "CostedOptions") +} + +trait CostedOptionsModule extends special.collection.impl.CostedOptionsDefs {self: Library =>} diff --git a/library/src/main/scala/special/collection/impl/CostsImpl.scala b/library/src/main/scala/special/collection/impl/CostsImpl.scala new file mode 100644 index 0000000000..33bdb96697 --- /dev/null +++ b/library/src/main/scala/special/collection/impl/CostsImpl.scala @@ -0,0 +1,1082 @@ +package special.collection + +import scalan._ +import scala.reflect.runtime.universe._ +import scala.reflect._ +import scala.collection.mutable.WrappedArray + +package impl { +// Abs ----------------------------------- +trait CostsDefs extends scalan.Scalan with Costs { + self: Library => +import Coll._ +import Costed._ +import CostedBuilder._ +import CostedColl._ +import CostedFunc._ +import CostedOption._ +import CostedPair._ +import CostedPrim._ +import MonoidBuilder._ +import Size._ +import SizeColl._ +import SizeFunc._ +import SizeOption._ +import SizePair._ +import SizePrim._ +import WOption._ +import WRType._ + +object Costed extends EntityObject("Costed") { + private val CostedClass = classOf[Costed[_]] + + // entityAdapter for Costed trait + case class CostedAdapter[Val](source: Ref[Costed[Val]]) + extends Node with Costed[Val] + with Def[Costed[Val]] { + implicit lazy val eVal = source.elem.typeArgs("Val")._1.asInstanceOf[Elem[Val]] + + val resultType: Elem[Costed[Val]] = element[Costed[Val]] + override def transform(t: Transformer) = CostedAdapter[Val](t(source)) + + def builder: Ref[CostedBuilder] = { + asRep[CostedBuilder](mkMethodCall(source, + CostedClass.getMethod("builder"), + WrappedArray.empty, + true, true, element[CostedBuilder])) + } + + def value: Ref[Val] = { + asRep[Val](mkMethodCall(source, + CostedClass.getMethod("value"), + WrappedArray.empty, + true, true, element[Val])) + } + + def cost: Ref[Int] = { + asRep[Int](mkMethodCall(source, + CostedClass.getMethod("cost"), + WrappedArray.empty, + true, true, element[Int])) + } + + def size: Ref[Size[Val]] = { + asRep[Size[Val]](mkMethodCall(source, + CostedClass.getMethod("size"), + WrappedArray.empty, + true, true, element[Size[Val]])) + } + } + + // entityUnref: single unref method for each type family + implicit final def unrefCosted[Val](p: Ref[Costed[Val]]): Costed[Val] = { + if (p.node.isInstanceOf[Costed[Val]@unchecked]) p.node.asInstanceOf[Costed[Val]] + else + CostedAdapter(p) + } + + // familyElem + class CostedElem[Val, To <: Costed[Val]](implicit _eVal: Elem[Val]) + extends EntityElem[To] { + def eVal = _eVal + + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("Val" -> (eVal -> scalan.util.Invariant)) + } + + implicit final def costedElement[Val](implicit eVal: Elem[Val]): Elem[Costed[Val]] = + cachedElemByClass(eVal)(classOf[CostedElem[Val, Costed[Val]]]) + + implicit case object CostedCompanionElem extends CompanionElem[CostedCompanionCtor] + + abstract class CostedCompanionCtor extends CompanionDef[CostedCompanionCtor] with CostedCompanion { + def resultType = CostedCompanionElem + override def toString = "Costed" + } + implicit final def unrefCostedCompanionCtor(p: Ref[CostedCompanionCtor]): CostedCompanionCtor = + p.node.asInstanceOf[CostedCompanionCtor] + + lazy val RCosted: MutableLazy[CostedCompanionCtor] = MutableLazy(new CostedCompanionCtor { + private val thisClass = classOf[CostedCompanion] + }) + + object CostedMethods { + object builder { + def unapply(d: Def[_]): Nullable[Ref[Costed[Val]] forSome {type Val}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "builder" && receiver.elem.isInstanceOf[CostedElem[_, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[Costed[Val]] forSome {type Val}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[Costed[Val]] forSome {type Val}] = unapply(exp.node) + } + + object value { + def unapply(d: Def[_]): Nullable[Ref[Costed[Val]] forSome {type Val}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "value" && receiver.elem.isInstanceOf[CostedElem[_, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[Costed[Val]] forSome {type Val}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[Costed[Val]] forSome {type Val}] = unapply(exp.node) + } + + object cost { + def unapply(d: Def[_]): Nullable[Ref[Costed[Val]] forSome {type Val}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "cost" && receiver.elem.isInstanceOf[CostedElem[_, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[Costed[Val]] forSome {type Val}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[Costed[Val]] forSome {type Val}] = unapply(exp.node) + } + + object size { + def unapply(d: Def[_]): Nullable[Ref[Costed[Val]] forSome {type Val}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "size" && receiver.elem.isInstanceOf[CostedElem[_, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[Costed[Val]] forSome {type Val}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[Costed[Val]] forSome {type Val}] = unapply(exp.node) + } + } + + object CostedCompanionMethods { + } +} // of object Costed + registerEntityObject("Costed", Costed) + +object CostedPrim extends EntityObject("CostedPrim") { + private val CostedPrimClass = classOf[CostedPrim[_]] + + // entityAdapter for CostedPrim trait + case class CostedPrimAdapter[Val](source: Ref[CostedPrim[Val]]) + extends Node with CostedPrim[Val] + with Def[CostedPrim[Val]] { + implicit lazy val eVal = source.elem.typeArgs("Val")._1.asInstanceOf[Elem[Val]] + + val resultType: Elem[CostedPrim[Val]] = element[CostedPrim[Val]] + override def transform(t: Transformer) = CostedPrimAdapter[Val](t(source)) + + def value: Ref[Val] = { + asRep[Val](mkMethodCall(source, + CostedPrimClass.getMethod("value"), + WrappedArray.empty, + true, true, element[Val])) + } + + def cost: Ref[Int] = { + asRep[Int](mkMethodCall(source, + CostedPrimClass.getMethod("cost"), + WrappedArray.empty, + true, true, element[Int])) + } + + def size: Ref[Size[Val]] = { + asRep[Size[Val]](mkMethodCall(source, + CostedPrimClass.getMethod("size"), + WrappedArray.empty, + true, true, element[Size[Val]])) + } + + def builder: Ref[CostedBuilder] = { + asRep[CostedBuilder](mkMethodCall(source, + CostedPrimClass.getMethod("builder"), + WrappedArray.empty, + true, true, element[CostedBuilder])) + } + } + + // entityUnref: single unref method for each type family + implicit final def unrefCostedPrim[Val](p: Ref[CostedPrim[Val]]): CostedPrim[Val] = { + if (p.node.isInstanceOf[CostedPrim[Val]@unchecked]) p.node.asInstanceOf[CostedPrim[Val]] + else + CostedPrimAdapter(p) + } + + // familyElem + class CostedPrimElem[Val, To <: CostedPrim[Val]](implicit _eVal: Elem[Val]) + extends CostedElem[Val, To] { + override def eVal = _eVal + + override lazy val parent: Option[Elem[_]] = Some(costedElement(element[Val])) + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("Val" -> (eVal -> scalan.util.Invariant)) + } + + implicit final def costedPrimElement[Val](implicit eVal: Elem[Val]): Elem[CostedPrim[Val]] = + cachedElemByClass(eVal)(classOf[CostedPrimElem[Val, CostedPrim[Val]]]) + + implicit case object CostedPrimCompanionElem extends CompanionElem[CostedPrimCompanionCtor] + + abstract class CostedPrimCompanionCtor extends CompanionDef[CostedPrimCompanionCtor] with CostedPrimCompanion { + def resultType = CostedPrimCompanionElem + override def toString = "CostedPrim" + } + implicit final def unrefCostedPrimCompanionCtor(p: Ref[CostedPrimCompanionCtor]): CostedPrimCompanionCtor = + p.node.asInstanceOf[CostedPrimCompanionCtor] + + lazy val RCostedPrim: MutableLazy[CostedPrimCompanionCtor] = MutableLazy(new CostedPrimCompanionCtor { + private val thisClass = classOf[CostedPrimCompanion] + }) +} // of object CostedPrim + registerEntityObject("CostedPrim", CostedPrim) + +object CostedPair extends EntityObject("CostedPair") { + private val CostedPairClass = classOf[CostedPair[_, _]] + + // entityAdapter for CostedPair trait + case class CostedPairAdapter[L, R](source: Ref[CostedPair[L, R]]) + extends Node with CostedPair[L, R] + with Def[CostedPair[L, R]] { + implicit lazy val eL = source.elem.typeArgs("L")._1.asInstanceOf[Elem[L]]; +implicit lazy val eR = source.elem.typeArgs("R")._1.asInstanceOf[Elem[R]] + override lazy val eVal: Elem[(L, R)] = implicitly[Elem[(L, R)]] + val resultType: Elem[CostedPair[L, R]] = element[CostedPair[L, R]] + override def transform(t: Transformer) = CostedPairAdapter[L, R](t(source)) + + def l: Ref[Costed[L]] = { + asRep[Costed[L]](mkMethodCall(source, + CostedPairClass.getMethod("l"), + WrappedArray.empty, + true, true, element[Costed[L]])) + } + + def r: Ref[Costed[R]] = { + asRep[Costed[R]](mkMethodCall(source, + CostedPairClass.getMethod("r"), + WrappedArray.empty, + true, true, element[Costed[R]])) + } + + def accCost: Ref[Int] = { + asRep[Int](mkMethodCall(source, + CostedPairClass.getMethod("accCost"), + WrappedArray.empty, + true, true, element[Int])) + } + + def builder: Ref[CostedBuilder] = { + asRep[CostedBuilder](mkMethodCall(source, + CostedPairClass.getMethod("builder"), + WrappedArray.empty, + true, true, element[CostedBuilder])) + } + + def value: Ref[(L, R)] = { + asRep[(L, R)](mkMethodCall(source, + CostedPairClass.getMethod("value"), + WrappedArray.empty, + true, true, element[(L, R)])) + } + + def cost: Ref[Int] = { + asRep[Int](mkMethodCall(source, + CostedPairClass.getMethod("cost"), + WrappedArray.empty, + true, true, element[Int])) + } + + def size: Ref[Size[(L, R)]] = { + asRep[Size[(L, R)]](mkMethodCall(source, + CostedPairClass.getMethod("size"), + WrappedArray.empty, + true, true, element[Size[(L, R)]])) + } + } + + // entityUnref: single unref method for each type family + implicit final def unrefCostedPair[L, R](p: Ref[CostedPair[L, R]]): CostedPair[L, R] = { + if (p.node.isInstanceOf[CostedPair[L, R]@unchecked]) p.node.asInstanceOf[CostedPair[L, R]] + else + CostedPairAdapter(p) + } + + // familyElem + class CostedPairElem[L, R, To <: CostedPair[L, R]](implicit _eL: Elem[L], _eR: Elem[R]) + extends CostedElem[(L, R), To] { + def eL = _eL + def eR = _eR + + override lazy val parent: Option[Elem[_]] = Some(costedElement(pairElement(element[L],element[R]))) + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("L" -> (eL -> scalan.util.Invariant), "R" -> (eR -> scalan.util.Invariant)) + } + + implicit final def costedPairElement[L, R](implicit eL: Elem[L], eR: Elem[R]): Elem[CostedPair[L, R]] = + cachedElemByClass(eL, eR)(classOf[CostedPairElem[L, R, CostedPair[L, R]]]) + + implicit case object CostedPairCompanionElem extends CompanionElem[CostedPairCompanionCtor] + + abstract class CostedPairCompanionCtor extends CompanionDef[CostedPairCompanionCtor] with CostedPairCompanion { + def resultType = CostedPairCompanionElem + override def toString = "CostedPair" + } + implicit final def unrefCostedPairCompanionCtor(p: Ref[CostedPairCompanionCtor]): CostedPairCompanionCtor = + p.node.asInstanceOf[CostedPairCompanionCtor] + + lazy val RCostedPair: MutableLazy[CostedPairCompanionCtor] = MutableLazy(new CostedPairCompanionCtor { + private val thisClass = classOf[CostedPairCompanion] + }) +} // of object CostedPair + registerEntityObject("CostedPair", CostedPair) + +object CostedFunc extends EntityObject("CostedFunc") { + private val CostedFuncClass = classOf[CostedFunc[_, _, _]] + + // entityAdapter for CostedFunc trait + case class CostedFuncAdapter[Env, Arg, Res](source: Ref[CostedFunc[Env, Arg, Res]]) + extends Node with CostedFunc[Env, Arg, Res] + with Def[CostedFunc[Env, Arg, Res]] { + implicit lazy val eEnv = source.elem.typeArgs("Env")._1.asInstanceOf[Elem[Env]]; +implicit lazy val eArg = source.elem.typeArgs("Arg")._1.asInstanceOf[Elem[Arg]]; +implicit lazy val eRes = source.elem.typeArgs("Res")._1.asInstanceOf[Elem[Res]] + override lazy val eVal: Elem[Arg => Res] = implicitly[Elem[Arg => Res]] + val resultType: Elem[CostedFunc[Env, Arg, Res]] = element[CostedFunc[Env, Arg, Res]] + override def transform(t: Transformer) = CostedFuncAdapter[Env, Arg, Res](t(source)) + + def envCosted: Ref[Costed[Env]] = { + asRep[Costed[Env]](mkMethodCall(source, + CostedFuncClass.getMethod("envCosted"), + WrappedArray.empty, + true, true, element[Costed[Env]])) + } + + def func: Ref[Costed[Arg] => Costed[Res]] = { + asRep[Costed[Arg] => Costed[Res]](mkMethodCall(source, + CostedFuncClass.getMethod("func"), + WrappedArray.empty, + true, true, element[Costed[Arg] => Costed[Res]])) + } + + def cost: Ref[Int] = { + asRep[Int](mkMethodCall(source, + CostedFuncClass.getMethod("cost"), + WrappedArray.empty, + true, true, element[Int])) + } + + def sliceCalc: Ref[Arg => Res] = { + asRep[Arg => Res](mkMethodCall(source, + CostedFuncClass.getMethod("sliceCalc"), + WrappedArray.empty, + true, true, element[Arg => Res])) + } + + def sliceCost: Ref[((Int, Size[Arg])) => Int] = { + asRep[((Int, Size[Arg])) => Int](mkMethodCall(source, + CostedFuncClass.getMethod("sliceCost"), + WrappedArray.empty, + true, true, element[((Int, Size[Arg])) => Int])) + } + + def sliceCostEx: Ref[((Arg, (Int, Size[Arg]))) => Int] = { + asRep[((Arg, (Int, Size[Arg]))) => Int](mkMethodCall(source, + CostedFuncClass.getMethod("sliceCostEx"), + WrappedArray.empty, + true, true, element[((Arg, (Int, Size[Arg]))) => Int])) + } + + def sliceSize: Ref[Size[Arg] => Size[Res]] = { + asRep[Size[Arg] => Size[Res]](mkMethodCall(source, + CostedFuncClass.getMethod("sliceSize"), + WrappedArray.empty, + true, true, element[Size[Arg] => Size[Res]])) + } + + def builder: Ref[CostedBuilder] = { + asRep[CostedBuilder](mkMethodCall(source, + CostedFuncClass.getMethod("builder"), + WrappedArray.empty, + true, true, element[CostedBuilder])) + } + + def value: Ref[Arg => Res] = { + asRep[Arg => Res](mkMethodCall(source, + CostedFuncClass.getMethod("value"), + WrappedArray.empty, + true, true, element[Arg => Res])) + } + + def size: Ref[Size[Arg => Res]] = { + asRep[Size[Arg => Res]](mkMethodCall(source, + CostedFuncClass.getMethod("size"), + WrappedArray.empty, + true, true, element[Size[Arg => Res]])) + } + } + + // entityUnref: single unref method for each type family + implicit final def unrefCostedFunc[Env, Arg, Res](p: Ref[CostedFunc[Env, Arg, Res]]): CostedFunc[Env, Arg, Res] = { + if (p.node.isInstanceOf[CostedFunc[Env, Arg, Res]@unchecked]) p.node.asInstanceOf[CostedFunc[Env, Arg, Res]] + else + CostedFuncAdapter(p) + } + + // familyElem + class CostedFuncElem[Env, Arg, Res, To <: CostedFunc[Env, Arg, Res]](implicit _eEnv: Elem[Env], _eArg: Elem[Arg], _eRes: Elem[Res]) + extends CostedElem[Arg => Res, To] { + def eEnv = _eEnv + def eArg = _eArg + def eRes = _eRes + + override lazy val parent: Option[Elem[_]] = Some(costedElement(funcElement(element[Arg],element[Res]))) + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("Env" -> (eEnv -> scalan.util.Invariant), "Arg" -> (eArg -> scalan.util.Invariant), "Res" -> (eRes -> scalan.util.Invariant)) + } + + implicit final def costedFuncElement[Env, Arg, Res](implicit eEnv: Elem[Env], eArg: Elem[Arg], eRes: Elem[Res]): Elem[CostedFunc[Env, Arg, Res]] = + cachedElemByClass(eEnv, eArg, eRes)(classOf[CostedFuncElem[Env, Arg, Res, CostedFunc[Env, Arg, Res]]]) + + implicit case object CostedFuncCompanionElem extends CompanionElem[CostedFuncCompanionCtor] + + abstract class CostedFuncCompanionCtor extends CompanionDef[CostedFuncCompanionCtor] with CostedFuncCompanion { + def resultType = CostedFuncCompanionElem + override def toString = "CostedFunc" + } + implicit final def unrefCostedFuncCompanionCtor(p: Ref[CostedFuncCompanionCtor]): CostedFuncCompanionCtor = + p.node.asInstanceOf[CostedFuncCompanionCtor] + + lazy val RCostedFunc: MutableLazy[CostedFuncCompanionCtor] = MutableLazy(new CostedFuncCompanionCtor { + private val thisClass = classOf[CostedFuncCompanion] + }) +} // of object CostedFunc + registerEntityObject("CostedFunc", CostedFunc) + +object CostedColl extends EntityObject("CostedColl") { + private val CostedCollClass = classOf[CostedColl[_]] + + // entityAdapter for CostedColl trait + case class CostedCollAdapter[Item](source: Ref[CostedColl[Item]]) + extends Node with CostedColl[Item] + with Def[CostedColl[Item]] { + implicit lazy val eItem = source.elem.typeArgs("Item")._1.asInstanceOf[Elem[Item]] + override lazy val eVal: Elem[Coll[Item]] = implicitly[Elem[Coll[Item]]] + val resultType: Elem[CostedColl[Item]] = element[CostedColl[Item]] + override def transform(t: Transformer) = CostedCollAdapter[Item](t(source)) + + def values: Ref[Coll[Item]] = { + asRep[Coll[Item]](mkMethodCall(source, + CostedCollClass.getMethod("values"), + WrappedArray.empty, + true, true, element[Coll[Item]])) + } + + def costs: Ref[Coll[Int]] = { + asRep[Coll[Int]](mkMethodCall(source, + CostedCollClass.getMethod("costs"), + WrappedArray.empty, + true, true, element[Coll[Int]])) + } + + def sizes: Ref[Coll[Size[Item]]] = { + asRep[Coll[Size[Item]]](mkMethodCall(source, + CostedCollClass.getMethod("sizes"), + WrappedArray.empty, + true, true, element[Coll[Size[Item]]])) + } + + def valuesCost: Ref[Int] = { + asRep[Int](mkMethodCall(source, + CostedCollClass.getMethod("valuesCost"), + WrappedArray.empty, + true, true, element[Int])) + } + + def mapCosted[Res](f: Ref[Costed[Item] => Costed[Res]]): Ref[CostedColl[Res]] = { + implicit val eRes = f.elem.eRange.typeArgs("Val")._1.asInstanceOf[Elem[Res]] + asRep[CostedColl[Res]](mkMethodCall(source, + CostedCollClass.getMethod("mapCosted", classOf[Sym]), + Array[AnyRef](f), + true, true, element[CostedColl[Res]])) + } + + def filterCosted(f: Ref[Costed[Item] => Costed[Boolean]]): Ref[CostedColl[Item]] = { + asRep[CostedColl[Item]](mkMethodCall(source, + CostedCollClass.getMethod("filterCosted", classOf[Sym]), + Array[AnyRef](f), + true, true, element[CostedColl[Item]])) + } + + def foldCosted[B](zero: Ref[Costed[B]], op: Ref[Costed[(B, Item)] => Costed[B]]): Ref[Costed[B]] = { + implicit val eB = zero.eVal + asRep[Costed[B]](mkMethodCall(source, + CostedCollClass.getMethod("foldCosted", classOf[Sym], classOf[Sym]), + Array[AnyRef](zero, op), + true, true, element[Costed[B]])) + } + + def builder: Ref[CostedBuilder] = { + asRep[CostedBuilder](mkMethodCall(source, + CostedCollClass.getMethod("builder"), + WrappedArray.empty, + true, true, element[CostedBuilder])) + } + + def value: Ref[Coll[Item]] = { + asRep[Coll[Item]](mkMethodCall(source, + CostedCollClass.getMethod("value"), + WrappedArray.empty, + true, true, element[Coll[Item]])) + } + + def cost: Ref[Int] = { + asRep[Int](mkMethodCall(source, + CostedCollClass.getMethod("cost"), + WrappedArray.empty, + true, true, element[Int])) + } + + def size: Ref[Size[Coll[Item]]] = { + asRep[Size[Coll[Item]]](mkMethodCall(source, + CostedCollClass.getMethod("size"), + WrappedArray.empty, + true, true, element[Size[Coll[Item]]])) + } + } + + // entityUnref: single unref method for each type family + implicit final def unrefCostedColl[Item](p: Ref[CostedColl[Item]]): CostedColl[Item] = { + if (p.node.isInstanceOf[CostedColl[Item]@unchecked]) p.node.asInstanceOf[CostedColl[Item]] + else + CostedCollAdapter(p) + } + + // familyElem + class CostedCollElem[Item, To <: CostedColl[Item]](implicit _eItem: Elem[Item]) + extends CostedElem[Coll[Item], To] { + def eItem = _eItem + + override lazy val parent: Option[Elem[_]] = Some(costedElement(collElement(element[Item]))) + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("Item" -> (eItem -> scalan.util.Invariant)) + } + + implicit final def costedCollElement[Item](implicit eItem: Elem[Item]): Elem[CostedColl[Item]] = + cachedElemByClass(eItem)(classOf[CostedCollElem[Item, CostedColl[Item]]]) + + implicit case object CostedCollCompanionElem extends CompanionElem[CostedCollCompanionCtor] + + abstract class CostedCollCompanionCtor extends CompanionDef[CostedCollCompanionCtor] with CostedCollCompanion { + def resultType = CostedCollCompanionElem + override def toString = "CostedColl" + } + implicit final def unrefCostedCollCompanionCtor(p: Ref[CostedCollCompanionCtor]): CostedCollCompanionCtor = + p.node.asInstanceOf[CostedCollCompanionCtor] + + lazy val RCostedColl: MutableLazy[CostedCollCompanionCtor] = MutableLazy(new CostedCollCompanionCtor { + private val thisClass = classOf[CostedCollCompanion] + }) + + object CostedCollMethods { + object values { + def unapply(d: Def[_]): Nullable[Ref[CostedColl[Item]] forSome {type Item}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "values" && receiver.elem.isInstanceOf[CostedCollElem[_, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[CostedColl[Item]] forSome {type Item}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[CostedColl[Item]] forSome {type Item}] = unapply(exp.node) + } + + object costs { + def unapply(d: Def[_]): Nullable[Ref[CostedColl[Item]] forSome {type Item}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "costs" && receiver.elem.isInstanceOf[CostedCollElem[_, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[CostedColl[Item]] forSome {type Item}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[CostedColl[Item]] forSome {type Item}] = unapply(exp.node) + } + + object sizes { + def unapply(d: Def[_]): Nullable[Ref[CostedColl[Item]] forSome {type Item}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "sizes" && receiver.elem.isInstanceOf[CostedCollElem[_, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[CostedColl[Item]] forSome {type Item}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[CostedColl[Item]] forSome {type Item}] = unapply(exp.node) + } + + object valuesCost { + def unapply(d: Def[_]): Nullable[Ref[CostedColl[Item]] forSome {type Item}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "valuesCost" && receiver.elem.isInstanceOf[CostedCollElem[_, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[CostedColl[Item]] forSome {type Item}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[CostedColl[Item]] forSome {type Item}] = unapply(exp.node) + } + + object mapCosted { + def unapply(d: Def[_]): Nullable[(Ref[CostedColl[Item]], Ref[Costed[Item] => Costed[Res]]) forSome {type Item; type Res}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "mapCosted" && receiver.elem.isInstanceOf[CostedCollElem[_, _]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[CostedColl[Item]], Ref[Costed[Item] => Costed[Res]]) forSome {type Item; type Res}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[CostedColl[Item]], Ref[Costed[Item] => Costed[Res]]) forSome {type Item; type Res}] = unapply(exp.node) + } + + object filterCosted { + def unapply(d: Def[_]): Nullable[(Ref[CostedColl[Item]], Ref[Costed[Item] => Costed[Boolean]]) forSome {type Item}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "filterCosted" && receiver.elem.isInstanceOf[CostedCollElem[_, _]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[CostedColl[Item]], Ref[Costed[Item] => Costed[Boolean]]) forSome {type Item}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[CostedColl[Item]], Ref[Costed[Item] => Costed[Boolean]]) forSome {type Item}] = unapply(exp.node) + } + + object foldCosted { + def unapply(d: Def[_]): Nullable[(Ref[CostedColl[Item]], Ref[Costed[B]], Ref[Costed[(B, Item)] => Costed[B]]) forSome {type Item; type B}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "foldCosted" && receiver.elem.isInstanceOf[CostedCollElem[_, _]] => + val res = (receiver, args(0), args(1)) + Nullable(res).asInstanceOf[Nullable[(Ref[CostedColl[Item]], Ref[Costed[B]], Ref[Costed[(B, Item)] => Costed[B]]) forSome {type Item; type B}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[CostedColl[Item]], Ref[Costed[B]], Ref[Costed[(B, Item)] => Costed[B]]) forSome {type Item; type B}] = unapply(exp.node) + } + } + + object CostedCollCompanionMethods { + } +} // of object CostedColl + registerEntityObject("CostedColl", CostedColl) + +object CostedOption extends EntityObject("CostedOption") { + private val CostedOptionClass = classOf[CostedOption[_]] + + // entityAdapter for CostedOption trait + case class CostedOptionAdapter[T](source: Ref[CostedOption[T]]) + extends Node with CostedOption[T] + with Def[CostedOption[T]] { + implicit lazy val eT = source.elem.typeArgs("T")._1.asInstanceOf[Elem[T]] + override lazy val eVal: Elem[WOption[T]] = implicitly[Elem[WOption[T]]] + val resultType: Elem[CostedOption[T]] = element[CostedOption[T]] + override def transform(t: Transformer) = CostedOptionAdapter[T](t(source)) + + def costOpt: Ref[WOption[Int]] = { + asRep[WOption[Int]](mkMethodCall(source, + CostedOptionClass.getMethod("costOpt"), + WrappedArray.empty, + true, true, element[WOption[Int]])) + } + + def sizeOpt: Ref[WOption[Size[T]]] = { + asRep[WOption[Size[T]]](mkMethodCall(source, + CostedOptionClass.getMethod("sizeOpt"), + WrappedArray.empty, + true, true, element[WOption[Size[T]]])) + } + + def accumulatedCost: Ref[Int] = { + asRep[Int](mkMethodCall(source, + CostedOptionClass.getMethod("accumulatedCost"), + WrappedArray.empty, + true, true, element[Int])) + } + + def builder: Ref[CostedBuilder] = { + asRep[CostedBuilder](mkMethodCall(source, + CostedOptionClass.getMethod("builder"), + WrappedArray.empty, + true, true, element[CostedBuilder])) + } + + def value: Ref[WOption[T]] = { + asRep[WOption[T]](mkMethodCall(source, + CostedOptionClass.getMethod("value"), + WrappedArray.empty, + true, true, element[WOption[T]])) + } + + def cost: Ref[Int] = { + asRep[Int](mkMethodCall(source, + CostedOptionClass.getMethod("cost"), + WrappedArray.empty, + true, true, element[Int])) + } + + def size: Ref[Size[WOption[T]]] = { + asRep[Size[WOption[T]]](mkMethodCall(source, + CostedOptionClass.getMethod("size"), + WrappedArray.empty, + true, true, element[Size[WOption[T]]])) + } + } + + // entityUnref: single unref method for each type family + implicit final def unrefCostedOption[T](p: Ref[CostedOption[T]]): CostedOption[T] = { + if (p.node.isInstanceOf[CostedOption[T]@unchecked]) p.node.asInstanceOf[CostedOption[T]] + else + CostedOptionAdapter(p) + } + + // familyElem + class CostedOptionElem[T, To <: CostedOption[T]](implicit _eT: Elem[T]) + extends CostedElem[WOption[T], To] { + def eT = _eT + + override lazy val parent: Option[Elem[_]] = Some(costedElement(wOptionElement(element[T]))) + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("T" -> (eT -> scalan.util.Invariant)) + } + + implicit final def costedOptionElement[T](implicit eT: Elem[T]): Elem[CostedOption[T]] = + cachedElemByClass(eT)(classOf[CostedOptionElem[T, CostedOption[T]]]) + + implicit case object CostedOptionCompanionElem extends CompanionElem[CostedOptionCompanionCtor] + + abstract class CostedOptionCompanionCtor extends CompanionDef[CostedOptionCompanionCtor] with CostedOptionCompanion { + def resultType = CostedOptionCompanionElem + override def toString = "CostedOption" + } + implicit final def unrefCostedOptionCompanionCtor(p: Ref[CostedOptionCompanionCtor]): CostedOptionCompanionCtor = + p.node.asInstanceOf[CostedOptionCompanionCtor] + + lazy val RCostedOption: MutableLazy[CostedOptionCompanionCtor] = MutableLazy(new CostedOptionCompanionCtor { + private val thisClass = classOf[CostedOptionCompanion] + }) +} // of object CostedOption + registerEntityObject("CostedOption", CostedOption) + +object CostedBuilder extends EntityObject("CostedBuilder") { + private val CostedBuilderClass = classOf[CostedBuilder] + + // entityAdapter for CostedBuilder trait + case class CostedBuilderAdapter(source: Ref[CostedBuilder]) + extends Node with CostedBuilder + with Def[CostedBuilder] { + val resultType: Elem[CostedBuilder] = element[CostedBuilder] + override def transform(t: Transformer) = CostedBuilderAdapter(t(source)) + + def costedValue[T](x: Ref[T], optCost: Ref[WOption[Int]]): Ref[Costed[T]] = { + implicit val eT = x.elem + asRep[Costed[T]](mkMethodCall(source, + CostedBuilderClass.getMethod("costedValue", classOf[Sym], classOf[Sym]), + Array[AnyRef](x, optCost), + true, true, element[Costed[T]])) + } + + def defaultValue[T](valueType: Ref[WRType[T]]): Ref[T] = { + implicit val eT = valueType.eA + asRep[T](mkMethodCall(source, + CostedBuilderClass.getMethod("defaultValue", classOf[Sym]), + Array[AnyRef](valueType), + true, true, element[T])) + } + + def monoidBuilder: Ref[MonoidBuilder] = { + asRep[MonoidBuilder](mkMethodCall(source, + CostedBuilderClass.getMethod("monoidBuilder"), + WrappedArray.empty, + true, true, element[MonoidBuilder])) + } + + def mkSizePrim[T](dataSize: Ref[Long], tT: Ref[WRType[T]]): Ref[SizePrim[T]] = { + implicit val eT = tT.eA + asRep[SizePrim[T]](mkMethodCall(source, + CostedBuilderClass.getMethod("mkSizePrim", classOf[Sym], classOf[Sym]), + Array[AnyRef](dataSize, tT), + true, true, element[SizePrim[T]])) + } + + def mkSizePair[L, R](l: Ref[Size[L]], r: Ref[Size[R]]): Ref[SizePair[L, R]] = { + implicit val eL = l.eVal +implicit val eR = r.eVal + asRep[SizePair[L, R]](mkMethodCall(source, + CostedBuilderClass.getMethod("mkSizePair", classOf[Sym], classOf[Sym]), + Array[AnyRef](l, r), + true, true, element[SizePair[L, R]])) + } + + def mkSizeColl[T](sizes: Ref[Coll[Size[T]]]): Ref[SizeColl[T]] = { + implicit val eT = sizes.eA.typeArgs("Val")._1.asInstanceOf[Elem[T]] + asRep[SizeColl[T]](mkMethodCall(source, + CostedBuilderClass.getMethod("mkSizeColl", classOf[Sym]), + Array[AnyRef](sizes), + true, true, element[SizeColl[T]])) + } + + def mkSizeFunc[E, A, R](sizeEnv: Ref[Size[E]], sizeFunc: Ref[Long], tA: Ref[WRType[A]], tR: Ref[WRType[R]]): Ref[SizeFunc[E, A, R]] = { + implicit val eE = sizeEnv.eVal +implicit val eA = tA.eA +implicit val eR = tR.eA + asRep[SizeFunc[E, A, R]](mkMethodCall(source, + CostedBuilderClass.getMethod("mkSizeFunc", classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym]), + Array[AnyRef](sizeEnv, sizeFunc, tA, tR), + true, true, element[SizeFunc[E, A, R]])) + } + + def mkSizeOption[T](sizeOpt: Ref[WOption[Size[T]]]): Ref[SizeOption[T]] = { + implicit val eT = sizeOpt.eA.typeArgs("Val")._1.asInstanceOf[Elem[T]] + asRep[SizeOption[T]](mkMethodCall(source, + CostedBuilderClass.getMethod("mkSizeOption", classOf[Sym]), + Array[AnyRef](sizeOpt), + true, true, element[SizeOption[T]])) + } + + def mkCostedPrim[T](value: Ref[T], cost: Ref[Int], size: Ref[Size[T]]): Ref[CostedPrim[T]] = { + implicit val eT = value.elem + asRep[CostedPrim[T]](mkMethodCall(source, + CostedBuilderClass.getMethod("mkCostedPrim", classOf[Sym], classOf[Sym], classOf[Sym]), + Array[AnyRef](value, cost, size), + true, true, element[CostedPrim[T]])) + } + + def mkCostedPair[L, R](first: Ref[Costed[L]], second: Ref[Costed[R]], accCost: Ref[Int]): Ref[CostedPair[L, R]] = { + implicit val eL = first.eVal +implicit val eR = second.eVal + asRep[CostedPair[L, R]](mkMethodCall(source, + CostedBuilderClass.getMethod("mkCostedPair", classOf[Sym], classOf[Sym], classOf[Sym]), + Array[AnyRef](first, second, accCost), + true, true, element[CostedPair[L, R]])) + } + + def mkCostedFunc[Env, Arg, Res](envCosted: Ref[Costed[Env]], func: Ref[Costed[Arg] => Costed[Res]], cost: Ref[Int], size: Ref[Size[Arg => Res]]): Ref[CostedFunc[Env, Arg, Res]] = { + implicit val eEnv = envCosted.eVal +implicit val eArg = func.elem.eDom.typeArgs("Val")._1.asInstanceOf[Elem[Arg]] +implicit val eRes = func.elem.eRange.typeArgs("Val")._1.asInstanceOf[Elem[Res]] + asRep[CostedFunc[Env, Arg, Res]](mkMethodCall(source, + CostedBuilderClass.getMethod("mkCostedFunc", classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym]), + Array[AnyRef](envCosted, func, cost, size), + true, true, element[CostedFunc[Env, Arg, Res]])) + } + + def mkCostedColl[T](values: Ref[Coll[T]], costs: Ref[Coll[Int]], sizes: Ref[Coll[Size[T]]], valuesCost: Ref[Int]): Ref[CostedColl[T]] = { + implicit val eT = values.eA + asRep[CostedColl[T]](mkMethodCall(source, + CostedBuilderClass.getMethod("mkCostedColl", classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym]), + Array[AnyRef](values, costs, sizes, valuesCost), + true, true, element[CostedColl[T]])) + } + + def mkCostedOption[T](value: Ref[WOption[T]], costOpt: Ref[WOption[Int]], sizeOpt: Ref[WOption[Size[T]]], accumulatedCost: Ref[Int]): Ref[CostedOption[T]] = { + implicit val eT = value.eA + asRep[CostedOption[T]](mkMethodCall(source, + CostedBuilderClass.getMethod("mkCostedOption", classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym]), + Array[AnyRef](value, costOpt, sizeOpt, accumulatedCost), + true, true, element[CostedOption[T]])) + } + } + + // entityUnref: single unref method for each type family + implicit final def unrefCostedBuilder(p: Ref[CostedBuilder]): CostedBuilder = { + if (p.node.isInstanceOf[CostedBuilder]) p.node.asInstanceOf[CostedBuilder] + else + CostedBuilderAdapter(p) + } + + // familyElem + class CostedBuilderElem[To <: CostedBuilder] + extends EntityElem[To] { + } + + implicit lazy val costedBuilderElement: Elem[CostedBuilder] = + new CostedBuilderElem[CostedBuilder] + + implicit case object CostedBuilderCompanionElem extends CompanionElem[CostedBuilderCompanionCtor] + + abstract class CostedBuilderCompanionCtor extends CompanionDef[CostedBuilderCompanionCtor] with CostedBuilderCompanion { + def resultType = CostedBuilderCompanionElem + override def toString = "CostedBuilder" + } + implicit final def unrefCostedBuilderCompanionCtor(p: Ref[CostedBuilderCompanionCtor]): CostedBuilderCompanionCtor = + p.node.asInstanceOf[CostedBuilderCompanionCtor] + + lazy val RCostedBuilder: MutableLazy[CostedBuilderCompanionCtor] = MutableLazy(new CostedBuilderCompanionCtor { + private val thisClass = classOf[CostedBuilderCompanion] + }) + + object CostedBuilderMethods { + object ConstructTupleCost { + def unapply(d: Def[_]): Nullable[Ref[CostedBuilder]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "ConstructTupleCost" && receiver.elem.isInstanceOf[CostedBuilderElem[_]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[CostedBuilder]]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[CostedBuilder]] = unapply(exp.node) + } + + object ConstructSumCost { + def unapply(d: Def[_]): Nullable[Ref[CostedBuilder]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "ConstructSumCost" && receiver.elem.isInstanceOf[CostedBuilderElem[_]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[CostedBuilder]]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[CostedBuilder]] = unapply(exp.node) + } + + object SelectFieldCost { + def unapply(d: Def[_]): Nullable[Ref[CostedBuilder]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "SelectFieldCost" && receiver.elem.isInstanceOf[CostedBuilderElem[_]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[CostedBuilder]]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[CostedBuilder]] = unapply(exp.node) + } + + object SumTagSize { + def unapply(d: Def[_]): Nullable[Ref[CostedBuilder]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "SumTagSize" && receiver.elem.isInstanceOf[CostedBuilderElem[_]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[CostedBuilder]]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[CostedBuilder]] = unapply(exp.node) + } + + object costedValue { + def unapply(d: Def[_]): Nullable[(Ref[CostedBuilder], Ref[T], Ref[WOption[Int]]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "costedValue" && receiver.elem.isInstanceOf[CostedBuilderElem[_]] => + val res = (receiver, args(0), args(1)) + Nullable(res).asInstanceOf[Nullable[(Ref[CostedBuilder], Ref[T], Ref[WOption[Int]]) forSome {type T}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[CostedBuilder], Ref[T], Ref[WOption[Int]]) forSome {type T}] = unapply(exp.node) + } + + object defaultValue { + def unapply(d: Def[_]): Nullable[(Ref[CostedBuilder], Ref[WRType[T]]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "defaultValue" && receiver.elem.isInstanceOf[CostedBuilderElem[_]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[CostedBuilder], Ref[WRType[T]]) forSome {type T}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[CostedBuilder], Ref[WRType[T]]) forSome {type T}] = unapply(exp.node) + } + + object monoidBuilder { + def unapply(d: Def[_]): Nullable[Ref[CostedBuilder]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "monoidBuilder" && receiver.elem.isInstanceOf[CostedBuilderElem[_]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[CostedBuilder]]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[CostedBuilder]] = unapply(exp.node) + } + + object mkSizePrim { + def unapply(d: Def[_]): Nullable[(Ref[CostedBuilder], Ref[Long], Ref[WRType[T]]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "mkSizePrim" && receiver.elem.isInstanceOf[CostedBuilderElem[_]] => + val res = (receiver, args(0), args(1)) + Nullable(res).asInstanceOf[Nullable[(Ref[CostedBuilder], Ref[Long], Ref[WRType[T]]) forSome {type T}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[CostedBuilder], Ref[Long], Ref[WRType[T]]) forSome {type T}] = unapply(exp.node) + } + + object mkSizePair { + def unapply(d: Def[_]): Nullable[(Ref[CostedBuilder], Ref[Size[L]], Ref[Size[R]]) forSome {type L; type R}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "mkSizePair" && receiver.elem.isInstanceOf[CostedBuilderElem[_]] => + val res = (receiver, args(0), args(1)) + Nullable(res).asInstanceOf[Nullable[(Ref[CostedBuilder], Ref[Size[L]], Ref[Size[R]]) forSome {type L; type R}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[CostedBuilder], Ref[Size[L]], Ref[Size[R]]) forSome {type L; type R}] = unapply(exp.node) + } + + object mkSizeColl { + def unapply(d: Def[_]): Nullable[(Ref[CostedBuilder], Ref[Coll[Size[T]]]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "mkSizeColl" && receiver.elem.isInstanceOf[CostedBuilderElem[_]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[CostedBuilder], Ref[Coll[Size[T]]]) forSome {type T}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[CostedBuilder], Ref[Coll[Size[T]]]) forSome {type T}] = unapply(exp.node) + } + + object mkSizeFunc { + def unapply(d: Def[_]): Nullable[(Ref[CostedBuilder], Ref[Size[E]], Ref[Long], Ref[WRType[A]], Ref[WRType[R]]) forSome {type E; type A; type R}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "mkSizeFunc" && receiver.elem.isInstanceOf[CostedBuilderElem[_]] => + val res = (receiver, args(0), args(1), args(2), args(3)) + Nullable(res).asInstanceOf[Nullable[(Ref[CostedBuilder], Ref[Size[E]], Ref[Long], Ref[WRType[A]], Ref[WRType[R]]) forSome {type E; type A; type R}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[CostedBuilder], Ref[Size[E]], Ref[Long], Ref[WRType[A]], Ref[WRType[R]]) forSome {type E; type A; type R}] = unapply(exp.node) + } + + object mkSizeOption { + def unapply(d: Def[_]): Nullable[(Ref[CostedBuilder], Ref[WOption[Size[T]]]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "mkSizeOption" && receiver.elem.isInstanceOf[CostedBuilderElem[_]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[CostedBuilder], Ref[WOption[Size[T]]]) forSome {type T}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[CostedBuilder], Ref[WOption[Size[T]]]) forSome {type T}] = unapply(exp.node) + } + + object mkCostedPrim { + def unapply(d: Def[_]): Nullable[(Ref[CostedBuilder], Ref[T], Ref[Int], Ref[Size[T]]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "mkCostedPrim" && receiver.elem.isInstanceOf[CostedBuilderElem[_]] => + val res = (receiver, args(0), args(1), args(2)) + Nullable(res).asInstanceOf[Nullable[(Ref[CostedBuilder], Ref[T], Ref[Int], Ref[Size[T]]) forSome {type T}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[CostedBuilder], Ref[T], Ref[Int], Ref[Size[T]]) forSome {type T}] = unapply(exp.node) + } + + object mkCostedPair { + def unapply(d: Def[_]): Nullable[(Ref[CostedBuilder], Ref[Costed[L]], Ref[Costed[R]], Ref[Int]) forSome {type L; type R}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "mkCostedPair" && receiver.elem.isInstanceOf[CostedBuilderElem[_]] => + val res = (receiver, args(0), args(1), args(2)) + Nullable(res).asInstanceOf[Nullable[(Ref[CostedBuilder], Ref[Costed[L]], Ref[Costed[R]], Ref[Int]) forSome {type L; type R}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[CostedBuilder], Ref[Costed[L]], Ref[Costed[R]], Ref[Int]) forSome {type L; type R}] = unapply(exp.node) + } + + object mkCostedFunc { + def unapply(d: Def[_]): Nullable[(Ref[CostedBuilder], Ref[Costed[Env]], Ref[Costed[Arg] => Costed[Res]], Ref[Int], Ref[Size[Arg => Res]]) forSome {type Env; type Arg; type Res}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "mkCostedFunc" && receiver.elem.isInstanceOf[CostedBuilderElem[_]] => + val res = (receiver, args(0), args(1), args(2), args(3)) + Nullable(res).asInstanceOf[Nullable[(Ref[CostedBuilder], Ref[Costed[Env]], Ref[Costed[Arg] => Costed[Res]], Ref[Int], Ref[Size[Arg => Res]]) forSome {type Env; type Arg; type Res}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[CostedBuilder], Ref[Costed[Env]], Ref[Costed[Arg] => Costed[Res]], Ref[Int], Ref[Size[Arg => Res]]) forSome {type Env; type Arg; type Res}] = unapply(exp.node) + } + + object mkCostedColl { + def unapply(d: Def[_]): Nullable[(Ref[CostedBuilder], Ref[Coll[T]], Ref[Coll[Int]], Ref[Coll[Size[T]]], Ref[Int]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "mkCostedColl" && receiver.elem.isInstanceOf[CostedBuilderElem[_]] => + val res = (receiver, args(0), args(1), args(2), args(3)) + Nullable(res).asInstanceOf[Nullable[(Ref[CostedBuilder], Ref[Coll[T]], Ref[Coll[Int]], Ref[Coll[Size[T]]], Ref[Int]) forSome {type T}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[CostedBuilder], Ref[Coll[T]], Ref[Coll[Int]], Ref[Coll[Size[T]]], Ref[Int]) forSome {type T}] = unapply(exp.node) + } + + object mkCostedOption { + def unapply(d: Def[_]): Nullable[(Ref[CostedBuilder], Ref[WOption[T]], Ref[WOption[Int]], Ref[WOption[Size[T]]], Ref[Int]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "mkCostedOption" && receiver.elem.isInstanceOf[CostedBuilderElem[_]] => + val res = (receiver, args(0), args(1), args(2), args(3)) + Nullable(res).asInstanceOf[Nullable[(Ref[CostedBuilder], Ref[WOption[T]], Ref[WOption[Int]], Ref[WOption[Size[T]]], Ref[Int]) forSome {type T}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[CostedBuilder], Ref[WOption[T]], Ref[WOption[Int]], Ref[WOption[Size[T]]], Ref[Int]) forSome {type T}] = unapply(exp.node) + } + } + + object CostedBuilderCompanionMethods { + } +} // of object CostedBuilder + registerEntityObject("CostedBuilder", CostedBuilder) + + override def resetContext(): Unit = { + super.resetContext() + RCosted.reset() + RCostedPrim.reset() + RCostedPair.reset() + RCostedFunc.reset() + RCostedColl.reset() + RCostedOption.reset() + RCostedBuilder.reset() + } + + registerModule(CostsModule) +} + +object CostsModule extends scalan.ModuleInfo("special.collection", "Costs") +} + +trait CostsModule extends special.collection.impl.CostsDefs {self: Library =>} diff --git a/library/src/main/scala/special/collection/impl/MonoidInstancesImpl.scala b/library/src/main/scala/special/collection/impl/MonoidInstancesImpl.scala new file mode 100644 index 0000000000..f739b2a6f5 --- /dev/null +++ b/library/src/main/scala/special/collection/impl/MonoidInstancesImpl.scala @@ -0,0 +1,225 @@ +package special.collection + +import scalan._ +import scala.reflect.runtime.universe._ +import scala.reflect._ +import scala.collection.mutable.WrappedArray + +package impl { +// Abs ----------------------------------- +trait MonoidInstancesDefs extends scalan.Scalan with MonoidInstances { + self: Library => +import IntPlusMonoid._ +import LongPlusMonoid._ +import Monoid._ +import MonoidBuilder._ +import MonoidBuilderInst._ + +object MonoidBuilderInst extends EntityObject("MonoidBuilderInst") { + case class MonoidBuilderInstCtor + () + extends MonoidBuilderInst() with Def[MonoidBuilderInst] { + lazy val resultType = element[MonoidBuilderInst] + override def transform(t: Transformer) = MonoidBuilderInstCtor() + } + + // state representation type + type MonoidBuilderInstData = Unit + + // elem for concrete class + class MonoidBuilderInstElem + extends MonoidBuilderElem[MonoidBuilderInst] + with ConcreteElem[MonoidBuilderInstData, MonoidBuilderInst] { + override lazy val parent: Option[Elem[_]] = Some(monoidBuilderElement) + } + + implicit lazy val monoidBuilderInstElement: Elem[MonoidBuilderInst] = + new MonoidBuilderInstElem + + // 4) constructor and deconstructor + class MonoidBuilderInstCompanionCtor extends CompanionDef[MonoidBuilderInstCompanionCtor] with MonoidBuilderInstCompanion { + def resultType = MonoidBuilderInstCompanionElem + override def toString = "MonoidBuilderInstCompanion" + @scalan.OverloadId("fromData") + def apply(p: Ref[MonoidBuilderInstData]): Ref[MonoidBuilderInst] = { + val unit = p + mkMonoidBuilderInst() + } + + @scalan.OverloadId("fromFields") + def apply(): Ref[MonoidBuilderInst] = + mkMonoidBuilderInst() + + def unapply(p: Ref[MonoidBuilder]) = unmkMonoidBuilderInst(p) + } + lazy val RMonoidBuilderInst: MutableLazy[MonoidBuilderInstCompanionCtor] = MutableLazy(new MonoidBuilderInstCompanionCtor) + implicit final def unrefMonoidBuilderInstCompanion(p: Ref[MonoidBuilderInstCompanionCtor]): MonoidBuilderInstCompanionCtor = { + if (p.node.isInstanceOf[MonoidBuilderInstCompanionCtor]) + p.node.asInstanceOf[MonoidBuilderInstCompanionCtor] + else + unrefDelegate[MonoidBuilderInstCompanionCtor](p) + } + + implicit case object MonoidBuilderInstCompanionElem extends CompanionElem[MonoidBuilderInstCompanionCtor] + + implicit final def unrefMonoidBuilderInst(p: Ref[MonoidBuilderInst]): MonoidBuilderInst = { + if (p.node.isInstanceOf[MonoidBuilderInst]) + p.node.asInstanceOf[MonoidBuilderInst] + else + unrefDelegate[MonoidBuilderInst](p) + } + + def mkMonoidBuilderInst + (): Ref[MonoidBuilderInst] = { + new MonoidBuilderInstCtor() + } + def unmkMonoidBuilderInst(p: Ref[MonoidBuilder]) = p.elem.asInstanceOf[Elem[_]] match { + case _: MonoidBuilderInstElem @unchecked => + Some(()) + case _ => + None + } +} // of object MonoidBuilderInst + registerEntityObject("MonoidBuilderInst", MonoidBuilderInst) + +object IntPlusMonoid extends EntityObject("IntPlusMonoid") { + case class IntPlusMonoidCtor + (override val zero: Ref[Int]) + extends IntPlusMonoid(zero) with Def[IntPlusMonoid] { + override lazy val eT: Elem[Int] = implicitly[Elem[Int]] + lazy val resultType = element[IntPlusMonoid] + override def transform(t: Transformer) = IntPlusMonoidCtor(t(zero)) + } + + // state representation type + type IntPlusMonoidData = Int + + // elem for concrete class + class IntPlusMonoidElem + extends MonoidElem[Int, IntPlusMonoid] + with ConcreteElem[IntPlusMonoidData, IntPlusMonoid] { + override lazy val parent: Option[Elem[_]] = Some(monoidElement(IntElement)) + } + + implicit lazy val intPlusMonoidElement: Elem[IntPlusMonoid] = + new IntPlusMonoidElem + + // 4) constructor and deconstructor + class IntPlusMonoidCompanionCtor extends CompanionDef[IntPlusMonoidCompanionCtor] with IntPlusMonoidCompanion { + def resultType = IntPlusMonoidCompanionElem + override def toString = "IntPlusMonoidCompanion" + + @scalan.OverloadId("fromFields") + def apply(zero: Ref[Int]): Ref[IntPlusMonoid] = + mkIntPlusMonoid(zero) + + def unapply(p: Ref[Monoid[Int]]) = unmkIntPlusMonoid(p) + } + lazy val RIntPlusMonoid: MutableLazy[IntPlusMonoidCompanionCtor] = MutableLazy(new IntPlusMonoidCompanionCtor) + implicit final def unrefIntPlusMonoidCompanion(p: Ref[IntPlusMonoidCompanionCtor]): IntPlusMonoidCompanionCtor = { + if (p.node.isInstanceOf[IntPlusMonoidCompanionCtor]) + p.node.asInstanceOf[IntPlusMonoidCompanionCtor] + else + unrefDelegate[IntPlusMonoidCompanionCtor](p) + } + + implicit case object IntPlusMonoidCompanionElem extends CompanionElem[IntPlusMonoidCompanionCtor] + + implicit final def unrefIntPlusMonoid(p: Ref[IntPlusMonoid]): IntPlusMonoid = { + if (p.node.isInstanceOf[IntPlusMonoid]) + p.node.asInstanceOf[IntPlusMonoid] + else + unrefDelegate[IntPlusMonoid](p) + } + + def mkIntPlusMonoid + (zero: Ref[Int]): Ref[IntPlusMonoid] = { + new IntPlusMonoidCtor(zero) + } + def unmkIntPlusMonoid(p: Ref[Monoid[Int]]) = p.elem.asInstanceOf[Elem[_]] match { + case _: IntPlusMonoidElem @unchecked => + Some((asRep[IntPlusMonoid](p).zero)) + case _ => + None + } +} // of object IntPlusMonoid + registerEntityObject("IntPlusMonoid", IntPlusMonoid) + +object LongPlusMonoid extends EntityObject("LongPlusMonoid") { + case class LongPlusMonoidCtor + (override val zero: Ref[Long]) + extends LongPlusMonoid(zero) with Def[LongPlusMonoid] { + override lazy val eT: Elem[Long] = implicitly[Elem[Long]] + lazy val resultType = element[LongPlusMonoid] + override def transform(t: Transformer) = LongPlusMonoidCtor(t(zero)) + } + + // state representation type + type LongPlusMonoidData = Long + + // elem for concrete class + class LongPlusMonoidElem + extends MonoidElem[Long, LongPlusMonoid] + with ConcreteElem[LongPlusMonoidData, LongPlusMonoid] { + override lazy val parent: Option[Elem[_]] = Some(monoidElement(LongElement)) + } + + implicit lazy val longPlusMonoidElement: Elem[LongPlusMonoid] = + new LongPlusMonoidElem + + // 4) constructor and deconstructor + class LongPlusMonoidCompanionCtor extends CompanionDef[LongPlusMonoidCompanionCtor] with LongPlusMonoidCompanion { + def resultType = LongPlusMonoidCompanionElem + override def toString = "LongPlusMonoidCompanion" + + @scalan.OverloadId("fromFields") + def apply(zero: Ref[Long]): Ref[LongPlusMonoid] = + mkLongPlusMonoid(zero) + + def unapply(p: Ref[Monoid[Long]]) = unmkLongPlusMonoid(p) + } + lazy val RLongPlusMonoid: MutableLazy[LongPlusMonoidCompanionCtor] = MutableLazy(new LongPlusMonoidCompanionCtor) + implicit final def unrefLongPlusMonoidCompanion(p: Ref[LongPlusMonoidCompanionCtor]): LongPlusMonoidCompanionCtor = { + if (p.node.isInstanceOf[LongPlusMonoidCompanionCtor]) + p.node.asInstanceOf[LongPlusMonoidCompanionCtor] + else + unrefDelegate[LongPlusMonoidCompanionCtor](p) + } + + implicit case object LongPlusMonoidCompanionElem extends CompanionElem[LongPlusMonoidCompanionCtor] + + implicit final def unrefLongPlusMonoid(p: Ref[LongPlusMonoid]): LongPlusMonoid = { + if (p.node.isInstanceOf[LongPlusMonoid]) + p.node.asInstanceOf[LongPlusMonoid] + else + unrefDelegate[LongPlusMonoid](p) + } + + def mkLongPlusMonoid + (zero: Ref[Long]): Ref[LongPlusMonoid] = { + new LongPlusMonoidCtor(zero) + } + def unmkLongPlusMonoid(p: Ref[Monoid[Long]]) = p.elem.asInstanceOf[Elem[_]] match { + case _: LongPlusMonoidElem @unchecked => + Some((asRep[LongPlusMonoid](p).zero)) + case _ => + None + } +} // of object LongPlusMonoid + registerEntityObject("LongPlusMonoid", LongPlusMonoid) + + override def resetContext(): Unit = { + super.resetContext() + + RMonoidBuilderInst.reset() + RIntPlusMonoid.reset() + RLongPlusMonoid.reset() + } + + registerModule(MonoidInstancesModule) +} + +object MonoidInstancesModule extends scalan.ModuleInfo("special.collection", "MonoidInstances") +} + +trait MonoidInstancesModule extends special.collection.impl.MonoidInstancesDefs {self: Library =>} diff --git a/library/src/main/scala/special/collection/impl/MonoidsImpl.scala b/library/src/main/scala/special/collection/impl/MonoidsImpl.scala new file mode 100644 index 0000000000..011647e54a --- /dev/null +++ b/library/src/main/scala/special/collection/impl/MonoidsImpl.scala @@ -0,0 +1,261 @@ +package special.collection + +import scalan._ +import scala.reflect.runtime.universe._ +import scala.reflect._ +import scala.collection.mutable.WrappedArray + +package impl { +// Abs ----------------------------------- +trait MonoidsDefs extends scalan.Scalan with Monoids { + self: Library => +import Monoid._ +import MonoidBuilder._ + +object Monoid extends EntityObject("Monoid") { + private val MonoidClass = classOf[Monoid[_]] + + // entityAdapter for Monoid trait + case class MonoidAdapter[T](source: Ref[Monoid[T]]) + extends Node with Monoid[T] + with Def[Monoid[T]] { + implicit lazy val eT = source.elem.typeArgs("T")._1.asInstanceOf[Elem[T]] + + val resultType: Elem[Monoid[T]] = element[Monoid[T]] + override def transform(t: Transformer) = MonoidAdapter[T](t(source)) + + def zero: Ref[T] = { + asRep[T](mkMethodCall(source, + MonoidClass.getMethod("zero"), + WrappedArray.empty, + true, true, element[T])) + } + + def plus(x: Ref[T], y: Ref[T]): Ref[T] = { + asRep[T](mkMethodCall(source, + MonoidClass.getMethod("plus", classOf[Sym], classOf[Sym]), + Array[AnyRef](x, y), + true, true, element[T])) + } + + def power(x: Ref[T], n: Ref[Int]): Ref[T] = { + asRep[T](mkMethodCall(source, + MonoidClass.getMethod("power", classOf[Sym], classOf[Sym]), + Array[AnyRef](x, n), + true, true, element[T])) + } + } + + // entityUnref: single unref method for each type family + implicit final def unrefMonoid[T](p: Ref[Monoid[T]]): Monoid[T] = { + if (p.node.isInstanceOf[Monoid[T]@unchecked]) p.node.asInstanceOf[Monoid[T]] + else + MonoidAdapter(p) + } + + // familyElem + class MonoidElem[T, To <: Monoid[T]](implicit _eT: Elem[T]) + extends EntityElem[To] { + def eT = _eT + + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("T" -> (eT -> scalan.util.Invariant)) + } + + implicit final def monoidElement[T](implicit eT: Elem[T]): Elem[Monoid[T]] = + cachedElemByClass(eT)(classOf[MonoidElem[T, Monoid[T]]]) + + implicit case object MonoidCompanionElem extends CompanionElem[MonoidCompanionCtor] + + abstract class MonoidCompanionCtor extends CompanionDef[MonoidCompanionCtor] with MonoidCompanion { + def resultType = MonoidCompanionElem + override def toString = "Monoid" + } + implicit final def unrefMonoidCompanionCtor(p: Ref[MonoidCompanionCtor]): MonoidCompanionCtor = + p.node.asInstanceOf[MonoidCompanionCtor] + + lazy val RMonoid: MutableLazy[MonoidCompanionCtor] = MutableLazy(new MonoidCompanionCtor { + private val thisClass = classOf[MonoidCompanion] + }) +} // of object Monoid + registerEntityObject("Monoid", Monoid) + +object MonoidBuilder extends EntityObject("MonoidBuilder") { + private val MonoidBuilderClass = classOf[MonoidBuilder] + + // entityAdapter for MonoidBuilder trait + case class MonoidBuilderAdapter(source: Ref[MonoidBuilder]) + extends Node with MonoidBuilder + with Def[MonoidBuilder] { + val resultType: Elem[MonoidBuilder] = element[MonoidBuilder] + override def transform(t: Transformer) = MonoidBuilderAdapter(t(source)) + + def intPlusMonoid: Ref[Monoid[Int]] = { + asRep[Monoid[Int]](mkMethodCall(source, + MonoidBuilderClass.getMethod("intPlusMonoid"), + WrappedArray.empty, + true, true, element[Monoid[Int]])) + } + + def intMaxMonoid: Ref[Monoid[Int]] = { + asRep[Monoid[Int]](mkMethodCall(source, + MonoidBuilderClass.getMethod("intMaxMonoid"), + WrappedArray.empty, + true, true, element[Monoid[Int]])) + } + + def intMinMonoid: Ref[Monoid[Int]] = { + asRep[Monoid[Int]](mkMethodCall(source, + MonoidBuilderClass.getMethod("intMinMonoid"), + WrappedArray.empty, + true, true, element[Monoid[Int]])) + } + + def longPlusMonoid: Ref[Monoid[Long]] = { + asRep[Monoid[Long]](mkMethodCall(source, + MonoidBuilderClass.getMethod("longPlusMonoid"), + WrappedArray.empty, + true, true, element[Monoid[Long]])) + } + + def longMaxMonoid: Ref[Monoid[Long]] = { + asRep[Monoid[Long]](mkMethodCall(source, + MonoidBuilderClass.getMethod("longMaxMonoid"), + WrappedArray.empty, + true, true, element[Monoid[Long]])) + } + + def longMinMonoid: Ref[Monoid[Long]] = { + asRep[Monoid[Long]](mkMethodCall(source, + MonoidBuilderClass.getMethod("longMinMonoid"), + WrappedArray.empty, + true, true, element[Monoid[Long]])) + } + + def pairMonoid[A, B](m1: Ref[Monoid[A]], m2: Ref[Monoid[B]]): Ref[Monoid[(A, B)]] = { + implicit val eA = m1.eT +implicit val eB = m2.eT + asRep[Monoid[(A, B)]](mkMethodCall(source, + MonoidBuilderClass.getMethod("pairMonoid", classOf[Sym], classOf[Sym]), + Array[AnyRef](m1, m2), + true, true, element[Monoid[(A, B)]])) + } + } + + // entityUnref: single unref method for each type family + implicit final def unrefMonoidBuilder(p: Ref[MonoidBuilder]): MonoidBuilder = { + if (p.node.isInstanceOf[MonoidBuilder]) p.node.asInstanceOf[MonoidBuilder] + else + MonoidBuilderAdapter(p) + } + + // familyElem + class MonoidBuilderElem[To <: MonoidBuilder] + extends EntityElem[To] { + } + + implicit lazy val monoidBuilderElement: Elem[MonoidBuilder] = + new MonoidBuilderElem[MonoidBuilder] + + implicit case object MonoidBuilderCompanionElem extends CompanionElem[MonoidBuilderCompanionCtor] + + abstract class MonoidBuilderCompanionCtor extends CompanionDef[MonoidBuilderCompanionCtor] with MonoidBuilderCompanion { + def resultType = MonoidBuilderCompanionElem + override def toString = "MonoidBuilder" + } + implicit final def unrefMonoidBuilderCompanionCtor(p: Ref[MonoidBuilderCompanionCtor]): MonoidBuilderCompanionCtor = + p.node.asInstanceOf[MonoidBuilderCompanionCtor] + + lazy val RMonoidBuilder: MutableLazy[MonoidBuilderCompanionCtor] = MutableLazy(new MonoidBuilderCompanionCtor { + private val thisClass = classOf[MonoidBuilderCompanion] + }) + + object MonoidBuilderMethods { + object intPlusMonoid { + def unapply(d: Def[_]): Nullable[Ref[MonoidBuilder]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "intPlusMonoid" && receiver.elem.isInstanceOf[MonoidBuilderElem[_]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[MonoidBuilder]]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[MonoidBuilder]] = unapply(exp.node) + } + + object intMaxMonoid { + def unapply(d: Def[_]): Nullable[Ref[MonoidBuilder]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "intMaxMonoid" && receiver.elem.isInstanceOf[MonoidBuilderElem[_]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[MonoidBuilder]]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[MonoidBuilder]] = unapply(exp.node) + } + + object intMinMonoid { + def unapply(d: Def[_]): Nullable[Ref[MonoidBuilder]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "intMinMonoid" && receiver.elem.isInstanceOf[MonoidBuilderElem[_]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[MonoidBuilder]]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[MonoidBuilder]] = unapply(exp.node) + } + + object longPlusMonoid { + def unapply(d: Def[_]): Nullable[Ref[MonoidBuilder]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "longPlusMonoid" && receiver.elem.isInstanceOf[MonoidBuilderElem[_]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[MonoidBuilder]]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[MonoidBuilder]] = unapply(exp.node) + } + + object longMaxMonoid { + def unapply(d: Def[_]): Nullable[Ref[MonoidBuilder]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "longMaxMonoid" && receiver.elem.isInstanceOf[MonoidBuilderElem[_]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[MonoidBuilder]]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[MonoidBuilder]] = unapply(exp.node) + } + + object longMinMonoid { + def unapply(d: Def[_]): Nullable[Ref[MonoidBuilder]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "longMinMonoid" && receiver.elem.isInstanceOf[MonoidBuilderElem[_]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[MonoidBuilder]]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[MonoidBuilder]] = unapply(exp.node) + } + + object pairMonoid { + def unapply(d: Def[_]): Nullable[(Ref[MonoidBuilder], Ref[Monoid[A]], Ref[Monoid[B]]) forSome {type A; type B}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "pairMonoid" && receiver.elem.isInstanceOf[MonoidBuilderElem[_]] => + val res = (receiver, args(0), args(1)) + Nullable(res).asInstanceOf[Nullable[(Ref[MonoidBuilder], Ref[Monoid[A]], Ref[Monoid[B]]) forSome {type A; type B}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[MonoidBuilder], Ref[Monoid[A]], Ref[Monoid[B]]) forSome {type A; type B}] = unapply(exp.node) + } + } + + object MonoidBuilderCompanionMethods { + } +} // of object MonoidBuilder + registerEntityObject("MonoidBuilder", MonoidBuilder) + + override def resetContext(): Unit = { + super.resetContext() + RMonoid.reset() + RMonoidBuilder.reset() + } + + registerModule(MonoidsModule) +} + +object MonoidsModule extends scalan.ModuleInfo("special.collection", "Monoids") +} + +trait MonoidsModule extends special.collection.impl.MonoidsDefs {self: Library =>} diff --git a/library/src/main/scala/special/collection/impl/SizesImpl.scala b/library/src/main/scala/special/collection/impl/SizesImpl.scala new file mode 100644 index 0000000000..b43eaa83a4 --- /dev/null +++ b/library/src/main/scala/special/collection/impl/SizesImpl.scala @@ -0,0 +1,839 @@ +package special.collection + +import scalan._ +import scala.reflect.runtime.universe._ +import scala.reflect._ +import scala.collection.mutable.WrappedArray + +package impl { +// Abs ----------------------------------- +trait SizesDefs extends scalan.Scalan with Sizes { + self: Library => +import Coll._ +import Size._ +import WOption._ +import WRType._ +import SizeColl._ +import SizeFunc._ +import SizeOption._ +import SizePair._ +import SizePrim._ + +object Size extends EntityObject("Size") { + // entityConst: single const for each entity + import Liftables._ + import scala.reflect.{ClassTag, classTag} + type SSize[Val] = special.collection.Size[Val] + case class SizeConst[SVal, Val]( + constValue: SSize[SVal], + lVal: Liftable[SVal, Val] + ) extends LiftedConst[SSize[SVal], Size[Val]] with Size[Val] + with Def[Size[Val]] with SizeConstMethods[Val] { + implicit final def eVal: Elem[Val] = lVal.eW + + val liftable: Liftable[SSize[SVal], Size[Val]] = liftableSize(lVal) + val resultType: Elem[Size[Val]] = liftable.eW + } + + trait SizeConstMethods[Val] extends Size[Val] { thisConst: Def[_] => + implicit def eVal: Elem[Val] + private val SizeClass = classOf[Size[Val]] + + override def dataSize: Ref[Long] = { + asRep[Long](mkMethodCall(self, + SizeClass.getMethod("dataSize"), + WrappedArray.empty, + true, false, element[Long])) + } + } + + case class LiftableSize[SVal, Val](lVal: Liftable[SVal, Val]) + extends Liftable[SSize[SVal], Size[Val]] { + lazy val eW: Elem[Size[Val]] = sizeElement(lVal.eW) + lazy val sourceType: RType[SSize[SVal]] = { + implicit val tagSVal = lVal.sourceType.asInstanceOf[RType[SVal]] + RType[SSize[SVal]] + } + def lift(x: SSize[SVal]): Ref[Size[Val]] = SizeConst(x, lVal) + def unlift(w: Ref[Size[Val]]): SSize[SVal] = w match { + case Def(SizeConst(x: SSize[_], _lVal)) + if _lVal == lVal => x.asInstanceOf[SSize[SVal]] + case _ => unliftError(w) + } + } + implicit final def liftableSize[SVal, Val](implicit lVal: Liftable[SVal,Val]): Liftable[SSize[SVal], Size[Val]] = + LiftableSize(lVal) + + private val SizeClass = classOf[Size[_]] + + // entityAdapter for Size trait + case class SizeAdapter[Val](source: Ref[Size[Val]]) + extends Node with Size[Val] + with Def[Size[Val]] { + implicit lazy val eVal = source.elem.typeArgs("Val")._1.asInstanceOf[Elem[Val]] + + val resultType: Elem[Size[Val]] = element[Size[Val]] + override def transform(t: Transformer) = SizeAdapter[Val](t(source)) + + def dataSize: Ref[Long] = { + asRep[Long](mkMethodCall(source, + SizeClass.getMethod("dataSize"), + WrappedArray.empty, + true, true, element[Long])) + } + } + + // entityUnref: single unref method for each type family + implicit final def unrefSize[Val](p: Ref[Size[Val]]): Size[Val] = { + if (p.node.isInstanceOf[Size[Val]@unchecked]) p.node.asInstanceOf[Size[Val]] + else + SizeAdapter(p) + } + + // familyElem + class SizeElem[Val, To <: Size[Val]](implicit _eVal: Elem[Val]) + extends EntityElem[To] { + def eVal = _eVal + + override val liftable: Liftables.Liftable[_, To] = asLiftable[SSize[_], To](liftableSize(_eVal.liftable)) + + override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { + super.collectMethods ++ + Elem.declaredMethods(classOf[Size[Val]], classOf[SSize[_]], Set( + "dataSize" + )) + } + + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("Val" -> (eVal -> scalan.util.Invariant)) + } + + implicit final def sizeElement[Val](implicit eVal: Elem[Val]): Elem[Size[Val]] = + cachedElemByClass(eVal)(classOf[SizeElem[Val, Size[Val]]]) + + implicit case object SizeCompanionElem extends CompanionElem[SizeCompanionCtor] + + abstract class SizeCompanionCtor extends CompanionDef[SizeCompanionCtor] with SizeCompanion { + def resultType = SizeCompanionElem + override def toString = "Size" + } + implicit final def unrefSizeCompanionCtor(p: Ref[SizeCompanionCtor]): SizeCompanionCtor = + p.node.asInstanceOf[SizeCompanionCtor] + + lazy val RSize: MutableLazy[SizeCompanionCtor] = MutableLazy(new SizeCompanionCtor { + private val thisClass = classOf[SizeCompanion] + }) + + object SizeMethods { + object dataSize { + def unapply(d: Def[_]): Nullable[Ref[Size[Val]] forSome {type Val}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "dataSize" && receiver.elem.isInstanceOf[SizeElem[_, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[Size[Val]] forSome {type Val}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[Size[Val]] forSome {type Val}] = unapply(exp.node) + } + } + + object SizeCompanionMethods { + } +} // of object Size + registerEntityObject("Size", Size) + +object SizePrim extends EntityObject("SizePrim") { + // entityConst: single const for each entity + import Liftables._ + import scala.reflect.{ClassTag, classTag} + type SSizePrim[Val] = special.collection.SizePrim[Val] + case class SizePrimConst[SVal, Val]( + constValue: SSizePrim[SVal], + lVal: Liftable[SVal, Val] + ) extends LiftedConst[SSizePrim[SVal], SizePrim[Val]] with SizePrim[Val] + with Def[SizePrim[Val]] with SizePrimConstMethods[Val] { + implicit final def eVal: Elem[Val] = lVal.eW + + val liftable: Liftable[SSizePrim[SVal], SizePrim[Val]] = liftableSizePrim(lVal) + val resultType: Elem[SizePrim[Val]] = liftable.eW + } + + trait SizePrimConstMethods[Val] extends SizePrim[Val] with SizeConstMethods[Val] { thisConst: Def[_] => + implicit def eVal: Elem[Val] + private val SizePrimClass = classOf[SizePrim[Val]] + + override def dataSize: Ref[Long] = { + asRep[Long](mkMethodCall(self, + SizePrimClass.getMethod("dataSize"), + WrappedArray.empty, + true, false, element[Long])) + } + + override def tVal: Ref[WRType[Val]] = { + asRep[WRType[Val]](mkMethodCall(self, + SizePrimClass.getMethod("tVal"), + WrappedArray.empty, + true, false, element[WRType[Val]])) + } + } + + case class LiftableSizePrim[SVal, Val](lVal: Liftable[SVal, Val]) + extends Liftable[SSizePrim[SVal], SizePrim[Val]] { + lazy val eW: Elem[SizePrim[Val]] = sizePrimElement(lVal.eW) + lazy val sourceType: RType[SSizePrim[SVal]] = { + implicit val tagSVal = lVal.sourceType.asInstanceOf[RType[SVal]] + RType[SSizePrim[SVal]] + } + def lift(x: SSizePrim[SVal]): Ref[SizePrim[Val]] = SizePrimConst(x, lVal) + def unlift(w: Ref[SizePrim[Val]]): SSizePrim[SVal] = w match { + case Def(SizePrimConst(x: SSizePrim[_], _lVal)) + if _lVal == lVal => x.asInstanceOf[SSizePrim[SVal]] + case _ => unliftError(w) + } + } + implicit final def liftableSizePrim[SVal, Val](implicit lVal: Liftable[SVal,Val]): Liftable[SSizePrim[SVal], SizePrim[Val]] = + LiftableSizePrim(lVal) + + private val SizePrimClass = classOf[SizePrim[_]] + + // entityAdapter for SizePrim trait + case class SizePrimAdapter[Val](source: Ref[SizePrim[Val]]) + extends Node with SizePrim[Val] + with Def[SizePrim[Val]] { + implicit lazy val eVal = source.elem.typeArgs("Val")._1.asInstanceOf[Elem[Val]] + + val resultType: Elem[SizePrim[Val]] = element[SizePrim[Val]] + override def transform(t: Transformer) = SizePrimAdapter[Val](t(source)) + + def dataSize: Ref[Long] = { + asRep[Long](mkMethodCall(source, + SizePrimClass.getMethod("dataSize"), + WrappedArray.empty, + true, true, element[Long])) + } + + def tVal: Ref[WRType[Val]] = { + asRep[WRType[Val]](mkMethodCall(source, + SizePrimClass.getMethod("tVal"), + WrappedArray.empty, + true, true, element[WRType[Val]])) + } + } + + // entityUnref: single unref method for each type family + implicit final def unrefSizePrim[Val](p: Ref[SizePrim[Val]]): SizePrim[Val] = { + if (p.node.isInstanceOf[SizePrim[Val]@unchecked]) p.node.asInstanceOf[SizePrim[Val]] + else + SizePrimAdapter(p) + } + + // familyElem + class SizePrimElem[Val, To <: SizePrim[Val]](implicit _eVal: Elem[Val]) + extends SizeElem[Val, To] { + override def eVal = _eVal + + override val liftable: Liftables.Liftable[_, To] = asLiftable[SSizePrim[_], To](liftableSizePrim(_eVal.liftable)) + + override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { + super.collectMethods ++ + Elem.declaredMethods(classOf[SizePrim[Val]], classOf[SSizePrim[_]], Set( + "dataSize", "tVal" + )) + } + + override lazy val parent: Option[Elem[_]] = Some(sizeElement(element[Val])) + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("Val" -> (eVal -> scalan.util.Invariant)) + } + + implicit final def sizePrimElement[Val](implicit eVal: Elem[Val]): Elem[SizePrim[Val]] = + cachedElemByClass(eVal)(classOf[SizePrimElem[Val, SizePrim[Val]]]) + + implicit case object SizePrimCompanionElem extends CompanionElem[SizePrimCompanionCtor] + + abstract class SizePrimCompanionCtor extends CompanionDef[SizePrimCompanionCtor] with SizePrimCompanion { + def resultType = SizePrimCompanionElem + override def toString = "SizePrim" + } + implicit final def unrefSizePrimCompanionCtor(p: Ref[SizePrimCompanionCtor]): SizePrimCompanionCtor = + p.node.asInstanceOf[SizePrimCompanionCtor] + + lazy val RSizePrim: MutableLazy[SizePrimCompanionCtor] = MutableLazy(new SizePrimCompanionCtor { + private val thisClass = classOf[SizePrimCompanion] + }) +} // of object SizePrim + registerEntityObject("SizePrim", SizePrim) + +object SizePair extends EntityObject("SizePair") { + // entityConst: single const for each entity + import Liftables._ + import scala.reflect.{ClassTag, classTag} + type SSizePair[L, R] = special.collection.SizePair[L, R] + case class SizePairConst[SL, SR, L, R]( + constValue: SSizePair[SL, SR], + lL: Liftable[SL, L], lR: Liftable[SR, R] + ) extends LiftedConst[SSizePair[SL, SR], SizePair[L, R]] with SizePair[L, R] + with Def[SizePair[L, R]] with SizePairConstMethods[L, R] { + implicit final def eL: Elem[L] = lL.eW + implicit final def eR: Elem[R] = lR.eW + implicit final def eVal: Elem[(L, R)] = element[(L, R)] + + val liftable: Liftable[SSizePair[SL, SR], SizePair[L, R]] = liftableSizePair(lL,lR) + val resultType: Elem[SizePair[L, R]] = liftable.eW + } + + trait SizePairConstMethods[L, R] extends SizePair[L, R] with SizeConstMethods[(L, R)] { thisConst: Def[_] => + implicit def eL: Elem[L] + implicit def eR: Elem[R] + private val SizePairClass = classOf[SizePair[L, R]] + + override def l: Ref[Size[L]] = { + asRep[Size[L]](mkMethodCall(self, + SizePairClass.getMethod("l"), + WrappedArray.empty, + true, false, element[Size[L]])) + } + + override def r: Ref[Size[R]] = { + asRep[Size[R]](mkMethodCall(self, + SizePairClass.getMethod("r"), + WrappedArray.empty, + true, false, element[Size[R]])) + } + } + + case class LiftableSizePair[SL, SR, L, R](lL: Liftable[SL, L],lR: Liftable[SR, R]) + extends Liftable[SSizePair[SL, SR], SizePair[L, R]] { + lazy val eW: Elem[SizePair[L, R]] = sizePairElement(lL.eW,lR.eW) + lazy val sourceType: RType[SSizePair[SL, SR]] = { + implicit val tagSL = lL.sourceType.asInstanceOf[RType[SL]] + implicit val tagSR = lR.sourceType.asInstanceOf[RType[SR]] + RType[SSizePair[SL, SR]] + } + def lift(x: SSizePair[SL, SR]): Ref[SizePair[L, R]] = SizePairConst(x, lL,lR) + def unlift(w: Ref[SizePair[L, R]]): SSizePair[SL, SR] = w match { + case Def(SizePairConst(x: SSizePair[_,_], _lL,_lR)) + if _lL == lL && _lR == lR => x.asInstanceOf[SSizePair[SL, SR]] + case _ => unliftError(w) + } + } + implicit final def liftableSizePair[SL, SR, L, R](implicit lL: Liftable[SL,L],lR: Liftable[SR,R]): Liftable[SSizePair[SL, SR], SizePair[L, R]] = + LiftableSizePair(lL,lR) + + private val SizePairClass = classOf[SizePair[_, _]] + + // entityAdapter for SizePair trait + case class SizePairAdapter[L, R](source: Ref[SizePair[L, R]]) + extends Node with SizePair[L, R] + with Def[SizePair[L, R]] { + implicit lazy val eL = source.elem.typeArgs("L")._1.asInstanceOf[Elem[L]]; +implicit lazy val eR = source.elem.typeArgs("R")._1.asInstanceOf[Elem[R]] + override lazy val eVal: Elem[(L, R)] = implicitly[Elem[(L, R)]] + val resultType: Elem[SizePair[L, R]] = element[SizePair[L, R]] + override def transform(t: Transformer) = SizePairAdapter[L, R](t(source)) + + def l: Ref[Size[L]] = { + asRep[Size[L]](mkMethodCall(source, + SizePairClass.getMethod("l"), + WrappedArray.empty, + true, true, element[Size[L]])) + } + + def r: Ref[Size[R]] = { + asRep[Size[R]](mkMethodCall(source, + SizePairClass.getMethod("r"), + WrappedArray.empty, + true, true, element[Size[R]])) + } + + def dataSize: Ref[Long] = { + asRep[Long](mkMethodCall(source, + SizePairClass.getMethod("dataSize"), + WrappedArray.empty, + true, true, element[Long])) + } + } + + // entityUnref: single unref method for each type family + implicit final def unrefSizePair[L, R](p: Ref[SizePair[L, R]]): SizePair[L, R] = { + if (p.node.isInstanceOf[SizePair[L, R]@unchecked]) p.node.asInstanceOf[SizePair[L, R]] + else + SizePairAdapter(p) + } + + // familyElem + class SizePairElem[L, R, To <: SizePair[L, R]](implicit _eL: Elem[L], _eR: Elem[R]) + extends SizeElem[(L, R), To] { + def eL = _eL + def eR = _eR + + override val liftable: Liftables.Liftable[_, To] = asLiftable[SSizePair[_,_], To](liftableSizePair(_eL.liftable, _eR.liftable)) + + override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { + super.collectMethods ++ + Elem.declaredMethods(classOf[SizePair[L, R]], classOf[SSizePair[_,_]], Set( + "l", "r" + )) + } + + override lazy val parent: Option[Elem[_]] = Some(sizeElement(pairElement(element[L],element[R]))) + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("L" -> (eL -> scalan.util.Invariant), "R" -> (eR -> scalan.util.Invariant)) + } + + implicit final def sizePairElement[L, R](implicit eL: Elem[L], eR: Elem[R]): Elem[SizePair[L, R]] = + cachedElemByClass(eL, eR)(classOf[SizePairElem[L, R, SizePair[L, R]]]) + + implicit case object SizePairCompanionElem extends CompanionElem[SizePairCompanionCtor] + + abstract class SizePairCompanionCtor extends CompanionDef[SizePairCompanionCtor] with SizePairCompanion { + def resultType = SizePairCompanionElem + override def toString = "SizePair" + } + implicit final def unrefSizePairCompanionCtor(p: Ref[SizePairCompanionCtor]): SizePairCompanionCtor = + p.node.asInstanceOf[SizePairCompanionCtor] + + lazy val RSizePair: MutableLazy[SizePairCompanionCtor] = MutableLazy(new SizePairCompanionCtor { + private val thisClass = classOf[SizePairCompanion] + }) + + object SizePairMethods { + object l { + def unapply(d: Def[_]): Nullable[Ref[SizePair[L, R]] forSome {type L; type R}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "l" && receiver.elem.isInstanceOf[SizePairElem[_, _, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[SizePair[L, R]] forSome {type L; type R}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[SizePair[L, R]] forSome {type L; type R}] = unapply(exp.node) + } + + object r { + def unapply(d: Def[_]): Nullable[Ref[SizePair[L, R]] forSome {type L; type R}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "r" && receiver.elem.isInstanceOf[SizePairElem[_, _, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[SizePair[L, R]] forSome {type L; type R}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[SizePair[L, R]] forSome {type L; type R}] = unapply(exp.node) + } + } + + object SizePairCompanionMethods { + } +} // of object SizePair + registerEntityObject("SizePair", SizePair) + +object SizeColl extends EntityObject("SizeColl") { + // entityConst: single const for each entity + import Liftables._ + import scala.reflect.{ClassTag, classTag} + type SSizeColl[Item] = special.collection.SizeColl[Item] + case class SizeCollConst[SItem, Item]( + constValue: SSizeColl[SItem], + lItem: Liftable[SItem, Item] + ) extends LiftedConst[SSizeColl[SItem], SizeColl[Item]] with SizeColl[Item] + with Def[SizeColl[Item]] with SizeCollConstMethods[Item] { + implicit final def eItem: Elem[Item] = lItem.eW + implicit final def eVal: Elem[Coll[Item]] = element[Coll[Item]] + + val liftable: Liftable[SSizeColl[SItem], SizeColl[Item]] = liftableSizeColl(lItem) + val resultType: Elem[SizeColl[Item]] = liftable.eW + } + + trait SizeCollConstMethods[Item] extends SizeColl[Item] with SizeConstMethods[Coll[Item]] { thisConst: Def[_] => + implicit def eItem: Elem[Item] + private val SizeCollClass = classOf[SizeColl[Item]] + + override def sizes: Ref[Coll[Size[Item]]] = { + asRep[Coll[Size[Item]]](mkMethodCall(self, + SizeCollClass.getMethod("sizes"), + WrappedArray.empty, + true, false, element[Coll[Size[Item]]])) + } + } + + case class LiftableSizeColl[SItem, Item](lItem: Liftable[SItem, Item]) + extends Liftable[SSizeColl[SItem], SizeColl[Item]] { + lazy val eW: Elem[SizeColl[Item]] = sizeCollElement(lItem.eW) + lazy val sourceType: RType[SSizeColl[SItem]] = { + implicit val tagSItem = lItem.sourceType.asInstanceOf[RType[SItem]] + RType[SSizeColl[SItem]] + } + def lift(x: SSizeColl[SItem]): Ref[SizeColl[Item]] = SizeCollConst(x, lItem) + def unlift(w: Ref[SizeColl[Item]]): SSizeColl[SItem] = w match { + case Def(SizeCollConst(x: SSizeColl[_], _lItem)) + if _lItem == lItem => x.asInstanceOf[SSizeColl[SItem]] + case _ => unliftError(w) + } + } + implicit final def liftableSizeColl[SItem, Item](implicit lItem: Liftable[SItem,Item]): Liftable[SSizeColl[SItem], SizeColl[Item]] = + LiftableSizeColl(lItem) + + private val SizeCollClass = classOf[SizeColl[_]] + + // entityAdapter for SizeColl trait + case class SizeCollAdapter[Item](source: Ref[SizeColl[Item]]) + extends Node with SizeColl[Item] + with Def[SizeColl[Item]] { + implicit lazy val eItem = source.elem.typeArgs("Item")._1.asInstanceOf[Elem[Item]] + override lazy val eVal: Elem[Coll[Item]] = implicitly[Elem[Coll[Item]]] + val resultType: Elem[SizeColl[Item]] = element[SizeColl[Item]] + override def transform(t: Transformer) = SizeCollAdapter[Item](t(source)) + + def sizes: Ref[Coll[Size[Item]]] = { + asRep[Coll[Size[Item]]](mkMethodCall(source, + SizeCollClass.getMethod("sizes"), + WrappedArray.empty, + true, true, element[Coll[Size[Item]]])) + } + + def dataSize: Ref[Long] = { + asRep[Long](mkMethodCall(source, + SizeCollClass.getMethod("dataSize"), + WrappedArray.empty, + true, true, element[Long])) + } + } + + // entityUnref: single unref method for each type family + implicit final def unrefSizeColl[Item](p: Ref[SizeColl[Item]]): SizeColl[Item] = { + if (p.node.isInstanceOf[SizeColl[Item]@unchecked]) p.node.asInstanceOf[SizeColl[Item]] + else + SizeCollAdapter(p) + } + + // familyElem + class SizeCollElem[Item, To <: SizeColl[Item]](implicit _eItem: Elem[Item]) + extends SizeElem[Coll[Item], To] { + def eItem = _eItem + + override val liftable: Liftables.Liftable[_, To] = asLiftable[SSizeColl[_], To](liftableSizeColl(_eItem.liftable)) + + override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { + super.collectMethods ++ + Elem.declaredMethods(classOf[SizeColl[Item]], classOf[SSizeColl[_]], Set( + "sizes" + )) + } + + override lazy val parent: Option[Elem[_]] = Some(sizeElement(collElement(element[Item]))) + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("Item" -> (eItem -> scalan.util.Invariant)) + } + + implicit final def sizeCollElement[Item](implicit eItem: Elem[Item]): Elem[SizeColl[Item]] = + cachedElemByClass(eItem)(classOf[SizeCollElem[Item, SizeColl[Item]]]) + + implicit case object SizeCollCompanionElem extends CompanionElem[SizeCollCompanionCtor] + + abstract class SizeCollCompanionCtor extends CompanionDef[SizeCollCompanionCtor] with SizeCollCompanion { + def resultType = SizeCollCompanionElem + override def toString = "SizeColl" + } + implicit final def unrefSizeCollCompanionCtor(p: Ref[SizeCollCompanionCtor]): SizeCollCompanionCtor = + p.node.asInstanceOf[SizeCollCompanionCtor] + + lazy val RSizeColl: MutableLazy[SizeCollCompanionCtor] = MutableLazy(new SizeCollCompanionCtor { + private val thisClass = classOf[SizeCollCompanion] + }) + + object SizeCollMethods { + object sizes { + def unapply(d: Def[_]): Nullable[Ref[SizeColl[Item]] forSome {type Item}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "sizes" && receiver.elem.isInstanceOf[SizeCollElem[_, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[SizeColl[Item]] forSome {type Item}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[SizeColl[Item]] forSome {type Item}] = unapply(exp.node) + } + } + + object SizeCollCompanionMethods { + } +} // of object SizeColl + registerEntityObject("SizeColl", SizeColl) + +object SizeFunc extends EntityObject("SizeFunc") { + // entityConst: single const for each entity + import Liftables._ + import scala.reflect.{ClassTag, classTag} + type SSizeFunc[Env, Arg, Res] = special.collection.SizeFunc[Env, Arg, Res] + case class SizeFuncConst[SEnv, SArg, SRes, Env, Arg, Res]( + constValue: SSizeFunc[SEnv, SArg, SRes], + lEnv: Liftable[SEnv, Env], lArg: Liftable[SArg, Arg], lRes: Liftable[SRes, Res] + ) extends LiftedConst[SSizeFunc[SEnv, SArg, SRes], SizeFunc[Env, Arg, Res]] with SizeFunc[Env, Arg, Res] + with Def[SizeFunc[Env, Arg, Res]] with SizeFuncConstMethods[Env, Arg, Res] { + implicit final def eEnv: Elem[Env] = lEnv.eW + implicit final def eArg: Elem[Arg] = lArg.eW + implicit final def eRes: Elem[Res] = lRes.eW + implicit final def eVal: Elem[Arg => Res] = element[Arg => Res] + + val liftable: Liftable[SSizeFunc[SEnv, SArg, SRes], SizeFunc[Env, Arg, Res]] = liftableSizeFunc(lEnv,lArg,lRes) + val resultType: Elem[SizeFunc[Env, Arg, Res]] = liftable.eW + } + + trait SizeFuncConstMethods[Env, Arg, Res] extends SizeFunc[Env, Arg, Res] with SizeConstMethods[Arg => Res] { thisConst: Def[_] => + implicit def eEnv: Elem[Env] + implicit def eArg: Elem[Arg] + implicit def eRes: Elem[Res] + private val SizeFuncClass = classOf[SizeFunc[Env, Arg, Res]] + + override def sizeEnv: Ref[Size[Env]] = { + asRep[Size[Env]](mkMethodCall(self, + SizeFuncClass.getMethod("sizeEnv"), + WrappedArray.empty, + true, false, element[Size[Env]])) + } + } + + case class LiftableSizeFunc[SEnv, SArg, SRes, Env, Arg, Res](lEnv: Liftable[SEnv, Env],lArg: Liftable[SArg, Arg],lRes: Liftable[SRes, Res]) + extends Liftable[SSizeFunc[SEnv, SArg, SRes], SizeFunc[Env, Arg, Res]] { + lazy val eW: Elem[SizeFunc[Env, Arg, Res]] = sizeFuncElement(lEnv.eW,lArg.eW,lRes.eW) + lazy val sourceType: RType[SSizeFunc[SEnv, SArg, SRes]] = { + implicit val tagSEnv = lEnv.sourceType.asInstanceOf[RType[SEnv]] + implicit val tagSArg = lArg.sourceType.asInstanceOf[RType[SArg]] + implicit val tagSRes = lRes.sourceType.asInstanceOf[RType[SRes]] + RType[SSizeFunc[SEnv, SArg, SRes]] + } + def lift(x: SSizeFunc[SEnv, SArg, SRes]): Ref[SizeFunc[Env, Arg, Res]] = SizeFuncConst(x, lEnv,lArg,lRes) + def unlift(w: Ref[SizeFunc[Env, Arg, Res]]): SSizeFunc[SEnv, SArg, SRes] = w match { + case Def(SizeFuncConst(x: SSizeFunc[_,_,_], _lEnv,_lArg,_lRes)) + if _lEnv == lEnv && _lArg == lArg && _lRes == lRes => x.asInstanceOf[SSizeFunc[SEnv, SArg, SRes]] + case _ => unliftError(w) + } + } + implicit final def liftableSizeFunc[SEnv, SArg, SRes, Env, Arg, Res](implicit lEnv: Liftable[SEnv,Env],lArg: Liftable[SArg,Arg],lRes: Liftable[SRes,Res]): Liftable[SSizeFunc[SEnv, SArg, SRes], SizeFunc[Env, Arg, Res]] = + LiftableSizeFunc(lEnv,lArg,lRes) + + private val SizeFuncClass = classOf[SizeFunc[_, _, _]] + + // entityAdapter for SizeFunc trait + case class SizeFuncAdapter[Env, Arg, Res](source: Ref[SizeFunc[Env, Arg, Res]]) + extends Node with SizeFunc[Env, Arg, Res] + with Def[SizeFunc[Env, Arg, Res]] { + implicit lazy val eEnv = source.elem.typeArgs("Env")._1.asInstanceOf[Elem[Env]]; +implicit lazy val eArg = source.elem.typeArgs("Arg")._1.asInstanceOf[Elem[Arg]]; +implicit lazy val eRes = source.elem.typeArgs("Res")._1.asInstanceOf[Elem[Res]] + override lazy val eVal: Elem[Arg => Res] = implicitly[Elem[Arg => Res]] + val resultType: Elem[SizeFunc[Env, Arg, Res]] = element[SizeFunc[Env, Arg, Res]] + override def transform(t: Transformer) = SizeFuncAdapter[Env, Arg, Res](t(source)) + + def sizeEnv: Ref[Size[Env]] = { + asRep[Size[Env]](mkMethodCall(source, + SizeFuncClass.getMethod("sizeEnv"), + WrappedArray.empty, + true, true, element[Size[Env]])) + } + + def dataSize: Ref[Long] = { + asRep[Long](mkMethodCall(source, + SizeFuncClass.getMethod("dataSize"), + WrappedArray.empty, + true, true, element[Long])) + } + } + + // entityUnref: single unref method for each type family + implicit final def unrefSizeFunc[Env, Arg, Res](p: Ref[SizeFunc[Env, Arg, Res]]): SizeFunc[Env, Arg, Res] = { + if (p.node.isInstanceOf[SizeFunc[Env, Arg, Res]@unchecked]) p.node.asInstanceOf[SizeFunc[Env, Arg, Res]] + else + SizeFuncAdapter(p) + } + + // familyElem + class SizeFuncElem[Env, Arg, Res, To <: SizeFunc[Env, Arg, Res]](implicit _eEnv: Elem[Env], _eArg: Elem[Arg], _eRes: Elem[Res]) + extends SizeElem[Arg => Res, To] { + def eEnv = _eEnv + def eArg = _eArg + def eRes = _eRes + + override val liftable: Liftables.Liftable[_, To] = asLiftable[SSizeFunc[_,_,_], To](liftableSizeFunc(_eEnv.liftable, _eArg.liftable, _eRes.liftable)) + + override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { + super.collectMethods ++ + Elem.declaredMethods(classOf[SizeFunc[Env, Arg, Res]], classOf[SSizeFunc[_,_,_]], Set( + "sizeEnv" + )) + } + + override lazy val parent: Option[Elem[_]] = Some(sizeElement(funcElement(element[Arg],element[Res]))) + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("Env" -> (eEnv -> scalan.util.Invariant), "Arg" -> (eArg -> scalan.util.Invariant), "Res" -> (eRes -> scalan.util.Invariant)) + } + + implicit final def sizeFuncElement[Env, Arg, Res](implicit eEnv: Elem[Env], eArg: Elem[Arg], eRes: Elem[Res]): Elem[SizeFunc[Env, Arg, Res]] = + cachedElemByClass(eEnv, eArg, eRes)(classOf[SizeFuncElem[Env, Arg, Res, SizeFunc[Env, Arg, Res]]]) + + implicit case object SizeFuncCompanionElem extends CompanionElem[SizeFuncCompanionCtor] + + abstract class SizeFuncCompanionCtor extends CompanionDef[SizeFuncCompanionCtor] with SizeFuncCompanion { + def resultType = SizeFuncCompanionElem + override def toString = "SizeFunc" + } + implicit final def unrefSizeFuncCompanionCtor(p: Ref[SizeFuncCompanionCtor]): SizeFuncCompanionCtor = + p.node.asInstanceOf[SizeFuncCompanionCtor] + + lazy val RSizeFunc: MutableLazy[SizeFuncCompanionCtor] = MutableLazy(new SizeFuncCompanionCtor { + private val thisClass = classOf[SizeFuncCompanion] + }) + + object SizeFuncMethods { + object sizeEnv { + def unapply(d: Def[_]): Nullable[Ref[SizeFunc[Env, Arg, Res]] forSome {type Env; type Arg; type Res}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "sizeEnv" && receiver.elem.isInstanceOf[SizeFuncElem[_, _, _, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[SizeFunc[Env, Arg, Res]] forSome {type Env; type Arg; type Res}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[SizeFunc[Env, Arg, Res]] forSome {type Env; type Arg; type Res}] = unapply(exp.node) + } + } + + object SizeFuncCompanionMethods { + } +} // of object SizeFunc + registerEntityObject("SizeFunc", SizeFunc) + +object SizeOption extends EntityObject("SizeOption") { + // entityConst: single const for each entity + import Liftables._ + import scala.reflect.{ClassTag, classTag} + type SSizeOption[T] = special.collection.SizeOption[T] + case class SizeOptionConst[ST, T]( + constValue: SSizeOption[ST], + lT: Liftable[ST, T] + ) extends LiftedConst[SSizeOption[ST], SizeOption[T]] with SizeOption[T] + with Def[SizeOption[T]] with SizeOptionConstMethods[T] { + implicit final def eT: Elem[T] = lT.eW + implicit final def eVal: Elem[WOption[T]] = element[WOption[T]] + + val liftable: Liftable[SSizeOption[ST], SizeOption[T]] = liftableSizeOption(lT) + val resultType: Elem[SizeOption[T]] = liftable.eW + } + + trait SizeOptionConstMethods[T] extends SizeOption[T] with SizeConstMethods[WOption[T]] { thisConst: Def[_] => + implicit def eT: Elem[T] + private val SizeOptionClass = classOf[SizeOption[T]] + + override def sizeOpt: Ref[WOption[Size[T]]] = { + asRep[WOption[Size[T]]](mkMethodCall(self, + SizeOptionClass.getMethod("sizeOpt"), + WrappedArray.empty, + true, false, element[WOption[Size[T]]])) + } + } + + case class LiftableSizeOption[ST, T](lT: Liftable[ST, T]) + extends Liftable[SSizeOption[ST], SizeOption[T]] { + lazy val eW: Elem[SizeOption[T]] = sizeOptionElement(lT.eW) + lazy val sourceType: RType[SSizeOption[ST]] = { + implicit val tagST = lT.sourceType.asInstanceOf[RType[ST]] + RType[SSizeOption[ST]] + } + def lift(x: SSizeOption[ST]): Ref[SizeOption[T]] = SizeOptionConst(x, lT) + def unlift(w: Ref[SizeOption[T]]): SSizeOption[ST] = w match { + case Def(SizeOptionConst(x: SSizeOption[_], _lT)) + if _lT == lT => x.asInstanceOf[SSizeOption[ST]] + case _ => unliftError(w) + } + } + implicit final def liftableSizeOption[ST, T](implicit lT: Liftable[ST,T]): Liftable[SSizeOption[ST], SizeOption[T]] = + LiftableSizeOption(lT) + + private val SizeOptionClass = classOf[SizeOption[_]] + + // entityAdapter for SizeOption trait + case class SizeOptionAdapter[T](source: Ref[SizeOption[T]]) + extends Node with SizeOption[T] + with Def[SizeOption[T]] { + implicit lazy val eT = source.elem.typeArgs("T")._1.asInstanceOf[Elem[T]] + override lazy val eVal: Elem[WOption[T]] = implicitly[Elem[WOption[T]]] + val resultType: Elem[SizeOption[T]] = element[SizeOption[T]] + override def transform(t: Transformer) = SizeOptionAdapter[T](t(source)) + + def sizeOpt: Ref[WOption[Size[T]]] = { + asRep[WOption[Size[T]]](mkMethodCall(source, + SizeOptionClass.getMethod("sizeOpt"), + WrappedArray.empty, + true, true, element[WOption[Size[T]]])) + } + + def dataSize: Ref[Long] = { + asRep[Long](mkMethodCall(source, + SizeOptionClass.getMethod("dataSize"), + WrappedArray.empty, + true, true, element[Long])) + } + } + + // entityUnref: single unref method for each type family + implicit final def unrefSizeOption[T](p: Ref[SizeOption[T]]): SizeOption[T] = { + if (p.node.isInstanceOf[SizeOption[T]@unchecked]) p.node.asInstanceOf[SizeOption[T]] + else + SizeOptionAdapter(p) + } + + // familyElem + class SizeOptionElem[T, To <: SizeOption[T]](implicit _eT: Elem[T]) + extends SizeElem[WOption[T], To] { + def eT = _eT + + override val liftable: Liftables.Liftable[_, To] = asLiftable[SSizeOption[_], To](liftableSizeOption(_eT.liftable)) + + override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { + super.collectMethods ++ + Elem.declaredMethods(classOf[SizeOption[T]], classOf[SSizeOption[_]], Set( + "sizeOpt" + )) + } + + override lazy val parent: Option[Elem[_]] = Some(sizeElement(wOptionElement(element[T]))) + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("T" -> (eT -> scalan.util.Invariant)) + } + + implicit final def sizeOptionElement[T](implicit eT: Elem[T]): Elem[SizeOption[T]] = + cachedElemByClass(eT)(classOf[SizeOptionElem[T, SizeOption[T]]]) + + implicit case object SizeOptionCompanionElem extends CompanionElem[SizeOptionCompanionCtor] + + abstract class SizeOptionCompanionCtor extends CompanionDef[SizeOptionCompanionCtor] with SizeOptionCompanion { + def resultType = SizeOptionCompanionElem + override def toString = "SizeOption" + } + implicit final def unrefSizeOptionCompanionCtor(p: Ref[SizeOptionCompanionCtor]): SizeOptionCompanionCtor = + p.node.asInstanceOf[SizeOptionCompanionCtor] + + lazy val RSizeOption: MutableLazy[SizeOptionCompanionCtor] = MutableLazy(new SizeOptionCompanionCtor { + private val thisClass = classOf[SizeOptionCompanion] + }) + + object SizeOptionMethods { + object sizeOpt { + def unapply(d: Def[_]): Nullable[Ref[SizeOption[T]] forSome {type T}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "sizeOpt" && receiver.elem.isInstanceOf[SizeOptionElem[_, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[SizeOption[T]] forSome {type T}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[SizeOption[T]] forSome {type T}] = unapply(exp.node) + } + } + + object SizeOptionCompanionMethods { + } +} // of object SizeOption + registerEntityObject("SizeOption", SizeOption) + + override def resetContext(): Unit = { + super.resetContext() + RSize.reset() + RSizePrim.reset() + RSizePair.reset() + RSizeColl.reset() + RSizeFunc.reset() + RSizeOption.reset() + } + + registerModule(SizesModule) +} + +object SizesModule extends scalan.ModuleInfo("special.collection", "Sizes") +} + +trait SizesModule extends special.collection.impl.SizesDefs {self: Library =>} diff --git a/library/src/main/scala/special/wrappers/WrappersModule.scala b/library/src/main/scala/special/wrappers/WrappersModule.scala new file mode 100644 index 0000000000..b74bec314e --- /dev/null +++ b/library/src/main/scala/special/wrappers/WrappersModule.scala @@ -0,0 +1,10 @@ +package special.wrappers + +import wrappers.scala.WOptionsModule +import wrappers.scalan.WRTypesModule +import wrappers.special.WSpecialPredefsModule + +trait WrappersModule + extends WSpecialPredefsModule + with WOptionsModule + with WRTypesModule \ No newline at end of file diff --git a/library/src/main/scala/special/wrappers/WrappersSpecUnit.scala b/library/src/main/scala/special/wrappers/WrappersSpecUnit.scala new file mode 100644 index 0000000000..ece554226e --- /dev/null +++ b/library/src/main/scala/special/wrappers/WrappersSpecUnit.scala @@ -0,0 +1,35 @@ +package special.wrappers { + import scalan._ + + trait WrappersSpec extends Base { self: Library => + import WOption._; + import WRType._; + import WSpecialPredef._; + import WrapSpecBase._; + trait WrapSpecBase extends Def[WrapSpecBase] with WrapSpec; + trait OptionWrapSpec extends WrapSpecBase { + def get[A](xs: Ref[WOption[A]]): Ref[A] = xs.get; + @NeverInline def getOrElse[A](xs: Ref[WOption[A]], default: Ref[Thunk[A]]): Ref[A] = delayInvoke; + def map[A, B](xs: Ref[WOption[A]], f: Ref[scala.Function1[A, B]]): Ref[WOption[B]] = xs.map[B](f); + def flatMap[A, B](xs: Ref[WOption[A]], f: Ref[scala.Function1[A, WOption[B]]]): Ref[WOption[B]] = xs.flatMap[B](f); + def filter[A](xs: Ref[WOption[A]], f: Ref[scala.Function1[A, Boolean]]): Ref[WOption[A]] = xs.filter(f); + def isDefined[A](xs: Ref[WOption[A]]): Ref[Boolean] = xs.isDefined; + def isEmpty[A](xs: Ref[WOption[A]]): Ref[Boolean] = xs.isEmpty; + @NeverInline def fold[A, B](xs: Ref[WOption[A]], ifEmpty: Ref[Thunk[B]], f: Ref[scala.Function1[A, B]]): Ref[B] = delayInvoke + }; + trait SpecialPredefWrapSpec extends WrapSpecBase { + def loopUntil[A](s1: Ref[A], isMatch: Ref[scala.Function1[A, Boolean]], step: Ref[scala.Function1[A, A]]): Ref[A] = RWSpecialPredef.loopUntil[A](s1, isMatch, step); + def cast[A](v: Ref[Any])(implicit cA: Elem[A]): Ref[WOption[A]] = RWSpecialPredef.cast[A](v); + def some[A](x: Ref[A]): Ref[WOption[A]] = RWSpecialPredef.some[A](x); + def none[A](implicit cA: Elem[A]): Ref[WOption[A]] = RWSpecialPredef.none[A]; + def optionGetOrElse[A](opt: Ref[WOption[A]], default: Ref[A]): Ref[A] = RWSpecialPredef.optionGetOrElse[A](opt, default) + }; + trait RTypeWrapSpec extends WrapSpecBase { + def name[T](d: Ref[WRType[T]]): Ref[String] = d.name + }; + trait WrapSpecBaseCompanion; + trait OptionWrapSpecCompanion; + trait SpecialPredefWrapSpecCompanion; + trait RTypeWrapSpecCompanion + } +} \ No newline at end of file diff --git a/library/src/main/scala/special/wrappers/impl/WrappersSpecImpl.scala b/library/src/main/scala/special/wrappers/impl/WrappersSpecImpl.scala new file mode 100644 index 0000000000..26f65a25ba --- /dev/null +++ b/library/src/main/scala/special/wrappers/impl/WrappersSpecImpl.scala @@ -0,0 +1,218 @@ +package special.wrappers + +import scalan._ +import scala.reflect.runtime.universe._ +import scala.reflect._ +import scala.collection.mutable.WrappedArray + +package impl { +// Abs ----------------------------------- +trait WrappersSpecDefs extends scalan.Scalan with WrappersSpec { + self: Library => +import WOption._ +import WRType._ +import WSpecialPredef._ +import WrapSpecBase._ +import OptionWrapSpec._ +import RTypeWrapSpec._ +import SpecialPredefWrapSpec._ + +object WrapSpecBase extends EntityObject("WrapSpecBase") { + private val WrapSpecBaseClass = classOf[WrapSpecBase] + + // entityAdapter for WrapSpecBase trait + case class WrapSpecBaseAdapter(source: Ref[WrapSpecBase]) + extends Node with WrapSpecBase + with Def[WrapSpecBase] { + val resultType: Elem[WrapSpecBase] = element[WrapSpecBase] + override def transform(t: Transformer) = WrapSpecBaseAdapter(t(source)) + } + + // entityUnref: single unref method for each type family + implicit final def unrefWrapSpecBase(p: Ref[WrapSpecBase]): WrapSpecBase = { + if (p.node.isInstanceOf[WrapSpecBase]) p.node.asInstanceOf[WrapSpecBase] + else + WrapSpecBaseAdapter(p) + } + + // familyElem + class WrapSpecBaseElem[To <: WrapSpecBase] + extends EntityElem[To] { + } + + implicit lazy val wrapSpecBaseElement: Elem[WrapSpecBase] = + new WrapSpecBaseElem[WrapSpecBase] + + implicit case object WrapSpecBaseCompanionElem extends CompanionElem[WrapSpecBaseCompanionCtor] + + abstract class WrapSpecBaseCompanionCtor extends CompanionDef[WrapSpecBaseCompanionCtor] with WrapSpecBaseCompanion { + def resultType = WrapSpecBaseCompanionElem + override def toString = "WrapSpecBase" + } + implicit final def unrefWrapSpecBaseCompanionCtor(p: Ref[WrapSpecBaseCompanionCtor]): WrapSpecBaseCompanionCtor = + p.node.asInstanceOf[WrapSpecBaseCompanionCtor] + + lazy val RWrapSpecBase: MutableLazy[WrapSpecBaseCompanionCtor] = MutableLazy(new WrapSpecBaseCompanionCtor { + private val thisClass = classOf[WrapSpecBaseCompanion] + }) +} // of object WrapSpecBase + registerEntityObject("WrapSpecBase", WrapSpecBase) + +object OptionWrapSpec extends EntityObject("OptionWrapSpec") { + private val OptionWrapSpecClass = classOf[OptionWrapSpec] + + // entityAdapter for OptionWrapSpec trait + case class OptionWrapSpecAdapter(source: Ref[OptionWrapSpec]) + extends Node with OptionWrapSpec + with Def[OptionWrapSpec] { + val resultType: Elem[OptionWrapSpec] = element[OptionWrapSpec] + override def transform(t: Transformer) = OptionWrapSpecAdapter(t(source)) + + override def getOrElse[A](xs: Ref[WOption[A]], default: Ref[Thunk[A]]): Ref[A] = { + implicit val eA = xs.eA + asRep[A](mkMethodCall(source, + OptionWrapSpecClass.getMethod("getOrElse", classOf[Sym], classOf[Sym]), + Array[AnyRef](xs, default), + true, true, element[A])) + } + + override def fold[A, B](xs: Ref[WOption[A]], ifEmpty: Ref[Thunk[B]], f: Ref[A => B]): Ref[B] = { + implicit val eA = xs.eA +implicit val eB = ifEmpty.elem.eItem + asRep[B](mkMethodCall(source, + OptionWrapSpecClass.getMethod("fold", classOf[Sym], classOf[Sym], classOf[Sym]), + Array[AnyRef](xs, ifEmpty, f), + true, true, element[B])) + } + } + + // entityUnref: single unref method for each type family + implicit final def unrefOptionWrapSpec(p: Ref[OptionWrapSpec]): OptionWrapSpec = { + if (p.node.isInstanceOf[OptionWrapSpec]) p.node.asInstanceOf[OptionWrapSpec] + else + OptionWrapSpecAdapter(p) + } + + // familyElem + class OptionWrapSpecElem[To <: OptionWrapSpec] + extends WrapSpecBaseElem[To] { + override lazy val parent: Option[Elem[_]] = Some(wrapSpecBaseElement) + } + + implicit lazy val optionWrapSpecElement: Elem[OptionWrapSpec] = + new OptionWrapSpecElem[OptionWrapSpec] + + implicit case object OptionWrapSpecCompanionElem extends CompanionElem[OptionWrapSpecCompanionCtor] + + abstract class OptionWrapSpecCompanionCtor extends CompanionDef[OptionWrapSpecCompanionCtor] with OptionWrapSpecCompanion { + def resultType = OptionWrapSpecCompanionElem + override def toString = "OptionWrapSpec" + } + implicit final def unrefOptionWrapSpecCompanionCtor(p: Ref[OptionWrapSpecCompanionCtor]): OptionWrapSpecCompanionCtor = + p.node.asInstanceOf[OptionWrapSpecCompanionCtor] + + lazy val ROptionWrapSpec: MutableLazy[OptionWrapSpecCompanionCtor] = MutableLazy(new OptionWrapSpecCompanionCtor { + private val thisClass = classOf[OptionWrapSpecCompanion] + }) +} // of object OptionWrapSpec + registerEntityObject("OptionWrapSpec", OptionWrapSpec) + +object SpecialPredefWrapSpec extends EntityObject("SpecialPredefWrapSpec") { + private val SpecialPredefWrapSpecClass = classOf[SpecialPredefWrapSpec] + + // entityAdapter for SpecialPredefWrapSpec trait + case class SpecialPredefWrapSpecAdapter(source: Ref[SpecialPredefWrapSpec]) + extends Node with SpecialPredefWrapSpec + with Def[SpecialPredefWrapSpec] { + val resultType: Elem[SpecialPredefWrapSpec] = element[SpecialPredefWrapSpec] + override def transform(t: Transformer) = SpecialPredefWrapSpecAdapter(t(source)) + } + + // entityUnref: single unref method for each type family + implicit final def unrefSpecialPredefWrapSpec(p: Ref[SpecialPredefWrapSpec]): SpecialPredefWrapSpec = { + if (p.node.isInstanceOf[SpecialPredefWrapSpec]) p.node.asInstanceOf[SpecialPredefWrapSpec] + else + SpecialPredefWrapSpecAdapter(p) + } + + // familyElem + class SpecialPredefWrapSpecElem[To <: SpecialPredefWrapSpec] + extends WrapSpecBaseElem[To] { + override lazy val parent: Option[Elem[_]] = Some(wrapSpecBaseElement) + } + + implicit lazy val specialPredefWrapSpecElement: Elem[SpecialPredefWrapSpec] = + new SpecialPredefWrapSpecElem[SpecialPredefWrapSpec] + + implicit case object SpecialPredefWrapSpecCompanionElem extends CompanionElem[SpecialPredefWrapSpecCompanionCtor] + + abstract class SpecialPredefWrapSpecCompanionCtor extends CompanionDef[SpecialPredefWrapSpecCompanionCtor] with SpecialPredefWrapSpecCompanion { + def resultType = SpecialPredefWrapSpecCompanionElem + override def toString = "SpecialPredefWrapSpec" + } + implicit final def unrefSpecialPredefWrapSpecCompanionCtor(p: Ref[SpecialPredefWrapSpecCompanionCtor]): SpecialPredefWrapSpecCompanionCtor = + p.node.asInstanceOf[SpecialPredefWrapSpecCompanionCtor] + + lazy val RSpecialPredefWrapSpec: MutableLazy[SpecialPredefWrapSpecCompanionCtor] = MutableLazy(new SpecialPredefWrapSpecCompanionCtor { + private val thisClass = classOf[SpecialPredefWrapSpecCompanion] + }) +} // of object SpecialPredefWrapSpec + registerEntityObject("SpecialPredefWrapSpec", SpecialPredefWrapSpec) + +object RTypeWrapSpec extends EntityObject("RTypeWrapSpec") { + private val RTypeWrapSpecClass = classOf[RTypeWrapSpec] + + // entityAdapter for RTypeWrapSpec trait + case class RTypeWrapSpecAdapter(source: Ref[RTypeWrapSpec]) + extends Node with RTypeWrapSpec + with Def[RTypeWrapSpec] { + val resultType: Elem[RTypeWrapSpec] = element[RTypeWrapSpec] + override def transform(t: Transformer) = RTypeWrapSpecAdapter(t(source)) + } + + // entityUnref: single unref method for each type family + implicit final def unrefRTypeWrapSpec(p: Ref[RTypeWrapSpec]): RTypeWrapSpec = { + if (p.node.isInstanceOf[RTypeWrapSpec]) p.node.asInstanceOf[RTypeWrapSpec] + else + RTypeWrapSpecAdapter(p) + } + + // familyElem + class RTypeWrapSpecElem[To <: RTypeWrapSpec] + extends WrapSpecBaseElem[To] { + override lazy val parent: Option[Elem[_]] = Some(wrapSpecBaseElement) + } + + implicit lazy val rTypeWrapSpecElement: Elem[RTypeWrapSpec] = + new RTypeWrapSpecElem[RTypeWrapSpec] + + implicit case object RTypeWrapSpecCompanionElem extends CompanionElem[RTypeWrapSpecCompanionCtor] + + abstract class RTypeWrapSpecCompanionCtor extends CompanionDef[RTypeWrapSpecCompanionCtor] with RTypeWrapSpecCompanion { + def resultType = RTypeWrapSpecCompanionElem + override def toString = "RTypeWrapSpec" + } + implicit final def unrefRTypeWrapSpecCompanionCtor(p: Ref[RTypeWrapSpecCompanionCtor]): RTypeWrapSpecCompanionCtor = + p.node.asInstanceOf[RTypeWrapSpecCompanionCtor] + + lazy val RRTypeWrapSpec: MutableLazy[RTypeWrapSpecCompanionCtor] = MutableLazy(new RTypeWrapSpecCompanionCtor { + private val thisClass = classOf[RTypeWrapSpecCompanion] + }) +} // of object RTypeWrapSpec + registerEntityObject("RTypeWrapSpec", RTypeWrapSpec) + + override def resetContext(): Unit = { + super.resetContext() + RWrapSpecBase.reset() + ROptionWrapSpec.reset() + RSpecialPredefWrapSpec.reset() + RRTypeWrapSpec.reset() + } + + registerModule(WrappersSpecModule) +} + +object WrappersSpecModule extends scalan.ModuleInfo("special.wrappers", "WrappersSpec") +} + +trait WrappersSpecModule extends special.wrappers.impl.WrappersSpecDefs {self: Library =>} diff --git a/library/src/main/scala/wrappers/scala/WOptions.scala b/library/src/main/scala/wrappers/scala/WOptions.scala new file mode 100644 index 0000000000..02b9082aa0 --- /dev/null +++ b/library/src/main/scala/wrappers/scala/WOptions.scala @@ -0,0 +1,20 @@ +package wrappers.scala { + import scalan._ + + import special.wrappers.WrappersModule + + trait WOptions extends Base { self: WrappersModule => + @External("Option") @ContainerType @FunctorType @Liftable @WithMethodCallRecognizers trait WOption[A] extends Def[WOption[A]] { + implicit def eA: Elem[A]; + @External def fold[B](ifEmpty: Ref[Thunk[B]], f: Ref[scala.Function1[A, B]]): Ref[B]; + @External def isEmpty: Ref[Boolean]; + @External def isDefined: Ref[Boolean]; + @External def filter(p: Ref[scala.Function1[A, Boolean]]): Ref[WOption[A]]; + @External def flatMap[B](f: Ref[scala.Function1[A, WOption[B]]]): Ref[WOption[B]]; + @External def map[B](f: Ref[scala.Function1[A, B]]): Ref[WOption[B]]; + @External def getOrElse[B](default: Ref[Thunk[B]]): Ref[B]; + @External def get: Ref[A] + }; + trait WOptionCompanion + } +} \ No newline at end of file diff --git a/library/src/main/scala/wrappers/scala/impl/WOptionsImpl.scala b/library/src/main/scala/wrappers/scala/impl/WOptionsImpl.scala new file mode 100644 index 0000000000..752a939276 --- /dev/null +++ b/library/src/main/scala/wrappers/scala/impl/WOptionsImpl.scala @@ -0,0 +1,340 @@ +package wrappers.scala + +import scalan._ +import special.wrappers.WrappersModule +import special.wrappers.OptionWrapSpec +import scala.collection.mutable.WrappedArray + +package impl { +// Abs ----------------------------------- +trait WOptionsDefs extends scalan.Scalan with WOptions { + self: WrappersModule => + +object WOption extends EntityObject("WOption") { + // entityConst: single const for each entity + import Liftables._ + + case class WOptionConst[SA, A]( + constValue: Option[SA], + lA: Liftable[SA, A] + ) extends LiftedConst[Option[SA], WOption[A]] with WOption[A] + with Def[WOption[A]] with WOptionConstMethods[A] { + implicit final def eA: Elem[A] = lA.eW + + val liftable: Liftable[Option[SA], WOption[A]] = liftableOption(lA) + val resultType: Elem[WOption[A]] = liftable.eW + } + + trait WOptionConstMethods[A] extends WOption[A] { thisConst: Def[_] => + implicit def eA: Elem[A] + private val WOptionClass = classOf[WOption[A]] + + override def fold[B](ifEmpty: Ref[Thunk[B]], f: Ref[A => B]): Ref[B] = { + implicit val eB = ifEmpty.elem.eItem + asRep[B](mkMethodCall(self, + WOptionClass.getMethod("fold", classOf[Sym], classOf[Sym]), + Array[AnyRef](ifEmpty, f), + true, false, element[B])) + } + + override def isEmpty: Ref[Boolean] = { + asRep[Boolean](mkMethodCall(self, + WOptionClass.getMethod("isEmpty"), + WrappedArray.empty, + true, false, element[Boolean])) + } + + override def isDefined: Ref[Boolean] = { + asRep[Boolean](mkMethodCall(self, + WOptionClass.getMethod("isDefined"), + WrappedArray.empty, + true, false, element[Boolean])) + } + + override def filter(p: Ref[A => Boolean]): Ref[WOption[A]] = { + asRep[WOption[A]](mkMethodCall(self, + WOptionClass.getMethod("filter", classOf[Sym]), + Array[AnyRef](p), + true, false, element[WOption[A]])) + } + + override def flatMap[B](f: Ref[A => WOption[B]]): Ref[WOption[B]] = { + implicit val eB = f.elem.eRange.typeArgs("A")._1.asInstanceOf[Elem[B]] + asRep[WOption[B]](mkMethodCall(self, + WOptionClass.getMethod("flatMap", classOf[Sym]), + Array[AnyRef](f), + true, false, element[WOption[B]])) + } + + override def map[B](f: Ref[A => B]): Ref[WOption[B]] = { + implicit val eB = f.elem.eRange + asRep[WOption[B]](mkMethodCall(self, + WOptionClass.getMethod("map", classOf[Sym]), + Array[AnyRef](f), + true, false, element[WOption[B]])) + } + + override def getOrElse[B](default: Ref[Thunk[B]]): Ref[B] = { + implicit val eB = default.elem.eItem + asRep[B](mkMethodCall(self, + WOptionClass.getMethod("getOrElse", classOf[Sym]), + Array[AnyRef](default), + true, false, element[B])) + } + + override def get: Ref[A] = { + asRep[A](mkMethodCall(self, + WOptionClass.getMethod("get"), + WrappedArray.empty, + true, false, element[A])) + } + } + + case class LiftableOption[SA, A](lA: Liftable[SA, A]) + extends Liftable[Option[SA], WOption[A]] { + lazy val eW: Elem[WOption[A]] = wOptionElement(lA.eW) + lazy val sourceType: RType[Option[SA]] = { + implicit val tagSA = lA.sourceType.asInstanceOf[RType[SA]] + RType[Option[SA]] + } + def lift(x: Option[SA]): Ref[WOption[A]] = WOptionConst(x, lA) + def unlift(w: Ref[WOption[A]]): Option[SA] = w match { + case Def(WOptionConst(x: Option[_], _lA)) + if _lA == lA => x.asInstanceOf[Option[SA]] + case _ => unliftError(w) + } + } + implicit final def liftableOption[SA, A](implicit lA: Liftable[SA,A]): Liftable[Option[SA], WOption[A]] = + LiftableOption(lA) + + private val _OptionWrapSpec = new OptionWrapSpec {} + + private val WOptionClass = classOf[WOption[_]] + + // entityAdapter for WOption trait + case class WOptionAdapter[A](source: Ref[WOption[A]]) + extends Node with WOption[A] + with Def[WOption[A]] { + implicit lazy val eA = source.elem.typeArgs("A")._1.asInstanceOf[Elem[A]] + + val resultType: Elem[WOption[A]] = element[WOption[A]] + override def transform(t: Transformer) = WOptionAdapter[A](t(source)) + + def fold[B](ifEmpty: Ref[Thunk[B]], f: Ref[A => B]): Ref[B] = { + implicit val eB = ifEmpty.elem.eItem + asRep[B](mkMethodCall(source, + WOptionClass.getMethod("fold", classOf[Sym], classOf[Sym]), + Array[AnyRef](ifEmpty, f), + true, true, element[B])) + } + + def isEmpty: Ref[Boolean] = { + asRep[Boolean](mkMethodCall(source, + WOptionClass.getMethod("isEmpty"), + WrappedArray.empty, + true, true, element[Boolean])) + } + + def isDefined: Ref[Boolean] = { + asRep[Boolean](mkMethodCall(source, + WOptionClass.getMethod("isDefined"), + WrappedArray.empty, + true, true, element[Boolean])) + } + + def filter(p: Ref[A => Boolean]): Ref[WOption[A]] = { + asRep[WOption[A]](mkMethodCall(source, + WOptionClass.getMethod("filter", classOf[Sym]), + Array[AnyRef](p), + true, true, element[WOption[A]])) + } + + def flatMap[B](f: Ref[A => WOption[B]]): Ref[WOption[B]] = { + implicit val eB = f.elem.eRange.typeArgs("A")._1.asInstanceOf[Elem[B]] + asRep[WOption[B]](mkMethodCall(source, + WOptionClass.getMethod("flatMap", classOf[Sym]), + Array[AnyRef](f), + true, true, element[WOption[B]])) + } + + def map[B](f: Ref[A => B]): Ref[WOption[B]] = { + implicit val eB = f.elem.eRange + asRep[WOption[B]](mkMethodCall(source, + WOptionClass.getMethod("map", classOf[Sym]), + Array[AnyRef](f), + true, true, element[WOption[B]])) + } + + def getOrElse[B](default: Ref[Thunk[B]]): Ref[B] = { + implicit val eB = default.elem.eItem + asRep[B](mkMethodCall(source, + WOptionClass.getMethod("getOrElse", classOf[Sym]), + Array[AnyRef](default), + true, true, element[B])) + } + + def get: Ref[A] = { + asRep[A](mkMethodCall(source, + WOptionClass.getMethod("get"), + WrappedArray.empty, + true, true, element[A])) + } + } + + // entityUnref: single unref method for each type family + implicit final def unrefWOption[A](p: Ref[WOption[A]]): WOption[A] = { + if (p.node.isInstanceOf[WOption[A]@unchecked]) p.node.asInstanceOf[WOption[A]] + else + WOptionAdapter(p) + } + + implicit final def castWOptionElement[A](elem: Elem[WOption[A]]): WOptionElem[A, WOption[A]] = + elem.asInstanceOf[WOptionElem[A, WOption[A]]] + + implicit lazy val containerWOption: Functor[WOption] = new Functor[WOption] { + def lift[A](implicit evA: Elem[A]) = element[WOption[A]] + def unlift[A](implicit eFT: Elem[WOption[A]]) = + castWOptionElement(eFT).eA + def unapply[T](e: Elem[_]) = e match { + case e: WOptionElem[_,_] => Some(asElem[WOption[T]](e)) + case _ => None + } + def map[A,B](xs: Ref[WOption[A]])(f: Ref[A] => Ref[B]) = { implicit val eA = unlift(xs.elem); xs.map(fun(f))} + } + + // manual fix: WOptionIso, wOptionIso + + // familyElem + class WOptionElem[A, To <: WOption[A]](implicit _eA: Elem[A]) + extends EntityElem1[A, To, WOption](_eA, container[WOption]) { + def eA = _eA + + override val liftable: Liftables.Liftable[_, To] = asLiftable[Option[_], To](liftableOption(_eA.liftable)) + + override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { + super.collectMethods ++ + Elem.declaredWrapperMethods(_OptionWrapSpec, classOf[WOption[A]], Set( + "fold", "isEmpty", "isDefined", "filter", "flatMap", "map", "getOrElse", "get" + )) + } + + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("A" -> (eA -> scalan.util.Invariant)) + } + + implicit final def wOptionElement[A](implicit eA: Elem[A]): Elem[WOption[A]] = + cachedElemByClass(eA)(classOf[WOptionElem[A, WOption[A]]]) + + implicit case object WOptionCompanionElem extends CompanionElem[WOptionCompanionCtor] + + abstract class WOptionCompanionCtor extends CompanionDef[WOptionCompanionCtor] with WOptionCompanion { + def resultType = WOptionCompanionElem + override def toString = "WOption" + } + implicit final def unrefWOptionCompanionCtor(p: Ref[WOptionCompanionCtor]): WOptionCompanionCtor = + p.node.asInstanceOf[WOptionCompanionCtor] + + lazy val RWOption: MutableLazy[WOptionCompanionCtor] = MutableLazy(new WOptionCompanionCtor { + private val thisClass = classOf[WOptionCompanion] + }) + + // manual fix: ViewWOption + + object WOptionMethods { + object fold { + def unapply(d: Def[_]): Nullable[(Ref[WOption[A]], Ref[Thunk[B]], Ref[A => B]) forSome {type A; type B}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "fold" && receiver.elem.isInstanceOf[WOptionElem[_, _]] => + val res = (receiver, args(0), args(1)) + Nullable(res).asInstanceOf[Nullable[(Ref[WOption[A]], Ref[Thunk[B]], Ref[A => B]) forSome {type A; type B}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[WOption[A]], Ref[Thunk[B]], Ref[A => B]) forSome {type A; type B}] = unapply(exp.node) + } + + object isEmpty { + def unapply(d: Def[_]): Nullable[Ref[WOption[A]] forSome {type A}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "isEmpty" && receiver.elem.isInstanceOf[WOptionElem[_, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[WOption[A]] forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[WOption[A]] forSome {type A}] = unapply(exp.node) + } + + object isDefined { + def unapply(d: Def[_]): Nullable[Ref[WOption[A]] forSome {type A}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "isDefined" && receiver.elem.isInstanceOf[WOptionElem[_, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[WOption[A]] forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[WOption[A]] forSome {type A}] = unapply(exp.node) + } + + object filter { + def unapply(d: Def[_]): Nullable[(Ref[WOption[A]], Ref[A => Boolean]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "filter" && receiver.elem.isInstanceOf[WOptionElem[_, _]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[WOption[A]], Ref[A => Boolean]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[WOption[A]], Ref[A => Boolean]) forSome {type A}] = unapply(exp.node) + } + + object flatMap { + def unapply(d: Def[_]): Nullable[(Ref[WOption[A]], Ref[A => WOption[B]]) forSome {type A; type B}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "flatMap" && receiver.elem.isInstanceOf[WOptionElem[_, _]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[WOption[A]], Ref[A => WOption[B]]) forSome {type A; type B}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[WOption[A]], Ref[A => WOption[B]]) forSome {type A; type B}] = unapply(exp.node) + } + + object map { + def unapply(d: Def[_]): Nullable[(Ref[WOption[A]], Ref[A => B]) forSome {type A; type B}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "map" && receiver.elem.isInstanceOf[WOptionElem[_, _]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[WOption[A]], Ref[A => B]) forSome {type A; type B}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[WOption[A]], Ref[A => B]) forSome {type A; type B}] = unapply(exp.node) + } + + object getOrElse { + def unapply(d: Def[_]): Nullable[(Ref[WOption[A]], Ref[Thunk[B]]) forSome {type A; type B}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "getOrElse" && receiver.elem.isInstanceOf[WOptionElem[_, _]] => + val res = (receiver, args(0)) + Nullable(res).asInstanceOf[Nullable[(Ref[WOption[A]], Ref[Thunk[B]]) forSome {type A; type B}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[WOption[A]], Ref[Thunk[B]]) forSome {type A; type B}] = unapply(exp.node) + } + + object get { + def unapply(d: Def[_]): Nullable[Ref[WOption[A]] forSome {type A}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "get" && receiver.elem.isInstanceOf[WOptionElem[_, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[WOption[A]] forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[WOption[A]] forSome {type A}] = unapply(exp.node) + } + } + + object WOptionCompanionMethods { + } +} // of object WOption + registerEntityObject("WOption", WOption) + + // manual fix: UserTypeWOption removed + // manual fix: unapplyViews removed + // manual fix: RepWOption removed + // manual fix: rewriteDef removed + + registerModule(WOptionsModule) +} + +object WOptionsModule extends scalan.ModuleInfo("wrappers.scala", "WOptions") +} + +trait WOptionsModule extends wrappers.scala.impl.WOptionsDefs {self: WrappersModule =>} diff --git a/library/src/main/scala/wrappers/scalan/WRTypes.scala b/library/src/main/scala/wrappers/scalan/WRTypes.scala new file mode 100644 index 0000000000..26566be4a7 --- /dev/null +++ b/library/src/main/scala/wrappers/scalan/WRTypes.scala @@ -0,0 +1,22 @@ +package wrappers.scalan { + import scalan._ + + import impl._ + + import scalan.RType + + import special.wrappers.WrappersModule + + import special.wrappers.RTypeWrapSpec + + import scala.collection.mutable.WrappedArray + + trait WRTypes extends Base { self: WrappersModule => + import WRType._; + @External("RType") @Liftable @WithMethodCallRecognizers trait WRType[A] extends Def[WRType[A]] { + implicit def eA: Elem[A]; + @External def name: Ref[String] + }; + trait WRTypeCompanion + } +} \ No newline at end of file diff --git a/library/src/main/scala/wrappers/scalan/impl/WRTypesImpl.scala b/library/src/main/scala/wrappers/scalan/impl/WRTypesImpl.scala new file mode 100644 index 0000000000..362a5cbe2a --- /dev/null +++ b/library/src/main/scala/wrappers/scalan/impl/WRTypesImpl.scala @@ -0,0 +1,148 @@ +package wrappers.scalan + +import scalan._ +import scalan.RType +import special.wrappers.WrappersModule +import special.wrappers.RTypeWrapSpec +import scala.collection.mutable.WrappedArray + +package impl { +// Abs ----------------------------------- +trait WRTypesDefs extends scalan.Scalan with WRTypes { + self: WrappersModule => +import WRType._ + +object WRType extends EntityObject("WRType") { + // entityConst: single const for each entity + import Liftables._ + + case class WRTypeConst[SA, A]( + constValue: RType[SA], + lA: Liftable[SA, A] + ) extends LiftedConst[RType[SA], WRType[A]] with WRType[A] + with Def[WRType[A]] with WRTypeConstMethods[A] { + implicit final def eA: Elem[A] = lA.eW + + val liftable: Liftable[RType[SA], WRType[A]] = liftableRType(lA) + val resultType: Elem[WRType[A]] = liftable.eW + } + + trait WRTypeConstMethods[A] extends WRType[A] { thisConst: Def[_] => + implicit def eA: Elem[A] + private val WRTypeClass = classOf[WRType[A]] + + override def name: Ref[String] = { + asRep[String](mkMethodCall(self, + WRTypeClass.getMethod("name"), + WrappedArray.empty, + true, false, element[String])) + } + } + + case class LiftableRType[SA, A](lA: Liftable[SA, A]) + extends Liftable[RType[SA], WRType[A]] { + lazy val eW: Elem[WRType[A]] = wRTypeElement(lA.eW) + lazy val sourceType: RType[RType[SA]] = { + implicit val tagSA = lA.sourceType.asInstanceOf[RType[SA]] + RType[RType[SA]] + } + def lift(x: RType[SA]): Ref[WRType[A]] = WRTypeConst(x, lA) + def unlift(w: Ref[WRType[A]]): RType[SA] = w match { + case Def(WRTypeConst(x: RType[_], _lA)) + if _lA == lA => x.asInstanceOf[RType[SA]] + case _ => unliftError(w) + } + } + implicit final def liftableRType[SA, A](implicit lA: Liftable[SA,A]): Liftable[RType[SA], WRType[A]] = + LiftableRType(lA) + + private val _RTypeWrapSpec = new RTypeWrapSpec {} + + private val WRTypeClass = classOf[WRType[_]] + + // entityAdapter for WRType trait + case class WRTypeAdapter[A](source: Ref[WRType[A]]) + extends Node with WRType[A] + with Def[WRType[A]] { + implicit lazy val eA = source.elem.typeArgs("A")._1.asInstanceOf[Elem[A]] + + val resultType: Elem[WRType[A]] = element[WRType[A]] + override def transform(t: Transformer) = WRTypeAdapter[A](t(source)) + + def name: Ref[String] = { + asRep[String](mkMethodCall(source, + WRTypeClass.getMethod("name"), + WrappedArray.empty, + true, true, element[String])) + } + } + + // entityUnref: single unref method for each type family + implicit final def unrefWRType[A](p: Ref[WRType[A]]): WRType[A] = { + if (p.node.isInstanceOf[WRType[A]@unchecked]) p.node.asInstanceOf[WRType[A]] + else + WRTypeAdapter(p) + } + + // familyElem + class WRTypeElem[A, To <: WRType[A]](implicit _eA: Elem[A]) + extends EntityElem[To] { + def eA = _eA + + override val liftable: Liftables.Liftable[_, To] = asLiftable[RType[_], To](liftableRType(_eA.liftable)) + + override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { + super.collectMethods ++ + Elem.declaredWrapperMethods(_RTypeWrapSpec, classOf[WRType[A]], Set( + "name" + )) + } + + override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs("A" -> (eA -> scalan.util.Invariant)) + } + + implicit final def wRTypeElement[A](implicit eA: Elem[A]): Elem[WRType[A]] = + cachedElemByClass(eA)(classOf[WRTypeElem[A, WRType[A]]]) + + implicit case object WRTypeCompanionElem extends CompanionElem[WRTypeCompanionCtor] + + abstract class WRTypeCompanionCtor extends CompanionDef[WRTypeCompanionCtor] with WRTypeCompanion { + def resultType = WRTypeCompanionElem + override def toString = "WRType" + } + implicit final def unrefWRTypeCompanionCtor(p: Ref[WRTypeCompanionCtor]): WRTypeCompanionCtor = + p.node.asInstanceOf[WRTypeCompanionCtor] + + lazy val RWRType: MutableLazy[WRTypeCompanionCtor] = MutableLazy(new WRTypeCompanionCtor { + private val thisClass = classOf[WRTypeCompanion] + }) + + object WRTypeMethods { + object name { + def unapply(d: Def[_]): Nullable[Ref[WRType[A]] forSome {type A}] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "name" && receiver.elem.isInstanceOf[WRTypeElem[_, _]] => + val res = receiver + Nullable(res).asInstanceOf[Nullable[Ref[WRType[A]] forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[WRType[A]] forSome {type A}] = unapply(exp.node) + } + } + + object WRTypeCompanionMethods { + } +} // of object WRType + registerEntityObject("WRType", WRType) + + override def resetContext(): Unit = { + super.resetContext() + RWRType.reset() + } + + registerModule(WRTypesModule) +} + +object WRTypesModule extends scalan.ModuleInfo("wrappers.scalan", "WRTypes") +} + +trait WRTypesModule extends wrappers.scalan.impl.WRTypesDefs {self: WrappersModule =>} diff --git a/library/src/main/scala/wrappers/special/WSpecialPredefs.scala b/library/src/main/scala/wrappers/special/WSpecialPredefs.scala new file mode 100644 index 0000000000..fbf2c7b614 --- /dev/null +++ b/library/src/main/scala/wrappers/special/WSpecialPredefs.scala @@ -0,0 +1,24 @@ +package wrappers.special { + import scalan._ + + import impl._ + + import special.wrappers.WrappersModule + + import special.wrappers.SpecialPredefWrapSpec + + import scala.collection.mutable.WrappedArray + + trait WSpecialPredefs extends Base { self: WrappersModule => + import WOption._; + import WSpecialPredef._; + @External("SpecialPredef") @WithMethodCallRecognizers trait WSpecialPredef extends Def[WSpecialPredef]; + trait WSpecialPredefCompanion { + @External def optionGetOrElse[A](opt: Ref[WOption[A]], default: Ref[A]): Ref[A]; + @External def none[@Reified A](implicit emA: Elem[A]): Ref[WOption[A]]; + @External def some[A](x: Ref[A]): Ref[WOption[A]]; + @External def cast[@Reified T](v: Ref[Any])(implicit emT: Elem[T]): Ref[WOption[T]]; + @External def loopUntil[A](s1: Ref[A], isMatch: Ref[scala.Function1[A, Boolean]], step: Ref[scala.Function1[A, A]]): Ref[A] + } + } +} \ No newline at end of file diff --git a/library/src/main/scala/wrappers/special/impl/WSpecialPredefsImpl.scala b/library/src/main/scala/wrappers/special/impl/WSpecialPredefsImpl.scala new file mode 100644 index 0000000000..292353c715 --- /dev/null +++ b/library/src/main/scala/wrappers/special/impl/WSpecialPredefsImpl.scala @@ -0,0 +1,163 @@ +package wrappers.special + +import scalan._ +import impl._ +import special.wrappers.WrappersModule +import special.wrappers.SpecialPredefWrapSpec +import scala.collection.mutable.WrappedArray +import scala.reflect.runtime.universe._ +import scala.reflect._ + +package impl { +// Abs ----------------------------------- +trait WSpecialPredefsDefs extends scalan.Scalan with WSpecialPredefs { + self: WrappersModule => +import WOption._ +import WSpecialPredef._ + +object WSpecialPredef extends EntityObject("WSpecialPredef") { + private val WSpecialPredefClass = classOf[WSpecialPredef] + + // entityAdapter for WSpecialPredef trait + case class WSpecialPredefAdapter(source: Ref[WSpecialPredef]) + extends Node with WSpecialPredef + with Def[WSpecialPredef] { + val resultType: Elem[WSpecialPredef] = element[WSpecialPredef] + override def transform(t: Transformer) = WSpecialPredefAdapter(t(source)) + } + + // entityUnref: single unref method for each type family + implicit final def unrefWSpecialPredef(p: Ref[WSpecialPredef]): WSpecialPredef = { + if (p.node.isInstanceOf[WSpecialPredef]) p.node.asInstanceOf[WSpecialPredef] + else + WSpecialPredefAdapter(p) + } + + // familyElem + class WSpecialPredefElem[To <: WSpecialPredef] + extends EntityElem[To] { + } + + implicit lazy val wSpecialPredefElement: Elem[WSpecialPredef] = + new WSpecialPredefElem[WSpecialPredef] + + implicit case object WSpecialPredefCompanionElem extends CompanionElem[WSpecialPredefCompanionCtor] + + abstract class WSpecialPredefCompanionCtor extends CompanionDef[WSpecialPredefCompanionCtor] with WSpecialPredefCompanion { + def resultType = WSpecialPredefCompanionElem + override def toString = "WSpecialPredef" + } + implicit final def unrefWSpecialPredefCompanionCtor(p: Ref[WSpecialPredefCompanionCtor]): WSpecialPredefCompanionCtor = + p.node.asInstanceOf[WSpecialPredefCompanionCtor] + + lazy val RWSpecialPredef: MutableLazy[WSpecialPredefCompanionCtor] = MutableLazy(new WSpecialPredefCompanionCtor { + private val thisClass = classOf[WSpecialPredefCompanion] + + def optionGetOrElse[A](opt: Ref[WOption[A]], default: Ref[A]): Ref[A] = { + implicit val eA = opt.eA + asRep[A](mkMethodCall(self, + thisClass.getMethod("optionGetOrElse", classOf[Sym], classOf[Sym]), + Array[AnyRef](opt, default), + true, false, element[A])) + } + + def none[A](implicit emA: Elem[A]): Ref[WOption[A]] = { + asRep[WOption[A]](mkMethodCall(self, + thisClass.getMethod("none", classOf[Elem[_]]), + Array[AnyRef](emA), + true, false, element[WOption[A]])) + } + + def some[A](x: Ref[A]): Ref[WOption[A]] = { + implicit val eA = x.elem + asRep[WOption[A]](mkMethodCall(self, + thisClass.getMethod("some", classOf[Sym]), + Array[AnyRef](x), + true, false, element[WOption[A]])) + } + + def cast[T](v: Ref[Any])(implicit emT: Elem[T]): Ref[WOption[T]] = { + asRep[WOption[T]](mkMethodCall(self, + thisClass.getMethod("cast", classOf[Sym], classOf[Elem[_]]), + Array[AnyRef](v, emT), + true, false, element[WOption[T]])) + } + + def loopUntil[A](s1: Ref[A], isMatch: Ref[A => Boolean], step: Ref[A => A]): Ref[A] = { + implicit val eA = s1.elem + asRep[A](mkMethodCall(self, + thisClass.getMethod("loopUntil", classOf[Sym], classOf[Sym], classOf[Sym]), + Array[AnyRef](s1, isMatch, step), + true, false, element[A])) + } + }) + + object WSpecialPredefMethods { + } + + object WSpecialPredefCompanionMethods { + object optionGetOrElse { + def unapply(d: Def[_]): Nullable[(Ref[WOption[A]], Ref[A]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "optionGetOrElse" && receiver.elem == WSpecialPredefCompanionElem => + val res = (args(0), args(1)) + Nullable(res).asInstanceOf[Nullable[(Ref[WOption[A]], Ref[A]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[WOption[A]], Ref[A]) forSome {type A}] = unapply(exp.node) + } + + object none { + def unapply(d: Def[_]): Nullable[Elem[A] forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "none" && receiver.elem == WSpecialPredefCompanionElem => + val res = args(0) + Nullable(res).asInstanceOf[Nullable[Elem[A] forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Elem[A] forSome {type A}] = unapply(exp.node) + } + + object some { + def unapply(d: Def[_]): Nullable[Ref[A] forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "some" && receiver.elem == WSpecialPredefCompanionElem => + val res = args(0) + Nullable(res).asInstanceOf[Nullable[Ref[A] forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[Ref[A] forSome {type A}] = unapply(exp.node) + } + + object cast { + def unapply(d: Def[_]): Nullable[(Ref[Any], Elem[T]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "cast" && receiver.elem == WSpecialPredefCompanionElem => + val res = (args(0), args(1)) + Nullable(res).asInstanceOf[Nullable[(Ref[Any], Elem[T]) forSome {type T}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[Any], Elem[T]) forSome {type T}] = unapply(exp.node) + } + + object loopUntil { + def unapply(d: Def[_]): Nullable[(Ref[A], Ref[A => Boolean], Ref[A => A]) forSome {type A}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "loopUntil" && receiver.elem == WSpecialPredefCompanionElem => + val res = (args(0), args(1), args(2)) + Nullable(res).asInstanceOf[Nullable[(Ref[A], Ref[A => Boolean], Ref[A => A]) forSome {type A}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[A], Ref[A => Boolean], Ref[A => A]) forSome {type A}] = unapply(exp.node) + } + } +} // of object WSpecialPredef + registerEntityObject("WSpecialPredef", WSpecialPredef) + + override def resetContext(): Unit = { + super.resetContext() + RWSpecialPredef.reset() + } + + registerModule(WSpecialPredefsModule) +} + +object WSpecialPredefsModule extends scalan.ModuleInfo("wrappers.special", "WSpecialPredefs") +} + +trait WSpecialPredefsModule extends wrappers.special.impl.WSpecialPredefsDefs {self: WrappersModule =>} diff --git a/library/src/test/scala/scalan/LibraryTests.scala b/library/src/test/scala/scalan/LibraryTests.scala new file mode 100644 index 0000000000..4714085ec7 --- /dev/null +++ b/library/src/test/scala/scalan/LibraryTests.scala @@ -0,0 +1,27 @@ +package scalan + +import scalan.util.BenchmarkUtil._ + +class Benchmark[T <: Scalan](createContext: => T) { + def run() = { + val (ctx, total) = measureTime { + var ctx = createContext + measure(100000, false) { i => + ctx = createContext + } + ctx + } + println(s"Def count: ${ctx.defCount}, total: $total msec") + /*Total time: 9335 ms*/ + } +} + +class LibraryTests extends BaseCtxTests { + test("Benchmark Library creation time") { + new Benchmark(new TestLibrary {}).run() + } +} + +object MeasureLibraryCreate extends App { + new Benchmark(new TestLibrary {}).run() +} diff --git a/library/src/test/scala/scalan/TestLibrary.scala b/library/src/test/scala/scalan/TestLibrary.scala new file mode 100644 index 0000000000..73c0a4c490 --- /dev/null +++ b/library/src/test/scala/scalan/TestLibrary.scala @@ -0,0 +1,13 @@ +package scalan + +trait TestLibrary extends Library { + import CollBuilder._ + import CCostedBuilder._ + import CostedBuilder._ + import MonoidBuilder._ + + lazy val colBuilder: Ref[CollBuilder] = variable[CollBuilder] + lazy val costedBuilder: Ref[CostedBuilder] = RCCostedBuilder() + lazy val intPlusMonoid: Ref[Monoid[Int]] = costedBuilder.monoidBuilder.intPlusMonoid + lazy val longPlusMonoid: Ref[Monoid[Long]] = costedBuilder.monoidBuilder.longPlusMonoid +} diff --git a/library/src/test/scala/special/collections/BaseCostedTests.scala b/library/src/test/scala/special/collections/BaseCostedTests.scala new file mode 100644 index 0000000000..8b3096ae0f --- /dev/null +++ b/library/src/test/scala/special/collections/BaseCostedTests.scala @@ -0,0 +1,8 @@ +package special.collections + +import scalan.{BaseCtxTests, TestLibrary} + +class BaseCostedTests extends BaseCtxTests { + class Ctx extends TestContext with TestLibrary { + } +} diff --git a/library/src/test/scala/special/collections/BasicBenchmarks.scala b/library/src/test/scala/special/collections/BasicBenchmarks.scala new file mode 100644 index 0000000000..a3db44d76a --- /dev/null +++ b/library/src/test/scala/special/collections/BasicBenchmarks.scala @@ -0,0 +1,83 @@ +package special.collections + +import org.scalameter.api._ +import spire.syntax.all.cfor + +trait BasicBenchmarkCases extends BenchmarkGens { suite: Bench[Double] => + performance of "Seq" in { + var res: Seq[Int] = null + measure method "Nil" in { + using(sizes) in { case n => + cfor(0)(_ < n, _ + 1) { _ => res = Nil } + } + } + measure method "empty" in { + using(sizes) in { case n => + cfor(0)(_ < n, _ + 1) { _ => res = Seq.empty } + } + } + measure method "apply" in { + using(sizes) in { case n => + cfor(0)(_ < n, _ + 1) { _ => res = Seq() } + } + } + } + + performance of "Map" in { + var res: Map[Int,Int] = null + measure method "empty" in { + using(sizes) in { case n => + cfor(0)(_ < n, _ + 1) { _ => res = Map.empty[Int,Int] } + } + } + measure method "apply" in { + using(sizes) in { case n => + cfor(0)(_ < n, _ + 1) { _ => + res = Map[Int,Int]() + } + } + } + } + + performance of "for" in { + var cell: Int = 0 + measure method "foreach" in { + using(arrays) in { case (xs, _) => + xs.foreach { x => cell = x } + } + } + measure method "cfor" in { + using(arrays) in { case (xs, _) => + cfor(0)(_ < xs.length, _ + 1) { i => cell = xs(i) } + } + } + } + + performance of "Seq vs Array" in { + var res: Seq[Int] = null + var head: Int = 0 + var tail: Seq[Int] = null + measure method "Seq(...)" in { + using(sizes) in { n => + cfor(0)(_ < n, _ + 1) { _ => + res = Seq(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + head = res.head + tail = res.tail + } + } + } + measure method "Array(...)" in { + using(sizes) in { n => + cfor(0)(_ < n, _ + 1) { _ => + res = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + head = res.head + tail = res.tail + } + } + } + } +} + +object FastBasicBenchmark extends Bench.LocalTime with BasicBenchmarkCases { +} + diff --git a/library/src/test/scala/special/collections/BenchmarkGens.scala b/library/src/test/scala/special/collections/BenchmarkGens.scala new file mode 100644 index 0000000000..7207b07b59 --- /dev/null +++ b/library/src/test/scala/special/collections/BenchmarkGens.scala @@ -0,0 +1,23 @@ +package special.collections + +import org.scalameter.KeyValue +import org.scalameter.api.{Gen, Bench, _} + +trait BenchmarkGens extends CollGens { suite: Bench[Double] => + val maxSize = 100000 + + val sizes = Gen.exponential("size")(10, maxSize, 10) + + val ranges = for { size <- sizes } yield (0 until size, maxSize / size) + + val arrays = ranges.map { case (r, i) => (r.toArray, i) } + + val colls = arrays.map { case (arr, i) => (builder.fromArray(arr), i) } + + private val config = Seq[KeyValue]( + exec.minWarmupRuns -> 5, + exec.maxWarmupRuns -> 10, + exec.benchRuns -> 30, + exec.requireGC -> true + ) +} diff --git a/library/src/test/scala/special/collections/BufferBenchmark.scala b/library/src/test/scala/special/collections/BufferBenchmark.scala new file mode 100644 index 0000000000..93e663ac72 --- /dev/null +++ b/library/src/test/scala/special/collections/BufferBenchmark.scala @@ -0,0 +1,99 @@ +package special.collections + +import debox.Buffer +import spire.syntax.all.cfor +import org.scalameter.api.Bench + +import scala.collection.mutable +import scala.collection.mutable.{ArrayBuffer, ListBuffer} + +trait BufferBenchmarkCases extends BenchmarkGens { suite: Bench[Double] => + val obj = new Object() + performance of "append[Int]" in { + measure method "of debox.Buffer" in { + using(arrays) in { case (arr, n) => + val buf = Buffer.ofSize[Int](16) + val limit = arr.length + cfor(0)(_ < limit, _ + 1) { i => + buf.append(arr(i)) + } + val res = buf.toArray() + } + } + measure method "of ArrayBuilder" in { + using(arrays) in { case (arr, n) => + val buf = mutable.ArrayBuilder.make[Int]() + val limit = arr.length + cfor(0)(_ < limit, _ + 1) { i => + buf += (arr(i)) + } + val res = buf.result() + } + } + measure method "of ArrayBuffer" in { + using(arrays) in { case (arr, n) => + val buf = ArrayBuffer.empty[Int] + val limit = arr.length + cfor(0)(_ < limit, _ + 1) { i => + buf.append(arr(i)) + } + val res = buf.toArray + } + } + measure method "of ListBuffer" in { + using(arrays) in { case (arr, n) => + val buf = ListBuffer.empty[Int] + val limit = arr.length + cfor(0)(_ < limit, _ + 1) { i => + buf.append(arr(i)) + } + val res = buf.toList + } + } + } + + performance of "append[Object]" in { + measure method "of debox.Buffer" in { + using(arrays) in { case (arr, n) => + val buf = Buffer.ofSize[Object](100) + val limit = arr.length + cfor(0)(_ < limit, _ + 1) { i => + buf.append(obj) + } + } + } + measure method "of ArrayBuilder" in { + using(arrays) in { case (arr, n) => + val buf = mutable.ArrayBuilder.make[Object]() + val limit = arr.length + cfor(0)(_ < limit, _ + 1) { i => + buf += (obj) + } + val res = buf.result() + } + } + measure method "of ArrayBuffer" in { + using(arrays) in { case (arr, n) => + val buf = ArrayBuffer.empty[Object] + val limit = arr.length + cfor(0)(_ < limit, _ + 1) { i => + buf.append(obj) + } + } + } + measure method "of ListBuffer" in { + using(arrays) in { case (arr, n) => + val buf = ListBuffer.empty[Object] + val limit = arr.length + cfor(0)(_ < limit, _ + 1) { i => + buf.append(obj) + } + val res = buf.toList + } + } + } +} + +object FastBufferBenchmark extends Bench.LocalTime with BufferBenchmarkCases { +} + diff --git a/library/src/test/scala/special/collections/CViewCollBenchmark.scala b/library/src/test/scala/special/collections/CViewCollBenchmark.scala new file mode 100644 index 0000000000..42a02a87b0 --- /dev/null +++ b/library/src/test/scala/special/collections/CViewCollBenchmark.scala @@ -0,0 +1,95 @@ +package special.collections + +import org.scalameter.{execution, Executor} +import org.scalameter.api._ +import org.scalameter.picklers.Implicits._ +import special.collection.Coll +import special.collection.ExtensionMethods._ +import spire.syntax.all._ + +trait CViewCollBenchmarkCases extends CollGens { suite: Bench[Double] => + val sizes = Gen.exponential("size")(10, 100000, 10) + + val ranges = for { size <- sizes } yield (0 until size, 100000 / size) + + val arrays = ranges.map { case (r, i) => (r.toArray, i) } + + val colls = arrays.map { case (arr, i) => (builder.fromArray(arr), i) } + + val incColls = arrays.map { case (arr, i) => (builder.makeView(builder.fromArray(arr), identity[Int]), i) } + + performance of "map" in { + measure method "of CViewColl" in { + using(incColls) in { case (coll, n) => + cfor(0)(_ < n, _ + 1) { _ => + coll.map(inc) + } + + } + } + measure method "of Coll" in { + using(colls) in { case (c, n) => + cfor(0)(_ < n, _ + 1) { _ => + c.map(inc) + } + } + } + } + performance of "map creation" in { + measure method "of CViewColl" in { + using(colls) in { case (coll, n) => + cfor(0)(_ < n, _ + 1) { _ => + builder.makeView(coll, inc) + } + + } + } + measure method "of Coll" in { + using(colls) in { case (c, n) => + cfor(0)(_ < n, _ + 1) { _ => + c.map(inc) + } + } + } + } + performance of "map usage" in { + + measure method "of CViewColl" in { + using(colls) in { case (coll, n) => + cfor(0)(_ < n, _ + 1) { _ => + val view = builder.makeView[Int, Int](coll, x => x * 10) + var sum = 0 + cfor(0)(_ < view.length, _ + 2) { i => + sum += view(i) + } + } + + } + } + measure method "of Coll" in { + using(colls) in { case (c, n) => + cfor(0)(_ < n, _ + 1) { _ => + val coll = c.map(x => x * 10) + var sum = 0 + cfor(0)(_ < c.length, _ + 2) { i => + sum += c(i) + } + } + } + } + } + // TODO: make more performance tests +} + +object FastCViewCollBenchmark extends Bench.LocalTime with CViewCollBenchmarkCases { +} + +object CViewCollBenchmark extends Bench.OfflineRegressionReport with CViewCollBenchmarkCases { + override def executor: Executor[Double] = new execution.LocalExecutor( + warmer, + aggregator, + measurer + ) +} + + diff --git a/library/src/test/scala/special/collections/CollBenchmark.scala b/library/src/test/scala/special/collections/CollBenchmark.scala new file mode 100644 index 0000000000..721dccf465 --- /dev/null +++ b/library/src/test/scala/special/collections/CollBenchmark.scala @@ -0,0 +1,178 @@ +package special.collections + +import org.scalameter.{execution, Executor} +import org.scalameter.api._ +import org.scalameter.picklers.Implicits._ +import special.collection.Coll +import special.collection.ExtensionMethods._ +import spire.syntax.all._ + + +trait CollBenchmarkCases extends BenchmarkGens { suite: Bench[Double] => + + performance of "map" in { + measure method "of Array" in { + using(arrays) in { case (arr, n) => + cfor(0)(_ < n, _ + 1) { _ => + arr.map(inc) + } + } + } + measure method "of Coll" in { + using(colls) in { case (c, n) => + cfor(0)(_ < n, _ + 1) { _ => + c.map(inc) + } + } + } + } + + performance of "filter" in { + measure method "of PairArray" in { + using(arrays) in { case (arr, n) => + cfor(0)(_ < n, _ + 1) { _ => + arr.zip(arr).filter(p => p._1 == p._2) + } + } + } + measure method "of PairColl" in { + @inline def doFilter(c: Coll[Int]) = c.zip(c).filter(p => p._1 == p._2) + using(colls) in { case (c, n) => + cfor(0)(_ < n, _ + 1) { _ => + doFilter(c) + } + } + } + } + + performance of "map" in { + measure method "of PairArray" in { + using(arrays) in { case (arr, n) => + cfor(0)(_ < n, _ + 1) { _ => + arr.zip(arr).map(p => p._1 + p._2) + } + } + } + measure method "of PairColl" in { + def doMap(c: Coll[Int]) = c.zip(c).map(p => (p._1 + p._2).toLong) + using(colls) in { case (c, n) => + cfor(0)(_ < n, _ + 1) { _ => + doMap(c) + } + } + } + } + + performance of "exists" in { + measure method "of PairArray" in { + using(arrays) in { case (arr, n) => + cfor(0)(_ < n, _ + 1) { _ => + arr.zip(arr).exists(p => p._1 != p._2) + } + } + } + measure method "of PairColl" in { + using(colls) in { case (c, n) => + cfor(0)(_ < n, _ + 1) { _ => + c.zip(c).exists(p => p._1 != p._2) + } + } + } + } + performance of "foldLeft" in { + measure method "PairArray" in { + using(arrays) in { case (arr, n) => + cfor(0)(_ < n, _ + 1) { _ => + arr.zip(arr).foldLeft(0)((b, p) => b + p._1 + p._2) + } + } + } + measure method "of PairColl" in { + using(colls) in { case (c, n) => + cfor(0)(_ < n, _ + 1) { _ => + c.zip(c).foldLeft[Int](0, p => p._1 + p._2._1 + p._2._2) + } + } + } + } + performance of "reverse" in { + measure method "of PairArray" in { + using(arrays) in { case (arr, n) => + cfor(0)(_ < n, _ + 1) { _ => + arr.zip(arr).reverse + } + } + } + measure method "of PairColl" in { + using(colls) in { case (c, n) => + cfor(0)(_ < n, _ + 1) { _ => + c.zip(c).reverse + } + } + } + } + performance of "mapFirst" in { + measure method "of PairArray" in { + using(arrays) in { case (arr, n) => + cfor(0)(_ < n, _ + 1) { _ => + arr.zip(arr).map(p => (inc(p._1), p._2)) + } + } + } + measure method "of PairColl" in { + using(colls) in { case (c, n) => + cfor(0)(_ < n, _ + 1) { _ => + c.zip(c).mapFirst(inc) + } + } + } + } + performance of "unionSet" in { + measure method "of PairArray" in { + using(arrays) in { case (arr, n) => + val reversed = arr.reverse + cfor(0)(_ < n, _ + 1) { _ => + arr.union(reversed).distinct + } + } + } + measure method "of PairColl" in { + using(colls) in { case (c, n) => + val reversed = c.reverse + cfor(0)(_ < n, _ + 1) { _ => + c.unionSet(c) + } + } + } + } +} + +object FastCollBenchmark extends Bench.LocalTime with CollBenchmarkCases { +} + +object CollBenchmark extends Bench.OfflineRegressionReport with CollBenchmarkCases { + override def executor: Executor[Double] = new execution.LocalExecutor( + warmer, + aggregator, + measurer + ) +// lazy val executor = LocalExecutor( +// new Executor.Warmer.Default, +// Aggregator.min[Double], +// measurer) +// lazy val measurer = new Measurer.Default +// def reporter: Reporter[Double] = Reporter.Composite( +// new LoggingReporter[Double], +//// new RegressionReporter( +//// RegressionReporter.Tester.OverlapIntervals(), +//// RegressionReporter.Historian.ExponentialBackoff() ), +// HtmlReporter(true) +// ) + +// reports.resultDir -> "tmp1" +// lazy val reporter = HtmlReporter(true) +// lazy val reporter = new LoggingReporter[Double] + +// lazy val persistor = Persistor.None +} + diff --git a/library/src/test/scala/special/collections/CollGens.scala b/library/src/test/scala/special/collections/CollGens.scala new file mode 100644 index 0000000000..b77e4d305b --- /dev/null +++ b/library/src/test/scala/special/collections/CollGens.scala @@ -0,0 +1,167 @@ +package special.collections + +import scala.collection.mutable.ArrayBuffer +import org.scalacheck.util.Buildable + +import scala.collection.mutable +import org.scalacheck.{Arbitrary, Gen} +import scalan._ +import special.collection.{Coll, CollBuilder, CollOverArray, CollOverArrayBuilder, PairColl, ReplColl} + +import scala.reflect.ClassTag +import scala.util.Random + +trait CollGens { testSuite => + import Gen._ + val builder: CollBuilder = new CollOverArrayBuilder + val monoid = builder.Monoids.intPlusMonoid + val valGen = choose(-100, 100) + val byteGen = choose[Byte](-100, 100) + val indexGen = choose(0, 100) + val replacedGen = choose(0, 100) + val lenGen = choose(0, 100) + + val shortGen = choose[Short](Short.MinValue, Short.MaxValue) + val intGen = choose[Int](Int.MinValue, Int.MaxValue) + val longGen = choose[Long](Long.MinValue, Long.MaxValue) + val charGen = choose[Char](Char.MinValue, Char.MaxValue) + val floatGen = choose[Float](Float.MinValue, Float.MaxValue) + val doubleGen = choose[Double](Double.MinValue, Double.MaxValue) + + def getArrayGen[T](valGen: Gen[T], count: Int = 100) + (implicit evb: Buildable[T,Array[T]], evt: Array[T] => Traversable[T]): Gen[Array[T]] = { + containerOfN[Array, T](count, valGen) + } + + def getCollOverArrayGen[T: RType](valGen: Gen[T], count: Int = 100): Gen[Coll[T]] = { + containerOfN[Array, T](count, valGen).map(builder.fromArray(_)) + } + + def getCollReplGen[T: RType](lenGen: Gen[Int], valGen: Gen[T], count: Int = 100): Gen[Coll[T]] = { + for { l <- lenGen; v <- valGen } yield builder.replicate(l, v) + } + + def getCollViewGen[A: RType](valGen: Gen[Coll[A]]): Gen[Coll[A]] = { + valGen.map(builder.makeView(_, identity[A])) + } + + def getCollViewGen[A, B: RType](valGen: Gen[Coll[A]], f: A => B): Gen[Coll[B]] = { + valGen.map(builder.makeView(_, f)) + } + + def getCollPairGenFinal[A: RType, B: RType](collGenLeft: Gen[Coll[A]], collGenRight: Gen[Coll[B]]): Gen[PairColl[A, B]] = { + for { left <- collGenLeft; right <- collGenRight } yield builder.pairColl(left, right) + } + + def getCollPairGenRight[A: RType, B: RType, C: RType](collGenLeft: Gen[Coll[A]], collGenRight: Gen[PairColl[B, C]]): Gen[PairColl[A, (B, C)]] = { + for { left <- collGenLeft; right <- collGenRight } yield builder.pairColl(left, right) + } + + def getCollPairGenLeft[A: RType, B: RType, C: RType](collGenLeft: Gen[PairColl[A, B]], collGenRight: Gen[Coll[C]]): Gen[PairColl[(A, B), C]] = { + for { left <- collGenLeft; right <- collGenRight } yield builder.pairColl(left, right) + } + + def getCollPairGenBoth[A: RType, B: RType, C: RType, D: RType](collGenLeft: Gen[PairColl[A, B]], collGenRight: Gen[PairColl[C, D]]): Gen[PairColl[(A, B), (C, D)]] = { + for { left <- collGenLeft; right <- collGenRight } yield builder.pairColl(left, right) + } + + // TODO: there's a need in generator that produces collections with different elements and the same type scheme + def getSuperGen[T: RType](length: Int = 1, collGen: Gen[Coll[T]]): Gen[PairColl[_, _]] = { + length match { + case 0 => { + Gen.oneOf(getCollPairGenFinal(collGen, collGen), + getCollPairGenFinal(collGen, collGen)) + } + case _ => { + getSuperGen(length - 1, collGen) match { + case lg: Gen[PairColl[RType[_], RType[_]]]@unchecked => { + getSuperGen(length - 1, collGen) match { + case rg: Gen[PairColl[RType[_], RType[_]]]@unchecked => { + val gen = Gen.oneOf( + getCollPairGenFinal(collGen, collGen), + getCollPairGenLeft(lg, collGen), + getCollPairGenRight(collGen, rg), + getCollPairGenBoth(lg, rg), + ) + return gen + } + case _ => throw new RuntimeException("Invalid rGen") + } + } + case _ => throw new RuntimeException("Invalid lGen") + } + } + } + } + + val bytesArrayGen: Gen[Array[Byte]] = getArrayGen[Byte](byteGen) //containerOfN[Array, Byte](100, byteGen) + val arrayGen: Gen[Array[Int]] = getArrayGen[Int](valGen) //containerOfN[Array, Int](100, valGen) + val indexesGen = containerOfN[Array, Int](10, indexGen).map(arr => builder.fromArray(arr.distinct.sorted)) + + val collOverArrayGen = getCollOverArrayGen(valGen) //arrayGen.map(builder.fromArray(_)) + + val bytesOverArrayGen = getCollOverArrayGen(byteGen) + val replCollGen = getCollReplGen(lenGen, valGen) + val replBytesCollGen = getCollReplGen(lenGen, byteGen) + + + val lazyCollGen = getCollViewGen(collOverArrayGen) + val lazyByteGen = getCollViewGen(bytesOverArrayGen) + + def easyFunction(arg: Int): Int = arg * 20 + 300 + def inverseEasyFunction(arg: Int): Int = (arg - 300) / 20 + + val lazyFuncCollGen = getCollViewGen[Int, Int](collOverArrayGen, easyFunction) + val lazyUnFuncCollGen = getCollViewGen[Int, Int](lazyFuncCollGen, inverseEasyFunction) + + val collGen = Gen.oneOf(collOverArrayGen, replCollGen, lazyCollGen, lazyUnFuncCollGen) + val bytesGen = Gen.oneOf(bytesOverArrayGen, replBytesCollGen, lazyByteGen) + + val innerGen = Gen.oneOf(collOverArrayGen, replCollGen) + + val superGenInt = getSuperGen(1, Gen.oneOf(collOverArrayGen, replCollGen, lazyCollGen, lazyUnFuncCollGen)) + val superGenByte = getSuperGen(1, Gen.oneOf(bytesOverArrayGen, replBytesCollGen, lazyByteGen)) + val superGen = Gen.oneOf(superGenInt, superGenByte) + + val allGen = Gen.oneOf(superGen, collGen) + + implicit val arbColl = Arbitrary(collGen) + implicit val arbBytes = Arbitrary(bytesGen) + + def eq0(x: Int) = x == 0 + def lt0(x: Int) = x < 0 + def plus(acc: Int, x: Int): Int = acc + x + val plusF = (p: (Int,Int)) => plus(p._1, p._2) + val predF = (p: (Int,Int)) => plus(p._1, p._2) > 0 + def inc(x: Int) = x + 1 + + def collMatchRepl[B](coll: B): Boolean = coll match { + case _ : ReplColl[_] => true + case _ => false + } + + def complexFunction(arg: Int): Int = { + var i = 0 + var res = 0 + while (i < 10) { + res += arg - i + i += 1 + } + res + } + + implicit def buildableColl[T:RType] = new Buildable[T,Coll[T]] { + def builder = new mutable.Builder[T,Coll[T]] { + val al = new ArrayBuffer[T] + def +=(x: T) = { + al += x + this + } + def clear() = al.clear() + def result() = testSuite.builder.fromArray(al.toArray) + } + } + + implicit def traversableColl[T](coll: Coll[T]): mutable.Traversable[T] = coll.toArray + +} diff --git a/library/src/test/scala/special/collections/CollsStagingTests.scala b/library/src/test/scala/special/collections/CollsStagingTests.scala new file mode 100644 index 0000000000..9ac3e34ed0 --- /dev/null +++ b/library/src/test/scala/special/collections/CollsStagingTests.scala @@ -0,0 +1,235 @@ +package special.collections + +import scala.language.reflectiveCalls +import special.wrappers.WrappersTests +import scalan._ +import scalan.util.BenchmarkUtil._ + +class CollsStagingTests extends WrappersTests { + class Ctx extends TestContext with TestLibrary { + import Coll._ + import CollBuilder._ + lazy val t2 = fun { (c: Ref[Coll[Long]]) => + c.map(fun { x => x + 1L }) + } + lazy val t3 = fun { (x: Ref[Int]) => + val b = colBuilder + b.fromItems(x, x + 1, x + 2) + } + } + + test("Coll methods") { + val ctx = new Ctx { + def test() = { +// { val Def(Lambda(_, _, x, RColOverArray(M.map(in, _)))) = t2; assert(in == x) } + } + } + ctx.test() + ctx.emit("t2", ctx.t2) + ctx.emit("t3", ctx.t3) + } + + test("measure: build graph and resetContext") { + val ctx = new Ctx { + useAlphaEquality = false + } + import ctx._ + import Coll._ + import CollBuilder._ +// import CollOverArrayBuilder._ + + var res: Sym = null + val nIters = 10 + measure(nIters) { i => + var sum: Int = 0 + for (j <- 0 until 3000) { + val col = colBuilder.replicate(i*j, 0) + res = col.map(fun {x => x + 1}) + sum += ctx.defCount + } + println(s"Defs: ${ctx.defCount}") + if (i == nIters - 1) emit("res", res) + ctx.resetContext() + } + } + + test("measure: build graph with new context") { + measure(10) { i => + var sum: Int = 0 + for (j <- 0 until 3000) { + val ctx = new Ctx { + useAlphaEquality = false + } + import ctx._ + import Coll._ + import CollBuilder._ + val col = colBuilder.replicate(i*j, 0) + val res = col.map(fun {x => x + 1}) + sum += ctx.defCount + } + println(s"Defs: ${sum}") + } + } + + def runMeasure(nRepeats: Int, name: String, alphaEq: Boolean, keepOrig: Boolean, unfoldWithOrig: Boolean) = { + println(s"runMeasure($name, alphaEq = $alphaEq, keepOrig = $keepOrig, unfoldWithOrig = $unfoldWithOrig)") + val nIters = 10 + def warmUp(i: Int) = { + val ctx = new Ctx { + useAlphaEquality = alphaEq + keepOriginalFunc = keepOrig + unfoldWithOriginalFunc = unfoldWithOrig + } + import ctx._ + import Coll._ + import CollBuilder._ + var outGraph: Sym = null + for (j <- 0 until nRepeats) { + val f = fun { in: Ref[(CollBuilder, Int)] => + val Pair(colBuilder, delta) = in + val col = colBuilder.replicate(i*j, 0) + val res = col.map(fun {x => x + delta}) + res + } + outGraph = Pair(f, f(Pair(colBuilder, 1))) + } + } + def measureUp(i: Int) = { + val ctx = new Ctx { + useAlphaEquality = alphaEq + keepOriginalFunc = keepOrig + unfoldWithOriginalFunc = unfoldWithOrig + } + import ctx._ + import Coll._ + import CollBuilder._ + var outGraph: Sym = null + for (j <- 0 until nRepeats) { + val f = fun { in: Ref[(CollBuilder, Int)] => + val Pair(colBuilder, delta) = in + val col = colBuilder.replicate(i*j, delta) + val col2 = colBuilder.replicate(j+i, delta) + val res = col.map(fun {x => x + delta}).zip(col2) + res + } + outGraph = Pair(f, f(Pair(colBuilder, 1))) + } + println(s"Defs: ${ctx.defCount}") + + if (i == nIters - 1) + emit(name, outGraph) + } + measure(nIters)(warmUp) + System.gc() + measure(nIters)(measureUp) + } + + test("measure: unfoldLambda") { + val dummyCtx = new Ctx // to force class loading + runMeasure(100, "default", true, true, true) + runMeasure(1000, "noAlpha", false, true, true) + runMeasure(1000, "noAlpha_noKeepOrig", false, false, true) + } +/* +runMeasure(noAlpha_noKeepOrig, alphaEq = false, keepOrig = false, unfoldWithOrig = true) +Iter 0: 1222 ms +Iter 1: 653 ms +Iter 2: 588 ms +Iter 3: 300 ms +Iter 4: 327 ms +Iter 5: 469 ms +Iter 6: 346 ms +Iter 7: 372 ms +Iter 8: 350 ms +Iter 9: 220 ms +Total time: 4847 ms +Defs: 220004 +Iter 0: 845 ms +Defs: 220005 +Iter 1: 580 ms +Defs: 225005 +Iter 2: 491 ms +Defs: 226671 +Iter 3: 620 ms +Defs: 227505 +Iter 4: 405 ms +Defs: 228005 +Iter 5: 558 ms +Defs: 228338 +Iter 6: 530 ms +Defs: 228576 +Iter 7: 418 ms +Defs: 228755 +Iter 8: 426 ms +Defs: 228893 +Iter 9: 533 ms +Total time: 5406 ms +*/ + test("invokeTransformedAdapterMethodCall") { + val ctx = new Ctx { + useAlphaEquality = true + keepOriginalFunc = false + } + import ctx._ + import Coll._ + val f = fun { col: Ref[Coll[Int]] => col.length } + val g = fun { col: Ref[Coll[Int]] => f(col) } + val exp = fun { col: Ref[Coll[Int]] => col.length } + emit("graphs", f, g, exp) + g shouldBe exp + } + + test("invokeUnlifted for Col") { + val ctx = new WrappersCtx with Library + import ctx._ + import Liftables._ + import Coll._ + import CollBuilder._ + import EnvRep._ + + val Cols: SCollBuilder = new special.collection.CollOverArrayBuilder + val arr = Array(1, 2, 3) + val col = Cols.fromArray(arr) + + check(col, { env: EnvRep[Coll[Int]] => for {xs <- env; arg <- lifted(2) } yield xs.apply(arg) }, col.apply(2)) + + val inc = (x: Int) => x + 1 + check(col, { env: EnvRep[Coll[Int]] => for { xs <- env; incL <- lifted(inc) } yield xs.map(incL) }, col.map(inc)) + +// check(Cols, { env: EnvRep[CollBuilder] => for { b <- env; arrL <- lifted(arr) } yield b.fromArray(arrL) }, Cols.fromArray(arr)) + + measure(10) { i => + (1 to 100).foreach { j => + check(Cols, + {env: EnvRep[CollBuilder] => for { + b <- env; x1 <- lifted(1); x2 <- lifted(j); x3 <- lifted(i) + } yield b.fromItems(x1, x2, x3) }, + Cols.fromItems(1, j, i)) + } + println(s"Defs: ${ctx.defCount}") + } + } + + test("invokeUnlifted for method of Ctor") { + val ctx = new WrappersCtx with Library + import ctx._ + import Liftables._ + import Coll._ + import CollBuilder._ + import EnvRep._ + + val Cols: SCollBuilder = new special.collection.CollOverArrayBuilder + val colData = Cols.replicate(10, 10) + val colSym = colBuilder.replicate(10, 10) + val resSym = colSym.append(colSym) + val resData = colData.append(colData) + val env = Map[Sym, AnyRef]() + val resEnvSym = EnvRep.add(colSym -> colData.asInstanceOf[AnyRef]) + val (resEnv, _) = resEnvSym.run(env) + resSym match { + case Def(mc: MethodCall) => + val res = invokeUnlifted(colSym.elem, mc, resEnv) + res shouldBe resData + } + } +} diff --git a/library/src/test/scala/special/collections/CollsTests.scala b/library/src/test/scala/special/collections/CollsTests.scala new file mode 100644 index 0000000000..0e93e1a09a --- /dev/null +++ b/library/src/test/scala/special/collections/CollsTests.scala @@ -0,0 +1,596 @@ +package special.collections + +import special.collection.{Coll, PairOfCols, CollOverArray, CReplColl} +import org.scalacheck.Gen +import org.scalatest.{PropSpec, Matchers} +import org.scalatest.prop.PropertyChecks + +class CollsTests extends PropSpec with PropertyChecks with Matchers with CollGens { testSuite => + import Gen._ + import special.collection.ExtensionMethods._ + + property("Coll.indices") { + val minSuccess = MinSuccessful(30) + forAll(collGen, collGen, minSuccess) { (col1: Coll[Int], col2: Coll[Int]) => + col1.indices.toArray shouldBe col1.toArray.indices.toArray + } + forAll(superGen, minSuccess) { cl => + cl.indices.toArray shouldBe cl.toArray.indices.toArray + } + } + + // TODO col1.zip(col2).length shouldBe col1.arr.zip(col2.arr).length + property("Coll.zip") { + } + + property("Coll.flatMap") { + forAll(containerOfN[Coll, Int](3, valGen), collGen) { (zs, col) => + val matrix = zs.map(_ => col) + val res = zs.zip(matrix).flatMap(_._2) + res.toArray shouldBe zs.toArray.flatMap(_ => col.toArray) + } + } + + property("Coll.segmentLength") { + forAll(collGen, indexGen) { (col, from) => + col.segmentLength(lt0, from) shouldBe col.toArray.segmentLength(lt0, from) + } + + val minSuccess = minSuccessful(30) + forAll(superGen, indexGen, minSuccess) { (col, from) => + col.segmentLength(collMatchRepl, from) shouldBe col.toArray.segmentLength(collMatchRepl, from) + } + } + + property("Coll.indexWhere") { + forAll(collGen, indexGen) { (col, from) => + col.indexWhere(eq0, from) shouldBe col.toArray.indexWhere(eq0, from) + def p2(ab: (Int, Int)) = eq0(ab._1) && eq0(ab._2) + col.zip(col).indexWhere(p2, from) shouldBe col.toArray.zip(col.toArray).indexWhere(p2, from) + } + } + + property("Coll.indexOf") { + forAll(collGen, indexGen, valGen) { (col, from, elem) => + col.indexOf(elem, from) shouldBe col.toArray.indexOf(elem, from) + col.zip(col).indexOf((elem, elem), from) shouldBe col.toArray.zip(col.toArray).indexOf((elem, elem), from) + } + } + + property("Coll.lastIndexWhere") { + forAll(collGen, indexGen) { (col, end) => + col.lastIndexWhere(eq0, end) shouldBe col.lastIndexWhere(eq0, end) + def p2(ab: (Int, Int)) = eq0(ab._1) && eq0(ab._2) + col.zip(col).lastIndexWhere(p2, end) shouldBe col.toArray.zip(col.toArray).lastIndexWhere(p2, end) + } + } + + property("Coll.partition") { + forAll(collGen) { col => + val (lsC, rsC) = col.partition(lt0) + val (ls, rs) = col.toArray.partition(lt0) + lsC.toArray shouldBe ls + rsC.toArray shouldBe rs + } + } + + property("Coll.patch") { + forAll(collGen, choose(-100, 100), collGen, replacedGen) { (col, from, patch, replaced) => + whenever(col.isValidIndex(from)) { + val patchedC = col.patch(from, patch, replaced) + val patched = col.toArray.patch(from, patch.toArray, replaced) + patchedC.toArray shouldBe patched + } + } + } + + property("Coll.updated") { + forAll(collGen, indexGen, valGen, MinSuccessful(200)) { (col, index, elem) => + whenever(col.isValidIndex(index)) { + val patchedC = col.updated(index, elem) + val patched = col.toArray.updated(index, elem) + patchedC.toArray shouldBe patched + } + whenever(col.isInstanceOf[CollOverArray[_]]) { + an[IndexOutOfBoundsException] should be thrownBy { + col.updated(col.length, elem) + } + an[IndexOutOfBoundsException] should be thrownBy { + col.updated(-1, elem) + } + } + } + } + + property("Coll.updateMany") { + forAll(collGen, indexesGen, MinSuccessful(200)) { (col, indexes) => + whenever(indexes.forall(col.isValidIndex(_))) { + val updatedC = col.updateMany(indexes, indexes) + val updated = col.toArray.clone() + for (i <- indexes) + updated.update(i, i) + updatedC.toArray shouldBe updated + } + whenever(col.isInstanceOf[CollOverArray[_]]) { + an[IndexOutOfBoundsException] should be thrownBy { + col.updateMany(builder.fromItems(col.length), builder.fromItems(0)) + } + an[IndexOutOfBoundsException] should be thrownBy { + col.updateMany(builder.fromItems(-1), builder.fromItems(0)) + } + } + } + } + + property("Coll methods") { + forAll(collGen, indexGen) { (col, index) => + { + val res = col.sum(monoid) + res shouldBe col.toArray.sum + val pairs = col.zip(col) + val pairMonoid = builder.Monoids.pairMonoid(monoid, monoid) + pairs.sum(pairMonoid) shouldBe ((res, res)) + } + { + val res = col.map(inc) + res.toArray shouldBe col.toArray.map(inc) + val pairs = col.zip(col) + pairs.map(plusF).toArray shouldBe pairs.toArray.map(plusF) + } + { + val res = col.filter(lt0) + res.toArray shouldBe col.toArray.filter(lt0) + } + { + val res = col.forall(lt0) + val emptyRepl = builder.replicate(0, 10) + val repl = builder.replicate(col.length, 10) + res shouldBe col.toArray.forall(lt0) + emptyRepl.forall(lt0) shouldBe Array[Int]().forall(lt0) + col.zip(repl).forall(predF) shouldBe col.zip(repl).toArray.forall(predF) + } + { + val res = col.exists(lt0) + res shouldBe col.toArray.exists(lt0) + builder.replicate(0, -10).exists(lt0) shouldBe Array[Int]().exists(lt0) + } + { + val res = col.foldLeft[Int](0, plusF) + res shouldBe col.toArray.foldLeft(0)(plus) + val pairs = col.zip(col) + val op = (in: (Int,(Int,Int))) => in._1 + in._2._1 + in._2._2 + pairs.foldLeft(0, op) shouldBe pairs.toArray.foldLeft(0)((b,a) => op((b,a))) + } + whenever(col.isValidIndex(index)) { + val res = col(index) + res shouldBe col.toArray(index) + + val res2 = col.getOrElse(index, index) + res2 shouldBe col.toArray(index) + } + + col.getOrElse(col.length, index) shouldBe index + col.getOrElse(-1, index) shouldBe index + } + forAll(superGen, indexGen) { (col, index) => + whenever(col.isValidIndex(index)) { + val res = col(index) + res shouldBe col.toArray(index) + } + } + } + + property("Coll.slice") { + forAll(collGen, indexGen, indexGen) { (col, from, until) => + whenever(col.isValidIndex(until)) { + val res = col.slice(from, until) + res.toArray shouldBe col.toArray.slice(from, until) + } + } + + forAll(superGen, indexGen, indexGen) { (col, from, until) => + whenever(col.isValidIndex(until)) { + val res = col.slice(from, until) + res.toArray shouldBe col.toArray.slice(from, until) + } + } + } + + property("Coll.append") { + forAll(collGen, collGen, valGen, MinSuccessful(50)) { (col1, col2, v) => + + { + val res = col1.append(col2) + res.toArray shouldBe (col1.toArray ++ col2.toArray) + val pairs1 = col1.zip(col1) + val pairs2 = col2.zip(col2) + val apairs = pairs1.append(pairs2) + apairs.toArray shouldBe (pairs1.toArray ++ pairs2.toArray) + } + + { + val repl1 = builder.replicate(col1.length, v) + val repl2 = builder.replicate(col2.length, v) + val arepl = repl1.append(repl2) + assert(arepl.isInstanceOf[CReplColl[Int]]) + arepl.toArray shouldBe (repl1.toArray ++ repl2.toArray) + + val pairs1 = repl1.zip(repl1) + val pairs2 = repl2.zip(repl2) + val apairs = pairs1.append(pairs2) + apairs.toArray shouldBe (pairs1.toArray ++ pairs2.toArray) + + apairs match { + case ps: PairOfCols[_,_] => + assert(ps.ls.isInstanceOf[CReplColl[Int]]) + assert(ps.rs.isInstanceOf[CReplColl[Int]]) + case _ => + assert(false, "Invalid type") + } + } + } + } + + property("Coll.mapReduce") { + import scalan.util.CollectionUtil.TraversableOps + def m(x: Int) = (math.abs(x) % 10, x) + forAll(collGen) { col => + val res = col.mapReduce(m, plusF) + val (ks, vs) = builder.unzip(res) + vs.toArray.sum shouldBe col.toArray.sum + ks.length <= 10 shouldBe true + res.toArray shouldBe col.toArray.toIterable.mapReduce(m)(plus).toArray + } + } + + property("Coll.groupBy") { + def key(x: Int) = math.abs(x) % 10 + forAll(collGen) { col => + val res = col.groupBy(key) + val (ks, vs) = builder.unzip(res) + vs.flatten.toArray.sum shouldBe col.toArray.sum + ks.length <= 10 shouldBe true + val pairs = col.map(x => (key(x), x)) + val res2 = pairs.groupByKey + val (ks2, vs2) = builder.unzip(res) + ks shouldBe ks2 + vs shouldBe vs2 + } + } + + property("Coll.reverse") { + val minSuccess = minSuccessful(50) + forAll(allGen, minSuccess) { col => + val res = col.reverse + res.toArray shouldBe col.toArray.reverse + val pairs = col.zip(col) + pairs.reverse.toArray shouldBe pairs.toArray.reverse +// TODO should work +// val c1 = col.asInstanceOf[Coll[Any]] +// val appended = c1.append(c1) +// appended.toArray shouldBe (c1.toArray ++ c1.toArray) + } + } + + property("Coll.take") { + val minSuccess = minSuccessful(50) + forAll(allGen, minSuccess) { col => + val n = col.length / 2 + val res = col.take(n) + res.toArray shouldBe col.toArray.take(n) + val pairs = col.zip(col) + pairs.take(n).toArray shouldBe pairs.toArray.take(n) + } + } + + property("Coll.distinct") { + forAll(collGen) { col => + val res = col.distinct + res.toArray shouldBe col.toArray.distinct + val pairs = col.zip(col) + pairs.distinct.toArray shouldBe pairs.toArray.distinct + } + forAll(superGen) { col => + val res = col.distinct + res.toArray shouldBe col.toArray.distinct + val pairs = col.zip(col) + pairs.distinct.toArray shouldBe pairs.toArray.distinct + } + } + + property("Coll.equals") { + def checkColls(repl: Coll[_], coll: Coll[_]) = { + assert(coll == repl) + assert(repl == coll) + repl.hashCode() shouldBe coll.hashCode() + + val zip1 = repl.zip(repl) + val zip2 = repl.zip(coll) + val zip3 = coll.zip(coll) + val zip4 = coll.zip(repl) + + assert(zip1 == zip2) + assert(zip2 == zip3) + assert(zip3 == zip4) + assert(zip4 == zip1) + zip1.hashCode() shouldBe zip2.hashCode() + zip2.hashCode() shouldBe zip3.hashCode() + zip3.hashCode() shouldBe zip4.hashCode() + zip4.hashCode() shouldBe zip1.hashCode() + } + val minSuccess = minSuccessful(50) + forAll(byteGen, indexGen, minSuccess) { (x, n) => + val repl = builder.replicate(n, x) + val coll = builder.fromArray(Array.fill(n)(x)) + + checkColls(repl, coll) + } + forAll(shortGen, indexGen, minSuccess) { (x, n) => + val repl = builder.replicate(n, x) + val coll = builder.fromArray(Array.fill(n)(x)) + + checkColls(repl, coll) + } + forAll(intGen, indexGen, minSuccess) { (x, n) => + val repl = builder.replicate(n, x) + val coll = builder.fromArray(Array.fill(n)(x)) + + checkColls(repl, coll) + } + forAll(longGen, indexGen, minSuccess) { (x, n) => + val repl = builder.replicate(n, x) + val coll = builder.fromArray(Array.fill(n)(x)) + + checkColls(repl, coll) + } + forAll(charGen, indexGen, minSuccess) { (x, n) => + val repl = builder.replicate(n, x) + val coll = builder.fromArray(Array.fill(n)(x)) + + checkColls(repl, coll) + } + forAll(floatGen, indexGen, minSuccess) { (x, n) => + val repl = builder.replicate(n, x) + val coll = builder.fromArray(Array.fill(n)(x)) + + checkColls(repl, coll) + } + forAll (doubleGen, indexGen, minSuccess) { (x, n) => + val repl = builder.replicate(n, x) + val coll = builder.fromArray(Array.fill(n)(x)) + + checkColls(repl, coll) + } + forAll (indexGen, minSuccess) { (n) => + val replTrue = builder.replicate(n, true) + val collTrue = builder.fromArray(Array.fill(n)(true)) + val replFalse = builder.replicate(n, false) + val collFalse = builder.fromArray(Array.fill(n)(false)) + + checkColls(replTrue, collTrue) + checkColls(replFalse, collFalse) + } + forAll(indexGen, minSuccess) { n => + val repl = builder.replicate(n, builder.fromItems(Array(1, 2, 3))) + val coll = builder.fromArray(Array.fill(n)(builder.fromItems(Array(1, 2, 3)))) + + checkColls(repl, coll) + } + forAll(indexGen, indexGen, minSuccess) { (n, m) => + val repl = builder.replicate(n, builder.replicate(m, 1)) + val coll = builder.fromArray(Array.fill(n)(builder.fromArray(Array.fill(m)(1)))) + + checkColls(repl, coll) + } + // This tuple tests fail with previous implementation + forAll (byteGen, doubleGen, intGen, indexGen, minSuccess) { (b, d, i, n) => + val repl = builder.replicate(n, (b, i)) + val coll = builder.fromArray(Array.fill[(Byte, Int)](n)((b, i))) + + checkColls(repl, coll) + } + forAll (byteGen, doubleGen, intGen, indexGen, minSuccess) { (b, d, i, n) => + val repl = builder.replicate(n, (b, (i, (d, b)))) + val coll = builder.fromArray(Array.fill[(Byte, (Int, (Double, Byte)))](n)((b, (i, (d, b))))) + + checkColls(repl, coll) + } + forAll (byteGen, doubleGen, intGen, indexGen, indexGen, minSuccess) { (b, d, i, n, m) => + val repl = builder.replicate(n, (b, ((i, (("string", builder.replicate(m, n)), Array(1, 2, 3, 4))), (d, b)))) + val coll = builder.fromArray(Array.fill(n)((b, ((i, (("string", builder.fromArray(Array.fill(m)(n))), Array(1, 2, 3, 4))), (d, b))))) + + checkColls(repl, coll) + } + } + + + property("PairColl.mapFirst") { + val minSuccess = minSuccessful(30) + + forAll(collGen, minSuccess) { col => + val pairs = col.zip(col) + pairs.mapFirst(inc).toArray shouldBe pairs.toArray.map { case (x, y) => (inc(x), y) } + pairs.mapSecond(inc).toArray shouldBe pairs.toArray.map { case (x, y) => (x, inc(y)) } + } + } + + property("Coll.unionSet") { + forAll(collGen, collGen) { (col1, col2) => + val res = col1.unionSet(col2) + res.toArray shouldBe (col1.toArray.union(col2.toArray).distinct) + } + builder.replicate(2, 10).unionSet(builder.replicate(3, 10)).toArray shouldBe Array(10) + forAll(superGen) { + case cl1: Coll[(_, _)] => { + val res = cl1.unionSet(cl1) + res.toArray shouldBe (cl1.toArray.union(cl1.toArray).distinct) + } + case _ => assert(false, "Generator returned invalid PairColl") + } + /* TODO: simplify the above code + * match-case removal gives the following compilation error: + type mismatch; + found : special.collection.PairColl[_$1(in value res),_$2(in value res)] where type _$2(in value res), type _$1(in value res) + required: special.collection.Coll[(_$1(in method getSuperGen), _$2(in method getSuperGen))] + val res = col1.unionSet(col1) + */ + } + + property("Coll.diff") { + forAll(collGen, collGen) { (col1, col2) => + val res = col1.diff(col2) + res.toArray shouldBe (col1.toArray.diff(col2.toArray)) + } + forAll(superGen) { + case col: Coll[(_, _)] => + val res = col.diff(col) + res.toArray shouldBe (col.toArray.diff(col.toArray)) + case _ => assert(false, "Generator returned invalid PairColl") // TODO make similar gens + } + /* TODO: simplify the above code + * match-case removal gives the following compilation error: + type mismatch; + found : special.collection.PairColl[_$1(in value res),_$2(in value res)] where type _$2(in value res), type _$1(in value res) + required: special.collection.Coll[(_$1(in method getSuperGen), _$2(in method getSuperGen))] + val res = col.diff(col) + */ + builder.replicate(2, 10).diff(builder.replicate(1, 10)).toArray shouldBe Array(10) + } + + property("Coll.intersect") { + forAll(collGen, collGen) { (col1, col2) => + val res = col1.intersect(col2) + res.toArray shouldBe (col1.toArray.intersect(col2.toArray)) + } + builder.replicate(2, 10).intersect(builder.replicate(3, 10)).toArray shouldBe Array(10, 10) + } + + property("CollBuilder.xor") { + forAll(bytesGen, bytesGen) { (col1, col2) => + val n = col1.length min col2.length + val c1 = col1.take(n) + val c2 = col2.take(n) + builder.xor(c1, c2).toArray shouldBe c1.toArray.zip(c2.toArray).map { case (l,r) => (l ^ r).toByte } + } + } + + property("CollBuilder.outerJoin") { + def test(col: Coll[Int]) = { + val inner = col.indices + val rightOnly = inner.map(i => i + col.length) + val leftOnly = rightOnly.map(i => -i) + + val leftKeys = inner.append(leftOnly) + val leftValues = col.append(col.map(x => x + 2)) + + val rightKeys = inner.append(rightOnly) + val rightValues = col.append(col.map(x => x + 3)) + + val left = builder.pairColl(leftKeys, leftValues) + val right = builder.pairColl(rightKeys, rightValues) + val res = builder.outerJoin(left, right)(l => l._2 - 2, r => r._2 - 3, i => i._2._1 + 5) + val (ks, vs) = builder.unzip(res) + vs.sum(monoid) shouldBe (col.sum(monoid) * 2 + col.map(_ + 5).sum(monoid)) + } +// test(builder.fromItems(0)) +// val gen = containerOfN[Array, Int](100, choose(20, 100)) +// .map(xs => builder.fromArray(xs.distinct)) + forAll(collGen) { col => + test(col) + } + } + + property("CViewColl.correctWork") { + forAll(collGen) { coll => + val view = builder.makeView(coll, complexFunction) + val usual = coll.map(complexFunction) + view.toArray shouldBe usual.toArray + } + } + + property("Coll equality") { + val arr1 = Array[Int](1, 2, 3) + val arr2 = Array[Int](1, 2, 3) + val repl1 = Array[Int](1,1,1) + val repl2 = Array[Int](1,1,1) + val pairs1 = arr1.zip(repl1) + val replPairs = repl1.zip(repl2) + def ids = Array.tabulate(3) { i => Array.fill(32)(i.toByte) } + def replIds = Array.fill(3) { Array.fill(32)(1) } + val tokensArr = ids.zip(arr1) + case class NoShrink[T](x: T) + + + val collGen = Gen.oneOf(builder.fromArray(arr1), builder.fromArray(arr2), builder.fromItems(1, 2, 3)).map(NoShrink(_)) + val replGen = Gen.oneOf(builder.fromArray(repl1), builder.replicate(3, 1)).map(NoShrink(_)) + val idsGen = Gen.oneOf(builder.fromArray(ids), builder.fromArray(ids)).map(NoShrink(_)) + val replIdsGen = Gen.oneOf(builder.fromArray(replIds), builder.replicate(3, Array.fill(32)(1))).map(NoShrink(_)) + + val pairsGen = Gen.oneOf( + for { c1 <- collGen; c2 <- replGen } yield builder.pairColl(c1.x, c2.x): Coll[(Int, Int)], + Gen.const(builder.fromArray(pairs1)), + Gen.const(builder.fromItems((1, 1), (2, 1), (3, 1))) + ).map(NoShrink(_)) + val replPairsGen = Gen.oneOf( + for { c1 <- replGen; c2 <- replGen } yield builder.pairColl(c1.x, c2.x): Coll[(Int, Int)], + Gen.const(builder.replicate(3, (1,1))), + Gen.const(builder.fromArray(replPairs)) + ).map(NoShrink(_)) + + val tokensGen = Gen.oneOf( + for { c1 <- idsGen; c2 <- collGen } yield builder.pairColl(c1.x, c2.x): Coll[(Array[Byte], Int)], + Gen.const(builder.fromArray(tokensArr)), + Gen.const(builder.fromItems(tokensArr(0), tokensArr(1), tokensArr(2))) + ).map(NoShrink(_)) + + val minSuccess = MinSuccessful(30) + + forAll(collGen, collGen, minSuccess) { (c1, c2) => + assert(c1.x == c2.x) + assert(c2.x == c1.x) + } + forAll(replGen, replGen, minSuccess) { (c1, c2) => + assert(c1.x == c2.x) + assert(c2.x == c1.x) + } + forAll(collGen, replGen, minSuccess) { (c1, c2) => + assert(c1.x != c2.x) + assert(c2.x != c1.x) + } + forAll(pairsGen, pairsGen, minSuccess) { (c1, c2) => + assert(c1.x == c2.x) + assert(c2.x == c1.x) + } + forAll(replPairsGen, replPairsGen, minSuccess) { (c1, c2) => + assert(c1.x == c2.x) + assert(c2.x == c1.x) +// println(s"c1=$c1; c2=$c2") + } + + forAll(idsGen, idsGen, minSuccess) { (c1, c2) => + assert(c1.x == c2.x) + assert(c2.x == c1.x) +// println(s"c1=$c1; c2=$c2") + } + + forAll(replIdsGen, replIdsGen, minSuccess) { (c1, c2) => + assert(c1.x == c2.x) + assert(c2.x == c1.x) +// println(s"c1=$c1; c2=$c2") + } + + forAll(tokensGen, tokensGen, minSuccess) { (c1, c2) => + assert(c1.x == c2.x) + assert(c2.x == c1.x) +// println(s"c1=$c1; c2=$c2") + } + +// TODO the following test fails because equality of Seq is not deep, and nested arrays are shallow compared +// forAll(tokensGen, minSuccess) { c1 => +// println(s"c1=${c1.x.toArray.toSeq.map { case (id, v) => (id.toSeq, v) }}") +// val tokens = c1.x +// assert(tokens.toArray.toSeq == tokensArr.toSeq) +// } + } + +} diff --git a/library/src/test/scala/special/collections/CostedTests.scala b/library/src/test/scala/special/collections/CostedTests.scala new file mode 100644 index 0000000000..ba9efb36d8 --- /dev/null +++ b/library/src/test/scala/special/collections/CostedTests.scala @@ -0,0 +1,83 @@ +package special.collections + +import scala.collection.mutable +import scala.language.reflectiveCalls +import scalan.util.BenchmarkUtil._ +import special.SpecialPredef + +class CostedTests extends BaseCostedTests { + + class ThisCtx extends Ctx { + } + lazy val ctx = new ThisCtx + import ctx._ + import CSizePrim._ + import CSizePair._ + import CSizeColl._ + import CSizeOption._ + import Costed._ + import CCostedPair._ + import CCostedPrim._ + import CCostedColl._ + import CCostedOption._ + import CollBuilder._ + import CostedBuilder._ + import Coll._ + import WOption._ + import WSpecialPredef._ + import Liftables._ + + def buildGraph[T](nIters: Int, name: String)(action: Int => Ref[T]) = { + val buf = mutable.ArrayBuilder.make[Ref[T]]() + measure(nIters) { i => + buf += action(i) + } + ctx.emit(name, buf.result(): _*) + } + + lazy val l = toRep(10) + lazy val r = toRep(10.toByte) + lazy val lC = RCCostedPrim(l, 1, RCSizePrim(4L, element[Int])) + lazy val rC = RCCostedPrim(r, 1, RCSizePrim(1L, element[Byte])) + lazy val pC = RCCostedPair(lC, rC, 1) + lazy val ppC = RCCostedPair(pC, pC, 1) + + ignore("dataSize of CostedPair") { + val sizeD= pC.size + val expected = RCSizePair(RCSizePrim(4L, element[Int]), RCSizePrim(1L, element[Byte])) + sizeD shouldBe expected + } + + ignore("dataSize of nested CostedPair") { + val sizeD= ppC.size + val ppSize = pC.size + val expected = RCSizePair(ppSize, ppSize) + sizeD shouldBe expected + } + + val Colls = new special.collection.CollOverArrayBuilder + val xs = Colls.fromItems(10, 20, 30) + lazy val xsSym: Ref[Coll[Int]] = liftConst(xs) + lazy val xsCosts = liftConst(Colls.replicate(3, 0)) + lazy val IntSize: RSize[Int] = costedBuilder.mkSizePrim(4L, element[Int]) + lazy val xsSizes = colBuilder.replicate(3, IntSize) + lazy val xsC = costedBuilder.mkCostedColl(xsSym, xsCosts, xsSizes, 0) + + test("dataSize of CostedColl") { + val sizeD = xsC.size + val expected = RCSizeColl(xsSizes) + sizeD shouldBe expected + } + + val opt: Option[Int] = Some(10) + lazy val optSym = liftConst(opt) + lazy val optSize = RWSpecialPredef.some(IntSize) + lazy val optC = costedBuilder.mkCostedOption(optSym, RWSpecialPredef.some(0), optSize, 0) + + test("dataSize of CostedOption") { + val sizeD = optC.size + val expected = RCSizeOption(optSize) + sizeD shouldBe expected + } + +} diff --git a/library/src/test/scala/special/collections/ExampleGens.scala b/library/src/test/scala/special/collections/ExampleGens.scala new file mode 100644 index 0000000000..4b1b06495e --- /dev/null +++ b/library/src/test/scala/special/collections/ExampleGens.scala @@ -0,0 +1,33 @@ +package special.collections + +import special.collection.Coll +import scalan.util.CollectionUtil._ +import scalan.RType._ + +trait ExampleGens extends CollGens { + import Examples._ + import org.scalacheck.Gen._ + import org.scalacheck.Arbitrary._ + + val genId = containerOfN[Coll, Byte](1, choose[Byte](1, Byte.MaxValue)) + val availableTokenIds = Range(0,10).map(_ => genId.sample.get).distinct + + val genTokenId = oneOf(availableTokenIds) + val genTokenValue = choose[Long](0, 100) + val genTokenData = for { + id <- genTokenId + value <- genTokenValue + } yield (id, value) + + val genBox = for { + id <- genId + tokens <- containerOfN[Coll, TokenData](5, genTokenData).map(_.distinctByKey) + } yield Box(id, tokens) + + val genContext = for { + inputs <- containerOfN[Coll, Box](5, genBox) + outputs <- containerOfN[Coll, Box](5, genBox) + iSelf <- choose(0, inputs.length) + } + yield Context(inputs, outputs, iSelf) +} diff --git a/library/src/test/scala/special/collections/Examples.scala b/library/src/test/scala/special/collections/Examples.scala new file mode 100644 index 0000000000..95c3ddf900 --- /dev/null +++ b/library/src/test/scala/special/collections/Examples.scala @@ -0,0 +1,68 @@ +package special.collections + +import scalan.RType +import special.collection.{Coll, CollBuilder} + +import scala.reflect.{ClassTag, classTag} + +class Examples(builder: CollBuilder) { + import builder._ + import Examples._ + import special.collection.ExtensionMethods._ + implicit val longMonoid = Monoids.longPlusMonoid + + def checkTokenBalance(ctx: Context): Boolean = { + val input = ctx.inputs.flatMap(_.tokens).sumByKey + val output = ctx.outputs.flatMap(_.tokens).sumByKey + val flagged = outerJoin(input, output)( + onlyIn => false, + onlyOut => false, + { case (tokenId, (inV, outV)) => inV == outV }) + flagged.forall { case (tokenId, ok) => ok } + } + + def tokenTotal1(ctx: Context, tokenId: TokenId): Long = { + val tokenValues = ctx.inputs.flatMap(box => box.tokens.filter(t => t._1 == tokenId).map(t => t._2)) + tokenValues.sum(longMonoid) + } + def tokenTotal2(ctx: Context, tokenId: TokenId): Long = { + val tokenRecords = ctx.inputs.flatMap(box => box.tokens) + val selectedTokens = tokenRecords.filter(t => t._1 == tokenId) + selectedTokens.map(_._2).sum(longMonoid) + } + def tokenTotal3(ctx: Context, tokenId: TokenId): Long = { + val tokenValues = ctx.inputs.map { box => + val optToken = box.tokens.find(t => t._1 == tokenId) + optToken.map(t => t._2).getOrElse(0L) + } + tokenValues.sum(longMonoid) + } +} + +object Examples { + type IdType = Coll[Byte] + type TokenId = IdType + type TokenData = (TokenId, Long) + case class Box(id: IdType, tokens: Coll[TokenData]) { + override def toString: String = { + val idVal = id.toArray(0) + val tokenStr = tokens.map(t => s"${t._1.toArray(0)}->${t._2}").toArray.mkString("[", ";", "]") + s"Box{id=$idVal; tokens=$tokenStr}" + } + } + implicit val boxType = RType.fromClassTag(classTag[Box]) + case class Context(inputs: Coll[Box], outputs: Coll[Box], selfBoxIndex: Int) { + override def toString: String = { + s"""Ctx { + | inputs=[ + | ${inputs.toArray.mkString(";\n ")} + | ] + | outputs=[ + | ${outputs.toArray.mkString(";\n ")} + | ] + | self=$selfBoxIndex + |} + """.stripMargin + } + } +} diff --git a/library/src/test/scala/special/collections/ExamplesBenchmark.scala b/library/src/test/scala/special/collections/ExamplesBenchmark.scala new file mode 100644 index 0000000000..e8655d2172 --- /dev/null +++ b/library/src/test/scala/special/collections/ExamplesBenchmark.scala @@ -0,0 +1,53 @@ +package special.collections + +import scalan.util.CollectionUtil.outerJoin +import org.scalameter.api.{Bench, Gen} +import org.scalameter.picklers.noPickler._ +import scalan.util.CollectionUtil._ + +trait ExamplesBenchmarkCases extends CollGens with ExampleGens { suite: Bench[Double] => + import Examples._ + val examples = new Examples(builder) + import examples._ + val context = genContext.sample.get + val contextG = Gen.single("context")(context) + + type ContextData = (Array[Array[(Array[Byte], Long)]], Array[Array[(Array[Byte], Long)]]) + def getContextData(ctx: Context): ContextData = { + val ins = ctx.inputs.map(box => box.tokens.map(t => (t._1.toArray, t._2)).toArray).toArray + val outs = ctx.outputs.map(box => box.tokens.map(t => (t._1.toArray, t._2)).toArray).toArray + (ins, outs) + } + + def checkTokenBalanceWithData(ctx: ContextData): Boolean = { + val input = ctx._1.flatMap(ts => ts).toIterable.mapReduce[Array[Byte], Long](t => t)((a,b) => a + b).toMap + val output = ctx._2.flatMap(ts => ts).toIterable.mapReduce[Array[Byte], Long](t => t)((a,b) => a + b).toMap + val flagged = outerJoin(input, output)( + (onlyIn: Array[Byte], _) => false, + (onlyOut: Array[Byte], _) => false, + { case (tokenId, inV, outV) => inV == outV }) + flagged.forall { case (tokenId, ok) => ok } + } + + val contextData = getContextData(context) + val contextDataG = Gen.single("contextData")(contextData) + + require(checkTokenBalanceWithData(contextData) == checkTokenBalance(context)) + + performance of "Examples" in { + measure method "checkTokenBalanceWithData" in { + using(contextDataG) in { + ctx => checkTokenBalanceWithData(ctx) + } + } + measure method "checkTokenBalance" in { + using(contextG) in { + ctx => checkTokenBalance(ctx) + } + } + } +} + +object FastExamplesBenchmark extends Bench.LocalTime with ExamplesBenchmarkCases { +} + diff --git a/library/src/test/scala/special/collections/ExamplesTests.scala b/library/src/test/scala/special/collections/ExamplesTests.scala new file mode 100644 index 0000000000..e7f5c992e6 --- /dev/null +++ b/library/src/test/scala/special/collections/ExamplesTests.scala @@ -0,0 +1,27 @@ +package special.collections + +import org.scalatest.prop.PropertyChecks +import org.scalatest.{Matchers, PropSpec} + +class ExamplesTests extends PropSpec with PropertyChecks with Matchers with CollGens with ExampleGens { testSuite => + import Examples._ + val examples = new Examples(builder) + import examples._ + + property("checkTokenBalance") { + forAll(genContext) { ctx => + checkTokenBalance(ctx) + } + } + + property("tokenTotal") { + forAll(genContext) { ctx => + val tokenId = ctx.inputs(0).tokens(0)._1 + val t1 = tokenTotal1(ctx, tokenId) + val t2 = tokenTotal2(ctx, tokenId) + val t3 = tokenTotal3(ctx, tokenId) + t1 shouldBe t2 + t2 shouldBe t3 + } + } +} diff --git a/library/src/test/scala/special/collections/MapBenchmark.scala b/library/src/test/scala/special/collections/MapBenchmark.scala new file mode 100644 index 0000000000..1c8668c2a4 --- /dev/null +++ b/library/src/test/scala/special/collections/MapBenchmark.scala @@ -0,0 +1,86 @@ +package special.collections + +import org.scalameter.api.Bench +import scalan.{AVHashMap, Nullable} +import spire.syntax.all.cfor + +trait MapBenchmarkCases extends BenchmarkGens { suite: Bench[Double] => + val obj = new Object() + var xOpt: Option[Object] = None + var xNullable: Nullable[Object] = Nullable.None + performance of "put[Object]" in { + measure method "of debox.Map" in { + using(arrays) in { case (arr, n) => + val m = debox.Map.ofSize[Int, Object](10000) + val limit = arr.length + cfor(0)(_ < limit, _ + 1) { i => + m.update(limit - i, obj) + } + } + } + measure method "of AVHashMap" in { + using(arrays) in { case (arr, n) => + val m = AVHashMap[Int, Object](10000) + val limit = arr.length + cfor(0)(_ < limit, _ + 1) { i => + m.put(limit - i, obj) + } + } + } + measure method "of immutable.Map" in { + var res: Map[Int, Object] = null + using(arrays) in { case (arr, n) => + var m = Map.empty[Int, Object] + val limit = arr.length + cfor(0)(_ < limit, _ + 1) { i => + m = m + ((limit - i, obj)) + } + res = m + } + } + } + + performance of "get[Object]" in { + measure method "of debox.Map" in { + val m = debox.Map.ofSize[Int, Object](maxSize) + var x: Option[Object] = None + cfor(0)(_ < maxSize, _ + 1) { i => + m.update(i, obj) + } + using(arrays) in { case (arr, n) => + val limit = arr.length + cfor(0)(_ < limit, _ + 1) { i => + x = m.get(i * 13 % limit) + } + } + } + measure method "of AVHashMap" in { + val m = AVHashMap[Int, Object](maxSize) + cfor(0)(_ < maxSize, _ + 1) { i => + m.put(i, obj) + } + using(arrays) in { case (arr, n) => + val limit = arr.length + cfor(0)(_ < limit, _ + 1) { i => + xNullable = m.get(i * 13 % limit) + } + } + } + measure method "of immutable.Map" in { + var m = Map.empty[Int, Object] + cfor(0)(_ < maxSize, _ + 1) { i => + m = m + ((i, obj)) + } + using(arrays) in { case (arr, n) => + val limit = arr.length + cfor(0)(_ < limit, _ + 1) { i => + xOpt = m.get(i * 13 % limit) + } + } + } + } +} + +object FastMapBenchmark extends Bench.LocalTime with MapBenchmarkCases { +} + diff --git a/library/src/test/scala/special/collections/SymBenchmark.scala b/library/src/test/scala/special/collections/SymBenchmark.scala new file mode 100644 index 0000000000..6bd42711c1 --- /dev/null +++ b/library/src/test/scala/special/collections/SymBenchmark.scala @@ -0,0 +1,73 @@ +package special.collections + +import debox.{Set => DSet, Map => DMap} +import scalan.TestLibrary +import org.scalameter.api.Bench +import spire.syntax.all.cfor + +trait SymBenchmarkCases extends BenchmarkGens { suite: Bench[Double] => + val obj = new Object() + class Ctx extends TestLibrary + val ctx = new Ctx + import ctx._ + val syms = arrays.map { case (arr, n) => arr.map(_ => placeholder[Int]) } + val symIds = syms.map { case arr => arr.map(s => s.node.nodeId) } + + performance of "Set[Sym] vs Set[Int]" in { + measure method "of add(syms(i))" in { + using(syms) in { syms => + val set = DSet.ofSize[Sym](0) + cfor(0)(_ < syms.length, _ + 1) { i => + set += syms(i) + } + } + } + measure method "of set += syms(i).rhs.nodeId" in { + using(syms) in { syms => + val set = DSet.ofSize[Int](0) + cfor(0)(_ < syms.length, _ + 1) { i => + set += syms(i).node.nodeId + } + } + } + measure method "of set += (ids(i)" in { + using(symIds) in { ids => + val set = DSet.ofSize[Int](0) + cfor(0)(_ < ids.length, _ + 1) { i => + set += ids(i) + } + } + } + } + + performance of "Map[Sym, Object] vs Map[Int, Object]" in { + measure method "of m.update(syms(i), obj)" in { + using(syms) in { syms => + val m = DMap.ofSize[Sym, Object](0) + cfor(0)(_ < syms.length, _ + 1) { i => + m.update(syms(i), obj) + } + } + } + measure method "of m.update(syms(i).rhs.nodeId, obj)" in { + using(syms) in { syms => + val m = DMap.ofSize[Int, Object](0) + cfor(0)(_ < syms.length, _ + 1) { i => + m.update(syms(i).node.nodeId, obj) + } + } + } + measure method "of m.update(ids(i), obj)" in { + using(symIds) in { ids => + val m = DMap.ofSize[Int, Object](0) + cfor(0)(_ < ids.length, _ + 1) { i => + m.update(ids(i), obj) + } + } + } + } +} + +object FastSymBenchmark extends Bench.LocalTime with SymBenchmarkCases { +} + diff --git a/library/src/test/scala/special/wrappers/WOptionTests.scala b/library/src/test/scala/special/wrappers/WOptionTests.scala new file mode 100644 index 0000000000..95b0d27416 --- /dev/null +++ b/library/src/test/scala/special/wrappers/WOptionTests.scala @@ -0,0 +1,40 @@ +package special.wrappers + +import scala.language.reflectiveCalls +import scalan.Library + +class WOptionTests extends WrappersTests { + + test("invokeUnlifted") { + val ctx = new WrappersCtx + import ctx._ + import WOption._ + import EnvRep._ + + val opt = Option(1) + check(opt, { env: EnvRep[WOption[Int]] => for { xs <- env } yield xs.get }, opt.get) + check(opt, { env: EnvRep[WOption[Int]] => for { xs <- env } yield xs.isEmpty }, opt.isEmpty) + check(opt, { env: EnvRep[WOption[Int]] => for { xs <- env } yield xs.isDefined }, opt.isDefined) + + val none: Option[Int] = None + val th = () => 10 + check(none, { env: EnvRep[WOption[Int]] => for { xs <- env; thL <- lifted(th) } yield xs.getOrElse(thL) }, none.getOrElse(th())) + + val p = (x: Int) => x == 2 + check(opt, { env: EnvRep[WOption[Int]] => for { xs <- env; pL <- lifted(p) } yield xs.filter(pL) }, opt.filter(p)) + + val inc = (x: Int) => x + 1 + check(opt, { env: EnvRep[WOption[Int]] => + for { xs <- env; thL <- lifted(th); incL <- lifted(inc) } yield xs.fold(thL, incL) }, + opt.fold(th())(inc)) + + check(none, { env: EnvRep[WOption[Int]] => + for { xs <- env; thL <- lifted(th); incL <- lifted(inc) } yield xs.fold(thL, incL) }, none.fold(th())(inc)) + check(opt, { env: EnvRep[WOption[Int]] => for { xs <- env; incL <- lifted(inc) } yield xs.map(incL) }, opt.map(inc)) + + val incOpt = (x: Int) => Option(x + 1) + val incNone = (x: Int) => (None: Option[Int]) + check(opt, { env: EnvRep[WOption[Int]] => for { xs <- env; incOptL <- lifted(incOpt)} yield xs.flatMap(incOptL) }, opt.flatMap(incOpt)) + check(opt, { env: EnvRep[WOption[Int]] => for { xs <- env; incNoneL <- lifted(incNone)} yield xs.flatMap(incNoneL) }, opt.flatMap(incNone)) + } +} diff --git a/library/src/test/scala/special/wrappers/WRTypeTests.scala b/library/src/test/scala/special/wrappers/WRTypeTests.scala new file mode 100644 index 0000000000..0378e7fbc3 --- /dev/null +++ b/library/src/test/scala/special/wrappers/WRTypeTests.scala @@ -0,0 +1,28 @@ +package special.wrappers + +import scalan.RType + +import scala.language.reflectiveCalls + +class WRTypeTests extends WrappersTests { + + lazy val ctx = new WrappersCtx + import ctx._ + import Coll._ + import WRType._ + import EnvRep._ + import Liftables._ + + test("invokeUnlifted") { + val ty = RType[Int] + check(ty, { env: EnvRep[WRType[Int]] => for { xs <- env } yield xs.name }, ty.name) + } + + test("Implicit conversion from RType to Elem") { + val eInt: Elem[Int] = RType.IntType + eInt shouldBe IntElement + + val ePair: Elem[(Int, Coll[Byte])] = RType[(Int, SColl[Byte])] + ePair shouldBe element[(Int, Coll[Byte])] + } +} diff --git a/library/src/test/scala/special/wrappers/WSpecialPredefTests.scala b/library/src/test/scala/special/wrappers/WSpecialPredefTests.scala new file mode 100644 index 0000000000..1c62584494 --- /dev/null +++ b/library/src/test/scala/special/wrappers/WSpecialPredefTests.scala @@ -0,0 +1,42 @@ +package special.wrappers + + +import scala.language.reflectiveCalls +import scalan.RType + +class WSpecialPredefTests extends WrappersTests { + + lazy val ctx = new WrappersCtx + import ctx._ + import WSpecialPredef._ + import CCostedBuilder._ + import CostedBuilder._ + + lazy val SPCM = WSpecialPredefCompanionMethods + lazy val CCB = CostedBuilderMethods + + test("some") { + val x: Ref[Int] = 10 + val opt = RWSpecialPredef.some(x) + opt match { + case SPCM.some(_x) => _x shouldBe x + case _ => assert(false) + } + } + + test("costedValue") { + val cost: Ref[Int] = 10 + val optCost = RWSpecialPredef.some(cost) + val b: Ref[CostedBuilder] = RCCostedBuilder() + val x: Ref[Long] = 1L + val value = b.costedValue(x, optCost) + value match { + case CCB.costedValue(_b, _x, SPCM.some(_cost)) => + _b shouldBe b + _x shouldBe x + _cost shouldBe cost + case _ => assert(false) + } + } + +} diff --git a/library/src/test/scala/special/wrappers/WrappersTests.scala b/library/src/test/scala/special/wrappers/WrappersTests.scala new file mode 100644 index 0000000000..600714f96d --- /dev/null +++ b/library/src/test/scala/special/wrappers/WrappersTests.scala @@ -0,0 +1,9 @@ +package special.wrappers + +import scalan.{BaseLiftableTests, TestLibrary, BaseCtxTests} + +/** Base class inhereted by test suite for each wrapper like WOption etc. */ +abstract class WrappersTests extends BaseCtxTests with BaseLiftableTests { + class WrappersCtx extends TestContext with TestLibrary with LiftableTestKit { + } +} diff --git a/project/plugins.sbt b/project/plugins.sbt index d4e535a944..0c2445295a 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -6,4 +6,6 @@ addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.9.0") addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "1.0.0") addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.9.2") addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.5.1") -addSbtPlugin("org.scoverage" % "sbt-coveralls" % "1.2.7") \ No newline at end of file +addSbtPlugin("org.scoverage" % "sbt-coveralls" % "1.2.7") +addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.8") +addSbtPlugin("com.jsuereth" % "sbt-pgp" % "2.0.0") \ No newline at end of file diff --git a/sigma-api/src/main/resources/special/sigma/CostedObjects.scalan b/sigma-api/src/main/resources/special/sigma/CostedObjects.scalan index 3baf3cc56a..cdde69cdb2 100644 --- a/sigma-api/src/main/resources/special/sigma/CostedObjects.scalan +++ b/sigma-api/src/main/resources/special/sigma/CostedObjects.scalan @@ -17,35 +17,35 @@ package special.sigma { import SizeContext._; import WOption._; import WRType._; - @Liftable trait SizeAnyValue extends Size[AnyValue] { - def tVal: Rep[WRType[Any]]; - def valueSize: Rep[Size[Any]] + @Liftable @WithMethodCallRecognizers trait SizeAnyValue extends Size[AnyValue] { + def tVal: Ref[WRType[Any]]; + def valueSize: Ref[Size[Any]] }; - @Liftable trait SizeSigmaProp extends Size[SigmaProp] { - def propBytes: Rep[Size[Coll[Byte]]] + @Liftable @WithMethodCallRecognizers trait SizeSigmaProp extends Size[SigmaProp] { + def propBytes: Ref[Size[Coll[Byte]]] }; - @Liftable trait SizeBox extends Size[Box] { - def propositionBytes: Rep[Size[Coll[Byte]]]; - def bytes: Rep[Size[Coll[Byte]]]; - def bytesWithoutRef: Rep[Size[Coll[Byte]]]; - def registers: Rep[Size[Coll[WOption[AnyValue]]]]; - def getReg[T](id: Rep[Byte])(implicit tT: Elem[T]): Rep[Size[WOption[T]]]; - def tokens: Rep[Size[Coll[scala.Tuple2[Coll[Byte], Long]]]] + @Liftable @WithMethodCallRecognizers trait SizeBox extends Size[Box] { + def propositionBytes: Ref[Size[Coll[Byte]]]; + def bytes: Ref[Size[Coll[Byte]]]; + def bytesWithoutRef: Ref[Size[Coll[Byte]]]; + def registers: Ref[Size[Coll[WOption[AnyValue]]]]; + def getReg[T](id: Ref[Byte])(implicit tT: Elem[T]): Ref[Size[WOption[T]]]; + def tokens: Ref[Size[Coll[scala.Tuple2[Coll[Byte], Long]]]] }; - @Liftable trait SizeContext extends Size[Context] { - def outputs: Rep[Size[Coll[Box]]]; - def inputs: Rep[Size[Coll[Box]]]; - def dataInputs: Rep[Size[Coll[Box]]]; - def selfBox: Rep[Size[Box]]; - def lastBlockUtxoRootHash: Rep[Size[AvlTree]]; - def headers: Rep[Size[Coll[Header]]]; - def preHeader: Rep[Size[PreHeader]]; - def getVar[T](id: Rep[Byte])(implicit tT: Elem[T]): Rep[Size[WOption[T]]] + @Liftable @WithMethodCallRecognizers trait SizeContext extends Size[Context] { + def outputs: Ref[Size[Coll[Box]]]; + def inputs: Ref[Size[Coll[Box]]]; + def dataInputs: Ref[Size[Coll[Box]]]; + def selfBox: Ref[Size[Box]]; + def lastBlockUtxoRootHash: Ref[Size[AvlTree]]; + def headers: Ref[Size[Coll[Header]]]; + def preHeader: Ref[Size[PreHeader]]; + def getVar[T](id: Ref[Byte])(implicit tT: Elem[T]): Ref[Size[WOption[T]]] }; @Liftable trait SizeBuilder extends Def[SizeBuilder] { - def mkSizeAnyValue(tVal: Rep[WRType[Any]], valueSize: Rep[Size[Any]]): Rep[SizeAnyValue]; - def mkSizeBox(propositionBytes: Rep[Size[Coll[Byte]]], bytes: Rep[Size[Coll[Byte]]], bytesWithoutRef: Rep[Size[Coll[Byte]]], registers: Rep[Size[Coll[WOption[AnyValue]]]], tokens: Rep[Size[Coll[scala.Tuple2[Coll[Byte], Long]]]]): Rep[SizeBox]; - def mkSizeContext(outputs: Rep[Size[Coll[Box]]], inputs: Rep[Size[Coll[Box]]], dataInputs: Rep[Size[Coll[Box]]], selfBox: Rep[Size[Box]], lastBlockUtxoRootHash: Rep[Size[AvlTree]], headers: Rep[Size[Coll[Header]]], preHeader: Rep[Size[PreHeader]], vars: Rep[Coll[Size[AnyValue]]]): Rep[SizeContext] + def mkSizeAnyValue(tVal: Ref[WRType[Any]], valueSize: Ref[Size[Any]]): Ref[SizeAnyValue]; + def mkSizeBox(propositionBytes: Ref[Size[Coll[Byte]]], bytes: Ref[Size[Coll[Byte]]], bytesWithoutRef: Ref[Size[Coll[Byte]]], registers: Ref[Size[Coll[WOption[AnyValue]]]], tokens: Ref[Size[Coll[scala.Tuple2[Coll[Byte], Long]]]]): Ref[SizeBox]; + def mkSizeContext(outputs: Ref[Size[Coll[Box]]], inputs: Ref[Size[Coll[Box]]], dataInputs: Ref[Size[Coll[Box]]], selfBox: Ref[Size[Box]], lastBlockUtxoRootHash: Ref[Size[AvlTree]], headers: Ref[Size[Coll[Header]]], preHeader: Ref[Size[PreHeader]], vars: Ref[Coll[Size[AnyValue]]]): Ref[SizeContext] }; trait SizeAnyValueCompanion; trait SizeSigmaPropCompanion; diff --git a/sigma-api/src/main/resources/special/sigma/SigmaDsl.scalan b/sigma-api/src/main/resources/special/sigma/SigmaDsl.scalan index b366a6829c..b846712fc2 100644 --- a/sigma-api/src/main/resources/special/sigma/SigmaDsl.scalan +++ b/sigma-api/src/main/resources/special/sigma/SigmaDsl.scalan @@ -18,196 +18,193 @@ package special.sigma { import SigmaContract._; import SigmaDslBuilder._; import SigmaProp._; - import WBigInteger._; import WOption._; import WRType._; @Liftable trait CostModel extends Def[CostModel] { - def AccessBox: Rep[Int]; - def AccessAvlTree: Rep[Int]; - def GetVar: Rep[Int]; - def DeserializeVar: Rep[Int]; - def GetRegister: Rep[Int]; - def DeserializeRegister: Rep[Int]; - def SelectField: Rep[Int]; - def CollectionConst: Rep[Int]; - def AccessKiloByteOfData: Rep[Int]; - @Reified(value = "T") def dataSize[T](x: Rep[T])(implicit cT: Elem[T]): Rep[Long]; - def PubKeySize: Rep[Long] + def AccessBox: Ref[Int]; + def AccessAvlTree: Ref[Int]; + def GetVar: Ref[Int]; + def DeserializeVar: Ref[Int]; + def GetRegister: Ref[Int]; + def DeserializeRegister: Ref[Int]; + def SelectField: Ref[Int]; + def CollectionConst: Ref[Int]; + def AccessKiloByteOfData: Ref[Int]; + def PubKeySize: Ref[Long] }; - @Liftable trait BigInt extends Def[BigInt] { - def toByte: Rep[Byte]; - def toShort: Rep[Short]; - def toInt: Rep[Int]; - def toLong: Rep[Long]; - def toBytes: Rep[Coll[Byte]]; - def toBits: Rep[Coll[Boolean]]; - def toAbs: Rep[BigInt]; - def compareTo(that: Rep[BigInt]): Rep[Int]; - def modQ: Rep[BigInt]; - def plusModQ(other: Rep[BigInt]): Rep[BigInt]; - def minusModQ(other: Rep[BigInt]): Rep[BigInt]; - def multModQ(other: Rep[BigInt]): Rep[BigInt]; - def inverseModQ: Rep[BigInt]; - def signum: Rep[Int]; - def add(that: Rep[BigInt]): Rep[BigInt]; - def subtract(that: Rep[BigInt]): Rep[BigInt]; - def multiply(that: Rep[BigInt]): Rep[BigInt]; - def divide(that: Rep[BigInt]): Rep[BigInt]; - def mod(m: Rep[BigInt]): Rep[BigInt]; - def remainder(that: Rep[BigInt]): Rep[BigInt]; - def min(that: Rep[BigInt]): Rep[BigInt]; - def max(that: Rep[BigInt]): Rep[BigInt]; - def negate: Rep[BigInt] + @Liftable @WithMethodCallRecognizers trait BigInt extends Def[BigInt] { + def toByte: Ref[Byte]; + def toShort: Ref[Short]; + def toInt: Ref[Int]; + def toLong: Ref[Long]; + def toBytes: Ref[Coll[Byte]]; + def toBits: Ref[Coll[Boolean]]; + def toAbs: Ref[BigInt]; + def compareTo(that: Ref[BigInt]): Ref[Int]; + def modQ: Ref[BigInt]; + def plusModQ(other: Ref[BigInt]): Ref[BigInt]; + def minusModQ(other: Ref[BigInt]): Ref[BigInt]; + def multModQ(other: Ref[BigInt]): Ref[BigInt]; + def inverseModQ: Ref[BigInt]; + def signum: Ref[Int]; + def add(that: Ref[BigInt]): Ref[BigInt]; + def subtract(that: Ref[BigInt]): Ref[BigInt]; + def multiply(that: Ref[BigInt]): Ref[BigInt]; + def divide(that: Ref[BigInt]): Ref[BigInt]; + def mod(m: Ref[BigInt]): Ref[BigInt]; + def remainder(that: Ref[BigInt]): Ref[BigInt]; + def min(that: Ref[BigInt]): Ref[BigInt]; + def max(that: Ref[BigInt]): Ref[BigInt]; + def negate: Ref[BigInt] }; - @Liftable trait GroupElement extends Def[GroupElement] { - def isInfinity: Rep[Boolean]; - def exp(k: Rep[BigInt]): Rep[GroupElement]; - def multiply(that: Rep[GroupElement]): Rep[GroupElement]; - def negate: Rep[GroupElement]; - def getEncoded: Rep[Coll[Byte]] + @Liftable @WithMethodCallRecognizers trait GroupElement extends Def[GroupElement] { + def isInfinity: Ref[Boolean]; + def exp(k: Ref[BigInt]): Ref[GroupElement]; + def multiply(that: Ref[GroupElement]): Ref[GroupElement]; + def negate: Ref[GroupElement]; + def getEncoded: Ref[Coll[Byte]] }; - @Liftable trait SigmaProp extends Def[SigmaProp] { - def isValid: Rep[Boolean]; - def propBytes: Rep[Coll[Byte]]; - @OverloadId(value = "and_sigma") def &&(other: Rep[SigmaProp]): Rep[SigmaProp]; - @OverloadId(value = "and_bool") def &&(other: Rep[Boolean]): Rep[SigmaProp]; - @OverloadId(value = "or_sigma") def ||(other: Rep[SigmaProp]): Rep[SigmaProp]; - @OverloadId(value = "or_bool") def ||(other: Rep[Boolean]): Rep[SigmaProp] + @Liftable @WithMethodCallRecognizers trait SigmaProp extends Def[SigmaProp] { + def isValid: Ref[Boolean]; + def propBytes: Ref[Coll[Byte]]; + @OverloadId(value = "and_sigma") def &&(other: Ref[SigmaProp]): Ref[SigmaProp]; + @OverloadId(value = "and_bool") def &&(other: Ref[Boolean]): Ref[SigmaProp]; + @OverloadId(value = "or_sigma") def ||(other: Ref[SigmaProp]): Ref[SigmaProp]; + @OverloadId(value = "or_bool") def ||(other: Ref[Boolean]): Ref[SigmaProp] }; - @Liftable trait AnyValue extends Def[AnyValue] { - def value: Rep[Any]; - def tVal: Rep[WRType[Any]] + @Liftable @WithMethodCallRecognizers trait AnyValue extends Def[AnyValue] { + def value: Ref[Any]; + def tVal: Ref[WRType[Any]] }; - @Liftable trait Box extends Def[Box] { - def id: Rep[Coll[Byte]]; - def value: Rep[Long]; - def propositionBytes: Rep[Coll[Byte]]; - def bytes: Rep[Coll[Byte]]; - def bytesWithoutRef: Rep[Coll[Byte]]; - def registers: Rep[Coll[AnyValue]]; - def getReg[T](i: Rep[Int])(implicit cT: Elem[T]): Rep[WOption[T]]; - def R0[T](implicit cT: Elem[T]): Rep[WOption[T]] = this.getReg[T](toRep(0.asInstanceOf[Int])); - def R1[T](implicit cT: Elem[T]): Rep[WOption[T]] = this.getReg[T](toRep(1.asInstanceOf[Int])); - def R2[T](implicit cT: Elem[T]): Rep[WOption[T]] = this.getReg[T](toRep(2.asInstanceOf[Int])); - def R3[T](implicit cT: Elem[T]): Rep[WOption[T]] = this.getReg[T](toRep(3.asInstanceOf[Int])); - def R4[T](implicit cT: Elem[T]): Rep[WOption[T]] = this.getReg[T](toRep(4.asInstanceOf[Int])); - def R5[T](implicit cT: Elem[T]): Rep[WOption[T]] = this.getReg[T](toRep(5.asInstanceOf[Int])); - def R6[T](implicit cT: Elem[T]): Rep[WOption[T]] = this.getReg[T](toRep(6.asInstanceOf[Int])); - def R7[T](implicit cT: Elem[T]): Rep[WOption[T]] = this.getReg[T](toRep(7.asInstanceOf[Int])); - def R8[T](implicit cT: Elem[T]): Rep[WOption[T]] = this.getReg[T](toRep(8.asInstanceOf[Int])); - def R9[T](implicit cT: Elem[T]): Rep[WOption[T]] = this.getReg[T](toRep(9.asInstanceOf[Int])); - def tokens: Rep[Coll[scala.Tuple2[Coll[Byte], Long]]]; - def creationInfo: Rep[scala.Tuple2[Int, Coll[Byte]]]; - def executeFromRegister[T](regId: Rep[Byte])(implicit cT: Elem[T]): Rep[T] + @Liftable @WithMethodCallRecognizers trait Box extends Def[Box] { + def id: Ref[Coll[Byte]]; + def value: Ref[Long]; + def propositionBytes: Ref[Coll[Byte]]; + def bytes: Ref[Coll[Byte]]; + def bytesWithoutRef: Ref[Coll[Byte]]; + def registers: Ref[Coll[AnyValue]]; + def getReg[T](i: Ref[Int])(implicit cT: Elem[T]): Ref[WOption[T]]; + def R0[T](implicit cT: Elem[T]): Ref[WOption[T]] = this.getReg[T](toRep(0.asInstanceOf[Int])); + def R1[T](implicit cT: Elem[T]): Ref[WOption[T]] = this.getReg[T](toRep(1.asInstanceOf[Int])); + def R2[T](implicit cT: Elem[T]): Ref[WOption[T]] = this.getReg[T](toRep(2.asInstanceOf[Int])); + def R3[T](implicit cT: Elem[T]): Ref[WOption[T]] = this.getReg[T](toRep(3.asInstanceOf[Int])); + def R4[T](implicit cT: Elem[T]): Ref[WOption[T]] = this.getReg[T](toRep(4.asInstanceOf[Int])); + def R5[T](implicit cT: Elem[T]): Ref[WOption[T]] = this.getReg[T](toRep(5.asInstanceOf[Int])); + def R6[T](implicit cT: Elem[T]): Ref[WOption[T]] = this.getReg[T](toRep(6.asInstanceOf[Int])); + def R7[T](implicit cT: Elem[T]): Ref[WOption[T]] = this.getReg[T](toRep(7.asInstanceOf[Int])); + def R8[T](implicit cT: Elem[T]): Ref[WOption[T]] = this.getReg[T](toRep(8.asInstanceOf[Int])); + def R9[T](implicit cT: Elem[T]): Ref[WOption[T]] = this.getReg[T](toRep(9.asInstanceOf[Int])); + def tokens: Ref[Coll[scala.Tuple2[Coll[Byte], Long]]]; + def creationInfo: Ref[scala.Tuple2[Int, Coll[Byte]]]; + def executeFromRegister[T](regId: Ref[Byte])(implicit cT: Elem[T]): Ref[T] }; @Liftable trait AvlTree extends Def[AvlTree] { - def digest: Rep[Coll[Byte]]; - def enabledOperations: Rep[Byte]; - def keyLength: Rep[Int]; - def valueLengthOpt: Rep[WOption[Int]]; - def isInsertAllowed: Rep[Boolean]; - def isUpdateAllowed: Rep[Boolean]; - def isRemoveAllowed: Rep[Boolean]; - def updateDigest(newDigest: Rep[Coll[Byte]]): Rep[AvlTree]; - def updateOperations(newOperations: Rep[Byte]): Rep[AvlTree]; - def contains(key: Rep[Coll[Byte]], proof: Rep[Coll[Byte]]): Rep[Boolean]; - def get(key: Rep[Coll[Byte]], proof: Rep[Coll[Byte]]): Rep[WOption[Coll[Byte]]]; - def getMany(keys: Rep[Coll[Coll[Byte]]], proof: Rep[Coll[Byte]]): Rep[Coll[WOption[Coll[Byte]]]]; - def insert(operations: Rep[Coll[scala.Tuple2[Coll[Byte], Coll[Byte]]]], proof: Rep[Coll[Byte]]): Rep[WOption[AvlTree]]; - def update(operations: Rep[Coll[scala.Tuple2[Coll[Byte], Coll[Byte]]]], proof: Rep[Coll[Byte]]): Rep[WOption[AvlTree]]; - def remove(operations: Rep[Coll[Coll[Byte]]], proof: Rep[Coll[Byte]]): Rep[WOption[AvlTree]] + def digest: Ref[Coll[Byte]]; + def enabledOperations: Ref[Byte]; + def keyLength: Ref[Int]; + def valueLengthOpt: Ref[WOption[Int]]; + def isInsertAllowed: Ref[Boolean]; + def isUpdateAllowed: Ref[Boolean]; + def isRemoveAllowed: Ref[Boolean]; + def updateDigest(newDigest: Ref[Coll[Byte]]): Ref[AvlTree]; + def updateOperations(newOperations: Ref[Byte]): Ref[AvlTree]; + def contains(key: Ref[Coll[Byte]], proof: Ref[Coll[Byte]]): Ref[Boolean]; + def get(key: Ref[Coll[Byte]], proof: Ref[Coll[Byte]]): Ref[WOption[Coll[Byte]]]; + def getMany(keys: Ref[Coll[Coll[Byte]]], proof: Ref[Coll[Byte]]): Ref[Coll[WOption[Coll[Byte]]]]; + def insert(operations: Ref[Coll[scala.Tuple2[Coll[Byte], Coll[Byte]]]], proof: Ref[Coll[Byte]]): Ref[WOption[AvlTree]]; + def update(operations: Ref[Coll[scala.Tuple2[Coll[Byte], Coll[Byte]]]], proof: Ref[Coll[Byte]]): Ref[WOption[AvlTree]]; + def remove(operations: Ref[Coll[Coll[Byte]]], proof: Ref[Coll[Byte]]): Ref[WOption[AvlTree]] }; @Liftable trait PreHeader extends Def[PreHeader] { - def version: Rep[Byte]; - def parentId: Rep[Coll[Byte]]; - def timestamp: Rep[Long]; - def nBits: Rep[Long]; - def height: Rep[Int]; - def minerPk: Rep[GroupElement]; - def votes: Rep[Coll[Byte]] + def version: Ref[Byte]; + def parentId: Ref[Coll[Byte]]; + def timestamp: Ref[Long]; + def nBits: Ref[Long]; + def height: Ref[Int]; + def minerPk: Ref[GroupElement]; + def votes: Ref[Coll[Byte]] }; @Liftable trait Header extends Def[Header] { - def id: Rep[Coll[Byte]]; - def version: Rep[Byte]; - def parentId: Rep[Coll[Byte]]; - def ADProofsRoot: Rep[Coll[Byte]]; - def stateRoot: Rep[AvlTree]; - def transactionsRoot: Rep[Coll[Byte]]; - def timestamp: Rep[Long]; - def nBits: Rep[Long]; - def height: Rep[Int]; - def extensionRoot: Rep[Coll[Byte]]; - def minerPk: Rep[GroupElement]; - def powOnetimePk: Rep[GroupElement]; - def powNonce: Rep[Coll[Byte]]; - def powDistance: Rep[BigInt]; - def votes: Rep[Coll[Byte]] + def id: Ref[Coll[Byte]]; + def version: Ref[Byte]; + def parentId: Ref[Coll[Byte]]; + def ADProofsRoot: Ref[Coll[Byte]]; + def stateRoot: Ref[AvlTree]; + def transactionsRoot: Ref[Coll[Byte]]; + def timestamp: Ref[Long]; + def nBits: Ref[Long]; + def height: Ref[Int]; + def extensionRoot: Ref[Coll[Byte]]; + def minerPk: Ref[GroupElement]; + def powOnetimePk: Ref[GroupElement]; + def powNonce: Ref[Coll[Byte]]; + def powDistance: Ref[BigInt]; + def votes: Ref[Coll[Byte]] }; - @Liftable trait Context extends Def[Context] { - def builder: Rep[SigmaDslBuilder]; - def OUTPUTS: Rep[Coll[Box]]; - def INPUTS: Rep[Coll[Box]]; - def dataInputs: Rep[Coll[Box]]; - def HEIGHT: Rep[Int]; - def SELF: Rep[Box]; - def selfBoxIndex: Rep[Int]; - def LastBlockUtxoRootHash: Rep[AvlTree]; - def headers: Rep[Coll[Header]]; - def preHeader: Rep[PreHeader]; - def minerPubKey: Rep[Coll[Byte]]; - def getVar[T](id: Rep[Byte])(implicit cT: Elem[T]): Rep[WOption[T]]; - def vars: Rep[Coll[AnyValue]] + @Liftable @WithMethodCallRecognizers trait Context extends Def[Context] { + def builder: Ref[SigmaDslBuilder]; + def OUTPUTS: Ref[Coll[Box]]; + def INPUTS: Ref[Coll[Box]]; + def dataInputs: Ref[Coll[Box]]; + def HEIGHT: Ref[Int]; + def SELF: Ref[Box]; + def selfBoxIndex: Ref[Int]; + def LastBlockUtxoRootHash: Ref[AvlTree]; + def headers: Ref[Coll[Header]]; + def preHeader: Ref[PreHeader]; + def minerPubKey: Ref[Coll[Byte]]; + def getVar[T](id: Ref[Byte])(implicit cT: Elem[T]): Ref[WOption[T]]; + def vars: Ref[Coll[AnyValue]] }; @Liftable trait SigmaContract extends Def[SigmaContract] { - def builder: Rep[SigmaDslBuilder]; - @NeverInline @Reified(value = "T") def Collection[T](items: Rep[T]*)(implicit cT: Elem[T]): Rep[Coll[T]] = delayInvoke; - def verifyZK(cond: Rep[Thunk[SigmaProp]]): Rep[Boolean] = this.builder.verifyZK(cond); - def atLeast(bound: Rep[Int], props: Rep[Coll[SigmaProp]]): Rep[SigmaProp] = this.builder.atLeast(bound, props); - def allOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean] = this.builder.allOf(conditions); - def allZK(conditions: Rep[Coll[SigmaProp]]): Rep[SigmaProp] = this.builder.allZK(conditions); - def anyOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean] = this.builder.anyOf(conditions); - def anyZK(conditions: Rep[Coll[SigmaProp]]): Rep[SigmaProp] = this.builder.anyZK(conditions); - def xorOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean] = this.builder.xorOf(conditions); - def PubKey(base64String: Rep[String]): Rep[SigmaProp] = this.builder.PubKey(base64String); - def sigmaProp(b: Rep[Boolean]): Rep[SigmaProp] = this.builder.sigmaProp(b); - def blake2b256(bytes: Rep[Coll[Byte]]): Rep[Coll[Byte]] = this.builder.blake2b256(bytes); - def sha256(bytes: Rep[Coll[Byte]]): Rep[Coll[Byte]] = this.builder.sha256(bytes); - def byteArrayToBigInt(bytes: Rep[Coll[Byte]]): Rep[BigInt] = this.builder.byteArrayToBigInt(bytes); - def longToByteArray(l: Rep[Long]): Rep[Coll[Byte]] = this.builder.longToByteArray(l); - def byteArrayToLong(bytes: Rep[Coll[Byte]]): Rep[Long] = this.builder.byteArrayToLong(bytes); - def proveDlog(g: Rep[GroupElement]): Rep[SigmaProp] = this.builder.proveDlog(g); - def proveDHTuple(g: Rep[GroupElement], h: Rep[GroupElement], u: Rep[GroupElement], v: Rep[GroupElement]): Rep[SigmaProp] = this.builder.proveDHTuple(g, h, u, v); - def groupGenerator: Rep[GroupElement] = this.builder.groupGenerator; - @clause def canOpen(ctx: Rep[Context]): Rep[Boolean]; - def asFunction: Rep[scala.Function1[Context, Boolean]] = fun(((ctx: Rep[Context]) => this.canOpen(ctx))) + def builder: Ref[SigmaDslBuilder]; + @NeverInline @Reified(value = "T") def Collection[T](items: Ref[T]*)(implicit cT: Elem[T]): Ref[Coll[T]] = delayInvoke; + def verifyZK(cond: Ref[Thunk[SigmaProp]]): Ref[Boolean] = this.builder.verifyZK(cond); + def atLeast(bound: Ref[Int], props: Ref[Coll[SigmaProp]]): Ref[SigmaProp] = this.builder.atLeast(bound, props); + def allOf(conditions: Ref[Coll[Boolean]]): Ref[Boolean] = this.builder.allOf(conditions); + def allZK(conditions: Ref[Coll[SigmaProp]]): Ref[SigmaProp] = this.builder.allZK(conditions); + def anyOf(conditions: Ref[Coll[Boolean]]): Ref[Boolean] = this.builder.anyOf(conditions); + def anyZK(conditions: Ref[Coll[SigmaProp]]): Ref[SigmaProp] = this.builder.anyZK(conditions); + def xorOf(conditions: Ref[Coll[Boolean]]): Ref[Boolean] = this.builder.xorOf(conditions); + def PubKey(base64String: Ref[String]): Ref[SigmaProp] = this.builder.PubKey(base64String); + def sigmaProp(b: Ref[Boolean]): Ref[SigmaProp] = this.builder.sigmaProp(b); + def blake2b256(bytes: Ref[Coll[Byte]]): Ref[Coll[Byte]] = this.builder.blake2b256(bytes); + def sha256(bytes: Ref[Coll[Byte]]): Ref[Coll[Byte]] = this.builder.sha256(bytes); + def byteArrayToBigInt(bytes: Ref[Coll[Byte]]): Ref[BigInt] = this.builder.byteArrayToBigInt(bytes); + def longToByteArray(l: Ref[Long]): Ref[Coll[Byte]] = this.builder.longToByteArray(l); + def byteArrayToLong(bytes: Ref[Coll[Byte]]): Ref[Long] = this.builder.byteArrayToLong(bytes); + def proveDlog(g: Ref[GroupElement]): Ref[SigmaProp] = this.builder.proveDlog(g); + def proveDHTuple(g: Ref[GroupElement], h: Ref[GroupElement], u: Ref[GroupElement], v: Ref[GroupElement]): Ref[SigmaProp] = this.builder.proveDHTuple(g, h, u, v); + def groupGenerator: Ref[GroupElement] = this.builder.groupGenerator; + def decodePoint(encoded: Ref[Coll[Byte]]): Ref[GroupElement] = this.builder.decodePoint(encoded); + @Reified(value = "T") def substConstants[T](scriptBytes: Ref[Coll[Byte]], positions: Ref[Coll[Int]], newValues: Ref[Coll[T]])(implicit cT: Elem[T]): Ref[Coll[Byte]] = this.builder.substConstants[T](scriptBytes, positions, newValues) }; - @Liftable trait SigmaDslBuilder extends Def[SigmaDslBuilder] { - def Colls: Rep[CollBuilder]; - def Monoids: Rep[MonoidBuilder]; - def Costing: Rep[CostedBuilder]; - def CostModel: Rep[CostModel]; - def verifyZK(cond: Rep[Thunk[SigmaProp]]): Rep[Boolean]; - def atLeast(bound: Rep[Int], props: Rep[Coll[SigmaProp]]): Rep[SigmaProp]; - def allOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean]; - def allZK(conditions: Rep[Coll[SigmaProp]]): Rep[SigmaProp]; - def anyOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean]; - def anyZK(conditions: Rep[Coll[SigmaProp]]): Rep[SigmaProp]; - def xorOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean]; - def PubKey(base64String: Rep[String]): Rep[SigmaProp]; - def sigmaProp(b: Rep[Boolean]): Rep[SigmaProp]; - def blake2b256(bytes: Rep[Coll[Byte]]): Rep[Coll[Byte]]; - def sha256(bytes: Rep[Coll[Byte]]): Rep[Coll[Byte]]; - def byteArrayToBigInt(bytes: Rep[Coll[Byte]]): Rep[BigInt]; - def longToByteArray(l: Rep[Long]): Rep[Coll[Byte]]; - def byteArrayToLong(bytes: Rep[Coll[Byte]]): Rep[Long]; - def proveDlog(g: Rep[GroupElement]): Rep[SigmaProp]; - def proveDHTuple(g: Rep[GroupElement], h: Rep[GroupElement], u: Rep[GroupElement], v: Rep[GroupElement]): Rep[SigmaProp]; - def groupGenerator: Rep[GroupElement]; - @Reified(value = "T") def substConstants[T](scriptBytes: Rep[Coll[Byte]], positions: Rep[Coll[Int]], newValues: Rep[Coll[T]])(implicit cT: Elem[T]): Rep[Coll[Byte]]; - def decodePoint(encoded: Rep[Coll[Byte]]): Rep[GroupElement]; - def BigInt(n: Rep[WBigInteger]): Rep[BigInt]; - def toBigInteger(n: Rep[BigInt]): Rep[WBigInteger]; - def avlTree(operationFlags: Rep[Byte], digest: Rep[Coll[Byte]], keyLength: Rep[Int], valueLengthOpt: Rep[WOption[Int]]): Rep[AvlTree] + @Liftable @WithMethodCallRecognizers trait SigmaDslBuilder extends Def[SigmaDslBuilder] { + def Colls: Ref[CollBuilder]; + def Monoids: Ref[MonoidBuilder]; + def Costing: Ref[CostedBuilder]; + def CostModel: Ref[CostModel]; + def verifyZK(cond: Ref[Thunk[SigmaProp]]): Ref[Boolean]; + def atLeast(bound: Ref[Int], props: Ref[Coll[SigmaProp]]): Ref[SigmaProp]; + def allOf(conditions: Ref[Coll[Boolean]]): Ref[Boolean]; + def allZK(conditions: Ref[Coll[SigmaProp]]): Ref[SigmaProp]; + def anyOf(conditions: Ref[Coll[Boolean]]): Ref[Boolean]; + def anyZK(conditions: Ref[Coll[SigmaProp]]): Ref[SigmaProp]; + def xorOf(conditions: Ref[Coll[Boolean]]): Ref[Boolean]; + def PubKey(base64String: Ref[String]): Ref[SigmaProp]; + def sigmaProp(b: Ref[Boolean]): Ref[SigmaProp]; + def blake2b256(bytes: Ref[Coll[Byte]]): Ref[Coll[Byte]]; + def sha256(bytes: Ref[Coll[Byte]]): Ref[Coll[Byte]]; + def byteArrayToBigInt(bytes: Ref[Coll[Byte]]): Ref[BigInt]; + def longToByteArray(l: Ref[Long]): Ref[Coll[Byte]]; + def byteArrayToLong(bytes: Ref[Coll[Byte]]): Ref[Long]; + def proveDlog(g: Ref[GroupElement]): Ref[SigmaProp]; + def proveDHTuple(g: Ref[GroupElement], h: Ref[GroupElement], u: Ref[GroupElement], v: Ref[GroupElement]): Ref[SigmaProp]; + def groupGenerator: Ref[GroupElement]; + @Reified(value = "T") def substConstants[T](scriptBytes: Ref[Coll[Byte]], positions: Ref[Coll[Int]], newValues: Ref[Coll[T]])(implicit cT: Elem[T]): Ref[Coll[Byte]]; + def decodePoint(encoded: Ref[Coll[Byte]]): Ref[GroupElement]; + def avlTree(operationFlags: Ref[Byte], digest: Ref[Coll[Byte]], keyLength: Ref[Int], valueLengthOpt: Ref[WOption[Int]]): Ref[AvlTree]; + def xor(l: Ref[Coll[Byte]], r: Ref[Coll[Byte]]): Ref[Coll[Byte]] }; trait CostModelCompanion; trait BigIntCompanion; diff --git a/sigma-api/src/main/resources/special/sigma/wrappers/WrappersSpec.scalan b/sigma-api/src/main/resources/special/sigma/wrappers/WrappersSpec.scalan deleted file mode 100644 index 1d3fabc31a..0000000000 --- a/sigma-api/src/main/resources/special/sigma/wrappers/WrappersSpec.scalan +++ /dev/null @@ -1,67 +0,0 @@ -package special.sigma.wrappers { - import scalan._ - - trait WrappersSpec extends Base { self: WrappersSpecModule => - import WArray._; - import WBigInteger._; - import WECPoint._; - import WSigmaPredef._; - import WrapSpecBase._; - trait ECPointWrapSpec extends WrapSpecBase { - def getEncoded[A](g: Rep[WECPoint], compressed: Rep[Boolean]): Rep[WArray[Byte]] = g.getEncoded(compressed); - def multiply(l: Rep[WECPoint], r: Rep[WBigInteger]): Rep[WECPoint] = l.multiply(r); - def add(l: Rep[WECPoint], r: Rep[WECPoint]): Rep[WECPoint] = l.add(r) - }; - trait BigIntegerWrapSpec extends WrapSpecBase { - def fromString(s: Rep[String]): Rep[WBigInteger] = RWBigInteger(s); - def fromArray(sig: Rep[Int], arr: Rep[WArray[Byte]]): Rep[WBigInteger] = RWBigInteger(sig, arr); - def valueOf(l: Rep[Long]): Rep[WBigInteger] = RWBigInteger.valueOf(l); - def toByteArray(l: Rep[WBigInteger]): Rep[WArray[Byte]] = l.toByteArray; - def add(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.add(r); - def subtract(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.subtract(r); - def multiply(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.multiply(r); - def mod(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.mod(r); - def modInverse(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.modInverse(r); - def modPow(l: Rep[WBigInteger], exponent: Rep[WBigInteger], m: Rep[WBigInteger]): Rep[WBigInteger] = l.modPow(exponent, m); - def remainder(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.remainder(r); - def divide(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.divide(r); - def compareTo(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[Int] = l.compareTo(r); - def min(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.min(r); - def max(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.max(r); - def gcd(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.gcd(r); - def and(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.and(r); - def or(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.or(r); - def xor(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.xor(r); - def not(l: Rep[WBigInteger]): Rep[WBigInteger] = l.not; - def andNot(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.andNot(r); - def pow(l: Rep[WBigInteger], r: Rep[Int]): Rep[WBigInteger] = l.pow(r); - def testBit(l: Rep[WBigInteger], r: Rep[Int]): Rep[Boolean] = l.testBit(r); - def setBit(l: Rep[WBigInteger], r: Rep[Int]): Rep[WBigInteger] = l.setBit(r); - def clearBit(l: Rep[WBigInteger], r: Rep[Int]): Rep[WBigInteger] = l.clearBit(r); - def flipBit(l: Rep[WBigInteger], r: Rep[Int]): Rep[WBigInteger] = l.flipBit(r); - def getLowestSetBit(l: Rep[WBigInteger]): Rep[Int] = l.getLowestSetBit; - def bitCount(l: Rep[WBigInteger]): Rep[Int] = l.bitCount; - def bitLength(l: Rep[WBigInteger]): Rep[Int] = l.bitLength; - def isProbablePrime(l: Rep[WBigInteger], r: Rep[Int]): Rep[Boolean] = l.isProbablePrime(r); - def shiftLeft(l: Rep[WBigInteger], r: Rep[Int]): Rep[WBigInteger] = l.shiftLeft(r); - def shiftRight(l: Rep[WBigInteger], r: Rep[Int]): Rep[WBigInteger] = l.shiftRight(r); - def abs(l: Rep[WBigInteger]): Rep[WBigInteger] = l.abs; - def negate(l: Rep[WBigInteger]): Rep[WBigInteger] = l.negate; - def signum(l: Rep[WBigInteger]): Rep[Int] = l.signum; - def byteValue(l: Rep[WBigInteger]): Rep[Byte] = l.byteValue; - def shortValue(l: Rep[WBigInteger]): Rep[Short] = l.shortValue; - def intValue(l: Rep[WBigInteger]): Rep[Int] = l.intValue; - def longValue(l: Rep[WBigInteger]): Rep[Long] = l.longValue; - def byteValueExact(l: Rep[WBigInteger]): Rep[Byte] = l.byteValueExact; - def shortValueExact(l: Rep[WBigInteger]): Rep[Short] = l.shortValueExact; - def intValueExact(l: Rep[WBigInteger]): Rep[Int] = l.intValueExact; - def longValueExact(l: Rep[WBigInteger]): Rep[Long] = l.longValueExact - }; - trait SigmaPredefWrapSpec extends WrapSpecBase { - def dataSize(v: Rep[Any]): Rep[Long] = RWSigmaPredef.dataSize[Any](v) - }; - trait ECPointWrapSpecCompanion; - trait BigIntegerWrapSpecCompanion; - trait SigmaPredefWrapSpecCompanion - } -} \ No newline at end of file diff --git a/sigma-api/src/main/resources/wrappers/java/math/WBigIntegers.scalan b/sigma-api/src/main/resources/wrappers/java/math/WBigIntegers.scalan deleted file mode 100644 index 129a5e0fd6..0000000000 --- a/sigma-api/src/main/resources/wrappers/java/math/WBigIntegers.scalan +++ /dev/null @@ -1,61 +0,0 @@ -package wrappers.java.math { - import scalan._ - - import impl._ - - import special.sigma.wrappers.WrappersModule - - import special.sigma.wrappers.BigIntegerWrapSpec - - trait WBigIntegers extends Base { self: WrappersModule => - import WArray._; - import WBigInteger._; - @External("BigInteger") @Liftable trait WBigInteger extends Def[WBigInteger] { self => - @External def longValueExact: Rep[Long]; - @External def intValueExact: Rep[Int]; - @External def shortValueExact: Rep[Short]; - @External def byteValueExact: Rep[Byte]; - @External def longValue: Rep[Long]; - @External def intValue: Rep[Int]; - @External def shortValue: Rep[Short]; - @External def byteValue: Rep[Byte]; - @External def signum: Rep[Int]; - @External def negate: Rep[WBigInteger]; - @External def abs: Rep[WBigInteger]; - @External def shiftRight(x$1: Rep[Int]): Rep[WBigInteger]; - @External def shiftLeft(x$1: Rep[Int]): Rep[WBigInteger]; - @External def isProbablePrime(x$1: Rep[Int]): Rep[Boolean]; - @External def bitLength: Rep[Int]; - @External def bitCount: Rep[Int]; - @External def getLowestSetBit: Rep[Int]; - @External def flipBit(x$1: Rep[Int]): Rep[WBigInteger]; - @External def clearBit(x$1: Rep[Int]): Rep[WBigInteger]; - @External def setBit(x$1: Rep[Int]): Rep[WBigInteger]; - @External def testBit(x$1: Rep[Int]): Rep[Boolean]; - @External def pow(x$1: Rep[Int]): Rep[WBigInteger]; - @External def andNot(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def not: Rep[WBigInteger]; - @External def xor(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def or(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def and(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def gcd(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def max(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def min(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def compareTo(x$1: Rep[WBigInteger]): Rep[Int]; - @External def divide(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def remainder(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def modPow(x$1: Rep[WBigInteger], x$2: Rep[WBigInteger]): Rep[WBigInteger]; - @External def modInverse(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def mod(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def multiply(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def subtract(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def add(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def toByteArray: Rep[WArray[Byte]] - }; - trait WBigIntegerCompanion { - @Constructor @OverloadId(value = "constructor_1") def apply(x$1: Rep[Int], x$2: Rep[WArray[Byte]]): Rep[WBigInteger]; - @Constructor @OverloadId(value = "constructor_2") def apply(x$1: Rep[String]): Rep[WBigInteger]; - @External def valueOf(x$1: Rep[Long]): Rep[WBigInteger] - } - } -} \ No newline at end of file diff --git a/sigma-api/src/main/resources/wrappers/org/bouncycastle/math/ec/WECPoints.scalan b/sigma-api/src/main/resources/wrappers/org/bouncycastle/math/ec/WECPoints.scalan deleted file mode 100644 index 0851c2fa30..0000000000 --- a/sigma-api/src/main/resources/wrappers/org/bouncycastle/math/ec/WECPoints.scalan +++ /dev/null @@ -1,21 +0,0 @@ -package wrappers.org.bouncycastle.math.ec { - import scalan._ - - import impl._ - - import special.sigma.wrappers.WrappersModule - - import special.sigma.wrappers.ECPointWrapSpec - - trait WECPoints extends Base { self: WrappersModule => - import WArray._; - import WBigInteger._; - import WECPoint._; - @External("ECPoint") @Liftable trait WECPoint extends Def[WECPoint] { self => - @External def add(x$1: Rep[WECPoint]): Rep[WECPoint]; - @External def multiply(x$1: Rep[WBigInteger]): Rep[WECPoint]; - @External def getEncoded(x$1: Rep[Boolean]): Rep[WArray[Byte]] - }; - trait WECPointCompanion - } -} \ No newline at end of file diff --git a/sigma-api/src/main/resources/wrappers/special/sigma/WSigmaPredefs.scalan b/sigma-api/src/main/resources/wrappers/special/sigma/WSigmaPredefs.scalan deleted file mode 100644 index 848917e56c..0000000000 --- a/sigma-api/src/main/resources/wrappers/special/sigma/WSigmaPredefs.scalan +++ /dev/null @@ -1,19 +0,0 @@ -package wrappers.special.sigma { - import scalan._ - - import impl._ - - import special.sigma.wrappers.WrappersModule - - import special.sigma.wrappers.SigmaPredefWrapSpec - - trait WSigmaPredefs extends Base { self: WrappersModule => - import WSigmaPredef._; - @External("SigmaPredef") trait WSigmaPredef extends Def[WSigmaPredef] { self => - - }; - trait WSigmaPredefCompanion { - @External def dataSize[T](v: Rep[T]): Rep[Long] - } - } -} \ No newline at end of file diff --git a/sigma-api/src/main/scala/special/sigma/CostedObjects.scala b/sigma-api/src/main/scala/special/sigma/CostedObjects.scala index 0a27b1e341..e2bf568118 100644 --- a/sigma-api/src/main/scala/special/sigma/CostedObjects.scala +++ b/sigma-api/src/main/scala/special/sigma/CostedObjects.scala @@ -4,17 +4,20 @@ import special.collection._ import scalan._ @scalan.Liftable +@WithMethodCallRecognizers trait SizeAnyValue extends Size[AnyValue] { def tVal: RType[Any] def valueSize: Size[Any] } @scalan.Liftable +@WithMethodCallRecognizers trait SizeSigmaProp extends Size[SigmaProp] { def propBytes: Size[Coll[Byte]] } @scalan.Liftable +@WithMethodCallRecognizers trait SizeBox extends Size[Box] { def propositionBytes: Size[Coll[Byte]] def bytes: Size[Coll[Byte]] @@ -25,6 +28,7 @@ trait SizeBox extends Size[Box] { } @scalan.Liftable +@WithMethodCallRecognizers trait SizeContext extends Size[Context] { def outputs: Size[Coll[Box]] def inputs: Size[Coll[Box]] diff --git a/sigma-api/src/main/scala/special/sigma/SigmaAnnotations.scala b/sigma-api/src/main/scala/special/sigma/SigmaAnnotations.scala deleted file mode 100644 index 65cbcb68c5..0000000000 --- a/sigma-api/src/main/scala/special/sigma/SigmaAnnotations.scala +++ /dev/null @@ -1,9 +0,0 @@ -package special.sigma - -import scala.annotation.Annotation -import scalan.lang - -@lang("sigmalang") -class sigmalang extends Annotation {} - -@sigmalang class clause extends Annotation diff --git a/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala b/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala index cdc431649c..669d0f56bd 100644 --- a/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala +++ b/sigma-api/src/main/scala/special/sigma/SigmaDsl.scala @@ -23,7 +23,6 @@ trait CostModel { def SelectField: Int // costOf("SelectField") def CollectionConst: Int // costOf("Const: () => Array[IV]") def AccessKiloByteOfData: Int // costOf("AccessKiloByteOfData") - @Reified("T") def dataSize[T](x: T)(implicit cT: ClassTag[T]): Long /** Size of public key in bytes */ def PubKeySize: Long } @@ -34,6 +33,7 @@ trait CostModel { * So it is globally and implicitly used in all methods. * */ @scalan.Liftable +@WithMethodCallRecognizers trait BigInt { @Internal private[sigma] def value: BigInteger @@ -118,7 +118,7 @@ trait BigInt { * @return { @code this + that} */ def add(that: BigInt): BigInt - def +(that: BigInt): BigInt = add(that) + @Internal def +(that: BigInt): BigInt = add(that) /** Returns a BigInt whose value is {@code (this - that)}. * @@ -126,7 +126,7 @@ trait BigInt { * @return { @code this - that} */ def subtract(that: BigInt): BigInt - def -(that: BigInt): BigInt = subtract(that) + @Internal def -(that: BigInt): BigInt = subtract(that) /** Returns a BigInt whose value is {@code (this * that)}. * @@ -136,7 +136,7 @@ trait BigInt { * @return { @code this * that} */ def multiply(that: BigInt): BigInt - def *(that: BigInt): BigInt = multiply(that) + @Internal def *(that: BigInt): BigInt = multiply(that) /** Returns a BigInt whose value is {@code (this / that)}. * @@ -145,7 +145,7 @@ trait BigInt { * @throws ArithmeticException if { @code that} is zero. */ def divide(that: BigInt): BigInt - def /(that: BigInt): BigInt = divide(that) + @Internal def /(that: BigInt): BigInt = divide(that) /** * Returns a BigInt whose value is {@code (this mod m}). This method @@ -158,7 +158,7 @@ trait BigInt { * @see #remainder */ def mod(m: BigInt): BigInt - def %(m: BigInt): BigInt = mod(m) + @Internal def %(m: BigInt): BigInt = mod(m) /** * Returns a BigInt whose value is {@code (this % that)}. @@ -197,6 +197,7 @@ trait BigInt { /** Base class for points on elliptic curves. */ @scalan.Liftable +@WithMethodCallRecognizers trait GroupElement { @Internal private[sigma] def value: ECPoint @@ -226,6 +227,7 @@ trait GroupElement { /** Proposition which can be proven and verified by sigma protocol. */ @scalan.Liftable +@WithMethodCallRecognizers trait SigmaProp { def isValid: Boolean /** Serialized bytes of this sigma proposition taken as ErgoTree and then serialized. */ @@ -251,12 +253,14 @@ trait SigmaProp { } @scalan.Liftable +@WithMethodCallRecognizers trait AnyValue { def value: Any def tVal: RType[Any] } @scalan.Liftable +@WithMethodCallRecognizers trait Box { /** Blake2b256 hash of this box's content, basically equals to `blake2b256(bytes)` */ def id: Coll[Byte] @@ -386,6 +390,8 @@ trait AvlTree { /** Checks if an entry with key `key` exists in this tree using proof `proof`. * Throws exception if proof is incorrect + * + * @note CAUTION! Does not support multiple keys check, use [[getMany]] instead. * Return `true` if a leaf with the key `key` exists * Return `false` if leaf with provided key does not exist. * @param key a key of an element of this authenticated dictionary. @@ -395,6 +401,8 @@ trait AvlTree { /** Perform a lookup of key `key` in this tree using proof `proof`. * Throws exception if proof is incorrect + * + * @note CAUTION! Does not support multiple keys check, use [[getMany]] instead. * Return Some(bytes) of leaf with key `key` if it exists * Return None if leaf with provided key does not exist. * @param key a key of an element of this authenticated dictionary. @@ -403,6 +411,8 @@ trait AvlTree { def get(key: Coll[Byte], proof: Coll[Byte]): Option[Coll[Byte]] /** Perform a lookup of many keys `keys` in this tree using proof `proof`. + * + * @note CAUTION! Keys must be ordered the same way they were in lookup before proof was generated. * For each key return Some(bytes) of leaf if it exists and None if is doesn't. * @param keys keys of elements of this authenticated dictionary. * @param proof @@ -411,6 +421,8 @@ trait AvlTree { /** Perform insertions of key-value entries into this tree using proof `proof`. * Throws exception if proof is incorrect + * + * @note CAUTION! Pairs must be ordered the same way they were in insert ops before proof was generated. * Return Some(newTree) if successful * Return None if operations were not performed. * @param operations collection of key-value pairs to insert in this authenticated dictionary. @@ -420,6 +432,8 @@ trait AvlTree { /** Perform updates of key-value entries into this tree using proof `proof`. * Throws exception if proof is incorrect + * + * @note CAUTION! Pairs must be ordered the same way they were in update ops before proof was generated. * Return Some(newTree) if successful * Return None if operations were not performed. * @param operations collection of key-value pairs to update in this authenticated dictionary. @@ -431,6 +445,8 @@ trait AvlTree { * Throws exception if proof is incorrect * Return Some(newTree) if successful * Return None if operations were not performed. + * + * @note CAUTION! Keys must be ordered the same way they were in remove ops before proof was generated. * @param operations collection of keys to remove from this authenticated dictionary. * @param proof */ @@ -519,6 +535,7 @@ trait Header { /** Represents data available in Sigma language using `CONTEXT` global variable*/ @scalan.Liftable +@WithMethodCallRecognizers trait Context { def builder: SigmaDslBuilder @@ -603,13 +620,10 @@ trait SigmaContract { positions: Coll[Int], newValues: Coll[T]) (implicit cT: RType[T]): Coll[Byte] = this.builder.substConstants(scriptBytes, positions, newValues) - - @clause def canOpen(ctx: Context): Boolean - - def asFunction: Context => Boolean = (ctx: Context) => this.canOpen(ctx) } @scalan.Liftable +@WithMethodCallRecognizers trait SigmaDslBuilder { def Colls: CollBuilder def Monoids: MonoidBuilder @@ -654,10 +668,10 @@ trait SigmaDslBuilder { def decodePoint(encoded: Coll[Byte]): GroupElement /** Create DSL big integer from existing `java.math.BigInteger`*/ - def BigInt(n: BigInteger): BigInt + @Internal def BigInt(n: BigInteger): BigInt /** Extract `java.math.BigInteger` from DSL's `BigInt` type*/ - def toBigInteger(n: BigInt): BigInteger + @Internal def toBigInteger(n: BigInt): BigInteger /** Construct a new authenticated dictionary with given parameters and tree root digest. */ def avlTree(operationFlags: Byte, digest: Coll[Byte], keyLength: Int, valueLengthOpt: Option[Int]): AvlTree diff --git a/sigma-api/src/main/scala/special/sigma/SigmaExamples.scala b/sigma-api/src/main/scala/special/sigma/SigmaExamples.scala deleted file mode 100644 index f31905b8ec..0000000000 --- a/sigma-api/src/main/scala/special/sigma/SigmaExamples.scala +++ /dev/null @@ -1,121 +0,0 @@ -package special.sigma - -import special.collection.Coll - -import scalan.RType -import RType._ - -trait CrowdFunding extends SigmaContract { - def deadline: Long - def minToRaise: Long - def backerPubKey: SigmaProp - def projectPubKey: SigmaProp - - @clause def canOpen(ctx: Context) = verifyZK { - val fundraisingFailure = sigmaProp(ctx.HEIGHT >= deadline) && backerPubKey - val enoughRaised = (outBox: Box) => { - outBox.value >= minToRaise && - outBox.propositionBytes == projectPubKey.propBytes - } - val fundraisingSuccess = ctx.HEIGHT < deadline && - projectPubKey.isValid && - ctx.OUTPUTS.exists(enoughRaised) - - fundraisingFailure || fundraisingSuccess - } -} - -trait CrossChainAtomicSwap extends SigmaContract { - def deadlineBob: Long - def deadlineAlice: Long - def pkA: SigmaProp - def pkB: SigmaProp - def hx: Coll[Byte] - - def templateForBobChain(ctx: Context) = verifyZK { - anyZK(Collection( - sigmaProp(ctx.HEIGHT > deadlineBob) && pkA, - pkB && blake2b256(ctx.getVar[Coll[Byte]](1).get) == hx - )) - } - - def templateForAliceChain(ctx: Context) = verifyZK { - val x = ctx.getVar[Coll[Byte]](1).get - anyZK(Collection( - sigmaProp(ctx.HEIGHT > deadlineAlice) && pkB, - allZK( Collection( - pkA, - sigmaProp(x.length < 33), - sigmaProp(blake2b256(x) == hx) - )) - )) - } -} - -trait InChainAtomicSwap extends SigmaContract { - def deadline: Long - def pkA: SigmaProp - def pkB: SigmaProp - def token1: Coll[Byte] - - def templateForAlice(ctx: Context) = verifyZK { - (pkA && ctx.HEIGHT > deadline) || { - val tokenData = ctx.OUTPUTS(0).tokens(0) - allOf(Collection( - tokenData._1 == token1, - tokenData._2 >= 60L, - ctx.OUTPUTS(0).propositionBytes == pkA.propBytes, - ctx.OUTPUTS(0).value >= 1L - )) - } - } - def templateForBob(ctx: Context) = verifyZK { - (pkB && ctx.HEIGHT > deadline) || - allOf( Collection( - ctx.OUTPUTS(1).value >= 100L, - ctx.OUTPUTS(1).propositionBytes == pkB.propBytes - )) - } -} - -trait CoinEmission extends SigmaContract { - def fixedRatePeriod: Long - def epochLength: Long - def fixedRate: Long - def oneEpochReduction: Long - - def templateForTotalAmountBox(ctx: Context) = { - val epoch = 1L + ((ctx.HEIGHT - fixedRatePeriod) / epochLength) - val out = ctx.OUTPUTS(0) - val coinsToIssue = - if (ctx.HEIGHT < fixedRatePeriod) fixedRate - else fixedRate - (oneEpochReduction * epoch) - val correctCoinsConsumed = coinsToIssue == (ctx.SELF.value - out.value) - val sameScriptRule = ctx.SELF.propositionBytes == out.propositionBytes - val heightIncreased = ctx.HEIGHT > ctx.SELF.getReg[Long](4).get - val heightCorrect = out.getReg[Long](4).get == ctx.HEIGHT - val lastCoins = ctx.SELF.value <= oneEpochReduction - allOf(Collection( - correctCoinsConsumed, - heightCorrect, - heightIncreased, - sameScriptRule)) || - (heightIncreased && lastCoins) - } -} - -trait DemurrageCurrency extends SigmaContract { - def demurragePeriod: Int - def demurrageCost: Long - def regScript: SigmaProp - - @clause def canOpen(ctx: Context) = verifyZK { - val c2 = - ctx.HEIGHT >= ctx.SELF.getReg[Int](4).get + demurragePeriod && - ctx.OUTPUTS.exists(out => { - out.value >= ctx.SELF.value - demurrageCost && out.propositionBytes == ctx.SELF.propositionBytes - }) - regScript || c2 - } -} - diff --git a/sigma-api/src/main/scala/special/sigma/SigmaPredef.scala b/sigma-api/src/main/scala/special/sigma/SigmaPredef.scala deleted file mode 100644 index 9cc8fa19bb..0000000000 --- a/sigma-api/src/main/scala/special/sigma/SigmaPredef.scala +++ /dev/null @@ -1,17 +0,0 @@ -package special.sigma - -object SigmaPredef { - - // TODO cleanup: since it is not really used - def dataSize[T](v: T): Long = v match { - case _: Boolean => 1 - case _: Byte => 1 - case _: Short => 2 - case _: Int => 4 - case _: Long => 8 - case _ => sys.error(s"Cannot compute dataSize($v)") - } - -} - - diff --git a/sigma-api/src/main/scala/special/sigma/wrappers/WrappersSpec.scala b/sigma-api/src/main/scala/special/sigma/wrappers/WrappersSpec.scala deleted file mode 100644 index 2111d24bdd..0000000000 --- a/sigma-api/src/main/scala/special/sigma/wrappers/WrappersSpec.scala +++ /dev/null @@ -1,70 +0,0 @@ -package special.sigma.wrappers - -import java.math.BigInteger - -import scalan.WrapSpec -import special.wrappers.{WrapSpecBase} -import org.bouncycastle.math.ec.ECPoint -import special.sigma.SigmaPredef - -import scala.reflect.ClassTag - -trait ECPointWrapSpec extends WrapSpecBase { - def getEncoded[A](g: ECPoint, compressed: Boolean): Array[Byte] = g.getEncoded(compressed) - def multiply(l: ECPoint, r: BigInteger) = l.multiply(r) - def add(l: ECPoint, r: ECPoint) = l.add(r) -} - -trait BigIntegerWrapSpec extends WrapSpecBase { - def fromString(s: String) = new BigInteger(s) - def fromArray(sig: Int, arr: Array[Byte]) = new BigInteger(sig, arr) -// def ZERO = BigInteger.ZERO -// def ONE = BigInteger.ONE - def valueOf(l: Long) = BigInteger.valueOf(l) -// def toString(l: BigInteger, radix: Int) = l.toString(radix) - def toByteArray(l: BigInteger): Array[Byte] = l.toByteArray() - def add(l: BigInteger, r: BigInteger) = l.add(r) - def subtract(l: BigInteger, r: BigInteger) = l.subtract(r) - def multiply(l: BigInteger, r: BigInteger) = l.multiply(r) - def mod(l: BigInteger, r: BigInteger) = l.mod(r) - def modInverse(l: BigInteger, r: BigInteger) = l.modInverse(r) - def modPow(l: BigInteger, exponent: BigInteger, m: BigInteger) = l.modPow(exponent, m) - def remainder(l: BigInteger, r: BigInteger) = l.remainder(r) - def divide(l: BigInteger, r: BigInteger) = l.divide(r) - def compareTo(l: BigInteger, r: BigInteger) = l.compareTo(r) - def min(l: BigInteger, r: BigInteger) = l.min(r) - def max(l: BigInteger, r: BigInteger) = l.max(r) - def gcd(l: BigInteger, r: BigInteger) = l.gcd(r) - def and(l: BigInteger, r: BigInteger) = l.and(r) - def or(l: BigInteger, r: BigInteger) = l.or(r) - def xor(l: BigInteger, r: BigInteger) = l.xor(r) - def not(l: BigInteger) = l.not() - def andNot(l: BigInteger, r: BigInteger) = l.andNot(r) - def pow(l: BigInteger, r: Int) = l.pow(r) - def testBit(l: BigInteger, r: Int) = l.testBit(r) - def setBit(l: BigInteger, r: Int) = l.setBit(r) - def clearBit(l: BigInteger, r: Int) = l.clearBit(r) - def flipBit(l: BigInteger, r: Int) = l.flipBit(r) - def getLowestSetBit(l: BigInteger) = l.getLowestSetBit() - def bitCount(l: BigInteger) = l.bitCount() - def bitLength(l: BigInteger) = l.bitLength() - def isProbablePrime(l: BigInteger, r: Int) = l.isProbablePrime(r) - def shiftLeft(l: BigInteger, r: Int) = l.shiftLeft(r) - def shiftRight(l: BigInteger, r: Int) = l.shiftRight(r) - def abs(l: BigInteger) = l.abs() - def negate(l: BigInteger) = l.negate() - def signum(l: BigInteger) = l.signum() - def byteValue(l: BigInteger) = l.byteValue() - def shortValue(l: BigInteger) = l.shortValue() - def intValue(l: BigInteger) = l.intValue() - def longValue(l: BigInteger) = l.longValue() - def byteValueExact(l: BigInteger) = l.byteValueExact() - def shortValueExact(l: BigInteger) = l.shortValueExact() - def intValueExact(l: BigInteger) = l.intValueExact() - def longValueExact(l: BigInteger) = l.longValueExact() - -} - -trait SigmaPredefWrapSpec extends WrapSpecBase { - def dataSize(v: Any): Long = SigmaPredef.dataSize(v) -} diff --git a/sigma-conf/src/main/scala/special/sigma/config/SigmaLibraryConfig.scala b/sigma-conf/src/main/scala/special/sigma/config/SigmaLibraryConfig.scala index e81bd8322f..2e93a3fb91 100644 --- a/sigma-conf/src/main/scala/special/sigma/config/SigmaLibraryConfig.scala +++ b/sigma-conf/src/main/scala/special/sigma/config/SigmaLibraryConfig.scala @@ -1,7 +1,6 @@ package special.sigma.config import special.library.config.SpecialLibraryConfig -import scalan.Liftable import scalan.meta.ScalanAst.WrapperConf import scalan.meta.{LibraryConfig, ConfMap, TargetModuleConf, SourceModuleConf} @@ -10,33 +9,19 @@ class SigmaLibraryConfig extends LibraryConfig { def baseDir = "" val specialLibrary = new SpecialLibraryConfig - def wrapperConfigs: Map[String, WrapperConf] = List( - WrapperConf(baseDir, - packageName = "org.bouncycastle.math.ec", - name = "ECPoint", - annotations = List(classOf[Liftable]).map(_.getSimpleName) - ), - WrapperConf(baseDir, - packageName = "java.math", - name = "BigInteger", - annotations = List(classOf[Liftable]).map(_.getSimpleName) - ), - WrapperConf(baseDir, - packageName = "special.sigma", - name = "SigmaPredef" - ) + def wrapperConfigs: Map[String, WrapperConf] = List[WrapperConf]( +// example wrapper declaration +// WrapperConf(baseDir, packageName = "special.sigma", name = "SigmaPredef", +// annotations = List(classOf[WithMethodCallRecognizers]).map(_.getSimpleName)) ).map(w => (w.name, w)).toMap val ApiModule: SourceModuleConf = new SourceModuleConf(baseDir, "sigma-api") .moduleDependencies(specialLibrary.ApiModule) - .addUnit("special/sigma/wrappers/WrappersSpec.scala", wrapperConfigs) .addUnit("special/sigma/SigmaDsl.scala") .addUnit("special/sigma/CostedObjects.scala") val ImplModule = new SourceModuleConf(baseDir, "sigma-impl") .moduleDependencies(specialLibrary.ApiModule, specialLibrary.ImplModule) - .addUnit("special/sigma/SigmaDslOverArrays.scala") - .addUnit("special/sigma/SigmaDslCosted.scala") .dependsOn(ApiModule) val TargetModule = new TargetModuleConf(baseDir, "sigma-library", diff --git a/sigma-impl/src/main/resources/special/sigma/SigmaDslCosted.scalan b/sigma-impl/src/main/resources/special/sigma/SigmaDslCosted.scalan index a9bda5e38e..388abd2c03 100644 --- a/sigma-impl/src/main/resources/special/sigma/SigmaDslCosted.scalan +++ b/sigma-impl/src/main/resources/special/sigma/SigmaDslCosted.scalan @@ -19,24 +19,24 @@ package special.sigma { import SizeSigmaProp._; import WOption._; import WRType._; - abstract class CSizeAnyValue(val tVal: Rep[WRType[Any]], val valueSize: Rep[Size[Any]]) extends SizeAnyValue { - @NeverInline override def dataSize: Rep[Long] = delayInvoke + abstract class CSizeAnyValue(val tVal: Ref[WRType[Any]], val valueSize: Ref[Size[Any]]) extends SizeAnyValue { + @NeverInline override def dataSize: Ref[Long] = delayInvoke }; - abstract class CSizeSigmaProp(val propBytes: Rep[Size[Coll[Byte]]]) extends SizeSigmaProp { - @NeverInline override def dataSize: Rep[Long] = delayInvoke + abstract class CSizeSigmaProp(val propBytes: Ref[Size[Coll[Byte]]]) extends SizeSigmaProp { + @NeverInline override def dataSize: Ref[Long] = delayInvoke }; - abstract class CSizeBox(val propositionBytes: Rep[Size[Coll[Byte]]], val bytes: Rep[Size[Coll[Byte]]], val bytesWithoutRef: Rep[Size[Coll[Byte]]], val registers: Rep[Size[Coll[WOption[AnyValue]]]], val tokens: Rep[Size[Coll[scala.Tuple2[Coll[Byte], Long]]]]) extends SizeBox { - @NeverInline override def dataSize: Rep[Long] = delayInvoke; - @NeverInline override def getReg[T](id: Rep[Byte])(implicit tT: Elem[T]): Rep[Size[WOption[T]]] = delayInvoke + abstract class CSizeBox(val propositionBytes: Ref[Size[Coll[Byte]]], val bytes: Ref[Size[Coll[Byte]]], val bytesWithoutRef: Ref[Size[Coll[Byte]]], val registers: Ref[Size[Coll[WOption[AnyValue]]]], val tokens: Ref[Size[Coll[scala.Tuple2[Coll[Byte], Long]]]]) extends SizeBox { + @NeverInline override def dataSize: Ref[Long] = delayInvoke; + @NeverInline override def getReg[T](id: Ref[Byte])(implicit tT: Elem[T]): Ref[Size[WOption[T]]] = delayInvoke }; - abstract class CSizeContext(val outputs: Rep[Size[Coll[Box]]], val inputs: Rep[Size[Coll[Box]]], val dataInputs: Rep[Size[Coll[Box]]], val selfBox: Rep[Size[Box]], val lastBlockUtxoRootHash: Rep[Size[AvlTree]], val headers: Rep[Size[Coll[Header]]], val preHeader: Rep[Size[PreHeader]], val vars: Rep[Coll[Size[AnyValue]]]) extends SizeContext { - @NeverInline override def dataSize: Rep[Long] = delayInvoke; - @NeverInline override def getVar[T](id: Rep[Byte])(implicit tT: Elem[T]): Rep[Size[WOption[T]]] = delayInvoke + abstract class CSizeContext(val outputs: Ref[Size[Coll[Box]]], val inputs: Ref[Size[Coll[Box]]], val dataInputs: Ref[Size[Coll[Box]]], val selfBox: Ref[Size[Box]], val lastBlockUtxoRootHash: Ref[Size[AvlTree]], val headers: Ref[Size[Coll[Header]]], val preHeader: Ref[Size[PreHeader]], val vars: Ref[Coll[Size[AnyValue]]]) extends SizeContext { + @NeverInline override def dataSize: Ref[Long] = delayInvoke; + @NeverInline override def getVar[T](id: Ref[Byte])(implicit tT: Elem[T]): Ref[Size[WOption[T]]] = delayInvoke }; abstract class CSizeBuilder extends SizeBuilder { - def mkSizeAnyValue(tVal: Rep[WRType[Any]], valueSize: Rep[Size[Any]]): Rep[SizeAnyValue] = RCSizeAnyValue(tVal, valueSize); - def mkSizeBox(propositionBytes: Rep[Size[Coll[Byte]]], bytes: Rep[Size[Coll[Byte]]], bytesWithoutRef: Rep[Size[Coll[Byte]]], registers: Rep[Size[Coll[WOption[AnyValue]]]], tokens: Rep[Size[Coll[scala.Tuple2[Coll[Byte], Long]]]]): Rep[SizeBox] = RCSizeBox(propositionBytes, bytes, bytesWithoutRef, registers, tokens); - def mkSizeContext(outputs: Rep[Size[Coll[Box]]], inputs: Rep[Size[Coll[Box]]], dataInputs: Rep[Size[Coll[Box]]], selfBox: Rep[Size[Box]], lastBlockUtxoRootHash: Rep[Size[AvlTree]], headers: Rep[Size[Coll[Header]]], preHeader: Rep[Size[PreHeader]], vars: Rep[Coll[Size[AnyValue]]]): Rep[SizeContext] = RCSizeContext(outputs, inputs, dataInputs, selfBox, lastBlockUtxoRootHash, headers, preHeader, vars) + def mkSizeAnyValue(tVal: Ref[WRType[Any]], valueSize: Ref[Size[Any]]): Ref[SizeAnyValue] = RCSizeAnyValue(tVal, valueSize); + def mkSizeBox(propositionBytes: Ref[Size[Coll[Byte]]], bytes: Ref[Size[Coll[Byte]]], bytesWithoutRef: Ref[Size[Coll[Byte]]], registers: Ref[Size[Coll[WOption[AnyValue]]]], tokens: Ref[Size[Coll[scala.Tuple2[Coll[Byte], Long]]]]): Ref[SizeBox] = RCSizeBox(propositionBytes, bytes, bytesWithoutRef, registers, tokens); + def mkSizeContext(outputs: Ref[Size[Coll[Box]]], inputs: Ref[Size[Coll[Box]]], dataInputs: Ref[Size[Coll[Box]]], selfBox: Ref[Size[Box]], lastBlockUtxoRootHash: Ref[Size[AvlTree]], headers: Ref[Size[Coll[Header]]], preHeader: Ref[Size[PreHeader]], vars: Ref[Coll[Size[AnyValue]]]): Ref[SizeContext] = RCSizeContext(outputs, inputs, dataInputs, selfBox, lastBlockUtxoRootHash, headers, preHeader, vars) }; trait CSizeAnyValueCompanion; trait CSizeSigmaPropCompanion; diff --git a/sigma-impl/src/main/resources/special/sigma/SigmaDslOverArrays.scalan b/sigma-impl/src/main/resources/special/sigma/SigmaDslOverArrays.scalan deleted file mode 100644 index 498d26036e..0000000000 --- a/sigma-impl/src/main/resources/special/sigma/SigmaDslOverArrays.scalan +++ /dev/null @@ -1,53 +0,0 @@ -package special.sigma { - import scalan._ - - trait SigmaDslOverArrays extends Base { self: SigmaDslOverArraysModule => - import AvlTree._; - import BigInt._; - import CCostedBuilder._; - import Coll._; - import CollBuilder._; - import CollOverArrayBuilder._; - import CostModel._; - import CostedBuilder._; - import GroupElement._; - import MonoidBuilder._; - import MonoidBuilderInst._; - import SigmaDslBuilder._; - import SigmaProp._; - import WBigInteger._; - import WECPoint._; - import WOption._; - abstract class TestSigmaDslBuilder extends SigmaDslBuilder { - def Colls: Rep[CollBuilder] = RCollOverArrayBuilder(); - def Monoids: Rep[MonoidBuilder] = RMonoidBuilderInst(); - def Costing: Rep[CostedBuilder] = RCCostedBuilder(); - @NeverInline def CostModel: Rep[CostModel] = delayInvoke; - @NeverInline def verifyZK(proof: Rep[Thunk[SigmaProp]]): Rep[Boolean] = delayInvoke; - @NeverInline def atLeast(bound: Rep[Int], props: Rep[Coll[SigmaProp]]): Rep[SigmaProp] = delayInvoke; - @NeverInline def allOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean] = delayInvoke; - @NeverInline def anyOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean] = delayInvoke; - @NeverInline def allZK(props: Rep[Coll[SigmaProp]]): Rep[SigmaProp] = delayInvoke; - @NeverInline def anyZK(props: Rep[Coll[SigmaProp]]): Rep[SigmaProp] = delayInvoke; - @NeverInline override def xorOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean] = delayInvoke; - @NeverInline def sigmaProp(b: Rep[Boolean]): Rep[SigmaProp] = delayInvoke; - @NeverInline def blake2b256(bytes: Rep[Coll[Byte]]): Rep[Coll[Byte]] = delayInvoke; - @NeverInline def sha256(bytes: Rep[Coll[Byte]]): Rep[Coll[Byte]] = delayInvoke; - @NeverInline def PubKey(base64String: Rep[String]): Rep[SigmaProp] = delayInvoke; - @NeverInline def byteArrayToBigInt(bytes: Rep[Coll[Byte]]): Rep[BigInt] = delayInvoke; - @NeverInline def longToByteArray(l: Rep[Long]): Rep[Coll[Byte]] = delayInvoke; - @NeverInline def byteArrayToLong(bytes: Rep[Coll[Byte]]): Rep[Long] = delayInvoke; - @NeverInline def proveDlog(g: Rep[GroupElement]): Rep[SigmaProp] = delayInvoke; - @NeverInline def proveDHTuple(g: Rep[GroupElement], h: Rep[GroupElement], u: Rep[GroupElement], v: Rep[GroupElement]): Rep[SigmaProp] = delayInvoke; - @NeverInline def groupGenerator: Rep[GroupElement] = delayInvoke; - @Reified(value = "T") @NeverInline override def substConstants[T](scriptBytes: Rep[Coll[Byte]], positions: Rep[Coll[Int]], newValues: Rep[Coll[T]])(implicit cT: Elem[T]): Rep[Coll[Byte]] = delayInvoke; - @NeverInline override def decodePoint(encoded: Rep[Coll[Byte]]): Rep[GroupElement] = delayInvoke; - @NeverInline override def BigInt(n: Rep[WBigInteger]): Rep[BigInt] = delayInvoke; - @NeverInline override def toBigInteger(n: Rep[BigInt]): Rep[WBigInteger] = delayInvoke; - @NeverInline def GroupElement(p: Rep[WECPoint]): Rep[GroupElement] = delayInvoke; - @NeverInline def toECPoint(ge: Rep[GroupElement]): Rep[WECPoint] = delayInvoke; - @NeverInline override def avlTree(operationFlags: Rep[Byte], digest: Rep[Coll[Byte]], keyLength: Rep[Int], valueLengthOpt: Rep[WOption[Int]]): Rep[AvlTree] = delayInvoke - }; - trait TestSigmaDslBuilderCompanion - } -} \ No newline at end of file diff --git a/sigma-impl/src/main/scala/sigma/types/Types.scala b/sigma-impl/src/main/scala/sigma/types/ConcreteTypes.scala similarity index 92% rename from sigma-impl/src/main/scala/sigma/types/Types.scala rename to sigma-impl/src/main/scala/sigma/types/ConcreteTypes.scala index 5b9528537f..9a3f2aa417 100644 --- a/sigma-impl/src/main/scala/sigma/types/Types.scala +++ b/sigma-impl/src/main/scala/sigma/types/ConcreteTypes.scala @@ -1,8 +1,7 @@ package sigma.types -import com.google.common.primitives.Ints -import sigma.util.Extensions._ -import special.collection.{Coll, Builder} +import scalan.util.Extensions._ +import special.collection.Coll case class CBoolean(value: scala.Boolean) extends Boolean { override def toByte: Byte = CByte(if (value) 1 else 0) diff --git a/sigma-impl/src/main/scala/sigma/util/Extensions.scala b/sigma-impl/src/main/scala/sigma/util/Extensions.scala index d418f1a265..c1d15a9e4f 100644 --- a/sigma-impl/src/main/scala/sigma/util/Extensions.scala +++ b/sigma-impl/src/main/scala/sigma/util/Extensions.scala @@ -1,239 +1,62 @@ package sigma.util -import java.math.BigInteger -import java.nio.ByteBuffer - import special.collection.{Coll, Builder} -import com.google.common.primitives.Ints +import com.google.common.primitives.{Ints, Shorts, Longs} import scala.language.higherKinds object Extensions { - implicit class BooleanOps(val b: Boolean) extends AnyVal { - /** Convert true to 1 and false to 0 - * @since 2.0 - */ - def toByte: Byte = if (b) 1 else 0 - } - - /** @hotspot it is used in deserialization so we avoid allocation by any means. */ - @inline final def toUByte(b: Byte) = b & 0xFF - - implicit class ByteOps(val b: Byte) extends AnyVal { - @inline def toUByte: Int = Extensions.toUByte(b) - - def addExact(b2: Byte): Byte = { - val r = b + b2 - if (r < Byte.MinValue || r > Byte.MaxValue) - throw new ArithmeticException("Byte overflow") - r.toByte - } - - def subtractExact(b2: Byte): Byte = { - val r = b - b2 - if (r < Byte.MinValue || r > Byte.MaxValue) - throw new ArithmeticException("Byte overflow") - r.toByte - } - def multiplyExact(b2: Byte): Byte = { - val r = b * b2 - if (r < Byte.MinValue || r > Byte.MaxValue) - throw new ArithmeticException("Byte overflow") - r.toByte - } - - def toShort: Short = b.toShort - def toInt: Int = b.toInt - def toLong: Long = b.toLong - - /** Returns a big-endian representation of this Int in a collection of bytes. - * For example, the Int value {@code 0x12131415} would yield the - * byte array {@code {0x12, 0x13, 0x14, 0x15}}. - * @since 2.0 + implicit class ByteOpsForSigma(val b: Byte) extends AnyVal { + /** Returns a big-endian representation of this Byte in a collection of bytes. + * For example, the Byte value {@code 0x12} would yield the + * byte array {@code {0x12}}. */ def toBytes: Coll[Byte] = Builder.DefaultCollBuilder.fromItems(b) /** Returns a big-endian representation of this numeric in a collection of Booleans. * Each boolean corresponds to one bit. - * @since 2.0 */ def toBits: Coll[Boolean] = ??? + } - /** Absolute value of this numeric value. - * @since 2.0 + implicit class ShortOpsForSigma(val x: Short) extends AnyVal { + /** Returns a big-endian representation of this Short in a collection of bytes. + * For example, the Short value {@code 0x1213} would yield the + * byte array {@code {0x12, 0x13}}. */ - def toAbs: Byte = if (b < 0) (-b).toByte else b + def toBytes: Coll[Byte] = Builder.DefaultCollBuilder.fromArray(Shorts.toByteArray(x)) - /** Compares this numeric with that numeric for order. Returns a negative integer, zero, or a positive integer as the - * `this` is less than, equal to, or greater than `that`. + /** Returns a big-endian representation of this numeric in a collection of Booleans. + * Each boolean corresponds to one bit. */ - def compare(that: Byte): Byte = if (b < that) -1.toByte else if (b == that) 0.toByte else 1.toByte - } - - implicit class ShortOps(val x: Short) extends AnyVal { - def toByteExact: Byte = { - if (x < Byte.MinValue || x > Byte.MaxValue) - throw new ArithmeticException("Byte overflow") - x.toByte - } - - def addExact(y: Short): Short = { - val r = x + y - if (r < Short.MinValue || r > Short.MaxValue) - throw new ArithmeticException("Short overflow") - r.toShort - } - - def subtractExact(y: Short): Short = { - val r = x - y - if (r < Short.MinValue || r > Short.MaxValue) - throw new ArithmeticException("Short overflow") - r.toShort - } - - def multiplyExact(y: Short): Short = { - val r = x * y - if (r < Short.MinValue || r > Short.MaxValue) - throw new ArithmeticException("Short overflow") - r.toShort - } + def toBits: Coll[Boolean] = ??? } - implicit class IntOps(val x: Int) extends AnyVal { - def toByteExact: Byte = { - if (x < Byte.MinValue || x > Byte.MaxValue) - throw new ArithmeticException("Byte overflow") - x.toByte - } - - def toShortExact: Short = { - if (x < Short.MinValue || x > Short.MaxValue) - throw new ArithmeticException("Short overflow") - x.toShort - } - + implicit class IntOpsForSigma(val x: Int) extends AnyVal { /** Returns a big-endian representation of this Int in a collection of bytes. * For example, the Int value {@code 0x12131415} would yield the * byte array {@code {0x12, 0x13, 0x14, 0x15}}. - * @since 2.0 */ def toBytes: Coll[Byte] = Builder.DefaultCollBuilder.fromArray(Ints.toByteArray(x)) /** Returns a big-endian representation of this numeric in a collection of Booleans. * Each boolean corresponds to one bit. - * @since 2.0 */ def toBits: Coll[Boolean] = ??? - - /** Absolute value of this numeric value. - * @since 2.0 - */ - def toAbs: Int = if (x < 0) -x else x - - /** Compares this numeric with that numeric for order. Returns a negative integer, zero, or a positive integer as the - * `this` is less than, equal to, or greater than `that`. - */ - def compare(that: Int): Int = if (x < that) -1 else if (x == that) 0 else 1 } - implicit class LongOps(val x: Long) extends AnyVal { - def toByteExact: Byte = { - if (x < Byte.MinValue || x > Byte.MaxValue) - throw new ArithmeticException("Byte overflow") - x.toByte - } - - def toShortExact: Short = { - if (x < Short.MinValue || x > Short.MaxValue) - throw new ArithmeticException("Short overflow") - x.toShort - } - - def toIntExact: Int = { - if (x < Int.MinValue || x > Int.MaxValue) - throw new ArithmeticException("Int overflow") - x.toInt - } - } - - implicit class BigIntegerOps(val x: BigInteger) extends AnyVal { - /** Returns this `mod` Q, i.e. remainder of division by Q, where Q is an order of the cryprographic group. - * @since 2.0 + implicit class LongOpsForSigma(val x: Long) extends AnyVal { + /** Returns a big-endian representation of this Long in a collection of bytes. + * For example, the Long value {@code 0x1213141516171819} would yield the + * byte array {@code {0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19}}. */ - def modQ: BigInt = ??? + def toBytes: Coll[Byte] = Builder.DefaultCollBuilder.fromArray(Longs.toByteArray(x)) - /** Adds this number with `other` by module Q. - * @since 2.0 - */ - def plusModQ(other: BigInt): BigInt = ??? - - /** Subracts this number with `other` by module Q. - * @since 2.0 - */ - def minusModQ(other: BigInt): BigInt = ??? - - /** Multiply this number with `other` by module Q. + /** Returns a big-endian representation of this numeric in a collection of Booleans. + * Each boolean corresponds to one bit. * @since 2.0 */ - def multModQ(other: BigInt): BigInt = ??? - - /** Multiply this number with `other` by module Q. - * @since Mainnet - */ - def multInverseModQ: BigInt = ??? - - /** Checks this {@code BigInteger} can be cust to 256 bit two's-compliment representation, - * checking for lost information. If the value of this {@code BigInteger} - * is out of the range of the 256 bits, then an {@code ArithmeticException} is thrown. - * - * @return this {@code BigInteger} if the check is successful - * @throws ArithmeticException if the value of {@code this} will - * not exactly fit in a 256 bit range. - * @see BigInteger#longValueExact - */ - @inline final def to256BitValueExact: BigInteger = { - if (x.bitLength() <= 255) x - else - throw new ArithmeticException("BigInteger out of 256 bit range"); - } - } - - implicit class OptionOps[T](val opt: Option[T]) extends AnyVal { - /** Elvis operator for Option. See https://en.wikipedia.org/wiki/Elvis_operator*/ - def ?:(whenNone: => T): T = if (opt.isDefined) opt.get else whenNone - } - - implicit class ProductOps(val source: Product) extends AnyVal { - def toArray: Array[Any] = { - val arity = source.productArity - val res = new Array[Any](arity) - var i = 0 - while (i < arity) { - res(i) = source.productElement(i) - i += 1 - } - res - } - } - - implicit class ByteBufferOps(val buf: ByteBuffer) extends AnyVal { - def toBytes: Array[Byte] = { - val res = new Array[Byte](buf.position()) - buf.array().copyToArray(res, 0, res.length) - res - } - def getBytes(size: Int): Array[Byte] = { - val res = new Array[Byte](size) - buf.get(res) - res - } - def getOption[T](getValue: => T): Option[T] = { - val tag = buf.get() - if (tag != 0) - Some(getValue) - else - None - } + def toBits: Coll[Boolean] = ??? } } diff --git a/sigma-impl/src/main/scala/special/sigma/SigmaDslOverArrays.scala b/sigma-impl/src/main/scala/special/sigma/SigmaDslOverArrays.scala index 47f279fd88..f14ba44ccd 100644 --- a/sigma-impl/src/main/scala/special/sigma/SigmaDslOverArrays.scala +++ b/sigma-impl/src/main/scala/special/sigma/SigmaDslOverArrays.scala @@ -11,7 +11,7 @@ import scalan.{RType, Internal, NeverInline, Reified} import scorex.crypto.hash.{Sha256, Blake2b256} import special.SpecialPredef import special.collection._ -import sigma.util.Extensions.BigIntegerOps +import scalan.util.Extensions.BigIntegerOps class TestSigmaDslBuilder extends SigmaDslBuilder { // manual fix @@ -87,17 +87,21 @@ class TestSigmaDslBuilder extends SigmaDslBuilder { this.GroupElement(__curve__.getCurve.decodePoint(encoded.toArray)) @NeverInline + @Internal override def BigInt(n: BigInteger): BigInt = SpecialPredef.rewritableMethod @NeverInline + @Internal override def toBigInteger(n: BigInt): BigInteger = n.asInstanceOf[TestBigInt].value /** Create DSL's group element from existing `org.bouncycastle.math.ec.ECPoint`. */ @NeverInline + @Internal def GroupElement(p: ECPoint): GroupElement = SpecialPredef.rewritableMethod /** Extract `org.bouncycastle.math.ec.ECPoint` from DSL's `GroupElement` type. */ @NeverInline + @Internal def toECPoint(ge: GroupElement): ECPoint = ge.value @NeverInline diff --git a/sigma-impl/src/main/scala/special/sigma/TestBigInt.scala b/sigma-impl/src/main/scala/special/sigma/TestBigInt.scala index 0fcbd38d0e..595e9cc2ec 100644 --- a/sigma-impl/src/main/scala/special/sigma/TestBigInt.scala +++ b/sigma-impl/src/main/scala/special/sigma/TestBigInt.scala @@ -1,8 +1,8 @@ package special.sigma -import special.collection.{Coll} +import special.collection.Coll import java.math.BigInteger -import sigma.util.Extensions.BigIntegerOps +import scalan.util.Extensions.BigIntegerOps abstract class TestBigInt(private[sigma] val value: BigInteger) extends BigInt { val dsl: TestSigmaDslBuilder = new TestSigmaDslBuilder diff --git a/sigma-impl/src/main/scala/special/sigma/TestContracts.scala b/sigma-impl/src/main/scala/special/sigma/TestContracts.scala deleted file mode 100644 index 5e828882f4..0000000000 --- a/sigma-impl/src/main/scala/special/sigma/TestContracts.scala +++ /dev/null @@ -1,18 +0,0 @@ -package special.sigma - -class CrowdFundingContract( - val deadline: Long, val minToRaise: Long, - val backerPubKey: SigmaProp, - val projectPubKey: SigmaProp -) extends CrowdFunding { - override def builder: SigmaDslBuilder = new TestSigmaDslBuilder -} - -class DemurrageCurrencyContract( - val demurragePeriod: Int, - val demurrageCost: Long, - val regScript: SigmaProp -) extends DemurrageCurrency { - override def builder: SigmaDslBuilder = new TestSigmaDslBuilder -} - diff --git a/sigma-impl/src/main/scala/special/sigma/TestCostModel.scala b/sigma-impl/src/main/scala/special/sigma/TestCostModel.scala index 57babeed93..2a7dd319e5 100644 --- a/sigma-impl/src/main/scala/special/sigma/TestCostModel.scala +++ b/sigma-impl/src/main/scala/special/sigma/TestCostModel.scala @@ -17,6 +17,5 @@ class TestCostModel extends CostModel { def SelectField: Int = CostTable.DefaultCosts("SelectField") def CollectionConst: Int = CostTable.DefaultCosts("Const: () => Array[IV]") def AccessKiloByteOfData: Int = CostTable.DefaultCosts("AccessKiloByteOfData") - def dataSize[T](x: T)(implicit cT: ClassTag[T]): Long = SigmaPredef.dataSize(x) override def PubKeySize: Long = 32 } diff --git a/sigma-impl/src/test/scala/sigma/types/TypesTests.scala b/sigma-impl/src/test/scala/sigma/types/TypesTests.scala index 7d183eedce..19d9e35d54 100644 --- a/sigma-impl/src/test/scala/sigma/types/TypesTests.scala +++ b/sigma-impl/src/test/scala/sigma/types/TypesTests.scala @@ -5,7 +5,7 @@ import org.scalatest.{PropSpec, Matchers} import org.scalacheck.{Arbitrary, Gen} import org.scalacheck.Arbitrary._ import special.collections.CollGens -import sigma.util.Extensions._ +import scalan.util.Extensions._ class TypesTests extends PropSpec with PropertyChecks with Matchers with CollGens { testSuite => diff --git a/sigma-library/src/main/scala/scalan/SigmaLibrary.scala b/sigma-library/src/main/scala/scalan/SigmaLibrary.scala index 8db82ef30f..eafb9551c6 100644 --- a/sigma-library/src/main/scala/scalan/SigmaLibrary.scala +++ b/sigma-library/src/main/scala/scalan/SigmaLibrary.scala @@ -1,26 +1,18 @@ package scalan -import org.bouncycastle.crypto.ec.CustomNamedCurves -import org.bouncycastle.math.ec.ECPoint import special.sigma._ -import special.sigma.wrappers.WrappersSpecModule import scala.collection.mutable.ArrayBuffer trait SigmaLibrary extends Library with special.sigma.wrappers.WrappersModule - with WrappersSpecModule with SigmaDslModule with CostedObjectsModule - with SigmaDslOverArraysModule - with SigmaDslCostedModule { - import WArray._ import Coll._ import CollBuilder._ import SigmaProp._ import SigmaContract._ - import WECPoint._ import SigmaDslBuilder._ import WRType._ import Size._ @@ -28,105 +20,8 @@ trait SigmaLibrary extends Library implicit lazy val wRTypeAnyElement = wRTypeElement(AnyElement) implicit lazy val sizeAnyElement = sizeElement(AnyElement) - private val WA = WArrayMethods - private val CM = CollMethods - private val CBM = CollBuilderMethods - private val SM = SigmaPropMethods - private val SCM = SigmaContractMethods - private val SDBM = SigmaDslBuilderMethods - def sigmaDslBuilder: Rep[SigmaDslBuilder] + def sigmaDslBuilder: Ref[SigmaDslBuilder] - object AnyOf { - def unapply(d: Def[_]): Option[(Rep[CollBuilder], Seq[Rep[A]], Elem[A]) forSome {type A}] = d match { - case SDBM.anyOf(_, CBM.fromItems(b, items, e)) => - Some((b, items, e.asInstanceOf[Elem[Any]])) - case _ => None - } - } - object AllOf { - def unapply(d: Def[_]): Option[(Rep[CollBuilder], Seq[Rep[A]], Elem[A]) forSome {type A}] = d match { - case SDBM.allOf(_, CBM.fromItems(b, items, e)) => - Some((b, items, e.asInstanceOf[Elem[Any]])) - case _ => None - } - } - object AnyZk { - def unapply(d: Def[_]): Option[(Rep[CollBuilder], Seq[Rep[SigmaProp]], Elem[SigmaProp])] = d match { - case SDBM.anyZK(_, CBM.fromItems(b, items, e)) => - Some((b, items.asInstanceOf[Seq[Rep[SigmaProp]]], e.asInstanceOf[Elem[SigmaProp]])) - case _ => None - } - } - object AllZk { - def unapply(d: Def[_]): Option[(Rep[CollBuilder], Seq[Rep[SigmaProp]], Elem[SigmaProp])] = d match { - case SDBM.allZK(_, CBM.fromItems(b, items, e)) => - Some((b, items.asInstanceOf[Seq[Rep[SigmaProp]]], e.asInstanceOf[Elem[SigmaProp]])) - case _ => None - } - } - object HasSigmas { - def unapply(items: Seq[Sym]): Option[(Seq[Rep[Boolean]], Seq[Rep[SigmaProp]])] = { - val bs = ArrayBuffer.empty[Rep[Boolean]] - val ss = ArrayBuffer.empty[Rep[SigmaProp]] - for (i <- items) { - i match { - case SM.isValid(s) => ss += s - case b => bs += b.asRep[Boolean] - } - } - assert(items.length == bs.length + ss.length) - if (ss.isEmpty) None - else Some((bs,ss)) - } - } - - override def rewriteDef[T](d: Def[T]) = d match { - case AllOf(b, HasSigmas(bools, sigmas), _) => - val zkAll = sigmaDslBuilder.allZK(b.fromItems(sigmas:_*)) - if (bools.isEmpty) - zkAll.isValid - else - (sigmaDslBuilder.sigmaProp(sigmaDslBuilder.allOf(b.fromItems(bools:_*))) && zkAll).isValid - case AnyOf(b, HasSigmas(bs, ss), _) => - val zkAny = sigmaDslBuilder.anyZK(b.fromItems(ss:_*)) - if (bs.isEmpty) - zkAny.isValid - else - (sigmaDslBuilder.sigmaProp(sigmaDslBuilder.anyOf(b.fromItems(bs:_*))) || zkAny).isValid - case AllOf(_,items,_) if items.length == 1 => items(0) - case AnyOf(_,items,_) if items.length == 1 => items(0) - case AllZk(_,items,_) if items.length == 1 => items(0) - case AnyZk(_,items,_) if items.length == 1 => items(0) - - case ApplyBinOp(op, lhs, rhs) => - op.asInstanceOf[BinOp[_, _]] match { - case And => - sigmaDslBuilder.allOf(sigmaDslBuilder.Colls.fromItems(Seq(lhs.asRep[Boolean], rhs.asRep[Boolean]):_*)) - case Or => - sigmaDslBuilder.anyOf(sigmaDslBuilder.Colls.fromItems(Seq(lhs.asRep[Boolean], rhs.asRep[Boolean]):_*)) - case _ => super.rewriteDef(d) - } - - case SDBM.sigmaProp(_, SM.isValid(p)) => p - case SM.isValid(SDBM.sigmaProp(_, bool)) => bool - - case _ => - if (currentPass.config.constantPropagation) { - // additional constant propagation rules (see other similar cases) - d match { - case AnyOf(_,items,_) if (items.forall(_.isConst)) => - val bs = items.map { case Def(Const(b: Boolean)) => b } - toRep(bs.exists(_ == true)) - case AllOf(_,items,_) if (items.forall(_.isConst)) => - val bs = items.map { case Def(Const(b: Boolean)) => b } - toRep(bs.forall(_ == true)) - case _ => - super.rewriteDef(d) - } - } - else - super.rewriteDef(d) - } } diff --git a/sigma-library/src/main/scala/special/sigma/CostedObjects.scala b/sigma-library/src/main/scala/special/sigma/CostedObjects.scala deleted file mode 100644 index 9e0ffcf3bb..0000000000 --- a/sigma-library/src/main/scala/special/sigma/CostedObjects.scala +++ /dev/null @@ -1,56 +0,0 @@ -package special.sigma { - import scalan._ - - trait CostedObjects extends Base { self: SigmaLibrary => - import AnyValue._; - import AvlTree._; - import Box._; - import Coll._; - import Context._; - import Header._; - import PreHeader._; - import SigmaProp._; - import Size._; - import SizeAnyValue._; - import SizeBox._; - import SizeBuilder._; - import SizeContext._; - import WOption._; - import WRType._; - @Liftable trait SizeAnyValue extends Size[AnyValue] { - def tVal: Rep[WRType[Any]]; - def valueSize: Rep[Size[Any]] - }; - @Liftable trait SizeSigmaProp extends Size[SigmaProp] { - def propBytes: Rep[Size[Coll[Byte]]] - }; - @Liftable trait SizeBox extends Size[Box] { - def propositionBytes: Rep[Size[Coll[Byte]]]; - def bytes: Rep[Size[Coll[Byte]]]; - def bytesWithoutRef: Rep[Size[Coll[Byte]]]; - def registers: Rep[Size[Coll[WOption[AnyValue]]]]; - def getReg[T](id: Rep[Byte])(implicit tT: Elem[T]): Rep[Size[WOption[T]]]; - def tokens: Rep[Size[Coll[scala.Tuple2[Coll[Byte], Long]]]] - }; - @Liftable trait SizeContext extends Size[Context] { - def outputs: Rep[Size[Coll[Box]]]; - def inputs: Rep[Size[Coll[Box]]]; - def dataInputs: Rep[Size[Coll[Box]]]; - def selfBox: Rep[Size[Box]]; - def lastBlockUtxoRootHash: Rep[Size[AvlTree]]; - def headers: Rep[Size[Coll[Header]]]; - def preHeader: Rep[Size[PreHeader]]; - def getVar[T](id: Rep[Byte])(implicit tT: Elem[T]): Rep[Size[WOption[T]]] - }; - @Liftable trait SizeBuilder extends Def[SizeBuilder] { - def mkSizeAnyValue(tVal: Rep[WRType[Any]], valueSize: Rep[Size[Any]]): Rep[SizeAnyValue]; - def mkSizeBox(propositionBytes: Rep[Size[Coll[Byte]]], bytes: Rep[Size[Coll[Byte]]], bytesWithoutRef: Rep[Size[Coll[Byte]]], registers: Rep[Size[Coll[WOption[AnyValue]]]], tokens: Rep[Size[Coll[scala.Tuple2[Coll[Byte], Long]]]]): Rep[SizeBox]; - def mkSizeContext(outputs: Rep[Size[Coll[Box]]], inputs: Rep[Size[Coll[Box]]], dataInputs: Rep[Size[Coll[Box]]], selfBox: Rep[Size[Box]], lastBlockUtxoRootHash: Rep[Size[AvlTree]], headers: Rep[Size[Coll[Header]]], preHeader: Rep[Size[PreHeader]], vars: Rep[Coll[Size[AnyValue]]]): Rep[SizeContext] - }; - trait SizeAnyValueCompanion; - trait SizeSigmaPropCompanion; - trait SizeBoxCompanion; - trait SizeContextCompanion; - trait SizeBuilderCompanion - } -} \ No newline at end of file diff --git a/sigma-library/src/main/scala/special/sigma/CostedObjectsUnit.scala b/sigma-library/src/main/scala/special/sigma/CostedObjectsUnit.scala new file mode 100644 index 0000000000..2c19629dff --- /dev/null +++ b/sigma-library/src/main/scala/special/sigma/CostedObjectsUnit.scala @@ -0,0 +1,56 @@ +package special.sigma { + import scalan._ + + trait CostedObjects extends Base { self: SigmaLibrary => + import AnyValue._; + import AvlTree._; + import Box._; + import Coll._; + import Context._; + import Header._; + import PreHeader._; + import SigmaProp._; + import Size._; + import SizeAnyValue._; + import SizeBox._; + import SizeBuilder._; + import SizeContext._; + import WOption._; + import WRType._; + @Liftable @WithMethodCallRecognizers trait SizeAnyValue extends Size[AnyValue] { + def tVal: Ref[WRType[Any]]; + def valueSize: Ref[Size[Any]] + }; + @Liftable @WithMethodCallRecognizers trait SizeSigmaProp extends Size[SigmaProp] { + def propBytes: Ref[Size[Coll[Byte]]] + }; + @Liftable @WithMethodCallRecognizers trait SizeBox extends Size[Box] { + def propositionBytes: Ref[Size[Coll[Byte]]]; + def bytes: Ref[Size[Coll[Byte]]]; + def bytesWithoutRef: Ref[Size[Coll[Byte]]]; + def registers: Ref[Size[Coll[WOption[AnyValue]]]]; + def getReg[T](id: Ref[Byte])(implicit tT: Elem[T]): Ref[Size[WOption[T]]]; + def tokens: Ref[Size[Coll[scala.Tuple2[Coll[Byte], Long]]]] + }; + @Liftable @WithMethodCallRecognizers trait SizeContext extends Size[Context] { + def outputs: Ref[Size[Coll[Box]]]; + def inputs: Ref[Size[Coll[Box]]]; + def dataInputs: Ref[Size[Coll[Box]]]; + def selfBox: Ref[Size[Box]]; + def lastBlockUtxoRootHash: Ref[Size[AvlTree]]; + def headers: Ref[Size[Coll[Header]]]; + def preHeader: Ref[Size[PreHeader]]; + def getVar[T](id: Ref[Byte])(implicit tT: Elem[T]): Ref[Size[WOption[T]]] + }; + @Liftable trait SizeBuilder extends Def[SizeBuilder] { + def mkSizeAnyValue(tVal: Ref[WRType[Any]], valueSize: Ref[Size[Any]]): Ref[SizeAnyValue]; + def mkSizeBox(propositionBytes: Ref[Size[Coll[Byte]]], bytes: Ref[Size[Coll[Byte]]], bytesWithoutRef: Ref[Size[Coll[Byte]]], registers: Ref[Size[Coll[WOption[AnyValue]]]], tokens: Ref[Size[Coll[scala.Tuple2[Coll[Byte], Long]]]]): Ref[SizeBox]; + def mkSizeContext(outputs: Ref[Size[Coll[Box]]], inputs: Ref[Size[Coll[Box]]], dataInputs: Ref[Size[Coll[Box]]], selfBox: Ref[Size[Box]], lastBlockUtxoRootHash: Ref[Size[AvlTree]], headers: Ref[Size[Coll[Header]]], preHeader: Ref[Size[PreHeader]], vars: Ref[Coll[Size[AnyValue]]]): Ref[SizeContext] + }; + trait SizeAnyValueCompanion; + trait SizeSigmaPropCompanion; + trait SizeBoxCompanion; + trait SizeContextCompanion; + trait SizeBuilderCompanion + } +} \ No newline at end of file diff --git a/sigma-library/src/main/scala/special/sigma/SigmaDsl.scala b/sigma-library/src/main/scala/special/sigma/SigmaDsl.scala deleted file mode 100644 index e2aefa733d..0000000000 --- a/sigma-library/src/main/scala/special/sigma/SigmaDsl.scala +++ /dev/null @@ -1,228 +0,0 @@ -package special.sigma { - import scalan.OverloadHack.Overloaded1 // manual fix - import scalan._ - - trait SigmaDsl extends Base { self: SigmaLibrary => - import AnyValue._; - import AvlTree._; - import BigInt._; - import Box._; - import Coll._; - import CollBuilder._; - import Context._; - import CostModel._; - import CostedBuilder._; - import GroupElement._; - import Header._; - import MonoidBuilder._; - import PreHeader._; - import SigmaContract._; - import SigmaDslBuilder._; - import SigmaProp._; - import WBigInteger._; - import WOption._; - import WRType._; - @Liftable trait CostModel extends Def[CostModel] { - def AccessBox: Rep[Int]; - def AccessAvlTree: Rep[Int]; - def GetVar: Rep[Int]; - def DeserializeVar: Rep[Int]; - def GetRegister: Rep[Int]; - def DeserializeRegister: Rep[Int]; - def SelectField: Rep[Int]; - def CollectionConst: Rep[Int]; - def AccessKiloByteOfData: Rep[Int]; - @Reified(value = "T") def dataSize[T](x: Rep[T])(implicit cT: Elem[T]): Rep[Long]; - def PubKeySize: Rep[Long] - }; - @Liftable trait BigInt extends Def[BigInt] { - def toByte: Rep[Byte]; - def toShort: Rep[Short]; - def toInt: Rep[Int]; - def toLong: Rep[Long]; - def toBytes: Rep[Coll[Byte]]; - def toBits: Rep[Coll[Boolean]]; - def toAbs: Rep[BigInt]; - def compareTo(that: Rep[BigInt]): Rep[Int]; - def modQ: Rep[BigInt]; - def plusModQ(other: Rep[BigInt]): Rep[BigInt]; - def minusModQ(other: Rep[BigInt]): Rep[BigInt]; - def multModQ(other: Rep[BigInt]): Rep[BigInt]; - def inverseModQ: Rep[BigInt]; - def signum: Rep[Int]; - def add(that: Rep[BigInt]): Rep[BigInt]; - def subtract(that: Rep[BigInt]): Rep[BigInt]; - def multiply(that: Rep[BigInt]): Rep[BigInt]; - def divide(that: Rep[BigInt]): Rep[BigInt]; - def mod(m: Rep[BigInt]): Rep[BigInt]; - def remainder(that: Rep[BigInt]): Rep[BigInt]; - def min(that: Rep[BigInt]): Rep[BigInt]; - def max(that: Rep[BigInt]): Rep[BigInt]; - def negate: Rep[BigInt] - }; - @Liftable trait GroupElement extends Def[GroupElement] { - def isInfinity: Rep[Boolean]; - def exp(k: Rep[BigInt]): Rep[GroupElement]; - def multiply(that: Rep[GroupElement]): Rep[GroupElement]; - def negate: Rep[GroupElement]; - def getEncoded: Rep[Coll[Byte]] - }; - @Liftable trait SigmaProp extends Def[SigmaProp] { - def isValid: Rep[Boolean]; - def propBytes: Rep[Coll[Byte]]; - @OverloadId(value = "and_sigma") def &&(other: Rep[SigmaProp]): Rep[SigmaProp]; - // manual fix - @OverloadId(value = "and_bool") def &&(other: Rep[Boolean])(implicit o: Overloaded1): Rep[SigmaProp]; - @OverloadId(value = "or_sigma") def ||(other: Rep[SigmaProp]): Rep[SigmaProp]; - // manual fix - @OverloadId(value = "or_bool") def ||(other: Rep[Boolean])(implicit o: Overloaded1): Rep[SigmaProp]; - }; - @Liftable trait AnyValue extends Def[AnyValue] { - def value: Rep[Any]; - def tVal: Rep[WRType[Any]] - }; - @Liftable trait Box extends Def[Box] { - def id: Rep[Coll[Byte]]; - def value: Rep[Long]; - def propositionBytes: Rep[Coll[Byte]]; - def bytes: Rep[Coll[Byte]]; - def bytesWithoutRef: Rep[Coll[Byte]]; - def registers: Rep[Coll[AnyValue]]; - def getReg[T](i: Rep[Int])(implicit cT: Elem[T]): Rep[WOption[T]]; - def R0[T](implicit cT: Elem[T]): Rep[WOption[T]] = this.getReg[T](toRep(0.asInstanceOf[Int])); - def R1[T](implicit cT: Elem[T]): Rep[WOption[T]] = this.getReg[T](toRep(1.asInstanceOf[Int])); - def R2[T](implicit cT: Elem[T]): Rep[WOption[T]] = this.getReg[T](toRep(2.asInstanceOf[Int])); - def R3[T](implicit cT: Elem[T]): Rep[WOption[T]] = this.getReg[T](toRep(3.asInstanceOf[Int])); - def R4[T](implicit cT: Elem[T]): Rep[WOption[T]] = this.getReg[T](toRep(4.asInstanceOf[Int])); - def R5[T](implicit cT: Elem[T]): Rep[WOption[T]] = this.getReg[T](toRep(5.asInstanceOf[Int])); - def R6[T](implicit cT: Elem[T]): Rep[WOption[T]] = this.getReg[T](toRep(6.asInstanceOf[Int])); - def R7[T](implicit cT: Elem[T]): Rep[WOption[T]] = this.getReg[T](toRep(7.asInstanceOf[Int])); - def R8[T](implicit cT: Elem[T]): Rep[WOption[T]] = this.getReg[T](toRep(8.asInstanceOf[Int])); - def R9[T](implicit cT: Elem[T]): Rep[WOption[T]] = this.getReg[T](toRep(9.asInstanceOf[Int])); - def tokens: Rep[Coll[scala.Tuple2[Coll[Byte], Long]]]; - def creationInfo: Rep[scala.Tuple2[Int, Coll[Byte]]]; - def executeFromRegister[T](regId: Rep[Byte])(implicit cT: Elem[T]): Rep[T] - }; - @Liftable trait AvlTree extends Def[AvlTree] { - def digest: Rep[Coll[Byte]]; - def enabledOperations: Rep[Byte]; - def keyLength: Rep[Int]; - def valueLengthOpt: Rep[WOption[Int]]; - def isInsertAllowed: Rep[Boolean]; - def isUpdateAllowed: Rep[Boolean]; - def isRemoveAllowed: Rep[Boolean]; - def updateDigest(newDigest: Rep[Coll[Byte]]): Rep[AvlTree]; - def updateOperations(newOperations: Rep[Byte]): Rep[AvlTree]; - def contains(key: Rep[Coll[Byte]], proof: Rep[Coll[Byte]]): Rep[Boolean]; - def get(key: Rep[Coll[Byte]], proof: Rep[Coll[Byte]]): Rep[WOption[Coll[Byte]]]; - def getMany(keys: Rep[Coll[Coll[Byte]]], proof: Rep[Coll[Byte]]): Rep[Coll[WOption[Coll[Byte]]]]; - def insert(operations: Rep[Coll[scala.Tuple2[Coll[Byte], Coll[Byte]]]], proof: Rep[Coll[Byte]]): Rep[WOption[AvlTree]]; - def update(operations: Rep[Coll[scala.Tuple2[Coll[Byte], Coll[Byte]]]], proof: Rep[Coll[Byte]]): Rep[WOption[AvlTree]]; - def remove(operations: Rep[Coll[Coll[Byte]]], proof: Rep[Coll[Byte]]): Rep[WOption[AvlTree]] - }; - @Liftable trait PreHeader extends Def[PreHeader] { - def version: Rep[Byte]; - def parentId: Rep[Coll[Byte]]; - def timestamp: Rep[Long]; - def nBits: Rep[Long]; - def height: Rep[Int]; - def minerPk: Rep[GroupElement]; - def votes: Rep[Coll[Byte]] - }; - @Liftable trait Header extends Def[Header] { - def id: Rep[Coll[Byte]]; - def version: Rep[Byte]; - def parentId: Rep[Coll[Byte]]; - def ADProofsRoot: Rep[Coll[Byte]]; - def stateRoot: Rep[AvlTree]; - def transactionsRoot: Rep[Coll[Byte]]; - def timestamp: Rep[Long]; - def nBits: Rep[Long]; - def height: Rep[Int]; - def extensionRoot: Rep[Coll[Byte]]; - def minerPk: Rep[GroupElement]; - def powOnetimePk: Rep[GroupElement]; - def powNonce: Rep[Coll[Byte]]; - def powDistance: Rep[BigInt]; - def votes: Rep[Coll[Byte]] - }; - @Liftable trait Context extends Def[Context] { - def builder: Rep[SigmaDslBuilder]; - def OUTPUTS: Rep[Coll[Box]]; - def INPUTS: Rep[Coll[Box]]; - def dataInputs: Rep[Coll[Box]]; - def HEIGHT: Rep[Int]; - def SELF: Rep[Box]; - def selfBoxIndex: Rep[Int]; - def LastBlockUtxoRootHash: Rep[AvlTree]; - def headers: Rep[Coll[Header]]; - def preHeader: Rep[PreHeader]; - def minerPubKey: Rep[Coll[Byte]]; - def getVar[T](id: Rep[Byte])(implicit cT: Elem[T]): Rep[WOption[T]]; - def vars: Rep[Coll[AnyValue]] - }; - @Liftable trait SigmaContract extends Def[SigmaContract] { - def builder: Rep[SigmaDslBuilder]; - @NeverInline @Reified(value = "T") def Collection[T](items: Rep[T]*)(implicit cT: Elem[T]): Rep[Coll[T]] = delayInvoke; - def verifyZK(cond: Rep[Thunk[SigmaProp]]): Rep[Boolean] = this.builder.verifyZK(cond); - def atLeast(bound: Rep[Int], props: Rep[Coll[SigmaProp]]): Rep[SigmaProp] = this.builder.atLeast(bound, props); - def allOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean] = this.builder.allOf(conditions); - def allZK(conditions: Rep[Coll[SigmaProp]]): Rep[SigmaProp] = this.builder.allZK(conditions); - def anyOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean] = this.builder.anyOf(conditions); - def anyZK(conditions: Rep[Coll[SigmaProp]]): Rep[SigmaProp] = this.builder.anyZK(conditions); - def xorOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean] = this.builder.xorOf(conditions); - def PubKey(base64String: Rep[String]): Rep[SigmaProp] = this.builder.PubKey(base64String); - def sigmaProp(b: Rep[Boolean]): Rep[SigmaProp] = this.builder.sigmaProp(b); - def blake2b256(bytes: Rep[Coll[Byte]]): Rep[Coll[Byte]] = this.builder.blake2b256(bytes); - def sha256(bytes: Rep[Coll[Byte]]): Rep[Coll[Byte]] = this.builder.sha256(bytes); - def byteArrayToBigInt(bytes: Rep[Coll[Byte]]): Rep[BigInt] = this.builder.byteArrayToBigInt(bytes); - def longToByteArray(l: Rep[Long]): Rep[Coll[Byte]] = this.builder.longToByteArray(l); - def byteArrayToLong(bytes: Rep[Coll[Byte]]): Rep[Long] = this.builder.byteArrayToLong(bytes); - def proveDlog(g: Rep[GroupElement]): Rep[SigmaProp] = this.builder.proveDlog(g); - def proveDHTuple(g: Rep[GroupElement], h: Rep[GroupElement], u: Rep[GroupElement], v: Rep[GroupElement]): Rep[SigmaProp] = this.builder.proveDHTuple(g, h, u, v); - def groupGenerator: Rep[GroupElement] = this.builder.groupGenerator; - @clause def canOpen(ctx: Rep[Context]): Rep[Boolean]; - def asFunction: Rep[scala.Function1[Context, Boolean]] = fun(((ctx: Rep[Context]) => this.canOpen(ctx))) - }; - @Liftable trait SigmaDslBuilder extends Def[SigmaDslBuilder] { - def Colls: Rep[CollBuilder]; - def Monoids: Rep[MonoidBuilder]; - def Costing: Rep[CostedBuilder]; - def CostModel: Rep[CostModel]; - def verifyZK(cond: Rep[Thunk[SigmaProp]]): Rep[Boolean]; - def atLeast(bound: Rep[Int], props: Rep[Coll[SigmaProp]]): Rep[SigmaProp]; - def allOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean]; - def allZK(conditions: Rep[Coll[SigmaProp]]): Rep[SigmaProp]; - def anyOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean]; - def anyZK(conditions: Rep[Coll[SigmaProp]]): Rep[SigmaProp]; - def xorOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean]; - def PubKey(base64String: Rep[String]): Rep[SigmaProp]; - def sigmaProp(b: Rep[Boolean]): Rep[SigmaProp]; - def blake2b256(bytes: Rep[Coll[Byte]]): Rep[Coll[Byte]]; - def sha256(bytes: Rep[Coll[Byte]]): Rep[Coll[Byte]]; - def byteArrayToBigInt(bytes: Rep[Coll[Byte]]): Rep[BigInt]; - def longToByteArray(l: Rep[Long]): Rep[Coll[Byte]]; - def byteArrayToLong(bytes: Rep[Coll[Byte]]): Rep[Long]; - def proveDlog(g: Rep[GroupElement]): Rep[SigmaProp]; - def proveDHTuple(g: Rep[GroupElement], h: Rep[GroupElement], u: Rep[GroupElement], v: Rep[GroupElement]): Rep[SigmaProp]; - def groupGenerator: Rep[GroupElement]; - @Reified(value = "T") def substConstants[T](scriptBytes: Rep[Coll[Byte]], positions: Rep[Coll[Int]], newValues: Rep[Coll[T]])(implicit cT: Elem[T]): Rep[Coll[Byte]]; - def decodePoint(encoded: Rep[Coll[Byte]]): Rep[GroupElement]; - def BigInt(n: Rep[WBigInteger]): Rep[BigInt]; - def toBigInteger(n: Rep[BigInt]): Rep[WBigInteger]; - def avlTree(operationFlags: Rep[Byte], digest: Rep[Coll[Byte]], keyLength: Rep[Int], valueLengthOpt: Rep[WOption[Int]]): Rep[AvlTree] - }; - trait CostModelCompanion; - trait BigIntCompanion; - trait GroupElementCompanion; - trait SigmaPropCompanion; - trait AnyValueCompanion; - trait BoxCompanion; - trait AvlTreeCompanion; - trait PreHeaderCompanion; - trait HeaderCompanion; - trait ContextCompanion; - trait SigmaContractCompanion; - trait SigmaDslBuilderCompanion - } -} \ No newline at end of file diff --git a/sigma-library/src/main/scala/special/sigma/SigmaDslCosted.scala b/sigma-library/src/main/scala/special/sigma/SigmaDslCosted.scala deleted file mode 100644 index 85653f79bd..0000000000 --- a/sigma-library/src/main/scala/special/sigma/SigmaDslCosted.scala +++ /dev/null @@ -1,47 +0,0 @@ -package special.sigma { - import scalan._ - - trait SigmaDslCosted extends Base { self: SigmaLibrary => - import AnyValue._; - import AvlTree._; - import Box._; - import CSizeAnyValue._; - import CSizeBox._; - import CSizeContext._; - import Coll._; - import Header._; - import PreHeader._; - import Size._; - import SizeAnyValue._; - import SizeBox._; - import SizeBuilder._; - import SizeContext._; - import SizeSigmaProp._; - import WOption._; - import WRType._; - abstract class CSizeAnyValue(val tVal: Rep[WRType[Any]], val valueSize: Rep[Size[Any]]) extends SizeAnyValue { - @NeverInline override def dataSize: Rep[Long] = delayInvoke - }; - abstract class CSizeSigmaProp(val propBytes: Rep[Size[Coll[Byte]]]) extends SizeSigmaProp { - @NeverInline override def dataSize: Rep[Long] = delayInvoke - }; - abstract class CSizeBox(val propositionBytes: Rep[Size[Coll[Byte]]], val bytes: Rep[Size[Coll[Byte]]], val bytesWithoutRef: Rep[Size[Coll[Byte]]], val registers: Rep[Size[Coll[WOption[AnyValue]]]], val tokens: Rep[Size[Coll[scala.Tuple2[Coll[Byte], Long]]]]) extends SizeBox { - @NeverInline override def dataSize: Rep[Long] = delayInvoke; - @NeverInline override def getReg[T](id: Rep[Byte])(implicit tT: Elem[T]): Rep[Size[WOption[T]]] = delayInvoke - }; - abstract class CSizeContext(val outputs: Rep[Size[Coll[Box]]], val inputs: Rep[Size[Coll[Box]]], val dataInputs: Rep[Size[Coll[Box]]], val selfBox: Rep[Size[Box]], val lastBlockUtxoRootHash: Rep[Size[AvlTree]], val headers: Rep[Size[Coll[Header]]], val preHeader: Rep[Size[PreHeader]], val vars: Rep[Coll[Size[AnyValue]]]) extends SizeContext { - @NeverInline override def dataSize: Rep[Long] = delayInvoke; - @NeverInline override def getVar[T](id: Rep[Byte])(implicit tT: Elem[T]): Rep[Size[WOption[T]]] = delayInvoke - }; - abstract class CSizeBuilder extends SizeBuilder { - def mkSizeAnyValue(tVal: Rep[WRType[Any]], valueSize: Rep[Size[Any]]): Rep[SizeAnyValue] = RCSizeAnyValue(tVal, valueSize); - def mkSizeBox(propositionBytes: Rep[Size[Coll[Byte]]], bytes: Rep[Size[Coll[Byte]]], bytesWithoutRef: Rep[Size[Coll[Byte]]], registers: Rep[Size[Coll[WOption[AnyValue]]]], tokens: Rep[Size[Coll[scala.Tuple2[Coll[Byte], Long]]]]): Rep[SizeBox] = RCSizeBox(propositionBytes, bytes, bytesWithoutRef, registers, tokens); - def mkSizeContext(outputs: Rep[Size[Coll[Box]]], inputs: Rep[Size[Coll[Box]]], dataInputs: Rep[Size[Coll[Box]]], selfBox: Rep[Size[Box]], lastBlockUtxoRootHash: Rep[Size[AvlTree]], headers: Rep[Size[Coll[Header]]], preHeader: Rep[Size[PreHeader]], vars: Rep[Coll[Size[AnyValue]]]): Rep[SizeContext] = RCSizeContext(outputs, inputs, dataInputs, selfBox, lastBlockUtxoRootHash, headers, preHeader, vars) - }; - trait CSizeAnyValueCompanion; - trait CSizeSigmaPropCompanion; - trait CSizeBoxCompanion; - trait CSizeContextCompanion; - trait CSizeBuilderCompanion - } -} \ No newline at end of file diff --git a/sigma-library/src/main/scala/special/sigma/SigmaDslOverArrays.scala b/sigma-library/src/main/scala/special/sigma/SigmaDslOverArrays.scala deleted file mode 100644 index 19dd014f1c..0000000000 --- a/sigma-library/src/main/scala/special/sigma/SigmaDslOverArrays.scala +++ /dev/null @@ -1,57 +0,0 @@ -package special.sigma { - import scalan.OverloadHack.Overloaded1 // manual fix - import scalan._ - - trait SigmaDslOverArrays extends Base { self: SigmaLibrary => - import AvlTree._; - import BigInt._; - import Box._; - import CostedBuilder._ // manual fix - import CCostedBuilder._; - import Coll._; - import CollBuilder._; - import CollOverArrayBuilder._; - import CostModel._; - import CostedBuilder._; - import GroupElement._; - import MonoidBuilder._; - import MonoidBuilderInst._; - import SigmaDslBuilder._; - import SigmaProp._; - import WBigInteger._; - import WECPoint._; - import WOption._; - import WSpecialPredef._; // manual fix - abstract class TestSigmaDslBuilder extends SigmaDslBuilder { - def Colls: Rep[CollBuilder] = RCollOverArrayBuilder(); - def Monoids: Rep[MonoidBuilder] = RMonoidBuilderInst(); - def Costing: Rep[CostedBuilder] = RCCostedBuilder(); - @NeverInline def CostModel: Rep[CostModel] = delayInvoke; - @NeverInline def verifyZK(proof: Rep[Thunk[SigmaProp]]): Rep[Boolean] = delayInvoke; - @NeverInline def atLeast(bound: Rep[Int], props: Rep[Coll[SigmaProp]]): Rep[SigmaProp] = delayInvoke; - @NeverInline def allOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean] = delayInvoke; - @NeverInline def anyOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean] = delayInvoke; - @NeverInline def allZK(props: Rep[Coll[SigmaProp]]): Rep[SigmaProp] = delayInvoke; - @NeverInline def anyZK(props: Rep[Coll[SigmaProp]]): Rep[SigmaProp] = delayInvoke; - @NeverInline override def xorOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean] = delayInvoke; - @NeverInline def sigmaProp(b: Rep[Boolean]): Rep[SigmaProp] = delayInvoke; - @NeverInline def blake2b256(bytes: Rep[Coll[Byte]]): Rep[Coll[Byte]] = delayInvoke; - @NeverInline def sha256(bytes: Rep[Coll[Byte]]): Rep[Coll[Byte]] = delayInvoke; - @NeverInline def PubKey(base64String: Rep[String]): Rep[SigmaProp] = delayInvoke; - @NeverInline def byteArrayToBigInt(bytes: Rep[Coll[Byte]]): Rep[BigInt] = delayInvoke; - @NeverInline def longToByteArray(l: Rep[Long]): Rep[Coll[Byte]] = delayInvoke; - @NeverInline def byteArrayToLong(bytes: Rep[Coll[Byte]]): Rep[Long] = delayInvoke; - @NeverInline def proveDlog(g: Rep[GroupElement]): Rep[SigmaProp] = delayInvoke; - @NeverInline def proveDHTuple(g: Rep[GroupElement], h: Rep[GroupElement], u: Rep[GroupElement], v: Rep[GroupElement]): Rep[SigmaProp] = delayInvoke; - @NeverInline def groupGenerator: Rep[GroupElement] = delayInvoke; - @Reified(value = "T") @NeverInline override def substConstants[T](scriptBytes: Rep[Coll[Byte]], positions: Rep[Coll[Int]], newValues: Rep[Coll[T]])(implicit cT: Elem[T]): Rep[Coll[Byte]] = delayInvoke; - @NeverInline override def decodePoint(encoded: Rep[Coll[Byte]]): Rep[GroupElement] = delayInvoke; - @NeverInline override def BigInt(n: Rep[WBigInteger]): Rep[BigInt] = delayInvoke; - @NeverInline override def toBigInteger(n: Rep[BigInt]): Rep[WBigInteger] = delayInvoke; - @NeverInline def GroupElement(p: Rep[WECPoint]): Rep[GroupElement] = delayInvoke; - @NeverInline def toECPoint(ge: Rep[GroupElement]): Rep[WECPoint] = delayInvoke; - @NeverInline override def avlTree(operationFlags: Rep[Byte], digest: Rep[Coll[Byte]], keyLength: Rep[Int], valueLengthOpt: Rep[WOption[Int]]): Rep[AvlTree] = delayInvoke - }; - trait TestSigmaDslBuilderCompanion - } -} \ No newline at end of file diff --git a/sigma-library/src/main/scala/special/sigma/SigmaDslUnit.scala b/sigma-library/src/main/scala/special/sigma/SigmaDslUnit.scala new file mode 100644 index 0000000000..a31b4e4fde --- /dev/null +++ b/sigma-library/src/main/scala/special/sigma/SigmaDslUnit.scala @@ -0,0 +1,225 @@ +package special.sigma { + import scalan.OverloadHack.Overloaded1 // manual fix + import scalan._ + + trait SigmaDsl extends Base { self: SigmaLibrary => + import AnyValue._; + import AvlTree._; + import BigInt._; + import Box._; + import Coll._; + import CollBuilder._; + import Context._; + import CostModel._; + import CostedBuilder._; + import GroupElement._; + import Header._; + import MonoidBuilder._; + import PreHeader._; + import SigmaContract._; + import SigmaDslBuilder._; + import SigmaProp._; + import WOption._; + import WRType._; + @Liftable trait CostModel extends Def[CostModel] { + def AccessBox: Ref[Int]; + def AccessAvlTree: Ref[Int]; + def GetVar: Ref[Int]; + def DeserializeVar: Ref[Int]; + def GetRegister: Ref[Int]; + def DeserializeRegister: Ref[Int]; + def SelectField: Ref[Int]; + def CollectionConst: Ref[Int]; + def AccessKiloByteOfData: Ref[Int]; + def PubKeySize: Ref[Long] + }; + @Liftable @WithMethodCallRecognizers trait BigInt extends Def[BigInt] { + def toByte: Ref[Byte]; + def toShort: Ref[Short]; + def toInt: Ref[Int]; + def toLong: Ref[Long]; + def toBytes: Ref[Coll[Byte]]; + def toBits: Ref[Coll[Boolean]]; + def toAbs: Ref[BigInt]; + def compareTo(that: Ref[BigInt]): Ref[Int]; + def modQ: Ref[BigInt]; + def plusModQ(other: Ref[BigInt]): Ref[BigInt]; + def minusModQ(other: Ref[BigInt]): Ref[BigInt]; + def multModQ(other: Ref[BigInt]): Ref[BigInt]; + def inverseModQ: Ref[BigInt]; + def signum: Ref[Int]; + def add(that: Ref[BigInt]): Ref[BigInt]; + def subtract(that: Ref[BigInt]): Ref[BigInt]; + def multiply(that: Ref[BigInt]): Ref[BigInt]; + def divide(that: Ref[BigInt]): Ref[BigInt]; + def mod(m: Ref[BigInt]): Ref[BigInt]; + def remainder(that: Ref[BigInt]): Ref[BigInt]; + def min(that: Ref[BigInt]): Ref[BigInt]; + def max(that: Ref[BigInt]): Ref[BigInt]; + def negate: Ref[BigInt] + }; + @Liftable @WithMethodCallRecognizers trait GroupElement extends Def[GroupElement] { + def isInfinity: Ref[Boolean]; + def exp(k: Ref[BigInt]): Ref[GroupElement]; + def multiply(that: Ref[GroupElement]): Ref[GroupElement]; + def negate: Ref[GroupElement]; + def getEncoded: Ref[Coll[Byte]] + }; + @Liftable @WithMethodCallRecognizers trait SigmaProp extends Def[SigmaProp] { + def isValid: Ref[Boolean]; + def propBytes: Ref[Coll[Byte]]; + @OverloadId(value = "and_sigma") def &&(other: Ref[SigmaProp]): Ref[SigmaProp]; + // manual fix + @OverloadId(value = "and_bool") def &&(other: Ref[Boolean])(implicit o: Overloaded1): Ref[SigmaProp]; + @OverloadId(value = "or_sigma") def ||(other: Ref[SigmaProp]): Ref[SigmaProp]; + // manual fix + @OverloadId(value = "or_bool") def ||(other: Ref[Boolean])(implicit o: Overloaded1): Ref[SigmaProp]; + }; + @Liftable @WithMethodCallRecognizers trait AnyValue extends Def[AnyValue] { + def value: Ref[Any]; + def tVal: Ref[WRType[Any]] + }; + @Liftable @WithMethodCallRecognizers trait Box extends Def[Box] { + def id: Ref[Coll[Byte]]; + def value: Ref[Long]; + def propositionBytes: Ref[Coll[Byte]]; + def bytes: Ref[Coll[Byte]]; + def bytesWithoutRef: Ref[Coll[Byte]]; + def registers: Ref[Coll[AnyValue]]; + def getReg[T](i: Ref[Int])(implicit cT: Elem[T]): Ref[WOption[T]]; + def R0[T](implicit cT: Elem[T]): Ref[WOption[T]] = this.getReg[T](toRep(0.asInstanceOf[Int])); + def R1[T](implicit cT: Elem[T]): Ref[WOption[T]] = this.getReg[T](toRep(1.asInstanceOf[Int])); + def R2[T](implicit cT: Elem[T]): Ref[WOption[T]] = this.getReg[T](toRep(2.asInstanceOf[Int])); + def R3[T](implicit cT: Elem[T]): Ref[WOption[T]] = this.getReg[T](toRep(3.asInstanceOf[Int])); + def R4[T](implicit cT: Elem[T]): Ref[WOption[T]] = this.getReg[T](toRep(4.asInstanceOf[Int])); + def R5[T](implicit cT: Elem[T]): Ref[WOption[T]] = this.getReg[T](toRep(5.asInstanceOf[Int])); + def R6[T](implicit cT: Elem[T]): Ref[WOption[T]] = this.getReg[T](toRep(6.asInstanceOf[Int])); + def R7[T](implicit cT: Elem[T]): Ref[WOption[T]] = this.getReg[T](toRep(7.asInstanceOf[Int])); + def R8[T](implicit cT: Elem[T]): Ref[WOption[T]] = this.getReg[T](toRep(8.asInstanceOf[Int])); + def R9[T](implicit cT: Elem[T]): Ref[WOption[T]] = this.getReg[T](toRep(9.asInstanceOf[Int])); + def tokens: Ref[Coll[scala.Tuple2[Coll[Byte], Long]]]; + def creationInfo: Ref[scala.Tuple2[Int, Coll[Byte]]]; + def executeFromRegister[T](regId: Ref[Byte])(implicit cT: Elem[T]): Ref[T] + }; + @Liftable trait AvlTree extends Def[AvlTree] { + def digest: Ref[Coll[Byte]]; + def enabledOperations: Ref[Byte]; + def keyLength: Ref[Int]; + def valueLengthOpt: Ref[WOption[Int]]; + def isInsertAllowed: Ref[Boolean]; + def isUpdateAllowed: Ref[Boolean]; + def isRemoveAllowed: Ref[Boolean]; + def updateDigest(newDigest: Ref[Coll[Byte]]): Ref[AvlTree]; + def updateOperations(newOperations: Ref[Byte]): Ref[AvlTree]; + def contains(key: Ref[Coll[Byte]], proof: Ref[Coll[Byte]]): Ref[Boolean]; + def get(key: Ref[Coll[Byte]], proof: Ref[Coll[Byte]]): Ref[WOption[Coll[Byte]]]; + def getMany(keys: Ref[Coll[Coll[Byte]]], proof: Ref[Coll[Byte]]): Ref[Coll[WOption[Coll[Byte]]]]; + def insert(operations: Ref[Coll[scala.Tuple2[Coll[Byte], Coll[Byte]]]], proof: Ref[Coll[Byte]]): Ref[WOption[AvlTree]]; + def update(operations: Ref[Coll[scala.Tuple2[Coll[Byte], Coll[Byte]]]], proof: Ref[Coll[Byte]]): Ref[WOption[AvlTree]]; + def remove(operations: Ref[Coll[Coll[Byte]]], proof: Ref[Coll[Byte]]): Ref[WOption[AvlTree]] + }; + @Liftable trait PreHeader extends Def[PreHeader] { + def version: Ref[Byte]; + def parentId: Ref[Coll[Byte]]; + def timestamp: Ref[Long]; + def nBits: Ref[Long]; + def height: Ref[Int]; + def minerPk: Ref[GroupElement]; + def votes: Ref[Coll[Byte]] + }; + @Liftable trait Header extends Def[Header] { + def id: Ref[Coll[Byte]]; + def version: Ref[Byte]; + def parentId: Ref[Coll[Byte]]; + def ADProofsRoot: Ref[Coll[Byte]]; + def stateRoot: Ref[AvlTree]; + def transactionsRoot: Ref[Coll[Byte]]; + def timestamp: Ref[Long]; + def nBits: Ref[Long]; + def height: Ref[Int]; + def extensionRoot: Ref[Coll[Byte]]; + def minerPk: Ref[GroupElement]; + def powOnetimePk: Ref[GroupElement]; + def powNonce: Ref[Coll[Byte]]; + def powDistance: Ref[BigInt]; + def votes: Ref[Coll[Byte]] + }; + @Liftable @WithMethodCallRecognizers trait Context extends Def[Context] { + def builder: Ref[SigmaDslBuilder]; + def OUTPUTS: Ref[Coll[Box]]; + def INPUTS: Ref[Coll[Box]]; + def dataInputs: Ref[Coll[Box]]; + def HEIGHT: Ref[Int]; + def SELF: Ref[Box]; + def selfBoxIndex: Ref[Int]; + def LastBlockUtxoRootHash: Ref[AvlTree]; + def headers: Ref[Coll[Header]]; + def preHeader: Ref[PreHeader]; + def minerPubKey: Ref[Coll[Byte]]; + def getVar[T](id: Ref[Byte])(implicit cT: Elem[T]): Ref[WOption[T]]; + def vars: Ref[Coll[AnyValue]] + }; + @Liftable trait SigmaContract extends Def[SigmaContract] { + def builder: Ref[SigmaDslBuilder]; + @NeverInline @Reified(value = "T") def Collection[T](items: Ref[T]*)(implicit cT: Elem[T]): Ref[Coll[T]] = delayInvoke; + def verifyZK(cond: Ref[Thunk[SigmaProp]]): Ref[Boolean] = this.builder.verifyZK(cond); + def atLeast(bound: Ref[Int], props: Ref[Coll[SigmaProp]]): Ref[SigmaProp] = this.builder.atLeast(bound, props); + def allOf(conditions: Ref[Coll[Boolean]]): Ref[Boolean] = this.builder.allOf(conditions); + def allZK(conditions: Ref[Coll[SigmaProp]]): Ref[SigmaProp] = this.builder.allZK(conditions); + def anyOf(conditions: Ref[Coll[Boolean]]): Ref[Boolean] = this.builder.anyOf(conditions); + def anyZK(conditions: Ref[Coll[SigmaProp]]): Ref[SigmaProp] = this.builder.anyZK(conditions); + def xorOf(conditions: Ref[Coll[Boolean]]): Ref[Boolean] = this.builder.xorOf(conditions); + def PubKey(base64String: Ref[String]): Ref[SigmaProp] = this.builder.PubKey(base64String); + def sigmaProp(b: Ref[Boolean]): Ref[SigmaProp] = this.builder.sigmaProp(b); + def blake2b256(bytes: Ref[Coll[Byte]]): Ref[Coll[Byte]] = this.builder.blake2b256(bytes); + def sha256(bytes: Ref[Coll[Byte]]): Ref[Coll[Byte]] = this.builder.sha256(bytes); + def byteArrayToBigInt(bytes: Ref[Coll[Byte]]): Ref[BigInt] = this.builder.byteArrayToBigInt(bytes); + def longToByteArray(l: Ref[Long]): Ref[Coll[Byte]] = this.builder.longToByteArray(l); + def byteArrayToLong(bytes: Ref[Coll[Byte]]): Ref[Long] = this.builder.byteArrayToLong(bytes); + def proveDlog(g: Ref[GroupElement]): Ref[SigmaProp] = this.builder.proveDlog(g); + def proveDHTuple(g: Ref[GroupElement], h: Ref[GroupElement], u: Ref[GroupElement], v: Ref[GroupElement]): Ref[SigmaProp] = this.builder.proveDHTuple(g, h, u, v); + def groupGenerator: Ref[GroupElement] = this.builder.groupGenerator; + def decodePoint(encoded: Ref[Coll[Byte]]): Ref[GroupElement] = this.builder.decodePoint(encoded); + @Reified(value = "T") def substConstants[T](scriptBytes: Ref[Coll[Byte]], positions: Ref[Coll[Int]], newValues: Ref[Coll[T]])(implicit cT: Elem[T]): Ref[Coll[Byte]] = this.builder.substConstants[T](scriptBytes, positions, newValues) + }; + @Liftable @WithMethodCallRecognizers trait SigmaDslBuilder extends Def[SigmaDslBuilder] { + def Colls: Ref[CollBuilder]; + def Monoids: Ref[MonoidBuilder]; + def Costing: Ref[CostedBuilder]; + def CostModel: Ref[CostModel]; + def verifyZK(cond: Ref[Thunk[SigmaProp]]): Ref[Boolean]; + def atLeast(bound: Ref[Int], props: Ref[Coll[SigmaProp]]): Ref[SigmaProp]; + def allOf(conditions: Ref[Coll[Boolean]]): Ref[Boolean]; + def allZK(conditions: Ref[Coll[SigmaProp]]): Ref[SigmaProp]; + def anyOf(conditions: Ref[Coll[Boolean]]): Ref[Boolean]; + def anyZK(conditions: Ref[Coll[SigmaProp]]): Ref[SigmaProp]; + def xorOf(conditions: Ref[Coll[Boolean]]): Ref[Boolean]; + def PubKey(base64String: Ref[String]): Ref[SigmaProp]; + def sigmaProp(b: Ref[Boolean]): Ref[SigmaProp]; + def blake2b256(bytes: Ref[Coll[Byte]]): Ref[Coll[Byte]]; + def sha256(bytes: Ref[Coll[Byte]]): Ref[Coll[Byte]]; + def byteArrayToBigInt(bytes: Ref[Coll[Byte]]): Ref[BigInt]; + def longToByteArray(l: Ref[Long]): Ref[Coll[Byte]]; + def byteArrayToLong(bytes: Ref[Coll[Byte]]): Ref[Long]; + def proveDlog(g: Ref[GroupElement]): Ref[SigmaProp]; + def proveDHTuple(g: Ref[GroupElement], h: Ref[GroupElement], u: Ref[GroupElement], v: Ref[GroupElement]): Ref[SigmaProp]; + def groupGenerator: Ref[GroupElement]; + @Reified(value = "T") def substConstants[T](scriptBytes: Ref[Coll[Byte]], positions: Ref[Coll[Int]], newValues: Ref[Coll[T]])(implicit cT: Elem[T]): Ref[Coll[Byte]]; + def decodePoint(encoded: Ref[Coll[Byte]]): Ref[GroupElement]; + def avlTree(operationFlags: Ref[Byte], digest: Ref[Coll[Byte]], keyLength: Ref[Int], valueLengthOpt: Ref[WOption[Int]]): Ref[AvlTree]; + def xor(l: Ref[Coll[Byte]], r: Ref[Coll[Byte]]): Ref[Coll[Byte]] + }; + trait CostModelCompanion; + trait BigIntCompanion; + trait GroupElementCompanion; + trait SigmaPropCompanion; + trait AnyValueCompanion; + trait BoxCompanion; + trait AvlTreeCompanion; + trait PreHeaderCompanion; + trait HeaderCompanion; + trait ContextCompanion; + trait SigmaContractCompanion; + trait SigmaDslBuilderCompanion + } +} \ No newline at end of file diff --git a/sigma-library/src/main/scala/special/sigma/impl/CostedObjectsImpl.scala b/sigma-library/src/main/scala/special/sigma/impl/CostedObjectsImpl.scala index 17362add1d..2e9632ca66 100644 --- a/sigma-library/src/main/scala/special/sigma/impl/CostedObjectsImpl.scala +++ b/sigma-library/src/main/scala/special/sigma/impl/CostedObjectsImpl.scala @@ -1,15 +1,12 @@ package special.sigma import scalan._ -import scala.reflect.runtime.universe._ -import scala.reflect._ +import scala.collection.mutable.WrappedArray package impl { // Abs ----------------------------------- trait CostedObjectsDefs extends scalan.Scalan with CostedObjects { self: SigmaLibrary => -import IsoUR._ -import Converter._ import AnyValue._ import AvlTree._ import Box._ @@ -34,13 +31,13 @@ object SizeAnyValue extends EntityObject("SizeAnyValue") { type SSizeAnyValue = special.sigma.SizeAnyValue case class SizeAnyValueConst( constValue: SSizeAnyValue - ) extends SizeAnyValue with LiftedConst[SSizeAnyValue, SizeAnyValue] + ) extends LiftedConst[SSizeAnyValue, SizeAnyValue] with SizeAnyValue with Def[SizeAnyValue] with SizeAnyValueConstMethods { -// manual fix - def eVal: Elem[AnyValue] = element[AnyValue] + // manual fix + final def eVal: Elem[AnyValue] = element[AnyValue] val liftable: Liftable[SSizeAnyValue, SizeAnyValue] = LiftableSizeAnyValue - val selfType: Elem[SizeAnyValue] = liftable.eW + val resultType: Elem[SizeAnyValue] = liftable.eW } trait SizeAnyValueConstMethods extends SizeAnyValue with SizeConstMethods[AnyValue] { thisConst: Def[_] => @@ -48,19 +45,19 @@ object SizeAnyValue extends EntityObject("SizeAnyValue") { private val SizeAnyValueClass = classOf[SizeAnyValue] // manual fix - override def tVal: Rep[WRType[Any]] = { + override def tVal: Ref[WRType[Any]] = { asRep[WRType[Any]](mkMethodCall(self, SizeAnyValueClass.getMethod("tVal"), - List(), - true, false, wRTypeElement(AnyElement))) + WrappedArray.empty, + true, false, wRTypeAnyElement)) } // manual fix - override def valueSize: Rep[Size[Any]] = { + override def valueSize: Ref[Size[Any]] = { asRep[Size[Any]](mkMethodCall(self, SizeAnyValueClass.getMethod("valueSize"), - List(), - true, false, sizeElement(AnyElement))) + WrappedArray.empty, + true, false, sizeAnyElement)) } } @@ -70,49 +67,51 @@ object SizeAnyValue extends EntityObject("SizeAnyValue") { lazy val sourceType: RType[SSizeAnyValue] = { RType[SSizeAnyValue] } - def lift(x: SSizeAnyValue): Rep[SizeAnyValue] = SizeAnyValueConst(x) - def unlift(w: Rep[SizeAnyValue]): SSizeAnyValue = w match { + def lift(x: SSizeAnyValue): Ref[SizeAnyValue] = SizeAnyValueConst(x) + def unlift(w: Ref[SizeAnyValue]): SSizeAnyValue = w match { case Def(SizeAnyValueConst(x: SSizeAnyValue)) => x.asInstanceOf[SSizeAnyValue] case _ => unliftError(w) } } + private val SizeAnyValueClass = classOf[SizeAnyValue] + // entityAdapter for SizeAnyValue trait - case class SizeAnyValueAdapter(source: Rep[SizeAnyValue]) - extends SizeAnyValue with Def[SizeAnyValue] { + case class SizeAnyValueAdapter(source: Ref[SizeAnyValue]) + extends Node with SizeAnyValue + with Def[SizeAnyValue] { override lazy val eVal: Elem[AnyValue] = implicitly[Elem[AnyValue]] - val selfType: Elem[SizeAnyValue] = element[SizeAnyValue] + val resultType: Elem[SizeAnyValue] = element[SizeAnyValue] override def transform(t: Transformer) = SizeAnyValueAdapter(t(source)) - private val thisClass = classOf[SizeAnyValue] // manual fix - def tVal: Rep[WRType[Any]] = { + def tVal: Ref[WRType[Any]] = { asRep[WRType[Any]](mkMethodCall(source, - thisClass.getMethod("tVal"), - List(), - true, true, wRTypeElement(AnyElement))) + SizeAnyValueClass.getMethod("tVal"), + WrappedArray.empty, + true, true, wRTypeAnyElement)) } // manual fix - def valueSize: Rep[Size[Any]] = { + def valueSize: Ref[Size[Any]] = { asRep[Size[Any]](mkMethodCall(source, - thisClass.getMethod("valueSize"), - List(), - true, true, sizeElement(AnyElement))) + SizeAnyValueClass.getMethod("valueSize"), + WrappedArray.empty, + true, true, sizeAnyElement)) } - def dataSize: Rep[Long] = { + def dataSize: Ref[Long] = { asRep[Long](mkMethodCall(source, - thisClass.getMethod("dataSize"), - List(), + SizeAnyValueClass.getMethod("dataSize"), + WrappedArray.empty, true, true, element[Long])) } } - // entityProxy: single proxy for each type family - implicit def proxySizeAnyValue(p: Rep[SizeAnyValue]): SizeAnyValue = { - if (p.rhs.isInstanceOf[SizeAnyValue@unchecked]) p.rhs.asInstanceOf[SizeAnyValue] + // entityUnref: single unref method for each type family + implicit final def unrefSizeAnyValue(p: Ref[SizeAnyValue]): SizeAnyValue = { + if (p.node.isInstanceOf[SizeAnyValue]) p.node.asInstanceOf[SizeAnyValue] else SizeAnyValueAdapter(p) } @@ -120,7 +119,7 @@ object SizeAnyValue extends EntityObject("SizeAnyValue") { // familyElem class SizeAnyValueElem[To <: SizeAnyValue] extends SizeElem[AnyValue, To] { - override val liftable: Liftables.Liftable[_, To] = LiftableSizeAnyValue.asLiftable[SSizeAnyValue, To] + override val liftable: Liftables.Liftable[_, To] = asLiftable[SSizeAnyValue, To](LiftableSizeAnyValue) override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { super.collectMethods ++ @@ -130,68 +129,43 @@ object SizeAnyValue extends EntityObject("SizeAnyValue") { } override lazy val parent: Option[Elem[_]] = Some(sizeElement(anyValueElement)) - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override lazy val tag = { - weakTypeTag[SizeAnyValue].asInstanceOf[WeakTypeTag[To]] - } - override def convert(x: Rep[Def[_]]) = { - val conv = fun {x: Rep[SizeAnyValue] => convertSizeAnyValue(x) } - tryConvert(element[SizeAnyValue], this, x, conv) - } - - def convertSizeAnyValue(x: Rep[SizeAnyValue]): Rep[To] = { - x.elem match { - case _: SizeAnyValueElem[_] => asRep[To](x) - case e => !!!(s"Expected $x to have SizeAnyValueElem[_], but got $e", x) - } - } - override def getDefaultRep: Rep[To] = ??? } implicit lazy val sizeAnyValueElement: Elem[SizeAnyValue] = new SizeAnyValueElem[SizeAnyValue] - implicit case object SizeAnyValueCompanionElem extends CompanionElem[SizeAnyValueCompanionCtor] { - lazy val tag = weakTypeTag[SizeAnyValueCompanionCtor] - protected def getDefaultRep = RSizeAnyValue - } + implicit case object SizeAnyValueCompanionElem extends CompanionElem[SizeAnyValueCompanionCtor] abstract class SizeAnyValueCompanionCtor extends CompanionDef[SizeAnyValueCompanionCtor] with SizeAnyValueCompanion { - def selfType = SizeAnyValueCompanionElem + def resultType = SizeAnyValueCompanionElem override def toString = "SizeAnyValue" } - implicit def proxySizeAnyValueCompanionCtor(p: Rep[SizeAnyValueCompanionCtor]): SizeAnyValueCompanionCtor = - proxyOps[SizeAnyValueCompanionCtor](p) + implicit final def unrefSizeAnyValueCompanionCtor(p: Ref[SizeAnyValueCompanionCtor]): SizeAnyValueCompanionCtor = + p.node.asInstanceOf[SizeAnyValueCompanionCtor] - lazy val RSizeAnyValue: Rep[SizeAnyValueCompanionCtor] = new SizeAnyValueCompanionCtor { + lazy val RSizeAnyValue: MutableLazy[SizeAnyValueCompanionCtor] = MutableLazy(new SizeAnyValueCompanionCtor { private val thisClass = classOf[SizeAnyValueCompanion] - } + }) object SizeAnyValueMethods { object tVal { - def unapply(d: Def[_]): Nullable[Rep[SizeAnyValue]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[SizeAnyValueElem[_]] && method.getName == "tVal" => + def unapply(d: Def[_]): Nullable[Ref[SizeAnyValue]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "tVal" && receiver.elem.isInstanceOf[SizeAnyValueElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[SizeAnyValue]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[SizeAnyValue]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[SizeAnyValue]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[SizeAnyValue]] = unapply(exp.node) } object valueSize { - def unapply(d: Def[_]): Nullable[Rep[SizeAnyValue]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[SizeAnyValueElem[_]] && method.getName == "valueSize" => + def unapply(d: Def[_]): Nullable[Ref[SizeAnyValue]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "valueSize" && receiver.elem.isInstanceOf[SizeAnyValueElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[SizeAnyValue]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[SizeAnyValue]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[SizeAnyValue]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[SizeAnyValue]] = unapply(exp.node) } } @@ -207,23 +181,23 @@ object SizeSigmaProp extends EntityObject("SizeSigmaProp") { type SSizeSigmaProp = special.sigma.SizeSigmaProp case class SizeSigmaPropConst( constValue: SSizeSigmaProp - ) extends SizeSigmaProp with LiftedConst[SSizeSigmaProp, SizeSigmaProp] + ) extends LiftedConst[SSizeSigmaProp, SizeSigmaProp] with SizeSigmaProp with Def[SizeSigmaProp] with SizeSigmaPropConstMethods { // manual fix - def eVal: Elem[SigmaProp] = element[SigmaProp] + final def eVal: Elem[SigmaProp] = element[SigmaProp] val liftable: Liftable[SSizeSigmaProp, SizeSigmaProp] = LiftableSizeSigmaProp - val selfType: Elem[SizeSigmaProp] = liftable.eW + val resultType: Elem[SizeSigmaProp] = liftable.eW } trait SizeSigmaPropConstMethods extends SizeSigmaProp with SizeConstMethods[SigmaProp] { thisConst: Def[_] => private val SizeSigmaPropClass = classOf[SizeSigmaProp] - override def propBytes: Rep[Size[Coll[Byte]]] = { + override def propBytes: Ref[Size[Coll[Byte]]] = { asRep[Size[Coll[Byte]]](mkMethodCall(self, SizeSigmaPropClass.getMethod("propBytes"), - List(), + WrappedArray.empty, true, false, element[Size[Coll[Byte]]])) } } @@ -234,40 +208,42 @@ object SizeSigmaProp extends EntityObject("SizeSigmaProp") { lazy val sourceType: RType[SSizeSigmaProp] = { RType[SSizeSigmaProp] } - def lift(x: SSizeSigmaProp): Rep[SizeSigmaProp] = SizeSigmaPropConst(x) - def unlift(w: Rep[SizeSigmaProp]): SSizeSigmaProp = w match { + def lift(x: SSizeSigmaProp): Ref[SizeSigmaProp] = SizeSigmaPropConst(x) + def unlift(w: Ref[SizeSigmaProp]): SSizeSigmaProp = w match { case Def(SizeSigmaPropConst(x: SSizeSigmaProp)) => x.asInstanceOf[SSizeSigmaProp] case _ => unliftError(w) } } + private val SizeSigmaPropClass = classOf[SizeSigmaProp] + // entityAdapter for SizeSigmaProp trait - case class SizeSigmaPropAdapter(source: Rep[SizeSigmaProp]) - extends SizeSigmaProp with Def[SizeSigmaProp] { + case class SizeSigmaPropAdapter(source: Ref[SizeSigmaProp]) + extends Node with SizeSigmaProp + with Def[SizeSigmaProp] { override lazy val eVal: Elem[SigmaProp] = implicitly[Elem[SigmaProp]] - val selfType: Elem[SizeSigmaProp] = element[SizeSigmaProp] + val resultType: Elem[SizeSigmaProp] = element[SizeSigmaProp] override def transform(t: Transformer) = SizeSigmaPropAdapter(t(source)) - private val thisClass = classOf[SizeSigmaProp] - def propBytes: Rep[Size[Coll[Byte]]] = { + def propBytes: Ref[Size[Coll[Byte]]] = { asRep[Size[Coll[Byte]]](mkMethodCall(source, - thisClass.getMethod("propBytes"), - List(), + SizeSigmaPropClass.getMethod("propBytes"), + WrappedArray.empty, true, true, element[Size[Coll[Byte]]])) } - def dataSize: Rep[Long] = { + def dataSize: Ref[Long] = { asRep[Long](mkMethodCall(source, - thisClass.getMethod("dataSize"), - List(), + SizeSigmaPropClass.getMethod("dataSize"), + WrappedArray.empty, true, true, element[Long])) } } - // entityProxy: single proxy for each type family - implicit def proxySizeSigmaProp(p: Rep[SizeSigmaProp]): SizeSigmaProp = { - if (p.rhs.isInstanceOf[SizeSigmaProp@unchecked]) p.rhs.asInstanceOf[SizeSigmaProp] + // entityUnref: single unref method for each type family + implicit final def unrefSizeSigmaProp(p: Ref[SizeSigmaProp]): SizeSigmaProp = { + if (p.node.isInstanceOf[SizeSigmaProp]) p.node.asInstanceOf[SizeSigmaProp] else SizeSigmaPropAdapter(p) } @@ -275,7 +251,7 @@ object SizeSigmaProp extends EntityObject("SizeSigmaProp") { // familyElem class SizeSigmaPropElem[To <: SizeSigmaProp] extends SizeElem[SigmaProp, To] { - override val liftable: Liftables.Liftable[_, To] = LiftableSizeSigmaProp.asLiftable[SSizeSigmaProp, To] + override val liftable: Liftables.Liftable[_, To] = asLiftable[SSizeSigmaProp, To](LiftableSizeSigmaProp) override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { super.collectMethods ++ @@ -285,55 +261,33 @@ object SizeSigmaProp extends EntityObject("SizeSigmaProp") { } override lazy val parent: Option[Elem[_]] = Some(sizeElement(sigmaPropElement)) - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override lazy val tag = { - weakTypeTag[SizeSigmaProp].asInstanceOf[WeakTypeTag[To]] - } - override def convert(x: Rep[Def[_]]) = { - val conv = fun {x: Rep[SizeSigmaProp] => convertSizeSigmaProp(x) } - tryConvert(element[SizeSigmaProp], this, x, conv) - } - - def convertSizeSigmaProp(x: Rep[SizeSigmaProp]): Rep[To] = { - x.elem match { - case _: SizeSigmaPropElem[_] => asRep[To](x) - case e => !!!(s"Expected $x to have SizeSigmaPropElem[_], but got $e", x) - } - } - override def getDefaultRep: Rep[To] = ??? } implicit lazy val sizeSigmaPropElement: Elem[SizeSigmaProp] = new SizeSigmaPropElem[SizeSigmaProp] - implicit case object SizeSigmaPropCompanionElem extends CompanionElem[SizeSigmaPropCompanionCtor] { - lazy val tag = weakTypeTag[SizeSigmaPropCompanionCtor] - protected def getDefaultRep = RSizeSigmaProp - } + implicit case object SizeSigmaPropCompanionElem extends CompanionElem[SizeSigmaPropCompanionCtor] abstract class SizeSigmaPropCompanionCtor extends CompanionDef[SizeSigmaPropCompanionCtor] with SizeSigmaPropCompanion { - def selfType = SizeSigmaPropCompanionElem + def resultType = SizeSigmaPropCompanionElem override def toString = "SizeSigmaProp" } - implicit def proxySizeSigmaPropCompanionCtor(p: Rep[SizeSigmaPropCompanionCtor]): SizeSigmaPropCompanionCtor = - proxyOps[SizeSigmaPropCompanionCtor](p) + implicit final def unrefSizeSigmaPropCompanionCtor(p: Ref[SizeSigmaPropCompanionCtor]): SizeSigmaPropCompanionCtor = + p.node.asInstanceOf[SizeSigmaPropCompanionCtor] - lazy val RSizeSigmaProp: Rep[SizeSigmaPropCompanionCtor] = new SizeSigmaPropCompanionCtor { + lazy val RSizeSigmaProp: MutableLazy[SizeSigmaPropCompanionCtor] = MutableLazy(new SizeSigmaPropCompanionCtor { private val thisClass = classOf[SizeSigmaPropCompanion] - } + }) object SizeSigmaPropMethods { object propBytes { - def unapply(d: Def[_]): Nullable[Rep[SizeSigmaProp]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[SizeSigmaPropElem[_]] && method.getName == "propBytes" => + def unapply(d: Def[_]): Nullable[Ref[SizeSigmaProp]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "propBytes" && receiver.elem.isInstanceOf[SizeSigmaPropElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[SizeSigmaProp]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[SizeSigmaProp]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[SizeSigmaProp]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[SizeSigmaProp]] = unapply(exp.node) } } @@ -349,58 +303,58 @@ object SizeBox extends EntityObject("SizeBox") { type SSizeBox = special.sigma.SizeBox case class SizeBoxConst( constValue: SSizeBox - ) extends SizeBox with LiftedConst[SSizeBox, SizeBox] + ) extends LiftedConst[SSizeBox, SizeBox] with SizeBox with Def[SizeBox] with SizeBoxConstMethods { // manual fix - def eVal: Elem[Box] = element[Box] + final def eVal: Elem[Box] = element[Box] val liftable: Liftable[SSizeBox, SizeBox] = LiftableSizeBox - val selfType: Elem[SizeBox] = liftable.eW + val resultType: Elem[SizeBox] = liftable.eW } trait SizeBoxConstMethods extends SizeBox with SizeConstMethods[Box] { thisConst: Def[_] => private val SizeBoxClass = classOf[SizeBox] - override def propositionBytes: Rep[Size[Coll[Byte]]] = { + override def propositionBytes: Ref[Size[Coll[Byte]]] = { asRep[Size[Coll[Byte]]](mkMethodCall(self, SizeBoxClass.getMethod("propositionBytes"), - List(), + WrappedArray.empty, true, false, element[Size[Coll[Byte]]])) } - override def bytes: Rep[Size[Coll[Byte]]] = { + override def bytes: Ref[Size[Coll[Byte]]] = { asRep[Size[Coll[Byte]]](mkMethodCall(self, SizeBoxClass.getMethod("bytes"), - List(), + WrappedArray.empty, true, false, element[Size[Coll[Byte]]])) } - override def bytesWithoutRef: Rep[Size[Coll[Byte]]] = { + override def bytesWithoutRef: Ref[Size[Coll[Byte]]] = { asRep[Size[Coll[Byte]]](mkMethodCall(self, SizeBoxClass.getMethod("bytesWithoutRef"), - List(), + WrappedArray.empty, true, false, element[Size[Coll[Byte]]])) } - override def registers: Rep[Size[Coll[WOption[AnyValue]]]] = { + override def registers: Ref[Size[Coll[WOption[AnyValue]]]] = { asRep[Size[Coll[WOption[AnyValue]]]](mkMethodCall(self, SizeBoxClass.getMethod("registers"), - List(), + WrappedArray.empty, true, false, element[Size[Coll[WOption[AnyValue]]]])) } - override def getReg[T](id: Rep[Byte])(implicit tT: Elem[T]): Rep[Size[WOption[T]]] = { + override def getReg[T](id: Ref[Byte])(implicit tT: Elem[T]): Ref[Size[WOption[T]]] = { asRep[Size[WOption[T]]](mkMethodCall(self, SizeBoxClass.getMethod("getReg", classOf[Sym], classOf[Elem[_]]), - List(id, tT), + Array[AnyRef](id, tT), true, false, element[Size[WOption[T]]])) } - override def tokens: Rep[Size[Coll[(Coll[Byte], Long)]]] = { + override def tokens: Ref[Size[Coll[(Coll[Byte], Long)]]] = { asRep[Size[Coll[(Coll[Byte], Long)]]](mkMethodCall(self, SizeBoxClass.getMethod("tokens"), - List(), + WrappedArray.empty, true, false, element[Size[Coll[(Coll[Byte], Long)]]])) } } @@ -411,75 +365,77 @@ object SizeBox extends EntityObject("SizeBox") { lazy val sourceType: RType[SSizeBox] = { RType[SSizeBox] } - def lift(x: SSizeBox): Rep[SizeBox] = SizeBoxConst(x) - def unlift(w: Rep[SizeBox]): SSizeBox = w match { + def lift(x: SSizeBox): Ref[SizeBox] = SizeBoxConst(x) + def unlift(w: Ref[SizeBox]): SSizeBox = w match { case Def(SizeBoxConst(x: SSizeBox)) => x.asInstanceOf[SSizeBox] case _ => unliftError(w) } } + private val SizeBoxClass = classOf[SizeBox] + // entityAdapter for SizeBox trait - case class SizeBoxAdapter(source: Rep[SizeBox]) - extends SizeBox with Def[SizeBox] { + case class SizeBoxAdapter(source: Ref[SizeBox]) + extends Node with SizeBox + with Def[SizeBox] { override lazy val eVal: Elem[Box] = implicitly[Elem[Box]] - val selfType: Elem[SizeBox] = element[SizeBox] + val resultType: Elem[SizeBox] = element[SizeBox] override def transform(t: Transformer) = SizeBoxAdapter(t(source)) - private val thisClass = classOf[SizeBox] - def propositionBytes: Rep[Size[Coll[Byte]]] = { + def propositionBytes: Ref[Size[Coll[Byte]]] = { asRep[Size[Coll[Byte]]](mkMethodCall(source, - thisClass.getMethod("propositionBytes"), - List(), + SizeBoxClass.getMethod("propositionBytes"), + WrappedArray.empty, true, true, element[Size[Coll[Byte]]])) } - def bytes: Rep[Size[Coll[Byte]]] = { + def bytes: Ref[Size[Coll[Byte]]] = { asRep[Size[Coll[Byte]]](mkMethodCall(source, - thisClass.getMethod("bytes"), - List(), + SizeBoxClass.getMethod("bytes"), + WrappedArray.empty, true, true, element[Size[Coll[Byte]]])) } - def bytesWithoutRef: Rep[Size[Coll[Byte]]] = { + def bytesWithoutRef: Ref[Size[Coll[Byte]]] = { asRep[Size[Coll[Byte]]](mkMethodCall(source, - thisClass.getMethod("bytesWithoutRef"), - List(), + SizeBoxClass.getMethod("bytesWithoutRef"), + WrappedArray.empty, true, true, element[Size[Coll[Byte]]])) } - def registers: Rep[Size[Coll[WOption[AnyValue]]]] = { + def registers: Ref[Size[Coll[WOption[AnyValue]]]] = { asRep[Size[Coll[WOption[AnyValue]]]](mkMethodCall(source, - thisClass.getMethod("registers"), - List(), + SizeBoxClass.getMethod("registers"), + WrappedArray.empty, true, true, element[Size[Coll[WOption[AnyValue]]]])) } - def getReg[T](id: Rep[Byte])(implicit tT: Elem[T]): Rep[Size[WOption[T]]] = { + def getReg[T](id: Ref[Byte])(implicit tT: Elem[T]): Ref[Size[WOption[T]]] = { asRep[Size[WOption[T]]](mkMethodCall(source, - thisClass.getMethod("getReg", classOf[Sym], classOf[Elem[_]]), - List(id, tT), + SizeBoxClass.getMethod("getReg", classOf[Sym], classOf[Elem[_]]), + Array[AnyRef](id, tT), true, true, element[Size[WOption[T]]])) } - def tokens: Rep[Size[Coll[(Coll[Byte], Long)]]] = { + def tokens: Ref[Size[Coll[(Coll[Byte], Long)]]] = { asRep[Size[Coll[(Coll[Byte], Long)]]](mkMethodCall(source, - thisClass.getMethod("tokens"), - List(), + SizeBoxClass.getMethod("tokens"), + WrappedArray.empty, true, true, element[Size[Coll[(Coll[Byte], Long)]]])) } - def dataSize: Rep[Long] = { + def dataSize: Ref[Long] = { asRep[Long](mkMethodCall(source, - thisClass.getMethod("dataSize"), - List(), + SizeBoxClass.getMethod("dataSize"), + WrappedArray.empty, true, true, element[Long])) } } - // entityProxy: single proxy for each type family - implicit def proxySizeBox(p: Rep[SizeBox]): SizeBox = { - if (p.rhs.isInstanceOf[SizeBox@unchecked]) p.rhs.asInstanceOf[SizeBox] + // entityUnref: single unref method for each type family + implicit final def unrefSizeBox(p: Ref[SizeBox]): SizeBox = { + if (p.node.isInstanceOf[SizeBox]) p.node.asInstanceOf[SizeBox] else SizeBoxAdapter(p) } @@ -487,7 +443,7 @@ object SizeBox extends EntityObject("SizeBox") { // familyElem class SizeBoxElem[To <: SizeBox] extends SizeElem[Box, To] { - override val liftable: Liftables.Liftable[_, To] = LiftableSizeBox.asLiftable[SSizeBox, To] + override val liftable: Liftables.Liftable[_, To] = asLiftable[SSizeBox, To](LiftableSizeBox) override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { super.collectMethods ++ @@ -497,120 +453,83 @@ object SizeBox extends EntityObject("SizeBox") { } override lazy val parent: Option[Elem[_]] = Some(sizeElement(boxElement)) - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override lazy val tag = { - weakTypeTag[SizeBox].asInstanceOf[WeakTypeTag[To]] - } - override def convert(x: Rep[Def[_]]) = { - val conv = fun {x: Rep[SizeBox] => convertSizeBox(x) } - tryConvert(element[SizeBox], this, x, conv) - } - - def convertSizeBox(x: Rep[SizeBox]): Rep[To] = { - x.elem match { - case _: SizeBoxElem[_] => asRep[To](x) - case e => !!!(s"Expected $x to have SizeBoxElem[_], but got $e", x) - } - } - override def getDefaultRep: Rep[To] = ??? } implicit lazy val sizeBoxElement: Elem[SizeBox] = new SizeBoxElem[SizeBox] - implicit case object SizeBoxCompanionElem extends CompanionElem[SizeBoxCompanionCtor] { - lazy val tag = weakTypeTag[SizeBoxCompanionCtor] - protected def getDefaultRep = RSizeBox - } + implicit case object SizeBoxCompanionElem extends CompanionElem[SizeBoxCompanionCtor] abstract class SizeBoxCompanionCtor extends CompanionDef[SizeBoxCompanionCtor] with SizeBoxCompanion { - def selfType = SizeBoxCompanionElem + def resultType = SizeBoxCompanionElem override def toString = "SizeBox" } - implicit def proxySizeBoxCompanionCtor(p: Rep[SizeBoxCompanionCtor]): SizeBoxCompanionCtor = - proxyOps[SizeBoxCompanionCtor](p) + implicit final def unrefSizeBoxCompanionCtor(p: Ref[SizeBoxCompanionCtor]): SizeBoxCompanionCtor = + p.node.asInstanceOf[SizeBoxCompanionCtor] - lazy val RSizeBox: Rep[SizeBoxCompanionCtor] = new SizeBoxCompanionCtor { + lazy val RSizeBox: MutableLazy[SizeBoxCompanionCtor] = MutableLazy(new SizeBoxCompanionCtor { private val thisClass = classOf[SizeBoxCompanion] - } + }) object SizeBoxMethods { object propositionBytes { - def unapply(d: Def[_]): Nullable[Rep[SizeBox]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[SizeBoxElem[_]] && method.getName == "propositionBytes" => + def unapply(d: Def[_]): Nullable[Ref[SizeBox]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "propositionBytes" && receiver.elem.isInstanceOf[SizeBoxElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[SizeBox]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[SizeBox]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[SizeBox]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[SizeBox]] = unapply(exp.node) } object bytes { - def unapply(d: Def[_]): Nullable[Rep[SizeBox]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[SizeBoxElem[_]] && method.getName == "bytes" => + def unapply(d: Def[_]): Nullable[Ref[SizeBox]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "bytes" && receiver.elem.isInstanceOf[SizeBoxElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[SizeBox]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[SizeBox]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[SizeBox]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[SizeBox]] = unapply(exp.node) } object bytesWithoutRef { - def unapply(d: Def[_]): Nullable[Rep[SizeBox]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[SizeBoxElem[_]] && method.getName == "bytesWithoutRef" => + def unapply(d: Def[_]): Nullable[Ref[SizeBox]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "bytesWithoutRef" && receiver.elem.isInstanceOf[SizeBoxElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[SizeBox]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[SizeBox]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[SizeBox]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[SizeBox]] = unapply(exp.node) } object registers { - def unapply(d: Def[_]): Nullable[Rep[SizeBox]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[SizeBoxElem[_]] && method.getName == "registers" => + def unapply(d: Def[_]): Nullable[Ref[SizeBox]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "registers" && receiver.elem.isInstanceOf[SizeBoxElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[SizeBox]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[SizeBox]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[SizeBox]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[SizeBox]] = unapply(exp.node) } object getReg { - def unapply(d: Def[_]): Nullable[(Rep[SizeBox], Rep[Byte], Elem[T]) forSome {type T}] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SizeBoxElem[_]] && method.getName == "getReg" => + def unapply(d: Def[_]): Nullable[(Ref[SizeBox], Ref[Byte], Elem[T]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "getReg" && receiver.elem.isInstanceOf[SizeBoxElem[_]] => val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[SizeBox], Rep[Byte], Elem[T]) forSome {type T}]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SizeBox], Rep[Byte], Elem[T]) forSome {type T}] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[SizeBox], Ref[Byte], Elem[T]) forSome {type T}]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[SizeBox], Ref[Byte], Elem[T]) forSome {type T}] = unapply(exp.node) } object tokens { - def unapply(d: Def[_]): Nullable[Rep[SizeBox]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[SizeBoxElem[_]] && method.getName == "tokens" => + def unapply(d: Def[_]): Nullable[Ref[SizeBox]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "tokens" && receiver.elem.isInstanceOf[SizeBoxElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[SizeBox]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[SizeBox]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[SizeBox]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[SizeBox]] = unapply(exp.node) } } @@ -626,72 +545,72 @@ object SizeContext extends EntityObject("SizeContext") { type SSizeContext = special.sigma.SizeContext case class SizeContextConst( constValue: SSizeContext - ) extends SizeContext with LiftedConst[SSizeContext, SizeContext] + ) extends LiftedConst[SSizeContext, SizeContext] with SizeContext with Def[SizeContext] with SizeContextConstMethods { // manual fix - def eVal: Elem[Context] = element[Context] + final def eVal: Elem[Context] = element[Context] val liftable: Liftable[SSizeContext, SizeContext] = LiftableSizeContext - val selfType: Elem[SizeContext] = liftable.eW + val resultType: Elem[SizeContext] = liftable.eW } trait SizeContextConstMethods extends SizeContext with SizeConstMethods[Context] { thisConst: Def[_] => private val SizeContextClass = classOf[SizeContext] - override def outputs: Rep[Size[Coll[Box]]] = { + override def outputs: Ref[Size[Coll[Box]]] = { asRep[Size[Coll[Box]]](mkMethodCall(self, SizeContextClass.getMethod("outputs"), - List(), + WrappedArray.empty, true, false, element[Size[Coll[Box]]])) } - override def inputs: Rep[Size[Coll[Box]]] = { + override def inputs: Ref[Size[Coll[Box]]] = { asRep[Size[Coll[Box]]](mkMethodCall(self, SizeContextClass.getMethod("inputs"), - List(), + WrappedArray.empty, true, false, element[Size[Coll[Box]]])) } - override def dataInputs: Rep[Size[Coll[Box]]] = { + override def dataInputs: Ref[Size[Coll[Box]]] = { asRep[Size[Coll[Box]]](mkMethodCall(self, SizeContextClass.getMethod("dataInputs"), - List(), + WrappedArray.empty, true, false, element[Size[Coll[Box]]])) } - override def selfBox: Rep[Size[Box]] = { + override def selfBox: Ref[Size[Box]] = { asRep[Size[Box]](mkMethodCall(self, SizeContextClass.getMethod("selfBox"), - List(), + WrappedArray.empty, true, false, element[Size[Box]])) } - override def lastBlockUtxoRootHash: Rep[Size[AvlTree]] = { + override def lastBlockUtxoRootHash: Ref[Size[AvlTree]] = { asRep[Size[AvlTree]](mkMethodCall(self, SizeContextClass.getMethod("lastBlockUtxoRootHash"), - List(), + WrappedArray.empty, true, false, element[Size[AvlTree]])) } - override def headers: Rep[Size[Coll[Header]]] = { + override def headers: Ref[Size[Coll[Header]]] = { asRep[Size[Coll[Header]]](mkMethodCall(self, SizeContextClass.getMethod("headers"), - List(), + WrappedArray.empty, true, false, element[Size[Coll[Header]]])) } - override def preHeader: Rep[Size[PreHeader]] = { + override def preHeader: Ref[Size[PreHeader]] = { asRep[Size[PreHeader]](mkMethodCall(self, SizeContextClass.getMethod("preHeader"), - List(), + WrappedArray.empty, true, false, element[Size[PreHeader]])) } - override def getVar[T](id: Rep[Byte])(implicit tT: Elem[T]): Rep[Size[WOption[T]]] = { + override def getVar[T](id: Ref[Byte])(implicit tT: Elem[T]): Ref[Size[WOption[T]]] = { asRep[Size[WOption[T]]](mkMethodCall(self, SizeContextClass.getMethod("getVar", classOf[Sym], classOf[Elem[_]]), - List(id, tT), + Array[AnyRef](id, tT), true, false, element[Size[WOption[T]]])) } } @@ -702,89 +621,91 @@ object SizeContext extends EntityObject("SizeContext") { lazy val sourceType: RType[SSizeContext] = { RType[SSizeContext] } - def lift(x: SSizeContext): Rep[SizeContext] = SizeContextConst(x) - def unlift(w: Rep[SizeContext]): SSizeContext = w match { + def lift(x: SSizeContext): Ref[SizeContext] = SizeContextConst(x) + def unlift(w: Ref[SizeContext]): SSizeContext = w match { case Def(SizeContextConst(x: SSizeContext)) => x.asInstanceOf[SSizeContext] case _ => unliftError(w) } } + private val SizeContextClass = classOf[SizeContext] + // entityAdapter for SizeContext trait - case class SizeContextAdapter(source: Rep[SizeContext]) - extends SizeContext with Def[SizeContext] { + case class SizeContextAdapter(source: Ref[SizeContext]) + extends Node with SizeContext + with Def[SizeContext] { override lazy val eVal: Elem[Context] = implicitly[Elem[Context]] - val selfType: Elem[SizeContext] = element[SizeContext] + val resultType: Elem[SizeContext] = element[SizeContext] override def transform(t: Transformer) = SizeContextAdapter(t(source)) - private val thisClass = classOf[SizeContext] - def outputs: Rep[Size[Coll[Box]]] = { + def outputs: Ref[Size[Coll[Box]]] = { asRep[Size[Coll[Box]]](mkMethodCall(source, - thisClass.getMethod("outputs"), - List(), + SizeContextClass.getMethod("outputs"), + WrappedArray.empty, true, true, element[Size[Coll[Box]]])) } - def inputs: Rep[Size[Coll[Box]]] = { + def inputs: Ref[Size[Coll[Box]]] = { asRep[Size[Coll[Box]]](mkMethodCall(source, - thisClass.getMethod("inputs"), - List(), + SizeContextClass.getMethod("inputs"), + WrappedArray.empty, true, true, element[Size[Coll[Box]]])) } - def dataInputs: Rep[Size[Coll[Box]]] = { + def dataInputs: Ref[Size[Coll[Box]]] = { asRep[Size[Coll[Box]]](mkMethodCall(source, - thisClass.getMethod("dataInputs"), - List(), + SizeContextClass.getMethod("dataInputs"), + WrappedArray.empty, true, true, element[Size[Coll[Box]]])) } - def selfBox: Rep[Size[Box]] = { + def selfBox: Ref[Size[Box]] = { asRep[Size[Box]](mkMethodCall(source, - thisClass.getMethod("selfBox"), - List(), + SizeContextClass.getMethod("selfBox"), + WrappedArray.empty, true, true, element[Size[Box]])) } - def lastBlockUtxoRootHash: Rep[Size[AvlTree]] = { + def lastBlockUtxoRootHash: Ref[Size[AvlTree]] = { asRep[Size[AvlTree]](mkMethodCall(source, - thisClass.getMethod("lastBlockUtxoRootHash"), - List(), + SizeContextClass.getMethod("lastBlockUtxoRootHash"), + WrappedArray.empty, true, true, element[Size[AvlTree]])) } - def headers: Rep[Size[Coll[Header]]] = { + def headers: Ref[Size[Coll[Header]]] = { asRep[Size[Coll[Header]]](mkMethodCall(source, - thisClass.getMethod("headers"), - List(), + SizeContextClass.getMethod("headers"), + WrappedArray.empty, true, true, element[Size[Coll[Header]]])) } - def preHeader: Rep[Size[PreHeader]] = { + def preHeader: Ref[Size[PreHeader]] = { asRep[Size[PreHeader]](mkMethodCall(source, - thisClass.getMethod("preHeader"), - List(), + SizeContextClass.getMethod("preHeader"), + WrappedArray.empty, true, true, element[Size[PreHeader]])) } - def getVar[T](id: Rep[Byte])(implicit tT: Elem[T]): Rep[Size[WOption[T]]] = { + def getVar[T](id: Ref[Byte])(implicit tT: Elem[T]): Ref[Size[WOption[T]]] = { asRep[Size[WOption[T]]](mkMethodCall(source, - thisClass.getMethod("getVar", classOf[Sym], classOf[Elem[_]]), - List(id, tT), + SizeContextClass.getMethod("getVar", classOf[Sym], classOf[Elem[_]]), + Array[AnyRef](id, tT), true, true, element[Size[WOption[T]]])) } - def dataSize: Rep[Long] = { + def dataSize: Ref[Long] = { asRep[Long](mkMethodCall(source, - thisClass.getMethod("dataSize"), - List(), + SizeContextClass.getMethod("dataSize"), + WrappedArray.empty, true, true, element[Long])) } } - // entityProxy: single proxy for each type family - implicit def proxySizeContext(p: Rep[SizeContext]): SizeContext = { - if (p.rhs.isInstanceOf[SizeContext@unchecked]) p.rhs.asInstanceOf[SizeContext] + // entityUnref: single unref method for each type family + implicit final def unrefSizeContext(p: Ref[SizeContext]): SizeContext = { + if (p.node.isInstanceOf[SizeContext]) p.node.asInstanceOf[SizeContext] else SizeContextAdapter(p) } @@ -792,7 +713,7 @@ object SizeContext extends EntityObject("SizeContext") { // familyElem class SizeContextElem[To <: SizeContext] extends SizeElem[Context, To] { - override val liftable: Liftables.Liftable[_, To] = LiftableSizeContext.asLiftable[SSizeContext, To] + override val liftable: Liftables.Liftable[_, To] = asLiftable[SSizeContext, To](LiftableSizeContext) override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { super.collectMethods ++ @@ -802,146 +723,103 @@ object SizeContext extends EntityObject("SizeContext") { } override lazy val parent: Option[Elem[_]] = Some(sizeElement(contextElement)) - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override lazy val tag = { - weakTypeTag[SizeContext].asInstanceOf[WeakTypeTag[To]] - } - override def convert(x: Rep[Def[_]]) = { - val conv = fun {x: Rep[SizeContext] => convertSizeContext(x) } - tryConvert(element[SizeContext], this, x, conv) - } - - def convertSizeContext(x: Rep[SizeContext]): Rep[To] = { - x.elem match { - case _: SizeContextElem[_] => asRep[To](x) - case e => !!!(s"Expected $x to have SizeContextElem[_], but got $e", x) - } - } - override def getDefaultRep: Rep[To] = ??? } implicit lazy val sizeContextElement: Elem[SizeContext] = new SizeContextElem[SizeContext] - implicit case object SizeContextCompanionElem extends CompanionElem[SizeContextCompanionCtor] { - lazy val tag = weakTypeTag[SizeContextCompanionCtor] - protected def getDefaultRep = RSizeContext - } + implicit case object SizeContextCompanionElem extends CompanionElem[SizeContextCompanionCtor] abstract class SizeContextCompanionCtor extends CompanionDef[SizeContextCompanionCtor] with SizeContextCompanion { - def selfType = SizeContextCompanionElem + def resultType = SizeContextCompanionElem override def toString = "SizeContext" } - implicit def proxySizeContextCompanionCtor(p: Rep[SizeContextCompanionCtor]): SizeContextCompanionCtor = - proxyOps[SizeContextCompanionCtor](p) + implicit final def unrefSizeContextCompanionCtor(p: Ref[SizeContextCompanionCtor]): SizeContextCompanionCtor = + p.node.asInstanceOf[SizeContextCompanionCtor] - lazy val RSizeContext: Rep[SizeContextCompanionCtor] = new SizeContextCompanionCtor { + lazy val RSizeContext: MutableLazy[SizeContextCompanionCtor] = MutableLazy(new SizeContextCompanionCtor { private val thisClass = classOf[SizeContextCompanion] - } + }) object SizeContextMethods { object outputs { - def unapply(d: Def[_]): Nullable[Rep[SizeContext]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[SizeContextElem[_]] && method.getName == "outputs" => + def unapply(d: Def[_]): Nullable[Ref[SizeContext]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "outputs" && receiver.elem.isInstanceOf[SizeContextElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[SizeContext]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[SizeContext]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[SizeContext]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[SizeContext]] = unapply(exp.node) } object inputs { - def unapply(d: Def[_]): Nullable[Rep[SizeContext]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[SizeContextElem[_]] && method.getName == "inputs" => + def unapply(d: Def[_]): Nullable[Ref[SizeContext]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "inputs" && receiver.elem.isInstanceOf[SizeContextElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[SizeContext]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[SizeContext]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[SizeContext]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[SizeContext]] = unapply(exp.node) } object dataInputs { - def unapply(d: Def[_]): Nullable[Rep[SizeContext]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[SizeContextElem[_]] && method.getName == "dataInputs" => + def unapply(d: Def[_]): Nullable[Ref[SizeContext]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "dataInputs" && receiver.elem.isInstanceOf[SizeContextElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[SizeContext]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[SizeContext]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[SizeContext]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[SizeContext]] = unapply(exp.node) } object selfBox { - def unapply(d: Def[_]): Nullable[Rep[SizeContext]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[SizeContextElem[_]] && method.getName == "selfBox" => + def unapply(d: Def[_]): Nullable[Ref[SizeContext]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "selfBox" && receiver.elem.isInstanceOf[SizeContextElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[SizeContext]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[SizeContext]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[SizeContext]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[SizeContext]] = unapply(exp.node) } object lastBlockUtxoRootHash { - def unapply(d: Def[_]): Nullable[Rep[SizeContext]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[SizeContextElem[_]] && method.getName == "lastBlockUtxoRootHash" => + def unapply(d: Def[_]): Nullable[Ref[SizeContext]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "lastBlockUtxoRootHash" && receiver.elem.isInstanceOf[SizeContextElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[SizeContext]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[SizeContext]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[SizeContext]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[SizeContext]] = unapply(exp.node) } object headers { - def unapply(d: Def[_]): Nullable[Rep[SizeContext]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[SizeContextElem[_]] && method.getName == "headers" => + def unapply(d: Def[_]): Nullable[Ref[SizeContext]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "headers" && receiver.elem.isInstanceOf[SizeContextElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[SizeContext]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[SizeContext]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[SizeContext]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[SizeContext]] = unapply(exp.node) } object preHeader { - def unapply(d: Def[_]): Nullable[Rep[SizeContext]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[SizeContextElem[_]] && method.getName == "preHeader" => + def unapply(d: Def[_]): Nullable[Ref[SizeContext]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "preHeader" && receiver.elem.isInstanceOf[SizeContextElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[SizeContext]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[SizeContext]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[SizeContext]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[SizeContext]] = unapply(exp.node) } object getVar { - def unapply(d: Def[_]): Nullable[(Rep[SizeContext], Rep[Byte], Elem[T]) forSome {type T}] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SizeContextElem[_]] && method.getName == "getVar" => + def unapply(d: Def[_]): Nullable[(Ref[SizeContext], Ref[Byte], Elem[T]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "getVar" && receiver.elem.isInstanceOf[SizeContextElem[_]] => val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[SizeContext], Rep[Byte], Elem[T]) forSome {type T}]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SizeContext], Rep[Byte], Elem[T]) forSome {type T}] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[SizeContext], Ref[Byte], Elem[T]) forSome {type T}]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[SizeContext], Ref[Byte], Elem[T]) forSome {type T}] = unapply(exp.node) } } @@ -957,34 +835,34 @@ object SizeBuilder extends EntityObject("SizeBuilder") { type SSizeBuilder = special.sigma.SizeBuilder case class SizeBuilderConst( constValue: SSizeBuilder - ) extends SizeBuilder with LiftedConst[SSizeBuilder, SizeBuilder] + ) extends LiftedConst[SSizeBuilder, SizeBuilder] with SizeBuilder with Def[SizeBuilder] with SizeBuilderConstMethods { val liftable: Liftable[SSizeBuilder, SizeBuilder] = LiftableSizeBuilder - val selfType: Elem[SizeBuilder] = liftable.eW + val resultType: Elem[SizeBuilder] = liftable.eW } trait SizeBuilderConstMethods extends SizeBuilder { thisConst: Def[_] => private val SizeBuilderClass = classOf[SizeBuilder] - override def mkSizeAnyValue(tVal: Rep[WRType[Any]], valueSize: Rep[Size[Any]]): Rep[SizeAnyValue] = { + override def mkSizeAnyValue(tVal: Ref[WRType[Any]], valueSize: Ref[Size[Any]]): Ref[SizeAnyValue] = { asRep[SizeAnyValue](mkMethodCall(self, SizeBuilderClass.getMethod("mkSizeAnyValue", classOf[Sym], classOf[Sym]), - List(tVal, valueSize), + Array[AnyRef](tVal, valueSize), true, false, element[SizeAnyValue])) } - override def mkSizeBox(propositionBytes: Rep[Size[Coll[Byte]]], bytes: Rep[Size[Coll[Byte]]], bytesWithoutRef: Rep[Size[Coll[Byte]]], registers: Rep[Size[Coll[WOption[AnyValue]]]], tokens: Rep[Size[Coll[(Coll[Byte], Long)]]]): Rep[SizeBox] = { + override def mkSizeBox(propositionBytes: Ref[Size[Coll[Byte]]], bytes: Ref[Size[Coll[Byte]]], bytesWithoutRef: Ref[Size[Coll[Byte]]], registers: Ref[Size[Coll[WOption[AnyValue]]]], tokens: Ref[Size[Coll[(Coll[Byte], Long)]]]): Ref[SizeBox] = { asRep[SizeBox](mkMethodCall(self, SizeBuilderClass.getMethod("mkSizeBox", classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym]), - List(propositionBytes, bytes, bytesWithoutRef, registers, tokens), + Array[AnyRef](propositionBytes, bytes, bytesWithoutRef, registers, tokens), true, false, element[SizeBox])) } - override def mkSizeContext(outputs: Rep[Size[Coll[Box]]], inputs: Rep[Size[Coll[Box]]], dataInputs: Rep[Size[Coll[Box]]], selfBox: Rep[Size[Box]], lastBlockUtxoRootHash: Rep[Size[AvlTree]], headers: Rep[Size[Coll[Header]]], preHeader: Rep[Size[PreHeader]], vars: Rep[Coll[Size[AnyValue]]]): Rep[SizeContext] = { + override def mkSizeContext(outputs: Ref[Size[Coll[Box]]], inputs: Ref[Size[Coll[Box]]], dataInputs: Ref[Size[Coll[Box]]], selfBox: Ref[Size[Box]], lastBlockUtxoRootHash: Ref[Size[AvlTree]], headers: Ref[Size[Coll[Header]]], preHeader: Ref[Size[PreHeader]], vars: Ref[Coll[Size[AnyValue]]]): Ref[SizeContext] = { asRep[SizeContext](mkMethodCall(self, SizeBuilderClass.getMethod("mkSizeContext", classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym]), - List(outputs, inputs, dataInputs, selfBox, lastBlockUtxoRootHash, headers, preHeader, vars), + Array[AnyRef](outputs, inputs, dataInputs, selfBox, lastBlockUtxoRootHash, headers, preHeader, vars), true, false, element[SizeContext])) } } @@ -995,46 +873,48 @@ object SizeBuilder extends EntityObject("SizeBuilder") { lazy val sourceType: RType[SSizeBuilder] = { RType[SSizeBuilder] } - def lift(x: SSizeBuilder): Rep[SizeBuilder] = SizeBuilderConst(x) - def unlift(w: Rep[SizeBuilder]): SSizeBuilder = w match { + def lift(x: SSizeBuilder): Ref[SizeBuilder] = SizeBuilderConst(x) + def unlift(w: Ref[SizeBuilder]): SSizeBuilder = w match { case Def(SizeBuilderConst(x: SSizeBuilder)) => x.asInstanceOf[SSizeBuilder] case _ => unliftError(w) } } + private val SizeBuilderClass = classOf[SizeBuilder] + // entityAdapter for SizeBuilder trait - case class SizeBuilderAdapter(source: Rep[SizeBuilder]) - extends SizeBuilder with Def[SizeBuilder] { - val selfType: Elem[SizeBuilder] = element[SizeBuilder] + case class SizeBuilderAdapter(source: Ref[SizeBuilder]) + extends Node with SizeBuilder + with Def[SizeBuilder] { + val resultType: Elem[SizeBuilder] = element[SizeBuilder] override def transform(t: Transformer) = SizeBuilderAdapter(t(source)) - private val thisClass = classOf[SizeBuilder] - def mkSizeAnyValue(tVal: Rep[WRType[Any]], valueSize: Rep[Size[Any]]): Rep[SizeAnyValue] = { + def mkSizeAnyValue(tVal: Ref[WRType[Any]], valueSize: Ref[Size[Any]]): Ref[SizeAnyValue] = { asRep[SizeAnyValue](mkMethodCall(source, - thisClass.getMethod("mkSizeAnyValue", classOf[Sym], classOf[Sym]), - List(tVal, valueSize), + SizeBuilderClass.getMethod("mkSizeAnyValue", classOf[Sym], classOf[Sym]), + Array[AnyRef](tVal, valueSize), true, true, element[SizeAnyValue])) } - def mkSizeBox(propositionBytes: Rep[Size[Coll[Byte]]], bytes: Rep[Size[Coll[Byte]]], bytesWithoutRef: Rep[Size[Coll[Byte]]], registers: Rep[Size[Coll[WOption[AnyValue]]]], tokens: Rep[Size[Coll[(Coll[Byte], Long)]]]): Rep[SizeBox] = { + def mkSizeBox(propositionBytes: Ref[Size[Coll[Byte]]], bytes: Ref[Size[Coll[Byte]]], bytesWithoutRef: Ref[Size[Coll[Byte]]], registers: Ref[Size[Coll[WOption[AnyValue]]]], tokens: Ref[Size[Coll[(Coll[Byte], Long)]]]): Ref[SizeBox] = { asRep[SizeBox](mkMethodCall(source, - thisClass.getMethod("mkSizeBox", classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym]), - List(propositionBytes, bytes, bytesWithoutRef, registers, tokens), + SizeBuilderClass.getMethod("mkSizeBox", classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym]), + Array[AnyRef](propositionBytes, bytes, bytesWithoutRef, registers, tokens), true, true, element[SizeBox])) } - def mkSizeContext(outputs: Rep[Size[Coll[Box]]], inputs: Rep[Size[Coll[Box]]], dataInputs: Rep[Size[Coll[Box]]], selfBox: Rep[Size[Box]], lastBlockUtxoRootHash: Rep[Size[AvlTree]], headers: Rep[Size[Coll[Header]]], preHeader: Rep[Size[PreHeader]], vars: Rep[Coll[Size[AnyValue]]]): Rep[SizeContext] = { + def mkSizeContext(outputs: Ref[Size[Coll[Box]]], inputs: Ref[Size[Coll[Box]]], dataInputs: Ref[Size[Coll[Box]]], selfBox: Ref[Size[Box]], lastBlockUtxoRootHash: Ref[Size[AvlTree]], headers: Ref[Size[Coll[Header]]], preHeader: Ref[Size[PreHeader]], vars: Ref[Coll[Size[AnyValue]]]): Ref[SizeContext] = { asRep[SizeContext](mkMethodCall(source, - thisClass.getMethod("mkSizeContext", classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym]), - List(outputs, inputs, dataInputs, selfBox, lastBlockUtxoRootHash, headers, preHeader, vars), + SizeBuilderClass.getMethod("mkSizeContext", classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym]), + Array[AnyRef](outputs, inputs, dataInputs, selfBox, lastBlockUtxoRootHash, headers, preHeader, vars), true, true, element[SizeContext])) } } - // entityProxy: single proxy for each type family - implicit def proxySizeBuilder(p: Rep[SizeBuilder]): SizeBuilder = { - if (p.rhs.isInstanceOf[SizeBuilder@unchecked]) p.rhs.asInstanceOf[SizeBuilder] + // entityUnref: single unref method for each type family + implicit final def unrefSizeBuilder(p: Ref[SizeBuilder]): SizeBuilder = { + if (p.node.isInstanceOf[SizeBuilder]) p.node.asInstanceOf[SizeBuilder] else SizeBuilderAdapter(p) } @@ -1042,7 +922,7 @@ object SizeBuilder extends EntityObject("SizeBuilder") { // familyElem class SizeBuilderElem[To <: SizeBuilder] extends EntityElem[To] { - override val liftable: Liftables.Liftable[_, To] = LiftableSizeBuilder.asLiftable[SSizeBuilder, To] + override val liftable: Liftables.Liftable[_, To] = asLiftable[SSizeBuilder, To](LiftableSizeBuilder) override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { super.collectMethods ++ @@ -1050,91 +930,35 @@ object SizeBuilder extends EntityObject("SizeBuilder") { "mkSizeAnyValue", "mkSizeBox", "mkSizeContext" )) } - - lazy val parent: Option[Elem[_]] = None - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override lazy val tag = { - weakTypeTag[SizeBuilder].asInstanceOf[WeakTypeTag[To]] - } - override def convert(x: Rep[Def[_]]) = { - val conv = fun {x: Rep[SizeBuilder] => convertSizeBuilder(x) } - tryConvert(element[SizeBuilder], this, x, conv) - } - - def convertSizeBuilder(x: Rep[SizeBuilder]): Rep[To] = { - x.elem match { - case _: SizeBuilderElem[_] => asRep[To](x) - case e => !!!(s"Expected $x to have SizeBuilderElem[_], but got $e", x) - } - } - override def getDefaultRep: Rep[To] = ??? } implicit lazy val sizeBuilderElement: Elem[SizeBuilder] = new SizeBuilderElem[SizeBuilder] - implicit case object SizeBuilderCompanionElem extends CompanionElem[SizeBuilderCompanionCtor] { - lazy val tag = weakTypeTag[SizeBuilderCompanionCtor] - protected def getDefaultRep = RSizeBuilder - } + implicit case object SizeBuilderCompanionElem extends CompanionElem[SizeBuilderCompanionCtor] abstract class SizeBuilderCompanionCtor extends CompanionDef[SizeBuilderCompanionCtor] with SizeBuilderCompanion { - def selfType = SizeBuilderCompanionElem + def resultType = SizeBuilderCompanionElem override def toString = "SizeBuilder" } - implicit def proxySizeBuilderCompanionCtor(p: Rep[SizeBuilderCompanionCtor]): SizeBuilderCompanionCtor = - proxyOps[SizeBuilderCompanionCtor](p) + implicit final def unrefSizeBuilderCompanionCtor(p: Ref[SizeBuilderCompanionCtor]): SizeBuilderCompanionCtor = + p.node.asInstanceOf[SizeBuilderCompanionCtor] - lazy val RSizeBuilder: Rep[SizeBuilderCompanionCtor] = new SizeBuilderCompanionCtor { + lazy val RSizeBuilder: MutableLazy[SizeBuilderCompanionCtor] = MutableLazy(new SizeBuilderCompanionCtor { private val thisClass = classOf[SizeBuilderCompanion] - } - - object SizeBuilderMethods { - object mkSizeAnyValue { - def unapply(d: Def[_]): Nullable[(Rep[SizeBuilder], Rep[WRType[Any]], Rep[Size[Any]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SizeBuilderElem[_]] && method.getName == "mkSizeAnyValue" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[SizeBuilder], Rep[WRType[Any]], Rep[Size[Any]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SizeBuilder], Rep[WRType[Any]], Rep[Size[Any]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object mkSizeBox { - def unapply(d: Def[_]): Nullable[(Rep[SizeBuilder], Rep[Size[Coll[Byte]]], Rep[Size[Coll[Byte]]], Rep[Size[Coll[Byte]]], Rep[Size[Coll[WOption[AnyValue]]]], Rep[Size[Coll[(Coll[Byte], Long)]]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SizeBuilderElem[_]] && method.getName == "mkSizeBox" => - val res = (receiver, args(0), args(1), args(2), args(3), args(4)) - Nullable(res).asInstanceOf[Nullable[(Rep[SizeBuilder], Rep[Size[Coll[Byte]]], Rep[Size[Coll[Byte]]], Rep[Size[Coll[Byte]]], Rep[Size[Coll[WOption[AnyValue]]]], Rep[Size[Coll[(Coll[Byte], Long)]]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SizeBuilder], Rep[Size[Coll[Byte]]], Rep[Size[Coll[Byte]]], Rep[Size[Coll[Byte]]], Rep[Size[Coll[WOption[AnyValue]]]], Rep[Size[Coll[(Coll[Byte], Long)]]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object mkSizeContext { - def unapply(d: Def[_]): Nullable[(Rep[SizeBuilder], Rep[Size[Coll[Box]]], Rep[Size[Coll[Box]]], Rep[Size[Coll[Box]]], Rep[Size[Box]], Rep[Size[AvlTree]], Rep[Size[Coll[Header]]], Rep[Size[PreHeader]], Rep[Coll[Size[AnyValue]]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SizeBuilderElem[_]] && method.getName == "mkSizeContext" => - val res = (receiver, args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7)) - Nullable(res).asInstanceOf[Nullable[(Rep[SizeBuilder], Rep[Size[Coll[Box]]], Rep[Size[Coll[Box]]], Rep[Size[Coll[Box]]], Rep[Size[Box]], Rep[Size[AvlTree]], Rep[Size[Coll[Header]]], Rep[Size[PreHeader]], Rep[Coll[Size[AnyValue]]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SizeBuilder], Rep[Size[Coll[Box]]], Rep[Size[Coll[Box]]], Rep[Size[Coll[Box]]], Rep[Size[Box]], Rep[Size[AvlTree]], Rep[Size[Coll[Header]]], Rep[Size[PreHeader]], Rep[Coll[Size[AnyValue]]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - } - - object SizeBuilderCompanionMethods { - } + }) } // of object SizeBuilder registerEntityObject("SizeBuilder", SizeBuilder) + override def resetContext(): Unit = { + super.resetContext() + RSizeAnyValue.reset() + RSizeSigmaProp.reset() + RSizeBox.reset() + RSizeContext.reset() + RSizeBuilder.reset() + } + registerModule(CostedObjectsModule) } diff --git a/sigma-library/src/main/scala/special/sigma/impl/SigmaDslCostedImpl.scala b/sigma-library/src/main/scala/special/sigma/impl/SigmaDslCostedImpl.scala deleted file mode 100644 index bcc97da2f1..0000000000 --- a/sigma-library/src/main/scala/special/sigma/impl/SigmaDslCostedImpl.scala +++ /dev/null @@ -1,740 +0,0 @@ -package special.sigma - -import scalan._ -import scala.reflect.runtime.universe._ -import scala.reflect._ - -package impl { -// Abs ----------------------------------- -trait SigmaDslCostedDefs extends scalan.Scalan with SigmaDslCosted { - self: SigmaLibrary => -import IsoUR._ -import Converter._ -import AnyValue._ -import AvlTree._ -import Box._ -import CSizeAnyValue._ -import CSizeBox._ -import CSizeContext._ -import Coll._ -import Header._ -import PreHeader._ -import Size._ -import SizeAnyValue._ -import SizeBox._ -import SizeBuilder._ -import SizeContext._ -import SizeSigmaProp._ -import WOption._ -import WRType._ -import CSizeBuilder._ -import CSizeSigmaProp._ -import Context._ // manual fix -import SigmaProp._ // manual fix - -object CSizeAnyValue extends EntityObject("CSizeAnyValue") { - case class CSizeAnyValueCtor - (override val tVal: Rep[WRType[Any]], override val valueSize: Rep[Size[Any]]) - extends CSizeAnyValue(tVal, valueSize) with Def[CSizeAnyValue] { - override lazy val eVal: Elem[AnyValue] = implicitly[Elem[AnyValue]] - lazy val selfType = element[CSizeAnyValue] - override def transform(t: Transformer) = CSizeAnyValueCtor(t(tVal), t(valueSize)) - private val thisClass = classOf[SizeAnyValue] - - override def dataSize: Rep[Long] = { - asRep[Long](mkMethodCall(self, - thisClass.getMethod("dataSize"), - List(), - true, false, element[Long])) - } - } - // elem for concrete class - class CSizeAnyValueElem(val iso: Iso[CSizeAnyValueData, CSizeAnyValue]) - extends SizeAnyValueElem[CSizeAnyValue] - with ConcreteElem[CSizeAnyValueData, CSizeAnyValue] { - override lazy val parent: Option[Elem[_]] = Some(sizeAnyValueElement) - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override def convertSizeAnyValue(x: Rep[SizeAnyValue]) = RCSizeAnyValue(x.tVal, x.valueSize) - override def getDefaultRep = RCSizeAnyValue(element[WRType[Any]].defaultRepValue, element[Size[Any]].defaultRepValue) - override lazy val tag = { - weakTypeTag[CSizeAnyValue] - } - } - - // state representation type - type CSizeAnyValueData = (WRType[Any], Size[Any]) - - // 3) Iso for concrete class - class CSizeAnyValueIso - extends EntityIso[CSizeAnyValueData, CSizeAnyValue] with Def[CSizeAnyValueIso] { - override def transform(t: Transformer) = new CSizeAnyValueIso() - private lazy val _safeFrom = fun { p: Rep[CSizeAnyValue] => (p.tVal, p.valueSize) } - override def from(p: Rep[CSizeAnyValue]) = - tryConvert[CSizeAnyValue, (WRType[Any], Size[Any])](eTo, eFrom, p, _safeFrom) - override def to(p: Rep[(WRType[Any], Size[Any])]) = { - val Pair(tVal, valueSize) = p - RCSizeAnyValue(tVal, valueSize) - } - lazy val eFrom = pairElement(element[WRType[Any]], element[Size[Any]]) - lazy val eTo = new CSizeAnyValueElem(self) - lazy val selfType = new CSizeAnyValueIsoElem - def productArity = 0 - def productElement(n: Int) = ??? - } - case class CSizeAnyValueIsoElem() extends Elem[CSizeAnyValueIso] { - def getDefaultRep = reifyObject(new CSizeAnyValueIso()) - lazy val tag = { - weakTypeTag[CSizeAnyValueIso] - } - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - } - // 4) constructor and deconstructor - class CSizeAnyValueCompanionCtor extends CompanionDef[CSizeAnyValueCompanionCtor] with CSizeAnyValueCompanion { - def selfType = CSizeAnyValueCompanionElem - override def toString = "CSizeAnyValueCompanion" - @scalan.OverloadId("fromData") - def apply(p: Rep[CSizeAnyValueData]): Rep[CSizeAnyValue] = { - isoCSizeAnyValue.to(p) - } - - @scalan.OverloadId("fromFields") - def apply(tVal: Rep[WRType[Any]], valueSize: Rep[Size[Any]]): Rep[CSizeAnyValue] = - mkCSizeAnyValue(tVal, valueSize) - - def unapply(p: Rep[SizeAnyValue]) = unmkCSizeAnyValue(p) - } - lazy val CSizeAnyValueRep: Rep[CSizeAnyValueCompanionCtor] = new CSizeAnyValueCompanionCtor - lazy val RCSizeAnyValue: CSizeAnyValueCompanionCtor = proxyCSizeAnyValueCompanion(CSizeAnyValueRep) - implicit def proxyCSizeAnyValueCompanion(p: Rep[CSizeAnyValueCompanionCtor]): CSizeAnyValueCompanionCtor = { - if (p.rhs.isInstanceOf[CSizeAnyValueCompanionCtor]) - p.rhs.asInstanceOf[CSizeAnyValueCompanionCtor] - else - proxyOps[CSizeAnyValueCompanionCtor](p) - } - - implicit case object CSizeAnyValueCompanionElem extends CompanionElem[CSizeAnyValueCompanionCtor] { - lazy val tag = weakTypeTag[CSizeAnyValueCompanionCtor] - protected def getDefaultRep = CSizeAnyValueRep - } - - implicit def proxyCSizeAnyValue(p: Rep[CSizeAnyValue]): CSizeAnyValue = - proxyOps[CSizeAnyValue](p) - - implicit class ExtendedCSizeAnyValue(p: Rep[CSizeAnyValue]) { - def toData: Rep[CSizeAnyValueData] = { - isoCSizeAnyValue.from(p) - } - } - - // 5) implicit resolution of Iso - implicit def isoCSizeAnyValue: Iso[CSizeAnyValueData, CSizeAnyValue] = - reifyObject(new CSizeAnyValueIso()) - - def mkCSizeAnyValue - (tVal: Rep[WRType[Any]], valueSize: Rep[Size[Any]]): Rep[CSizeAnyValue] = { - new CSizeAnyValueCtor(tVal, valueSize) - } - def unmkCSizeAnyValue(p: Rep[SizeAnyValue]) = p.elem.asInstanceOf[Elem[_]] match { - case _: CSizeAnyValueElem @unchecked => - Some((asRep[CSizeAnyValue](p).tVal, asRep[CSizeAnyValue](p).valueSize)) - case _ => - None - } - - object CSizeAnyValueMethods { - object dataSize { - def unapply(d: Def[_]): Nullable[Rep[CSizeAnyValue]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[CSizeAnyValueElem] && method.getName == "dataSize" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[CSizeAnyValue]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[CSizeAnyValue]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - } - - object CSizeAnyValueCompanionMethods { - } -} // of object CSizeAnyValue - registerEntityObject("CSizeAnyValue", CSizeAnyValue) - -object CSizeSigmaProp extends EntityObject("CSizeSigmaProp") { - case class CSizeSigmaPropCtor - (override val propBytes: Rep[Size[Coll[Byte]]]) - extends CSizeSigmaProp(propBytes) with Def[CSizeSigmaProp] { - override lazy val eVal: Elem[SigmaProp] = implicitly[Elem[SigmaProp]] - lazy val selfType = element[CSizeSigmaProp] - override def transform(t: Transformer) = CSizeSigmaPropCtor(t(propBytes)) - private val thisClass = classOf[SizeSigmaProp] - - override def dataSize: Rep[Long] = { - asRep[Long](mkMethodCall(self, - thisClass.getMethod("dataSize"), - List(), - true, false, element[Long])) - } - } - // elem for concrete class - class CSizeSigmaPropElem(val iso: Iso[CSizeSigmaPropData, CSizeSigmaProp]) - extends SizeSigmaPropElem[CSizeSigmaProp] - with ConcreteElem[CSizeSigmaPropData, CSizeSigmaProp] { - override lazy val parent: Option[Elem[_]] = Some(sizeSigmaPropElement) - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override def convertSizeSigmaProp(x: Rep[SizeSigmaProp]) = RCSizeSigmaProp(x.propBytes) - override def getDefaultRep = RCSizeSigmaProp(element[Size[Coll[Byte]]].defaultRepValue) - override lazy val tag = { - weakTypeTag[CSizeSigmaProp] - } - } - - // state representation type - type CSizeSigmaPropData = Size[Coll[Byte]] - - // 3) Iso for concrete class - class CSizeSigmaPropIso - extends EntityIso[CSizeSigmaPropData, CSizeSigmaProp] with Def[CSizeSigmaPropIso] { - override def transform(t: Transformer) = new CSizeSigmaPropIso() - private lazy val _safeFrom = fun { p: Rep[CSizeSigmaProp] => p.propBytes } - override def from(p: Rep[CSizeSigmaProp]) = - tryConvert[CSizeSigmaProp, Size[Coll[Byte]]](eTo, eFrom, p, _safeFrom) - override def to(p: Rep[Size[Coll[Byte]]]) = { - val propBytes = p - RCSizeSigmaProp(propBytes) - } - lazy val eFrom = element[Size[Coll[Byte]]] - lazy val eTo = new CSizeSigmaPropElem(self) - lazy val selfType = new CSizeSigmaPropIsoElem - def productArity = 0 - def productElement(n: Int) = ??? - } - case class CSizeSigmaPropIsoElem() extends Elem[CSizeSigmaPropIso] { - def getDefaultRep = reifyObject(new CSizeSigmaPropIso()) - lazy val tag = { - weakTypeTag[CSizeSigmaPropIso] - } - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - } - // 4) constructor and deconstructor - class CSizeSigmaPropCompanionCtor extends CompanionDef[CSizeSigmaPropCompanionCtor] with CSizeSigmaPropCompanion { - def selfType = CSizeSigmaPropCompanionElem - override def toString = "CSizeSigmaPropCompanion" - - @scalan.OverloadId("fromFields") - def apply(propBytes: Rep[Size[Coll[Byte]]]): Rep[CSizeSigmaProp] = - mkCSizeSigmaProp(propBytes) - - def unapply(p: Rep[SizeSigmaProp]) = unmkCSizeSigmaProp(p) - } - lazy val CSizeSigmaPropRep: Rep[CSizeSigmaPropCompanionCtor] = new CSizeSigmaPropCompanionCtor - lazy val RCSizeSigmaProp: CSizeSigmaPropCompanionCtor = proxyCSizeSigmaPropCompanion(CSizeSigmaPropRep) - implicit def proxyCSizeSigmaPropCompanion(p: Rep[CSizeSigmaPropCompanionCtor]): CSizeSigmaPropCompanionCtor = { - if (p.rhs.isInstanceOf[CSizeSigmaPropCompanionCtor]) - p.rhs.asInstanceOf[CSizeSigmaPropCompanionCtor] - else - proxyOps[CSizeSigmaPropCompanionCtor](p) - } - - implicit case object CSizeSigmaPropCompanionElem extends CompanionElem[CSizeSigmaPropCompanionCtor] { - lazy val tag = weakTypeTag[CSizeSigmaPropCompanionCtor] - protected def getDefaultRep = CSizeSigmaPropRep - } - - implicit def proxyCSizeSigmaProp(p: Rep[CSizeSigmaProp]): CSizeSigmaProp = - proxyOps[CSizeSigmaProp](p) - - implicit class ExtendedCSizeSigmaProp(p: Rep[CSizeSigmaProp]) { - def toData: Rep[CSizeSigmaPropData] = { - isoCSizeSigmaProp.from(p) - } - } - - // 5) implicit resolution of Iso - implicit def isoCSizeSigmaProp: Iso[CSizeSigmaPropData, CSizeSigmaProp] = - reifyObject(new CSizeSigmaPropIso()) - - def mkCSizeSigmaProp - (propBytes: Rep[Size[Coll[Byte]]]): Rep[CSizeSigmaProp] = { - new CSizeSigmaPropCtor(propBytes) - } - def unmkCSizeSigmaProp(p: Rep[SizeSigmaProp]) = p.elem.asInstanceOf[Elem[_]] match { - case _: CSizeSigmaPropElem @unchecked => - Some((asRep[CSizeSigmaProp](p).propBytes)) - case _ => - None - } - - object CSizeSigmaPropMethods { - object dataSize { - def unapply(d: Def[_]): Nullable[Rep[CSizeSigmaProp]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[CSizeSigmaPropElem] && method.getName == "dataSize" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[CSizeSigmaProp]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[CSizeSigmaProp]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - } - - object CSizeSigmaPropCompanionMethods { - } -} // of object CSizeSigmaProp - registerEntityObject("CSizeSigmaProp", CSizeSigmaProp) - -object CSizeBox extends EntityObject("CSizeBox") { - case class CSizeBoxCtor - (override val propositionBytes: Rep[Size[Coll[Byte]]], override val bytes: Rep[Size[Coll[Byte]]], override val bytesWithoutRef: Rep[Size[Coll[Byte]]], override val registers: Rep[Size[Coll[WOption[AnyValue]]]], override val tokens: Rep[Size[Coll[(Coll[Byte], Long)]]]) - extends CSizeBox(propositionBytes, bytes, bytesWithoutRef, registers, tokens) with Def[CSizeBox] { - override lazy val eVal: Elem[Box] = implicitly[Elem[Box]] - lazy val selfType = element[CSizeBox] - override def transform(t: Transformer) = CSizeBoxCtor(t(propositionBytes), t(bytes), t(bytesWithoutRef), t(registers), t(tokens)) - private val thisClass = classOf[SizeBox] - - override def dataSize: Rep[Long] = { - asRep[Long](mkMethodCall(self, - thisClass.getMethod("dataSize"), - List(), - true, false, element[Long])) - } - - override def getReg[T](id: Rep[Byte])(implicit tT: Elem[T]): Rep[Size[WOption[T]]] = { - asRep[Size[WOption[T]]](mkMethodCall(self, - thisClass.getMethod("getReg", classOf[Sym], classOf[Elem[_]]), - List(id, tT), - true, false, element[Size[WOption[T]]])) - } - } - // elem for concrete class - class CSizeBoxElem(val iso: Iso[CSizeBoxData, CSizeBox]) - extends SizeBoxElem[CSizeBox] - with ConcreteElem[CSizeBoxData, CSizeBox] { - override lazy val parent: Option[Elem[_]] = Some(sizeBoxElement) - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override def convertSizeBox(x: Rep[SizeBox]) = RCSizeBox(x.propositionBytes, x.bytes, x.bytesWithoutRef, x.registers, x.tokens) - override def getDefaultRep = RCSizeBox(element[Size[Coll[Byte]]].defaultRepValue, element[Size[Coll[Byte]]].defaultRepValue, element[Size[Coll[Byte]]].defaultRepValue, element[Size[Coll[WOption[AnyValue]]]].defaultRepValue, element[Size[Coll[(Coll[Byte], Long)]]].defaultRepValue) - override lazy val tag = { - weakTypeTag[CSizeBox] - } - } - - // state representation type - type CSizeBoxData = (Size[Coll[Byte]], (Size[Coll[Byte]], (Size[Coll[Byte]], (Size[Coll[WOption[AnyValue]]], Size[Coll[(Coll[Byte], Long)]])))) - - // 3) Iso for concrete class - class CSizeBoxIso - extends EntityIso[CSizeBoxData, CSizeBox] with Def[CSizeBoxIso] { - override def transform(t: Transformer) = new CSizeBoxIso() - private lazy val _safeFrom = fun { p: Rep[CSizeBox] => (p.propositionBytes, p.bytes, p.bytesWithoutRef, p.registers, p.tokens) } - override def from(p: Rep[CSizeBox]) = - tryConvert[CSizeBox, (Size[Coll[Byte]], (Size[Coll[Byte]], (Size[Coll[Byte]], (Size[Coll[WOption[AnyValue]]], Size[Coll[(Coll[Byte], Long)]]))))](eTo, eFrom, p, _safeFrom) - override def to(p: Rep[(Size[Coll[Byte]], (Size[Coll[Byte]], (Size[Coll[Byte]], (Size[Coll[WOption[AnyValue]]], Size[Coll[(Coll[Byte], Long)]]))))]) = { - val Pair(propositionBytes, Pair(bytes, Pair(bytesWithoutRef, Pair(registers, tokens)))) = p - RCSizeBox(propositionBytes, bytes, bytesWithoutRef, registers, tokens) - } - lazy val eFrom = pairElement(element[Size[Coll[Byte]]], pairElement(element[Size[Coll[Byte]]], pairElement(element[Size[Coll[Byte]]], pairElement(element[Size[Coll[WOption[AnyValue]]]], element[Size[Coll[(Coll[Byte], Long)]]])))) - lazy val eTo = new CSizeBoxElem(self) - lazy val selfType = new CSizeBoxIsoElem - def productArity = 0 - def productElement(n: Int) = ??? - } - case class CSizeBoxIsoElem() extends Elem[CSizeBoxIso] { - def getDefaultRep = reifyObject(new CSizeBoxIso()) - lazy val tag = { - weakTypeTag[CSizeBoxIso] - } - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - } - // 4) constructor and deconstructor - class CSizeBoxCompanionCtor extends CompanionDef[CSizeBoxCompanionCtor] with CSizeBoxCompanion { - def selfType = CSizeBoxCompanionElem - override def toString = "CSizeBoxCompanion" - @scalan.OverloadId("fromData") - def apply(p: Rep[CSizeBoxData]): Rep[CSizeBox] = { - isoCSizeBox.to(p) - } - - @scalan.OverloadId("fromFields") - def apply(propositionBytes: Rep[Size[Coll[Byte]]], bytes: Rep[Size[Coll[Byte]]], bytesWithoutRef: Rep[Size[Coll[Byte]]], registers: Rep[Size[Coll[WOption[AnyValue]]]], tokens: Rep[Size[Coll[(Coll[Byte], Long)]]]): Rep[CSizeBox] = - mkCSizeBox(propositionBytes, bytes, bytesWithoutRef, registers, tokens) - - def unapply(p: Rep[SizeBox]) = unmkCSizeBox(p) - } - lazy val CSizeBoxRep: Rep[CSizeBoxCompanionCtor] = new CSizeBoxCompanionCtor - lazy val RCSizeBox: CSizeBoxCompanionCtor = proxyCSizeBoxCompanion(CSizeBoxRep) - implicit def proxyCSizeBoxCompanion(p: Rep[CSizeBoxCompanionCtor]): CSizeBoxCompanionCtor = { - if (p.rhs.isInstanceOf[CSizeBoxCompanionCtor]) - p.rhs.asInstanceOf[CSizeBoxCompanionCtor] - else - proxyOps[CSizeBoxCompanionCtor](p) - } - - implicit case object CSizeBoxCompanionElem extends CompanionElem[CSizeBoxCompanionCtor] { - lazy val tag = weakTypeTag[CSizeBoxCompanionCtor] - protected def getDefaultRep = CSizeBoxRep - } - - implicit def proxyCSizeBox(p: Rep[CSizeBox]): CSizeBox = - proxyOps[CSizeBox](p) - - implicit class ExtendedCSizeBox(p: Rep[CSizeBox]) { - def toData: Rep[CSizeBoxData] = { - isoCSizeBox.from(p) - } - } - - // 5) implicit resolution of Iso - implicit def isoCSizeBox: Iso[CSizeBoxData, CSizeBox] = - reifyObject(new CSizeBoxIso()) - - def mkCSizeBox - (propositionBytes: Rep[Size[Coll[Byte]]], bytes: Rep[Size[Coll[Byte]]], bytesWithoutRef: Rep[Size[Coll[Byte]]], registers: Rep[Size[Coll[WOption[AnyValue]]]], tokens: Rep[Size[Coll[(Coll[Byte], Long)]]]): Rep[CSizeBox] = { - new CSizeBoxCtor(propositionBytes, bytes, bytesWithoutRef, registers, tokens) - } - def unmkCSizeBox(p: Rep[SizeBox]) = p.elem.asInstanceOf[Elem[_]] match { - case _: CSizeBoxElem @unchecked => - Some((asRep[CSizeBox](p).propositionBytes, asRep[CSizeBox](p).bytes, asRep[CSizeBox](p).bytesWithoutRef, asRep[CSizeBox](p).registers, asRep[CSizeBox](p).tokens)) - case _ => - None - } - - object CSizeBoxMethods { - object dataSize { - def unapply(d: Def[_]): Nullable[Rep[CSizeBox]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[CSizeBoxElem] && method.getName == "dataSize" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[CSizeBox]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[CSizeBox]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object getReg { - def unapply(d: Def[_]): Nullable[(Rep[CSizeBox], Rep[Byte], Elem[T]) forSome {type T}] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[CSizeBoxElem] && method.getName == "getReg" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[CSizeBox], Rep[Byte], Elem[T]) forSome {type T}]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[CSizeBox], Rep[Byte], Elem[T]) forSome {type T}] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - } - - object CSizeBoxCompanionMethods { - } -} // of object CSizeBox - registerEntityObject("CSizeBox", CSizeBox) - -object CSizeContext extends EntityObject("CSizeContext") { - case class CSizeContextCtor - (override val outputs: Rep[Size[Coll[Box]]], override val inputs: Rep[Size[Coll[Box]]], override val dataInputs: Rep[Size[Coll[Box]]], override val selfBox: Rep[Size[Box]], override val lastBlockUtxoRootHash: Rep[Size[AvlTree]], override val headers: Rep[Size[Coll[Header]]], override val preHeader: Rep[Size[PreHeader]], override val vars: Rep[Coll[Size[AnyValue]]]) - extends CSizeContext(outputs, inputs, dataInputs, selfBox, lastBlockUtxoRootHash, headers, preHeader, vars) with Def[CSizeContext] { - override lazy val eVal: Elem[Context] = implicitly[Elem[Context]] - lazy val selfType = element[CSizeContext] - override def transform(t: Transformer) = CSizeContextCtor(t(outputs), t(inputs), t(dataInputs), t(selfBox), t(lastBlockUtxoRootHash), t(headers), t(preHeader), t(vars)) - private val thisClass = classOf[SizeContext] - - override def dataSize: Rep[Long] = { - asRep[Long](mkMethodCall(self, - thisClass.getMethod("dataSize"), - List(), - true, false, element[Long])) - } - - override def getVar[T](id: Rep[Byte])(implicit tT: Elem[T]): Rep[Size[WOption[T]]] = { - asRep[Size[WOption[T]]](mkMethodCall(self, - thisClass.getMethod("getVar", classOf[Sym], classOf[Elem[_]]), - List(id, tT), - true, false, element[Size[WOption[T]]])) - } - } - // elem for concrete class - class CSizeContextElem(val iso: Iso[CSizeContextData, CSizeContext]) - extends SizeContextElem[CSizeContext] - with ConcreteElem[CSizeContextData, CSizeContext] { - override lazy val parent: Option[Elem[_]] = Some(sizeContextElement) - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override def convertSizeContext(x: Rep[SizeContext]) = // Converter is not generated by meta -!!!("Cannot convert from SizeContext to CSizeContext: missing fields List(vars)") - override def getDefaultRep = RCSizeContext(element[Size[Coll[Box]]].defaultRepValue, element[Size[Coll[Box]]].defaultRepValue, element[Size[Coll[Box]]].defaultRepValue, element[Size[Box]].defaultRepValue, element[Size[AvlTree]].defaultRepValue, element[Size[Coll[Header]]].defaultRepValue, element[Size[PreHeader]].defaultRepValue, element[Coll[Size[AnyValue]]].defaultRepValue) - override lazy val tag = { - weakTypeTag[CSizeContext] - } - } - - // state representation type - type CSizeContextData = (Size[Coll[Box]], (Size[Coll[Box]], (Size[Coll[Box]], (Size[Box], (Size[AvlTree], (Size[Coll[Header]], (Size[PreHeader], Coll[Size[AnyValue]]))))))) - - // 3) Iso for concrete class - class CSizeContextIso - extends EntityIso[CSizeContextData, CSizeContext] with Def[CSizeContextIso] { - override def transform(t: Transformer) = new CSizeContextIso() - private lazy val _safeFrom = fun { p: Rep[CSizeContext] => (p.outputs, p.inputs, p.dataInputs, p.selfBox, p.lastBlockUtxoRootHash, p.headers, p.preHeader, p.vars) } - override def from(p: Rep[CSizeContext]) = - tryConvert[CSizeContext, (Size[Coll[Box]], (Size[Coll[Box]], (Size[Coll[Box]], (Size[Box], (Size[AvlTree], (Size[Coll[Header]], (Size[PreHeader], Coll[Size[AnyValue]])))))))](eTo, eFrom, p, _safeFrom) - override def to(p: Rep[(Size[Coll[Box]], (Size[Coll[Box]], (Size[Coll[Box]], (Size[Box], (Size[AvlTree], (Size[Coll[Header]], (Size[PreHeader], Coll[Size[AnyValue]])))))))]) = { - val Pair(outputs, Pair(inputs, Pair(dataInputs, Pair(selfBox, Pair(lastBlockUtxoRootHash, Pair(headers, Pair(preHeader, vars))))))) = p - RCSizeContext(outputs, inputs, dataInputs, selfBox, lastBlockUtxoRootHash, headers, preHeader, vars) - } - lazy val eFrom = pairElement(element[Size[Coll[Box]]], pairElement(element[Size[Coll[Box]]], pairElement(element[Size[Coll[Box]]], pairElement(element[Size[Box]], pairElement(element[Size[AvlTree]], pairElement(element[Size[Coll[Header]]], pairElement(element[Size[PreHeader]], element[Coll[Size[AnyValue]]]))))))) - lazy val eTo = new CSizeContextElem(self) - lazy val selfType = new CSizeContextIsoElem - def productArity = 0 - def productElement(n: Int) = ??? - } - case class CSizeContextIsoElem() extends Elem[CSizeContextIso] { - def getDefaultRep = reifyObject(new CSizeContextIso()) - lazy val tag = { - weakTypeTag[CSizeContextIso] - } - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - } - // 4) constructor and deconstructor - class CSizeContextCompanionCtor extends CompanionDef[CSizeContextCompanionCtor] with CSizeContextCompanion { - def selfType = CSizeContextCompanionElem - override def toString = "CSizeContextCompanion" - @scalan.OverloadId("fromData") - def apply(p: Rep[CSizeContextData]): Rep[CSizeContext] = { - isoCSizeContext.to(p) - } - - @scalan.OverloadId("fromFields") - def apply(outputs: Rep[Size[Coll[Box]]], inputs: Rep[Size[Coll[Box]]], dataInputs: Rep[Size[Coll[Box]]], selfBox: Rep[Size[Box]], lastBlockUtxoRootHash: Rep[Size[AvlTree]], headers: Rep[Size[Coll[Header]]], preHeader: Rep[Size[PreHeader]], vars: Rep[Coll[Size[AnyValue]]]): Rep[CSizeContext] = - mkCSizeContext(outputs, inputs, dataInputs, selfBox, lastBlockUtxoRootHash, headers, preHeader, vars) - - def unapply(p: Rep[SizeContext]) = unmkCSizeContext(p) - } - lazy val CSizeContextRep: Rep[CSizeContextCompanionCtor] = new CSizeContextCompanionCtor - lazy val RCSizeContext: CSizeContextCompanionCtor = proxyCSizeContextCompanion(CSizeContextRep) - implicit def proxyCSizeContextCompanion(p: Rep[CSizeContextCompanionCtor]): CSizeContextCompanionCtor = { - if (p.rhs.isInstanceOf[CSizeContextCompanionCtor]) - p.rhs.asInstanceOf[CSizeContextCompanionCtor] - else - proxyOps[CSizeContextCompanionCtor](p) - } - - implicit case object CSizeContextCompanionElem extends CompanionElem[CSizeContextCompanionCtor] { - lazy val tag = weakTypeTag[CSizeContextCompanionCtor] - protected def getDefaultRep = CSizeContextRep - } - - implicit def proxyCSizeContext(p: Rep[CSizeContext]): CSizeContext = - proxyOps[CSizeContext](p) - - implicit class ExtendedCSizeContext(p: Rep[CSizeContext]) { - def toData: Rep[CSizeContextData] = { - isoCSizeContext.from(p) - } - } - - // 5) implicit resolution of Iso - implicit def isoCSizeContext: Iso[CSizeContextData, CSizeContext] = - reifyObject(new CSizeContextIso()) - - def mkCSizeContext - (outputs: Rep[Size[Coll[Box]]], inputs: Rep[Size[Coll[Box]]], dataInputs: Rep[Size[Coll[Box]]], selfBox: Rep[Size[Box]], lastBlockUtxoRootHash: Rep[Size[AvlTree]], headers: Rep[Size[Coll[Header]]], preHeader: Rep[Size[PreHeader]], vars: Rep[Coll[Size[AnyValue]]]): Rep[CSizeContext] = { - new CSizeContextCtor(outputs, inputs, dataInputs, selfBox, lastBlockUtxoRootHash, headers, preHeader, vars) - } - def unmkCSizeContext(p: Rep[SizeContext]) = p.elem.asInstanceOf[Elem[_]] match { - case _: CSizeContextElem @unchecked => - Some((asRep[CSizeContext](p).outputs, asRep[CSizeContext](p).inputs, asRep[CSizeContext](p).dataInputs, asRep[CSizeContext](p).selfBox, asRep[CSizeContext](p).lastBlockUtxoRootHash, asRep[CSizeContext](p).headers, asRep[CSizeContext](p).preHeader, asRep[CSizeContext](p).vars)) - case _ => - None - } - - object CSizeContextMethods { - object dataSize { - def unapply(d: Def[_]): Nullable[Rep[CSizeContext]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[CSizeContextElem] && method.getName == "dataSize" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[CSizeContext]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[CSizeContext]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object getVar { - def unapply(d: Def[_]): Nullable[(Rep[CSizeContext], Rep[Byte], Elem[T]) forSome {type T}] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[CSizeContextElem] && method.getName == "getVar" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[CSizeContext], Rep[Byte], Elem[T]) forSome {type T}]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[CSizeContext], Rep[Byte], Elem[T]) forSome {type T}] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - } - - object CSizeContextCompanionMethods { - } -} // of object CSizeContext - registerEntityObject("CSizeContext", CSizeContext) - -object CSizeBuilder extends EntityObject("CSizeBuilder") { - case class CSizeBuilderCtor - () - extends CSizeBuilder() with Def[CSizeBuilder] { - lazy val selfType = element[CSizeBuilder] - override def transform(t: Transformer) = CSizeBuilderCtor() - } - // elem for concrete class - class CSizeBuilderElem(val iso: Iso[CSizeBuilderData, CSizeBuilder]) - extends SizeBuilderElem[CSizeBuilder] - with ConcreteElem[CSizeBuilderData, CSizeBuilder] { - override lazy val parent: Option[Elem[_]] = Some(sizeBuilderElement) - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override def convertSizeBuilder(x: Rep[SizeBuilder]) = RCSizeBuilder() - override def getDefaultRep = RCSizeBuilder() - override lazy val tag = { - weakTypeTag[CSizeBuilder] - } - } - - // state representation type - type CSizeBuilderData = Unit - - // 3) Iso for concrete class - class CSizeBuilderIso - extends EntityIso[CSizeBuilderData, CSizeBuilder] with Def[CSizeBuilderIso] { - override def transform(t: Transformer) = new CSizeBuilderIso() - private lazy val _safeFrom = fun { p: Rep[CSizeBuilder] => () } - override def from(p: Rep[CSizeBuilder]) = - tryConvert[CSizeBuilder, Unit](eTo, eFrom, p, _safeFrom) - override def to(p: Rep[Unit]) = { - val unit = p - RCSizeBuilder() - } - lazy val eFrom = UnitElement - lazy val eTo = new CSizeBuilderElem(self) - lazy val selfType = new CSizeBuilderIsoElem - def productArity = 0 - def productElement(n: Int) = ??? - } - case class CSizeBuilderIsoElem() extends Elem[CSizeBuilderIso] { - def getDefaultRep = reifyObject(new CSizeBuilderIso()) - lazy val tag = { - weakTypeTag[CSizeBuilderIso] - } - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - } - // 4) constructor and deconstructor - class CSizeBuilderCompanionCtor extends CompanionDef[CSizeBuilderCompanionCtor] with CSizeBuilderCompanion { - def selfType = CSizeBuilderCompanionElem - override def toString = "CSizeBuilderCompanion" - @scalan.OverloadId("fromData") - def apply(p: Rep[CSizeBuilderData]): Rep[CSizeBuilder] = { - isoCSizeBuilder.to(p) - } - - @scalan.OverloadId("fromFields") - def apply(): Rep[CSizeBuilder] = - mkCSizeBuilder() - - def unapply(p: Rep[SizeBuilder]) = unmkCSizeBuilder(p) - } - lazy val CSizeBuilderRep: Rep[CSizeBuilderCompanionCtor] = new CSizeBuilderCompanionCtor - lazy val RCSizeBuilder: CSizeBuilderCompanionCtor = proxyCSizeBuilderCompanion(CSizeBuilderRep) - implicit def proxyCSizeBuilderCompanion(p: Rep[CSizeBuilderCompanionCtor]): CSizeBuilderCompanionCtor = { - if (p.rhs.isInstanceOf[CSizeBuilderCompanionCtor]) - p.rhs.asInstanceOf[CSizeBuilderCompanionCtor] - else - proxyOps[CSizeBuilderCompanionCtor](p) - } - - implicit case object CSizeBuilderCompanionElem extends CompanionElem[CSizeBuilderCompanionCtor] { - lazy val tag = weakTypeTag[CSizeBuilderCompanionCtor] - protected def getDefaultRep = CSizeBuilderRep - } - - implicit def proxyCSizeBuilder(p: Rep[CSizeBuilder]): CSizeBuilder = - proxyOps[CSizeBuilder](p) - - implicit class ExtendedCSizeBuilder(p: Rep[CSizeBuilder]) { - def toData: Rep[CSizeBuilderData] = { - isoCSizeBuilder.from(p) - } - } - - // 5) implicit resolution of Iso - implicit def isoCSizeBuilder: Iso[CSizeBuilderData, CSizeBuilder] = - reifyObject(new CSizeBuilderIso()) - - def mkCSizeBuilder - (): Rep[CSizeBuilder] = { - new CSizeBuilderCtor() - } - def unmkCSizeBuilder(p: Rep[SizeBuilder]) = p.elem.asInstanceOf[Elem[_]] match { - case _: CSizeBuilderElem @unchecked => - Some(()) - case _ => - None - } - - object CSizeBuilderMethods { - object mkSizeAnyValue { - def unapply(d: Def[_]): Nullable[(Rep[CSizeBuilder], Rep[WRType[Any]], Rep[Size[Any]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[CSizeBuilderElem] && method.getName == "mkSizeAnyValue" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[CSizeBuilder], Rep[WRType[Any]], Rep[Size[Any]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[CSizeBuilder], Rep[WRType[Any]], Rep[Size[Any]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object mkSizeBox { - def unapply(d: Def[_]): Nullable[(Rep[CSizeBuilder], Rep[Size[Coll[Byte]]], Rep[Size[Coll[Byte]]], Rep[Size[Coll[Byte]]], Rep[Size[Coll[WOption[AnyValue]]]], Rep[Size[Coll[(Coll[Byte], Long)]]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[CSizeBuilderElem] && method.getName == "mkSizeBox" => - val res = (receiver, args(0), args(1), args(2), args(3), args(4)) - Nullable(res).asInstanceOf[Nullable[(Rep[CSizeBuilder], Rep[Size[Coll[Byte]]], Rep[Size[Coll[Byte]]], Rep[Size[Coll[Byte]]], Rep[Size[Coll[WOption[AnyValue]]]], Rep[Size[Coll[(Coll[Byte], Long)]]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[CSizeBuilder], Rep[Size[Coll[Byte]]], Rep[Size[Coll[Byte]]], Rep[Size[Coll[Byte]]], Rep[Size[Coll[WOption[AnyValue]]]], Rep[Size[Coll[(Coll[Byte], Long)]]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object mkSizeContext { - def unapply(d: Def[_]): Nullable[(Rep[CSizeBuilder], Rep[Size[Coll[Box]]], Rep[Size[Coll[Box]]], Rep[Size[Coll[Box]]], Rep[Size[Box]], Rep[Size[AvlTree]], Rep[Size[Coll[Header]]], Rep[Size[PreHeader]], Rep[Coll[Size[AnyValue]]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[CSizeBuilderElem] && method.getName == "mkSizeContext" => - val res = (receiver, args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7)) - Nullable(res).asInstanceOf[Nullable[(Rep[CSizeBuilder], Rep[Size[Coll[Box]]], Rep[Size[Coll[Box]]], Rep[Size[Coll[Box]]], Rep[Size[Box]], Rep[Size[AvlTree]], Rep[Size[Coll[Header]]], Rep[Size[PreHeader]], Rep[Coll[Size[AnyValue]]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[CSizeBuilder], Rep[Size[Coll[Box]]], Rep[Size[Coll[Box]]], Rep[Size[Coll[Box]]], Rep[Size[Box]], Rep[Size[AvlTree]], Rep[Size[Coll[Header]]], Rep[Size[PreHeader]], Rep[Coll[Size[AnyValue]]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - } - - object CSizeBuilderCompanionMethods { - } -} // of object CSizeBuilder - registerEntityObject("CSizeBuilder", CSizeBuilder) - - registerModule(SigmaDslCostedModule) -} - -object SigmaDslCostedModule extends scalan.ModuleInfo("special.sigma", "SigmaDslCosted") -} - -trait SigmaDslCostedModule extends special.sigma.impl.SigmaDslCostedDefs {self: SigmaLibrary =>} diff --git a/sigma-library/src/main/scala/special/sigma/impl/SigmaDslImpl.scala b/sigma-library/src/main/scala/special/sigma/impl/SigmaDslImpl.scala index a23120051d..0682271b7e 100644 --- a/sigma-library/src/main/scala/special/sigma/impl/SigmaDslImpl.scala +++ b/sigma-library/src/main/scala/special/sigma/impl/SigmaDslImpl.scala @@ -3,6 +3,7 @@ package special.sigma import scalan._ import scala.reflect.runtime.universe._ import scala.reflect._ +import scala.collection.mutable.WrappedArray package impl { import scalan.OverloadHack.Overloaded1 // manual fix @@ -10,8 +11,6 @@ package impl { // Abs ----------------------------------- trait SigmaDslDefs extends scalan.Scalan with SigmaDsl { self: SigmaLibrary => -import IsoUR._ -import Converter._ import AnyValue._ import AvlTree._ import BigInt._ @@ -28,7 +27,6 @@ import PreHeader._ import SigmaContract._ import SigmaDslBuilder._ import SigmaProp._ -import WBigInteger._ import WOption._ import WRType._ @@ -39,91 +37,83 @@ object CostModel extends EntityObject("CostModel") { type SCostModel = special.sigma.CostModel case class CostModelConst( constValue: SCostModel - ) extends CostModel with LiftedConst[SCostModel, CostModel] + ) extends LiftedConst[SCostModel, CostModel] with CostModel with Def[CostModel] with CostModelConstMethods { val liftable: Liftable[SCostModel, CostModel] = LiftableCostModel - val selfType: Elem[CostModel] = liftable.eW + val resultType: Elem[CostModel] = liftable.eW } trait CostModelConstMethods extends CostModel { thisConst: Def[_] => private val CostModelClass = classOf[CostModel] - override def AccessBox: Rep[Int] = { + override def AccessBox: Ref[Int] = { asRep[Int](mkMethodCall(self, CostModelClass.getMethod("AccessBox"), - List(), + WrappedArray.empty, true, false, element[Int])) } - override def AccessAvlTree: Rep[Int] = { + override def AccessAvlTree: Ref[Int] = { asRep[Int](mkMethodCall(self, CostModelClass.getMethod("AccessAvlTree"), - List(), + WrappedArray.empty, true, false, element[Int])) } - override def GetVar: Rep[Int] = { + override def GetVar: Ref[Int] = { asRep[Int](mkMethodCall(self, CostModelClass.getMethod("GetVar"), - List(), + WrappedArray.empty, true, false, element[Int])) } - override def DeserializeVar: Rep[Int] = { + override def DeserializeVar: Ref[Int] = { asRep[Int](mkMethodCall(self, CostModelClass.getMethod("DeserializeVar"), - List(), + WrappedArray.empty, true, false, element[Int])) } - override def GetRegister: Rep[Int] = { + override def GetRegister: Ref[Int] = { asRep[Int](mkMethodCall(self, CostModelClass.getMethod("GetRegister"), - List(), + WrappedArray.empty, true, false, element[Int])) } - override def DeserializeRegister: Rep[Int] = { + override def DeserializeRegister: Ref[Int] = { asRep[Int](mkMethodCall(self, CostModelClass.getMethod("DeserializeRegister"), - List(), + WrappedArray.empty, true, false, element[Int])) } - override def SelectField: Rep[Int] = { + override def SelectField: Ref[Int] = { asRep[Int](mkMethodCall(self, CostModelClass.getMethod("SelectField"), - List(), + WrappedArray.empty, true, false, element[Int])) } - override def CollectionConst: Rep[Int] = { + override def CollectionConst: Ref[Int] = { asRep[Int](mkMethodCall(self, CostModelClass.getMethod("CollectionConst"), - List(), + WrappedArray.empty, true, false, element[Int])) } - override def AccessKiloByteOfData: Rep[Int] = { + override def AccessKiloByteOfData: Ref[Int] = { asRep[Int](mkMethodCall(self, CostModelClass.getMethod("AccessKiloByteOfData"), - List(), + WrappedArray.empty, true, false, element[Int])) } - override def dataSize[T](x: Rep[T])(implicit cT: Elem[T]): Rep[Long] = { - implicit val eT = x.elem - asRep[Long](mkMethodCall(self, - CostModelClass.getMethod("dataSize", classOf[Sym], classOf[Elem[_]]), - List(x, cT), - true, false, element[Long])) - } - - override def PubKeySize: Rep[Long] = { + override def PubKeySize: Ref[Long] = { asRep[Long](mkMethodCall(self, CostModelClass.getMethod("PubKeySize"), - List(), + WrappedArray.empty, true, false, element[Long])) } } @@ -134,103 +124,97 @@ object CostModel extends EntityObject("CostModel") { lazy val sourceType: RType[SCostModel] = { RType[SCostModel] } - def lift(x: SCostModel): Rep[CostModel] = CostModelConst(x) - def unlift(w: Rep[CostModel]): SCostModel = w match { + def lift(x: SCostModel): Ref[CostModel] = CostModelConst(x) + def unlift(w: Ref[CostModel]): SCostModel = w match { case Def(CostModelConst(x: SCostModel)) => x.asInstanceOf[SCostModel] case _ => unliftError(w) } } + private val CostModelClass = classOf[CostModel] + // entityAdapter for CostModel trait - case class CostModelAdapter(source: Rep[CostModel]) - extends CostModel with Def[CostModel] { - val selfType: Elem[CostModel] = element[CostModel] + case class CostModelAdapter(source: Ref[CostModel]) + extends Node with CostModel + with Def[CostModel] { + val resultType: Elem[CostModel] = element[CostModel] override def transform(t: Transformer) = CostModelAdapter(t(source)) - private val thisClass = classOf[CostModel] - def AccessBox: Rep[Int] = { + def AccessBox: Ref[Int] = { asRep[Int](mkMethodCall(source, - thisClass.getMethod("AccessBox"), - List(), + CostModelClass.getMethod("AccessBox"), + WrappedArray.empty, true, true, element[Int])) } - def AccessAvlTree: Rep[Int] = { + def AccessAvlTree: Ref[Int] = { asRep[Int](mkMethodCall(source, - thisClass.getMethod("AccessAvlTree"), - List(), + CostModelClass.getMethod("AccessAvlTree"), + WrappedArray.empty, true, true, element[Int])) } - def GetVar: Rep[Int] = { + def GetVar: Ref[Int] = { asRep[Int](mkMethodCall(source, - thisClass.getMethod("GetVar"), - List(), + CostModelClass.getMethod("GetVar"), + WrappedArray.empty, true, true, element[Int])) } - def DeserializeVar: Rep[Int] = { + def DeserializeVar: Ref[Int] = { asRep[Int](mkMethodCall(source, - thisClass.getMethod("DeserializeVar"), - List(), + CostModelClass.getMethod("DeserializeVar"), + WrappedArray.empty, true, true, element[Int])) } - def GetRegister: Rep[Int] = { + def GetRegister: Ref[Int] = { asRep[Int](mkMethodCall(source, - thisClass.getMethod("GetRegister"), - List(), + CostModelClass.getMethod("GetRegister"), + WrappedArray.empty, true, true, element[Int])) } - def DeserializeRegister: Rep[Int] = { + def DeserializeRegister: Ref[Int] = { asRep[Int](mkMethodCall(source, - thisClass.getMethod("DeserializeRegister"), - List(), + CostModelClass.getMethod("DeserializeRegister"), + WrappedArray.empty, true, true, element[Int])) } - def SelectField: Rep[Int] = { + def SelectField: Ref[Int] = { asRep[Int](mkMethodCall(source, - thisClass.getMethod("SelectField"), - List(), + CostModelClass.getMethod("SelectField"), + WrappedArray.empty, true, true, element[Int])) } - def CollectionConst: Rep[Int] = { + def CollectionConst: Ref[Int] = { asRep[Int](mkMethodCall(source, - thisClass.getMethod("CollectionConst"), - List(), + CostModelClass.getMethod("CollectionConst"), + WrappedArray.empty, true, true, element[Int])) } - def AccessKiloByteOfData: Rep[Int] = { + def AccessKiloByteOfData: Ref[Int] = { asRep[Int](mkMethodCall(source, - thisClass.getMethod("AccessKiloByteOfData"), - List(), + CostModelClass.getMethod("AccessKiloByteOfData"), + WrappedArray.empty, true, true, element[Int])) } - def dataSize[T](x: Rep[T])(implicit cT: Elem[T]): Rep[Long] = { - implicit val eT = x.elem - asRep[Long](mkMethodCall(source, - thisClass.getMethod("dataSize", classOf[Sym], classOf[Elem[_]]), - List(x, cT), - true, true, element[Long])) - } - - def PubKeySize: Rep[Long] = { + def PubKeySize: Ref[Long] = { asRep[Long](mkMethodCall(source, - thisClass.getMethod("PubKeySize"), - List(), + CostModelClass.getMethod("PubKeySize"), + WrappedArray.empty, true, true, element[Long])) } } - // entityProxy: single proxy for each type family - implicit def proxyCostModel(p: Rep[CostModel]): CostModel = { - if (p.rhs.isInstanceOf[CostModel@unchecked]) p.rhs.asInstanceOf[CostModel] + // entityUnref: single unref method for each type family + implicit final def unrefCostModel(p: Ref[CostModel]): CostModel = { + if (p.node.isInstanceOf[CostModel]) p.node.asInstanceOf[CostModel] else CostModelAdapter(p) } @@ -238,200 +222,31 @@ object CostModel extends EntityObject("CostModel") { // familyElem class CostModelElem[To <: CostModel] extends EntityElem[To] { - override val liftable: Liftables.Liftable[_, To] = LiftableCostModel.asLiftable[SCostModel, To] + override val liftable: Liftables.Liftable[_, To] = asLiftable[SCostModel, To](LiftableCostModel) override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { super.collectMethods ++ Elem.declaredMethods(classOf[CostModel], classOf[SCostModel], Set( - "AccessBox", "AccessAvlTree", "GetVar", "DeserializeVar", "GetRegister", "DeserializeRegister", "SelectField", "CollectionConst", "AccessKiloByteOfData", "dataSize", "PubKeySize" + "AccessBox", "AccessAvlTree", "GetVar", "DeserializeVar", "GetRegister", "DeserializeRegister", "SelectField", "CollectionConst", "AccessKiloByteOfData", "PubKeySize" )) } - - lazy val parent: Option[Elem[_]] = None - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override lazy val tag = { - weakTypeTag[CostModel].asInstanceOf[WeakTypeTag[To]] - } - override def convert(x: Rep[Def[_]]) = { - val conv = fun {x: Rep[CostModel] => convertCostModel(x) } - tryConvert(element[CostModel], this, x, conv) - } - - def convertCostModel(x: Rep[CostModel]): Rep[To] = { - x.elem match { - case _: CostModelElem[_] => asRep[To](x) - case e => !!!(s"Expected $x to have CostModelElem[_], but got $e", x) - } - } - override def getDefaultRep: Rep[To] = ??? } implicit lazy val costModelElement: Elem[CostModel] = new CostModelElem[CostModel] - implicit case object CostModelCompanionElem extends CompanionElem[CostModelCompanionCtor] { - lazy val tag = weakTypeTag[CostModelCompanionCtor] - protected def getDefaultRep = RCostModel - } + implicit case object CostModelCompanionElem extends CompanionElem[CostModelCompanionCtor] abstract class CostModelCompanionCtor extends CompanionDef[CostModelCompanionCtor] with CostModelCompanion { - def selfType = CostModelCompanionElem + def resultType = CostModelCompanionElem override def toString = "CostModel" } - implicit def proxyCostModelCompanionCtor(p: Rep[CostModelCompanionCtor]): CostModelCompanionCtor = - proxyOps[CostModelCompanionCtor](p) + implicit final def unrefCostModelCompanionCtor(p: Ref[CostModelCompanionCtor]): CostModelCompanionCtor = + p.node.asInstanceOf[CostModelCompanionCtor] - lazy val RCostModel: Rep[CostModelCompanionCtor] = new CostModelCompanionCtor { + lazy val RCostModel: MutableLazy[CostModelCompanionCtor] = MutableLazy(new CostModelCompanionCtor { private val thisClass = classOf[CostModelCompanion] - } - - object CostModelMethods { - object AccessBox { - def unapply(d: Def[_]): Nullable[Rep[CostModel]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[CostModelElem[_]] && method.getName == "AccessBox" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[CostModel]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[CostModel]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object AccessAvlTree { - def unapply(d: Def[_]): Nullable[Rep[CostModel]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[CostModelElem[_]] && method.getName == "AccessAvlTree" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[CostModel]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[CostModel]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object GetVar { - def unapply(d: Def[_]): Nullable[Rep[CostModel]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[CostModelElem[_]] && method.getName == "GetVar" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[CostModel]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[CostModel]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object DeserializeVar { - def unapply(d: Def[_]): Nullable[Rep[CostModel]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[CostModelElem[_]] && method.getName == "DeserializeVar" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[CostModel]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[CostModel]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object GetRegister { - def unapply(d: Def[_]): Nullable[Rep[CostModel]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[CostModelElem[_]] && method.getName == "GetRegister" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[CostModel]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[CostModel]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object DeserializeRegister { - def unapply(d: Def[_]): Nullable[Rep[CostModel]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[CostModelElem[_]] && method.getName == "DeserializeRegister" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[CostModel]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[CostModel]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object SelectField { - def unapply(d: Def[_]): Nullable[Rep[CostModel]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[CostModelElem[_]] && method.getName == "SelectField" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[CostModel]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[CostModel]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object CollectionConst { - def unapply(d: Def[_]): Nullable[Rep[CostModel]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[CostModelElem[_]] && method.getName == "CollectionConst" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[CostModel]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[CostModel]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object AccessKiloByteOfData { - def unapply(d: Def[_]): Nullable[Rep[CostModel]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[CostModelElem[_]] && method.getName == "AccessKiloByteOfData" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[CostModel]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[CostModel]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object dataSize { - def unapply(d: Def[_]): Nullable[(Rep[CostModel], Rep[T], Elem[T]) forSome {type T}] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[CostModelElem[_]] && method.getName == "dataSize" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[CostModel], Rep[T], Elem[T]) forSome {type T}]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[CostModel], Rep[T], Elem[T]) forSome {type T}] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object PubKeySize { - def unapply(d: Def[_]): Nullable[Rep[CostModel]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[CostModelElem[_]] && method.getName == "PubKeySize" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[CostModel]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[CostModel]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - } - - object CostModelCompanionMethods { - } + }) } // of object CostModel registerEntityObject("CostModel", CostModel) @@ -442,174 +257,174 @@ object BigInt extends EntityObject("BigInt") { type SBigInt = special.sigma.BigInt case class BigIntConst( constValue: SBigInt - ) extends BigInt with LiftedConst[SBigInt, BigInt] + ) extends LiftedConst[SBigInt, BigInt] with BigInt with Def[BigInt] with BigIntConstMethods { val liftable: Liftable[SBigInt, BigInt] = LiftableBigInt - val selfType: Elem[BigInt] = liftable.eW + val resultType: Elem[BigInt] = liftable.eW } trait BigIntConstMethods extends BigInt { thisConst: Def[_] => private val BigIntClass = classOf[BigInt] - override def toByte: Rep[Byte] = { + override def toByte: Ref[Byte] = { asRep[Byte](mkMethodCall(self, BigIntClass.getMethod("toByte"), - List(), + WrappedArray.empty, true, false, element[Byte])) } - override def toShort: Rep[Short] = { + override def toShort: Ref[Short] = { asRep[Short](mkMethodCall(self, BigIntClass.getMethod("toShort"), - List(), + WrappedArray.empty, true, false, element[Short])) } - override def toInt: Rep[Int] = { + override def toInt: Ref[Int] = { asRep[Int](mkMethodCall(self, BigIntClass.getMethod("toInt"), - List(), + WrappedArray.empty, true, false, element[Int])) } - override def toLong: Rep[Long] = { + override def toLong: Ref[Long] = { asRep[Long](mkMethodCall(self, BigIntClass.getMethod("toLong"), - List(), + WrappedArray.empty, true, false, element[Long])) } - override def toBytes: Rep[Coll[Byte]] = { + override def toBytes: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(self, BigIntClass.getMethod("toBytes"), - List(), + WrappedArray.empty, true, false, element[Coll[Byte]])) } - override def toBits: Rep[Coll[Boolean]] = { + override def toBits: Ref[Coll[Boolean]] = { asRep[Coll[Boolean]](mkMethodCall(self, BigIntClass.getMethod("toBits"), - List(), + WrappedArray.empty, true, false, element[Coll[Boolean]])) } - override def toAbs: Rep[BigInt] = { + override def toAbs: Ref[BigInt] = { asRep[BigInt](mkMethodCall(self, BigIntClass.getMethod("toAbs"), - List(), + WrappedArray.empty, true, false, element[BigInt])) } - override def compareTo(that: Rep[BigInt]): Rep[Int] = { + override def compareTo(that: Ref[BigInt]): Ref[Int] = { asRep[Int](mkMethodCall(self, BigIntClass.getMethod("compareTo", classOf[Sym]), - List(that), + Array[AnyRef](that), true, false, element[Int])) } - override def modQ: Rep[BigInt] = { + override def modQ: Ref[BigInt] = { asRep[BigInt](mkMethodCall(self, BigIntClass.getMethod("modQ"), - List(), + WrappedArray.empty, true, false, element[BigInt])) } - override def plusModQ(other: Rep[BigInt]): Rep[BigInt] = { + override def plusModQ(other: Ref[BigInt]): Ref[BigInt] = { asRep[BigInt](mkMethodCall(self, BigIntClass.getMethod("plusModQ", classOf[Sym]), - List(other), + Array[AnyRef](other), true, false, element[BigInt])) } - override def minusModQ(other: Rep[BigInt]): Rep[BigInt] = { + override def minusModQ(other: Ref[BigInt]): Ref[BigInt] = { asRep[BigInt](mkMethodCall(self, BigIntClass.getMethod("minusModQ", classOf[Sym]), - List(other), + Array[AnyRef](other), true, false, element[BigInt])) } - override def multModQ(other: Rep[BigInt]): Rep[BigInt] = { + override def multModQ(other: Ref[BigInt]): Ref[BigInt] = { asRep[BigInt](mkMethodCall(self, BigIntClass.getMethod("multModQ", classOf[Sym]), - List(other), + Array[AnyRef](other), true, false, element[BigInt])) } - override def inverseModQ: Rep[BigInt] = { + override def inverseModQ: Ref[BigInt] = { asRep[BigInt](mkMethodCall(self, BigIntClass.getMethod("inverseModQ"), - List(), + WrappedArray.empty, true, false, element[BigInt])) } - override def signum: Rep[Int] = { + override def signum: Ref[Int] = { asRep[Int](mkMethodCall(self, BigIntClass.getMethod("signum"), - List(), + WrappedArray.empty, true, false, element[Int])) } - override def add(that: Rep[BigInt]): Rep[BigInt] = { + override def add(that: Ref[BigInt]): Ref[BigInt] = { asRep[BigInt](mkMethodCall(self, BigIntClass.getMethod("add", classOf[Sym]), - List(that), + Array[AnyRef](that), true, false, element[BigInt])) } - override def subtract(that: Rep[BigInt]): Rep[BigInt] = { + override def subtract(that: Ref[BigInt]): Ref[BigInt] = { asRep[BigInt](mkMethodCall(self, BigIntClass.getMethod("subtract", classOf[Sym]), - List(that), + Array[AnyRef](that), true, false, element[BigInt])) } - override def multiply(that: Rep[BigInt]): Rep[BigInt] = { + override def multiply(that: Ref[BigInt]): Ref[BigInt] = { asRep[BigInt](mkMethodCall(self, BigIntClass.getMethod("multiply", classOf[Sym]), - List(that), + Array[AnyRef](that), true, false, element[BigInt])) } - override def divide(that: Rep[BigInt]): Rep[BigInt] = { + override def divide(that: Ref[BigInt]): Ref[BigInt] = { asRep[BigInt](mkMethodCall(self, BigIntClass.getMethod("divide", classOf[Sym]), - List(that), + Array[AnyRef](that), true, false, element[BigInt])) } - override def mod(m: Rep[BigInt]): Rep[BigInt] = { + override def mod(m: Ref[BigInt]): Ref[BigInt] = { asRep[BigInt](mkMethodCall(self, BigIntClass.getMethod("mod", classOf[Sym]), - List(m), + Array[AnyRef](m), true, false, element[BigInt])) } - override def remainder(that: Rep[BigInt]): Rep[BigInt] = { + override def remainder(that: Ref[BigInt]): Ref[BigInt] = { asRep[BigInt](mkMethodCall(self, BigIntClass.getMethod("remainder", classOf[Sym]), - List(that), + Array[AnyRef](that), true, false, element[BigInt])) } - override def min(that: Rep[BigInt]): Rep[BigInt] = { + override def min(that: Ref[BigInt]): Ref[BigInt] = { asRep[BigInt](mkMethodCall(self, BigIntClass.getMethod("min", classOf[Sym]), - List(that), + Array[AnyRef](that), true, false, element[BigInt])) } - override def max(that: Rep[BigInt]): Rep[BigInt] = { + override def max(that: Ref[BigInt]): Ref[BigInt] = { asRep[BigInt](mkMethodCall(self, BigIntClass.getMethod("max", classOf[Sym]), - List(that), + Array[AnyRef](that), true, false, element[BigInt])) } - override def negate: Rep[BigInt] = { + override def negate: Ref[BigInt] = { asRep[BigInt](mkMethodCall(self, BigIntClass.getMethod("negate"), - List(), + WrappedArray.empty, true, false, element[BigInt])) } } @@ -620,186 +435,188 @@ object BigInt extends EntityObject("BigInt") { lazy val sourceType: RType[SBigInt] = { RType[SBigInt] } - def lift(x: SBigInt): Rep[BigInt] = BigIntConst(x) - def unlift(w: Rep[BigInt]): SBigInt = w match { + def lift(x: SBigInt): Ref[BigInt] = BigIntConst(x) + def unlift(w: Ref[BigInt]): SBigInt = w match { case Def(BigIntConst(x: SBigInt)) => x.asInstanceOf[SBigInt] case _ => unliftError(w) } } + private val BigIntClass = classOf[BigInt] + // entityAdapter for BigInt trait - case class BigIntAdapter(source: Rep[BigInt]) - extends BigInt with Def[BigInt] { - val selfType: Elem[BigInt] = element[BigInt] + case class BigIntAdapter(source: Ref[BigInt]) + extends Node with BigInt + with Def[BigInt] { + val resultType: Elem[BigInt] = element[BigInt] override def transform(t: Transformer) = BigIntAdapter(t(source)) - private val thisClass = classOf[BigInt] - def toByte: Rep[Byte] = { + def toByte: Ref[Byte] = { asRep[Byte](mkMethodCall(source, - thisClass.getMethod("toByte"), - List(), + BigIntClass.getMethod("toByte"), + WrappedArray.empty, true, true, element[Byte])) } - def toShort: Rep[Short] = { + def toShort: Ref[Short] = { asRep[Short](mkMethodCall(source, - thisClass.getMethod("toShort"), - List(), + BigIntClass.getMethod("toShort"), + WrappedArray.empty, true, true, element[Short])) } - def toInt: Rep[Int] = { + def toInt: Ref[Int] = { asRep[Int](mkMethodCall(source, - thisClass.getMethod("toInt"), - List(), + BigIntClass.getMethod("toInt"), + WrappedArray.empty, true, true, element[Int])) } - def toLong: Rep[Long] = { + def toLong: Ref[Long] = { asRep[Long](mkMethodCall(source, - thisClass.getMethod("toLong"), - List(), + BigIntClass.getMethod("toLong"), + WrappedArray.empty, true, true, element[Long])) } - def toBytes: Rep[Coll[Byte]] = { + def toBytes: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(source, - thisClass.getMethod("toBytes"), - List(), + BigIntClass.getMethod("toBytes"), + WrappedArray.empty, true, true, element[Coll[Byte]])) } - def toBits: Rep[Coll[Boolean]] = { + def toBits: Ref[Coll[Boolean]] = { asRep[Coll[Boolean]](mkMethodCall(source, - thisClass.getMethod("toBits"), - List(), + BigIntClass.getMethod("toBits"), + WrappedArray.empty, true, true, element[Coll[Boolean]])) } - def toAbs: Rep[BigInt] = { + def toAbs: Ref[BigInt] = { asRep[BigInt](mkMethodCall(source, - thisClass.getMethod("toAbs"), - List(), + BigIntClass.getMethod("toAbs"), + WrappedArray.empty, true, true, element[BigInt])) } - def compareTo(that: Rep[BigInt]): Rep[Int] = { + def compareTo(that: Ref[BigInt]): Ref[Int] = { asRep[Int](mkMethodCall(source, - thisClass.getMethod("compareTo", classOf[Sym]), - List(that), + BigIntClass.getMethod("compareTo", classOf[Sym]), + Array[AnyRef](that), true, true, element[Int])) } - def modQ: Rep[BigInt] = { + def modQ: Ref[BigInt] = { asRep[BigInt](mkMethodCall(source, - thisClass.getMethod("modQ"), - List(), + BigIntClass.getMethod("modQ"), + WrappedArray.empty, true, true, element[BigInt])) } - def plusModQ(other: Rep[BigInt]): Rep[BigInt] = { + def plusModQ(other: Ref[BigInt]): Ref[BigInt] = { asRep[BigInt](mkMethodCall(source, - thisClass.getMethod("plusModQ", classOf[Sym]), - List(other), + BigIntClass.getMethod("plusModQ", classOf[Sym]), + Array[AnyRef](other), true, true, element[BigInt])) } - def minusModQ(other: Rep[BigInt]): Rep[BigInt] = { + def minusModQ(other: Ref[BigInt]): Ref[BigInt] = { asRep[BigInt](mkMethodCall(source, - thisClass.getMethod("minusModQ", classOf[Sym]), - List(other), + BigIntClass.getMethod("minusModQ", classOf[Sym]), + Array[AnyRef](other), true, true, element[BigInt])) } - def multModQ(other: Rep[BigInt]): Rep[BigInt] = { + def multModQ(other: Ref[BigInt]): Ref[BigInt] = { asRep[BigInt](mkMethodCall(source, - thisClass.getMethod("multModQ", classOf[Sym]), - List(other), + BigIntClass.getMethod("multModQ", classOf[Sym]), + Array[AnyRef](other), true, true, element[BigInt])) } - def inverseModQ: Rep[BigInt] = { + def inverseModQ: Ref[BigInt] = { asRep[BigInt](mkMethodCall(source, - thisClass.getMethod("inverseModQ"), - List(), + BigIntClass.getMethod("inverseModQ"), + WrappedArray.empty, true, true, element[BigInt])) } - def signum: Rep[Int] = { + def signum: Ref[Int] = { asRep[Int](mkMethodCall(source, - thisClass.getMethod("signum"), - List(), + BigIntClass.getMethod("signum"), + WrappedArray.empty, true, true, element[Int])) } - def add(that: Rep[BigInt]): Rep[BigInt] = { + def add(that: Ref[BigInt]): Ref[BigInt] = { asRep[BigInt](mkMethodCall(source, - thisClass.getMethod("add", classOf[Sym]), - List(that), + BigIntClass.getMethod("add", classOf[Sym]), + Array[AnyRef](that), true, true, element[BigInt])) } - def subtract(that: Rep[BigInt]): Rep[BigInt] = { + def subtract(that: Ref[BigInt]): Ref[BigInt] = { asRep[BigInt](mkMethodCall(source, - thisClass.getMethod("subtract", classOf[Sym]), - List(that), + BigIntClass.getMethod("subtract", classOf[Sym]), + Array[AnyRef](that), true, true, element[BigInt])) } - def multiply(that: Rep[BigInt]): Rep[BigInt] = { + def multiply(that: Ref[BigInt]): Ref[BigInt] = { asRep[BigInt](mkMethodCall(source, - thisClass.getMethod("multiply", classOf[Sym]), - List(that), + BigIntClass.getMethod("multiply", classOf[Sym]), + Array[AnyRef](that), true, true, element[BigInt])) } - def divide(that: Rep[BigInt]): Rep[BigInt] = { + def divide(that: Ref[BigInt]): Ref[BigInt] = { asRep[BigInt](mkMethodCall(source, - thisClass.getMethod("divide", classOf[Sym]), - List(that), + BigIntClass.getMethod("divide", classOf[Sym]), + Array[AnyRef](that), true, true, element[BigInt])) } - def mod(m: Rep[BigInt]): Rep[BigInt] = { + def mod(m: Ref[BigInt]): Ref[BigInt] = { asRep[BigInt](mkMethodCall(source, - thisClass.getMethod("mod", classOf[Sym]), - List(m), + BigIntClass.getMethod("mod", classOf[Sym]), + Array[AnyRef](m), true, true, element[BigInt])) } - def remainder(that: Rep[BigInt]): Rep[BigInt] = { + def remainder(that: Ref[BigInt]): Ref[BigInt] = { asRep[BigInt](mkMethodCall(source, - thisClass.getMethod("remainder", classOf[Sym]), - List(that), + BigIntClass.getMethod("remainder", classOf[Sym]), + Array[AnyRef](that), true, true, element[BigInt])) } - def min(that: Rep[BigInt]): Rep[BigInt] = { + def min(that: Ref[BigInt]): Ref[BigInt] = { asRep[BigInt](mkMethodCall(source, - thisClass.getMethod("min", classOf[Sym]), - List(that), + BigIntClass.getMethod("min", classOf[Sym]), + Array[AnyRef](that), true, true, element[BigInt])) } - def max(that: Rep[BigInt]): Rep[BigInt] = { + def max(that: Ref[BigInt]): Ref[BigInt] = { asRep[BigInt](mkMethodCall(source, - thisClass.getMethod("max", classOf[Sym]), - List(that), + BigIntClass.getMethod("max", classOf[Sym]), + Array[AnyRef](that), true, true, element[BigInt])) } - def negate: Rep[BigInt] = { + def negate: Ref[BigInt] = { asRep[BigInt](mkMethodCall(source, - thisClass.getMethod("negate"), - List(), + BigIntClass.getMethod("negate"), + WrappedArray.empty, true, true, element[BigInt])) } } - // entityProxy: single proxy for each type family - implicit def proxyBigInt(p: Rep[BigInt]): BigInt = { - if (p.rhs.isInstanceOf[BigInt@unchecked]) p.rhs.asInstanceOf[BigInt] + // entityUnref: single unref method for each type family + implicit final def unrefBigInt(p: Ref[BigInt]): BigInt = { + if (p.node.isInstanceOf[BigInt]) p.node.asInstanceOf[BigInt] else BigIntAdapter(p) } @@ -807,7 +624,7 @@ object BigInt extends EntityObject("BigInt") { // familyElem class BigIntElem[To <: BigInt] extends EntityElem[To] { - override val liftable: Liftables.Liftable[_, To] = LiftableBigInt.asLiftable[SBigInt, To] + override val liftable: Liftables.Liftable[_, To] = asLiftable[SBigInt, To](LiftableBigInt) override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { super.collectMethods ++ @@ -815,343 +632,253 @@ object BigInt extends EntityObject("BigInt") { "toByte", "toShort", "toInt", "toLong", "toBytes", "toBits", "toAbs", "compareTo", "modQ", "plusModQ", "minusModQ", "multModQ", "inverseModQ", "signum", "add", "subtract", "multiply", "divide", "mod", "remainder", "min", "max", "negate" )) } - - lazy val parent: Option[Elem[_]] = None - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override lazy val tag = { - weakTypeTag[BigInt].asInstanceOf[WeakTypeTag[To]] - } - override def convert(x: Rep[Def[_]]) = { - val conv = fun {x: Rep[BigInt] => convertBigInt(x) } - tryConvert(element[BigInt], this, x, conv) - } - - def convertBigInt(x: Rep[BigInt]): Rep[To] = { - x.elem match { - case _: BigIntElem[_] => asRep[To](x) - case e => !!!(s"Expected $x to have BigIntElem[_], but got $e", x) - } - } - override def getDefaultRep: Rep[To] = ??? } implicit lazy val bigIntElement: Elem[BigInt] = new BigIntElem[BigInt] - implicit case object BigIntCompanionElem extends CompanionElem[BigIntCompanionCtor] { - lazy val tag = weakTypeTag[BigIntCompanionCtor] - protected def getDefaultRep = RBigInt - } + implicit case object BigIntCompanionElem extends CompanionElem[BigIntCompanionCtor] abstract class BigIntCompanionCtor extends CompanionDef[BigIntCompanionCtor] with BigIntCompanion { - def selfType = BigIntCompanionElem + def resultType = BigIntCompanionElem override def toString = "BigInt" } - implicit def proxyBigIntCompanionCtor(p: Rep[BigIntCompanionCtor]): BigIntCompanionCtor = - proxyOps[BigIntCompanionCtor](p) + implicit final def unrefBigIntCompanionCtor(p: Ref[BigIntCompanionCtor]): BigIntCompanionCtor = + p.node.asInstanceOf[BigIntCompanionCtor] - lazy val RBigInt: Rep[BigIntCompanionCtor] = new BigIntCompanionCtor { + lazy val RBigInt: MutableLazy[BigIntCompanionCtor] = MutableLazy(new BigIntCompanionCtor { private val thisClass = classOf[BigIntCompanion] - } + }) object BigIntMethods { object toByte { - def unapply(d: Def[_]): Nullable[Rep[BigInt]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[BigIntElem[_]] && method.getName == "toByte" => + def unapply(d: Def[_]): Nullable[Ref[BigInt]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "toByte" && receiver.elem.isInstanceOf[BigIntElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[BigInt]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[BigInt]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[BigInt]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[BigInt]] = unapply(exp.node) } object toShort { - def unapply(d: Def[_]): Nullable[Rep[BigInt]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[BigIntElem[_]] && method.getName == "toShort" => + def unapply(d: Def[_]): Nullable[Ref[BigInt]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "toShort" && receiver.elem.isInstanceOf[BigIntElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[BigInt]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[BigInt]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[BigInt]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[BigInt]] = unapply(exp.node) } object toInt { - def unapply(d: Def[_]): Nullable[Rep[BigInt]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[BigIntElem[_]] && method.getName == "toInt" => + def unapply(d: Def[_]): Nullable[Ref[BigInt]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "toInt" && receiver.elem.isInstanceOf[BigIntElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[BigInt]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[BigInt]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[BigInt]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[BigInt]] = unapply(exp.node) } object toLong { - def unapply(d: Def[_]): Nullable[Rep[BigInt]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[BigIntElem[_]] && method.getName == "toLong" => + def unapply(d: Def[_]): Nullable[Ref[BigInt]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "toLong" && receiver.elem.isInstanceOf[BigIntElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[BigInt]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[BigInt]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[BigInt]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[BigInt]] = unapply(exp.node) } object toBytes { - def unapply(d: Def[_]): Nullable[Rep[BigInt]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[BigIntElem[_]] && method.getName == "toBytes" => + def unapply(d: Def[_]): Nullable[Ref[BigInt]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "toBytes" && receiver.elem.isInstanceOf[BigIntElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[BigInt]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[BigInt]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[BigInt]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[BigInt]] = unapply(exp.node) } object toBits { - def unapply(d: Def[_]): Nullable[Rep[BigInt]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[BigIntElem[_]] && method.getName == "toBits" => + def unapply(d: Def[_]): Nullable[Ref[BigInt]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "toBits" && receiver.elem.isInstanceOf[BigIntElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[BigInt]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[BigInt]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[BigInt]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[BigInt]] = unapply(exp.node) } object toAbs { - def unapply(d: Def[_]): Nullable[Rep[BigInt]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[BigIntElem[_]] && method.getName == "toAbs" => + def unapply(d: Def[_]): Nullable[Ref[BigInt]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "toAbs" && receiver.elem.isInstanceOf[BigIntElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[BigInt]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[BigInt]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[BigInt]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[BigInt]] = unapply(exp.node) } object compareTo { - def unapply(d: Def[_]): Nullable[(Rep[BigInt], Rep[BigInt])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntElem[_]] && method.getName == "compareTo" => + def unapply(d: Def[_]): Nullable[(Ref[BigInt], Ref[BigInt])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "compareTo" && receiver.elem.isInstanceOf[BigIntElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigInt], Rep[BigInt])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigInt], Rep[BigInt])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[BigInt], Ref[BigInt])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[BigInt], Ref[BigInt])] = unapply(exp.node) } object modQ { - def unapply(d: Def[_]): Nullable[Rep[BigInt]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[BigIntElem[_]] && method.getName == "modQ" => + def unapply(d: Def[_]): Nullable[Ref[BigInt]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "modQ" && receiver.elem.isInstanceOf[BigIntElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[BigInt]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[BigInt]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[BigInt]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[BigInt]] = unapply(exp.node) } object plusModQ { - def unapply(d: Def[_]): Nullable[(Rep[BigInt], Rep[BigInt])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntElem[_]] && method.getName == "plusModQ" => + def unapply(d: Def[_]): Nullable[(Ref[BigInt], Ref[BigInt])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "plusModQ" && receiver.elem.isInstanceOf[BigIntElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigInt], Rep[BigInt])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigInt], Rep[BigInt])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[BigInt], Ref[BigInt])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[BigInt], Ref[BigInt])] = unapply(exp.node) } object minusModQ { - def unapply(d: Def[_]): Nullable[(Rep[BigInt], Rep[BigInt])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntElem[_]] && method.getName == "minusModQ" => + def unapply(d: Def[_]): Nullable[(Ref[BigInt], Ref[BigInt])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "minusModQ" && receiver.elem.isInstanceOf[BigIntElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigInt], Rep[BigInt])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigInt], Rep[BigInt])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[BigInt], Ref[BigInt])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[BigInt], Ref[BigInt])] = unapply(exp.node) } object multModQ { - def unapply(d: Def[_]): Nullable[(Rep[BigInt], Rep[BigInt])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntElem[_]] && method.getName == "multModQ" => + def unapply(d: Def[_]): Nullable[(Ref[BigInt], Ref[BigInt])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "multModQ" && receiver.elem.isInstanceOf[BigIntElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigInt], Rep[BigInt])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigInt], Rep[BigInt])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[BigInt], Ref[BigInt])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[BigInt], Ref[BigInt])] = unapply(exp.node) } object inverseModQ { - def unapply(d: Def[_]): Nullable[Rep[BigInt]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[BigIntElem[_]] && method.getName == "inverseModQ" => + def unapply(d: Def[_]): Nullable[Ref[BigInt]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "inverseModQ" && receiver.elem.isInstanceOf[BigIntElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[BigInt]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[BigInt]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[BigInt]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[BigInt]] = unapply(exp.node) } object signum { - def unapply(d: Def[_]): Nullable[Rep[BigInt]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[BigIntElem[_]] && method.getName == "signum" => + def unapply(d: Def[_]): Nullable[Ref[BigInt]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "signum" && receiver.elem.isInstanceOf[BigIntElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[BigInt]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[BigInt]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[BigInt]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[BigInt]] = unapply(exp.node) } object add { - def unapply(d: Def[_]): Nullable[(Rep[BigInt], Rep[BigInt])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntElem[_]] && method.getName == "add" => + def unapply(d: Def[_]): Nullable[(Ref[BigInt], Ref[BigInt])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "add" && receiver.elem.isInstanceOf[BigIntElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigInt], Rep[BigInt])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigInt], Rep[BigInt])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[BigInt], Ref[BigInt])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[BigInt], Ref[BigInt])] = unapply(exp.node) } object subtract { - def unapply(d: Def[_]): Nullable[(Rep[BigInt], Rep[BigInt])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntElem[_]] && method.getName == "subtract" => + def unapply(d: Def[_]): Nullable[(Ref[BigInt], Ref[BigInt])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "subtract" && receiver.elem.isInstanceOf[BigIntElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigInt], Rep[BigInt])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigInt], Rep[BigInt])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[BigInt], Ref[BigInt])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[BigInt], Ref[BigInt])] = unapply(exp.node) } object multiply { - def unapply(d: Def[_]): Nullable[(Rep[BigInt], Rep[BigInt])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntElem[_]] && method.getName == "multiply" => + def unapply(d: Def[_]): Nullable[(Ref[BigInt], Ref[BigInt])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "multiply" && receiver.elem.isInstanceOf[BigIntElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigInt], Rep[BigInt])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigInt], Rep[BigInt])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[BigInt], Ref[BigInt])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[BigInt], Ref[BigInt])] = unapply(exp.node) } object divide { - def unapply(d: Def[_]): Nullable[(Rep[BigInt], Rep[BigInt])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntElem[_]] && method.getName == "divide" => + def unapply(d: Def[_]): Nullable[(Ref[BigInt], Ref[BigInt])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "divide" && receiver.elem.isInstanceOf[BigIntElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigInt], Rep[BigInt])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigInt], Rep[BigInt])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[BigInt], Ref[BigInt])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[BigInt], Ref[BigInt])] = unapply(exp.node) } object mod { - def unapply(d: Def[_]): Nullable[(Rep[BigInt], Rep[BigInt])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntElem[_]] && method.getName == "mod" => + def unapply(d: Def[_]): Nullable[(Ref[BigInt], Ref[BigInt])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "mod" && receiver.elem.isInstanceOf[BigIntElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigInt], Rep[BigInt])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigInt], Rep[BigInt])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[BigInt], Ref[BigInt])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[BigInt], Ref[BigInt])] = unapply(exp.node) } object remainder { - def unapply(d: Def[_]): Nullable[(Rep[BigInt], Rep[BigInt])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntElem[_]] && method.getName == "remainder" => + def unapply(d: Def[_]): Nullable[(Ref[BigInt], Ref[BigInt])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "remainder" && receiver.elem.isInstanceOf[BigIntElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigInt], Rep[BigInt])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigInt], Rep[BigInt])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[BigInt], Ref[BigInt])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[BigInt], Ref[BigInt])] = unapply(exp.node) } object min { - def unapply(d: Def[_]): Nullable[(Rep[BigInt], Rep[BigInt])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntElem[_]] && method.getName == "min" => + def unapply(d: Def[_]): Nullable[(Ref[BigInt], Ref[BigInt])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "min" && receiver.elem.isInstanceOf[BigIntElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigInt], Rep[BigInt])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigInt], Rep[BigInt])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[BigInt], Ref[BigInt])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[BigInt], Ref[BigInt])] = unapply(exp.node) } object max { - def unapply(d: Def[_]): Nullable[(Rep[BigInt], Rep[BigInt])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntElem[_]] && method.getName == "max" => + def unapply(d: Def[_]): Nullable[(Ref[BigInt], Ref[BigInt])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "max" && receiver.elem.isInstanceOf[BigIntElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigInt], Rep[BigInt])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigInt], Rep[BigInt])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[BigInt], Ref[BigInt])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[BigInt], Ref[BigInt])] = unapply(exp.node) } object negate { - def unapply(d: Def[_]): Nullable[Rep[BigInt]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[BigIntElem[_]] && method.getName == "negate" => + def unapply(d: Def[_]): Nullable[Ref[BigInt]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "negate" && receiver.elem.isInstanceOf[BigIntElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[BigInt]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[BigInt]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[BigInt]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[BigInt]] = unapply(exp.node) } } @@ -1167,48 +894,48 @@ object GroupElement extends EntityObject("GroupElement") { type SGroupElement = special.sigma.GroupElement case class GroupElementConst( constValue: SGroupElement - ) extends GroupElement with LiftedConst[SGroupElement, GroupElement] + ) extends LiftedConst[SGroupElement, GroupElement] with GroupElement with Def[GroupElement] with GroupElementConstMethods { val liftable: Liftable[SGroupElement, GroupElement] = LiftableGroupElement - val selfType: Elem[GroupElement] = liftable.eW + val resultType: Elem[GroupElement] = liftable.eW } trait GroupElementConstMethods extends GroupElement { thisConst: Def[_] => private val GroupElementClass = classOf[GroupElement] - override def isInfinity: Rep[Boolean] = { + override def isInfinity: Ref[Boolean] = { asRep[Boolean](mkMethodCall(self, GroupElementClass.getMethod("isInfinity"), - List(), + WrappedArray.empty, true, false, element[Boolean])) } - override def exp(k: Rep[BigInt]): Rep[GroupElement] = { + override def exp(k: Ref[BigInt]): Ref[GroupElement] = { asRep[GroupElement](mkMethodCall(self, GroupElementClass.getMethod("exp", classOf[Sym]), - List(k), + Array[AnyRef](k), true, false, element[GroupElement])) } - override def multiply(that: Rep[GroupElement]): Rep[GroupElement] = { + override def multiply(that: Ref[GroupElement]): Ref[GroupElement] = { asRep[GroupElement](mkMethodCall(self, GroupElementClass.getMethod("multiply", classOf[Sym]), - List(that), + Array[AnyRef](that), true, false, element[GroupElement])) } - override def negate: Rep[GroupElement] = { + override def negate: Ref[GroupElement] = { asRep[GroupElement](mkMethodCall(self, GroupElementClass.getMethod("negate"), - List(), + WrappedArray.empty, true, false, element[GroupElement])) } - override def getEncoded: Rep[Coll[Byte]] = { + override def getEncoded: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(self, GroupElementClass.getMethod("getEncoded"), - List(), + WrappedArray.empty, true, false, element[Coll[Byte]])) } } @@ -1219,60 +946,62 @@ object GroupElement extends EntityObject("GroupElement") { lazy val sourceType: RType[SGroupElement] = { RType[SGroupElement] } - def lift(x: SGroupElement): Rep[GroupElement] = GroupElementConst(x) - def unlift(w: Rep[GroupElement]): SGroupElement = w match { + def lift(x: SGroupElement): Ref[GroupElement] = GroupElementConst(x) + def unlift(w: Ref[GroupElement]): SGroupElement = w match { case Def(GroupElementConst(x: SGroupElement)) => x.asInstanceOf[SGroupElement] case _ => unliftError(w) } } + private val GroupElementClass = classOf[GroupElement] + // entityAdapter for GroupElement trait - case class GroupElementAdapter(source: Rep[GroupElement]) - extends GroupElement with Def[GroupElement] { - val selfType: Elem[GroupElement] = element[GroupElement] + case class GroupElementAdapter(source: Ref[GroupElement]) + extends Node with GroupElement + with Def[GroupElement] { + val resultType: Elem[GroupElement] = element[GroupElement] override def transform(t: Transformer) = GroupElementAdapter(t(source)) - private val thisClass = classOf[GroupElement] - def isInfinity: Rep[Boolean] = { + def isInfinity: Ref[Boolean] = { asRep[Boolean](mkMethodCall(source, - thisClass.getMethod("isInfinity"), - List(), + GroupElementClass.getMethod("isInfinity"), + WrappedArray.empty, true, true, element[Boolean])) } - def exp(k: Rep[BigInt]): Rep[GroupElement] = { + def exp(k: Ref[BigInt]): Ref[GroupElement] = { asRep[GroupElement](mkMethodCall(source, - thisClass.getMethod("exp", classOf[Sym]), - List(k), + GroupElementClass.getMethod("exp", classOf[Sym]), + Array[AnyRef](k), true, true, element[GroupElement])) } - def multiply(that: Rep[GroupElement]): Rep[GroupElement] = { + def multiply(that: Ref[GroupElement]): Ref[GroupElement] = { asRep[GroupElement](mkMethodCall(source, - thisClass.getMethod("multiply", classOf[Sym]), - List(that), + GroupElementClass.getMethod("multiply", classOf[Sym]), + Array[AnyRef](that), true, true, element[GroupElement])) } - def negate: Rep[GroupElement] = { + def negate: Ref[GroupElement] = { asRep[GroupElement](mkMethodCall(source, - thisClass.getMethod("negate"), - List(), + GroupElementClass.getMethod("negate"), + WrappedArray.empty, true, true, element[GroupElement])) } - def getEncoded: Rep[Coll[Byte]] = { + def getEncoded: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(source, - thisClass.getMethod("getEncoded"), - List(), + GroupElementClass.getMethod("getEncoded"), + WrappedArray.empty, true, true, element[Coll[Byte]])) } } - // entityProxy: single proxy for each type family - implicit def proxyGroupElement(p: Rep[GroupElement]): GroupElement = { - if (p.rhs.isInstanceOf[GroupElement@unchecked]) p.rhs.asInstanceOf[GroupElement] + // entityUnref: single unref method for each type family + implicit final def unrefGroupElement(p: Ref[GroupElement]): GroupElement = { + if (p.node.isInstanceOf[GroupElement]) p.node.asInstanceOf[GroupElement] else GroupElementAdapter(p) } @@ -1280,7 +1009,7 @@ object GroupElement extends EntityObject("GroupElement") { // familyElem class GroupElementElem[To <: GroupElement] extends EntityElem[To] { - override val liftable: Liftables.Liftable[_, To] = LiftableGroupElement.asLiftable[SGroupElement, To] + override val liftable: Liftables.Liftable[_, To] = asLiftable[SGroupElement, To](LiftableGroupElement) override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { super.collectMethods ++ @@ -1288,109 +1017,73 @@ object GroupElement extends EntityObject("GroupElement") { "isInfinity", "exp", "multiply", "negate", "getEncoded" )) } - - lazy val parent: Option[Elem[_]] = None - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override lazy val tag = { - weakTypeTag[GroupElement].asInstanceOf[WeakTypeTag[To]] - } - override def convert(x: Rep[Def[_]]) = { - val conv = fun {x: Rep[GroupElement] => convertGroupElement(x) } - tryConvert(element[GroupElement], this, x, conv) - } - - def convertGroupElement(x: Rep[GroupElement]): Rep[To] = { - x.elem match { - case _: GroupElementElem[_] => asRep[To](x) - case e => !!!(s"Expected $x to have GroupElementElem[_], but got $e", x) - } - } - override def getDefaultRep: Rep[To] = ??? } implicit lazy val groupElementElement: Elem[GroupElement] = new GroupElementElem[GroupElement] - implicit case object GroupElementCompanionElem extends CompanionElem[GroupElementCompanionCtor] { - lazy val tag = weakTypeTag[GroupElementCompanionCtor] - protected def getDefaultRep = RGroupElement - } + implicit case object GroupElementCompanionElem extends CompanionElem[GroupElementCompanionCtor] abstract class GroupElementCompanionCtor extends CompanionDef[GroupElementCompanionCtor] with GroupElementCompanion { - def selfType = GroupElementCompanionElem + def resultType = GroupElementCompanionElem override def toString = "GroupElement" } - implicit def proxyGroupElementCompanionCtor(p: Rep[GroupElementCompanionCtor]): GroupElementCompanionCtor = - proxyOps[GroupElementCompanionCtor](p) + implicit final def unrefGroupElementCompanionCtor(p: Ref[GroupElementCompanionCtor]): GroupElementCompanionCtor = + p.node.asInstanceOf[GroupElementCompanionCtor] - lazy val RGroupElement: Rep[GroupElementCompanionCtor] = new GroupElementCompanionCtor { + lazy val RGroupElement: MutableLazy[GroupElementCompanionCtor] = MutableLazy(new GroupElementCompanionCtor { private val thisClass = classOf[GroupElementCompanion] - } + }) object GroupElementMethods { object isInfinity { - def unapply(d: Def[_]): Nullable[Rep[GroupElement]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[GroupElementElem[_]] && method.getName == "isInfinity" => + def unapply(d: Def[_]): Nullable[Ref[GroupElement]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "isInfinity" && receiver.elem.isInstanceOf[GroupElementElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[GroupElement]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[GroupElement]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[GroupElement]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[GroupElement]] = unapply(exp.node) } object exp { - def unapply(d: Def[_]): Nullable[(Rep[GroupElement], Rep[BigInt])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[GroupElementElem[_]] && method.getName == "exp" => + def unapply(d: Def[_]): Nullable[(Ref[GroupElement], Ref[BigInt])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "exp" && receiver.elem.isInstanceOf[GroupElementElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[GroupElement], Rep[BigInt])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[GroupElement], Rep[BigInt])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[GroupElement], Ref[BigInt])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[GroupElement], Ref[BigInt])] = unapply(exp.node) } object multiply { - def unapply(d: Def[_]): Nullable[(Rep[GroupElement], Rep[GroupElement])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[GroupElementElem[_]] && method.getName == "multiply" => + def unapply(d: Def[_]): Nullable[(Ref[GroupElement], Ref[GroupElement])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "multiply" && receiver.elem.isInstanceOf[GroupElementElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[GroupElement], Rep[GroupElement])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[GroupElement], Rep[GroupElement])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[GroupElement], Ref[GroupElement])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[GroupElement], Ref[GroupElement])] = unapply(exp.node) } object negate { - def unapply(d: Def[_]): Nullable[Rep[GroupElement]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[GroupElementElem[_]] && method.getName == "negate" => + def unapply(d: Def[_]): Nullable[Ref[GroupElement]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "negate" && receiver.elem.isInstanceOf[GroupElementElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[GroupElement]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[GroupElement]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[GroupElement]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[GroupElement]] = unapply(exp.node) } object getEncoded { - def unapply(d: Def[_]): Nullable[Rep[GroupElement]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[GroupElementElem[_]] && method.getName == "getEncoded" => + def unapply(d: Def[_]): Nullable[Ref[GroupElement]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "getEncoded" && receiver.elem.isInstanceOf[GroupElementElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[GroupElement]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[GroupElement]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[GroupElement]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[GroupElement]] = unapply(exp.node) } } @@ -1406,59 +1099,59 @@ object SigmaProp extends EntityObject("SigmaProp") { type SSigmaProp = special.sigma.SigmaProp case class SigmaPropConst( constValue: SSigmaProp - ) extends SigmaProp with LiftedConst[SSigmaProp, SigmaProp] + ) extends LiftedConst[SSigmaProp, SigmaProp] with SigmaProp with Def[SigmaProp] with SigmaPropConstMethods { val liftable: Liftable[SSigmaProp, SigmaProp] = LiftableSigmaProp - val selfType: Elem[SigmaProp] = liftable.eW + val resultType: Elem[SigmaProp] = liftable.eW } trait SigmaPropConstMethods extends SigmaProp { thisConst: Def[_] => private val SigmaPropClass = classOf[SigmaProp] - override def isValid: Rep[Boolean] = { + override def isValid: Ref[Boolean] = { asRep[Boolean](mkMethodCall(self, SigmaPropClass.getMethod("isValid"), - List(), + WrappedArray.empty, true, false, element[Boolean])) } - override def propBytes: Rep[Coll[Byte]] = { + override def propBytes: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(self, SigmaPropClass.getMethod("propBytes"), - List(), + WrappedArray.empty, true, false, element[Coll[Byte]])) } // manual fix && - override def &&(other: Rep[SigmaProp]): Rep[SigmaProp] = { + override def &&(other: Ref[SigmaProp]): Ref[SigmaProp] = { asRep[SigmaProp](mkMethodCall(self, SigmaPropClass.getMethod("$amp$amp", classOf[Sym]), - List(other), + Array[AnyRef](other), true, false, element[SigmaProp])) } // manual fix && - override def &&(other: Rep[Boolean])(implicit o: Overloaded1): Rep[SigmaProp] = { + override def &&(other: Ref[Boolean])(implicit o: Overloaded1): Ref[SigmaProp] = { asRep[SigmaProp](mkMethodCall(self, SigmaPropClass.getMethod("$amp$amp", classOf[Sym], classOf[Overloaded1]), - List(other, o), + Array[AnyRef](other, o), true, false, element[SigmaProp])) } // manual fix || - override def ||(other: Rep[SigmaProp]): Rep[SigmaProp] = { + override def ||(other: Ref[SigmaProp]): Ref[SigmaProp] = { asRep[SigmaProp](mkMethodCall(self, SigmaPropClass.getMethod("$bar$bar", classOf[Sym]), - List(other), + Array[AnyRef](other), true, false, element[SigmaProp])) } // manual fix || - override def ||(other: Rep[Boolean])(implicit o: Overloaded1): Rep[SigmaProp] = { + override def ||(other: Ref[Boolean])(implicit o: Overloaded1): Ref[SigmaProp] = { asRep[SigmaProp](mkMethodCall(self, SigmaPropClass.getMethod("$bar$bar", classOf[Sym], classOf[Overloaded1]), - List(other, o), + Array[AnyRef](other, o), true, false, element[SigmaProp])) } } @@ -1469,92 +1162,95 @@ object SigmaProp extends EntityObject("SigmaProp") { lazy val sourceType: RType[SSigmaProp] = { RType[SSigmaProp] } - def lift(x: SSigmaProp): Rep[SigmaProp] = SigmaPropConst(x) - def unlift(w: Rep[SigmaProp]): SSigmaProp = w match { + def lift(x: SSigmaProp): Ref[SigmaProp] = SigmaPropConst(x) + def unlift(w: Ref[SigmaProp]): SSigmaProp = w match { case Def(SigmaPropConst(x: SSigmaProp)) => x.asInstanceOf[SSigmaProp] case _ => unliftError(w) } } + private val SigmaPropClass = classOf[SigmaProp] + // entityAdapter for SigmaProp trait - case class SigmaPropAdapter(source: Rep[SigmaProp]) - extends SigmaProp with Def[SigmaProp] { - val selfType: Elem[SigmaProp] = element[SigmaProp] + case class SigmaPropAdapter(source: Ref[SigmaProp]) + extends Node with SigmaProp + with Def[SigmaProp] { + val resultType: Elem[SigmaProp] = element[SigmaProp] override def transform(t: Transformer) = SigmaPropAdapter(t(source)) - private val thisClass = classOf[SigmaProp] - def isValid: Rep[Boolean] = { + def isValid: Ref[Boolean] = { asRep[Boolean](mkMethodCall(source, - thisClass.getMethod("isValid"), - List(), + SigmaPropClass.getMethod("isValid"), + WrappedArray.empty, true, true, element[Boolean])) } - def propBytes: Rep[Coll[Byte]] = { + def propBytes: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(source, - thisClass.getMethod("propBytes"), - List(), + SigmaPropClass.getMethod("propBytes"), + WrappedArray.empty, true, true, element[Coll[Byte]])) } // manual fix && - def &&(other: Rep[SigmaProp]): Rep[SigmaProp] = { + def &&(other: Ref[SigmaProp]): Ref[SigmaProp] = { asRep[SigmaProp](mkMethodCall(source, - thisClass.getMethod("$amp$amp", classOf[Sym]), - List(other), + SigmaPropClass.getMethod("$amp$amp", classOf[Sym]), + Array[AnyRef](other), true, true, element[SigmaProp])) } // manual fix && - def &&(other: Rep[Boolean])(implicit o: Overloaded1): Rep[SigmaProp] = { + def &&(other: Ref[Boolean])(implicit o: Overloaded1): Ref[SigmaProp] = { asRep[SigmaProp](mkMethodCall(source, - thisClass.getMethod("$amp$amp", classOf[Sym], classOf[Overloaded1]), - List(other, o), + SigmaPropClass.getMethod("$amp$amp", classOf[Sym], classOf[Overloaded1]), + Array[AnyRef](other, o), true, true, element[SigmaProp])) } // manual fix || - def ||(other: Rep[SigmaProp]): Rep[SigmaProp] = { + def ||(other: Ref[SigmaProp]): Ref[SigmaProp] = { asRep[SigmaProp](mkMethodCall(source, - thisClass.getMethod("$bar$bar", classOf[Sym]), - List(other), + SigmaPropClass.getMethod("$bar$bar", classOf[Sym]), + Array[AnyRef](other), true, true, element[SigmaProp])) } // manual fix || - def ||(other: Rep[Boolean])(implicit o: Overloaded1): Rep[SigmaProp] = { + def ||(other: Ref[Boolean])(implicit o: Overloaded1): Ref[SigmaProp] = { asRep[SigmaProp](mkMethodCall(source, - thisClass.getMethod("$bar$bar", classOf[Sym], classOf[Overloaded1]), - List(other, o), + SigmaPropClass.getMethod("$bar$bar", classOf[Sym], classOf[Overloaded1]), + Array[AnyRef](other, o), true, true, element[SigmaProp])) } - def lazyAnd(other: Rep[Thunk[SigmaProp]]): Rep[SigmaProp] = { + def lazyAnd(other: Ref[Thunk[SigmaProp]]): Ref[SigmaProp] = { asRep[SigmaProp](mkMethodCall(source, - thisClass.getMethod("lazyAnd", classOf[Sym]), - List(other), + SigmaPropClass.getMethod("lazyAnd", classOf[Sym]), + Array[AnyRef](other), true, true, element[SigmaProp])) } - def lazyOr(other: Rep[Thunk[SigmaProp]]): Rep[SigmaProp] = { + def lazyOr(other: Ref[Thunk[SigmaProp]]): Ref[SigmaProp] = { asRep[SigmaProp](mkMethodCall(source, - thisClass.getMethod("lazyOr", classOf[Sym]), - List(other), + SigmaPropClass.getMethod("lazyOr", classOf[Sym]), + Array[AnyRef](other), true, true, element[SigmaProp])) } - def builder: Rep[SigmaDslBuilder] = { + // manual fix + def builder: Ref[SigmaDslBuilder] = { asRep[SigmaDslBuilder](mkMethodCall(source, - thisClass.getMethod("builder"), - List(), + SigmaPropClass.getMethod("builder"), + Array[AnyRef](), true, true, element[SigmaDslBuilder])) } } - // entityProxy: single proxy for each type family - implicit def proxySigmaProp(p: Rep[SigmaProp]): SigmaProp = { - if (p.rhs.isInstanceOf[SigmaProp@unchecked]) p.rhs.asInstanceOf[SigmaProp] + // entityUnref: single unref method for each type family + implicit final def unrefSigmaProp(p: Ref[SigmaProp]): SigmaProp = { + if (p.node.isInstanceOf[SigmaProp]) p.node.asInstanceOf[SigmaProp] else SigmaPropAdapter(p) } @@ -1562,7 +1258,7 @@ object SigmaProp extends EntityObject("SigmaProp") { // familyElem class SigmaPropElem[To <: SigmaProp] extends EntityElem[To] { - override val liftable: Liftables.Liftable[_, To] = LiftableSigmaProp.asLiftable[SSigmaProp, To] + override val liftable: Liftables.Liftable[_, To] = asLiftable[SSigmaProp, To](LiftableSigmaProp) override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { super.collectMethods ++ @@ -1570,123 +1266,83 @@ object SigmaProp extends EntityObject("SigmaProp") { "isValid", "propBytes", "$amp$amp", "$amp$amp", "$bar$bar", "$bar$bar" )) } - - lazy val parent: Option[Elem[_]] = None - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override lazy val tag = { - weakTypeTag[SigmaProp].asInstanceOf[WeakTypeTag[To]] - } - override def convert(x: Rep[Def[_]]) = { - val conv = fun {x: Rep[SigmaProp] => convertSigmaProp(x) } - tryConvert(element[SigmaProp], this, x, conv) - } - - def convertSigmaProp(x: Rep[SigmaProp]): Rep[To] = { - x.elem match { - case _: SigmaPropElem[_] => asRep[To](x) - case e => !!!(s"Expected $x to have SigmaPropElem[_], but got $e", x) - } - } - override def getDefaultRep: Rep[To] = ??? } implicit lazy val sigmaPropElement: Elem[SigmaProp] = new SigmaPropElem[SigmaProp] - implicit case object SigmaPropCompanionElem extends CompanionElem[SigmaPropCompanionCtor] { - lazy val tag = weakTypeTag[SigmaPropCompanionCtor] - protected def getDefaultRep = RSigmaProp - } + implicit case object SigmaPropCompanionElem extends CompanionElem[SigmaPropCompanionCtor] abstract class SigmaPropCompanionCtor extends CompanionDef[SigmaPropCompanionCtor] with SigmaPropCompanion { - def selfType = SigmaPropCompanionElem + def resultType = SigmaPropCompanionElem override def toString = "SigmaProp" } - implicit def proxySigmaPropCompanionCtor(p: Rep[SigmaPropCompanionCtor]): SigmaPropCompanionCtor = - proxyOps[SigmaPropCompanionCtor](p) + implicit final def unrefSigmaPropCompanionCtor(p: Ref[SigmaPropCompanionCtor]): SigmaPropCompanionCtor = + p.node.asInstanceOf[SigmaPropCompanionCtor] - lazy val RSigmaProp: Rep[SigmaPropCompanionCtor] = new SigmaPropCompanionCtor { + lazy val RSigmaProp: MutableLazy[SigmaPropCompanionCtor] = MutableLazy(new SigmaPropCompanionCtor { private val thisClass = classOf[SigmaPropCompanion] - } + }) - // manual fix object SigmaPropMethods { object isValid { - def unapply(d: Def[_]): Nullable[Rep[SigmaProp]] = d match { + def unapply(d: Def[_]): Nullable[Ref[SigmaProp]] = d match { case MethodCall(receiver, method, _, _) if method.getName == "isValid" && receiver.elem.isInstanceOf[SigmaPropElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[SigmaProp]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[SigmaProp]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[SigmaProp]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[SigmaProp]] = unapply(exp.node) } object propBytes { - def unapply(d: Def[_]): Nullable[Rep[SigmaProp]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[SigmaPropElem[_]] && method.getName == "propBytes" => + def unapply(d: Def[_]): Nullable[Ref[SigmaProp]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "propBytes" && receiver.elem.isInstanceOf[SigmaPropElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[SigmaProp]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[SigmaProp]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[SigmaProp]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[SigmaProp]] = unapply(exp.node) } object and_sigma_&& { - def unapply(d: Def[_]): Nullable[(Rep[SigmaProp], Rep[SigmaProp])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaPropElem[_]] && method.getName == "$amp$amp" && { val ann = method.getAnnotation(classOf[scalan.OverloadId]); ann != null && ann.value == "and_sigma" } => + def unapply(d: Def[_]): Nullable[(Ref[SigmaProp], Ref[SigmaProp])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "$amp$amp" && receiver.elem.isInstanceOf[SigmaPropElem[_]] && { val ann = method.getAnnotation(classOf[scalan.OverloadId]); ann != null && ann.value == "and_sigma" } => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaProp], Rep[SigmaProp])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaProp], Rep[SigmaProp])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[SigmaProp], Ref[SigmaProp])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[SigmaProp], Ref[SigmaProp])] = unapply(exp.node) } object and_bool_&& { - def unapply(d: Def[_]): Nullable[(Rep[SigmaProp], Rep[Boolean])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaPropElem[_]] && method.getName == "$amp$amp" && { val ann = method.getAnnotation(classOf[scalan.OverloadId]); ann != null && ann.value == "and_bool" } => + def unapply(d: Def[_]): Nullable[(Ref[SigmaProp], Ref[Boolean])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "$amp$amp" && receiver.elem.isInstanceOf[SigmaPropElem[_]] && { val ann = method.getAnnotation(classOf[scalan.OverloadId]); ann != null && ann.value == "and_bool" } => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaProp], Rep[Boolean])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaProp], Rep[Boolean])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[SigmaProp], Ref[Boolean])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[SigmaProp], Ref[Boolean])] = unapply(exp.node) } object or_sigma_|| { - def unapply(d: Def[_]): Nullable[(Rep[SigmaProp], Rep[SigmaProp])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaPropElem[_]] && method.getName == "$bar$bar" && { val ann = method.getAnnotation(classOf[scalan.OverloadId]); ann != null && ann.value == "or_sigma" } => + def unapply(d: Def[_]): Nullable[(Ref[SigmaProp], Ref[SigmaProp])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "$bar$bar" && receiver.elem.isInstanceOf[SigmaPropElem[_]] && { val ann = method.getAnnotation(classOf[scalan.OverloadId]); ann != null && ann.value == "or_sigma" } => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaProp], Rep[SigmaProp])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaProp], Rep[SigmaProp])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[SigmaProp], Ref[SigmaProp])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[SigmaProp], Ref[SigmaProp])] = unapply(exp.node) } object or_bool_|| { - def unapply(d: Def[_]): Nullable[(Rep[SigmaProp], Rep[Boolean])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaPropElem[_]] && method.getName == "$bar$bar" && { val ann = method.getAnnotation(classOf[scalan.OverloadId]); ann != null && ann.value == "or_bool" } => + def unapply(d: Def[_]): Nullable[(Ref[SigmaProp], Ref[Boolean])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "$bar$bar" && receiver.elem.isInstanceOf[SigmaPropElem[_]] && { val ann = method.getAnnotation(classOf[scalan.OverloadId]); ann != null && ann.value == "or_bool" } => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaProp], Rep[Boolean])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaProp], Rep[Boolean])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[SigmaProp], Ref[Boolean])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[SigmaProp], Ref[Boolean])] = unapply(exp.node) } } @@ -1702,10 +1358,10 @@ object AnyValue extends EntityObject("AnyValue") { type SAnyValue = special.sigma.AnyValue case class AnyValueConst( constValue: SAnyValue - ) extends AnyValue with LiftedConst[SAnyValue, AnyValue] + ) extends LiftedConst[SAnyValue, AnyValue] with AnyValue with Def[AnyValue] with AnyValueConstMethods { val liftable: Liftable[SAnyValue, AnyValue] = LiftableAnyValue - val selfType: Elem[AnyValue] = liftable.eW + val resultType: Elem[AnyValue] = liftable.eW } trait AnyValueConstMethods extends AnyValue { thisConst: Def[_] => @@ -1713,17 +1369,17 @@ object AnyValue extends EntityObject("AnyValue") { private val AnyValueClass = classOf[AnyValue] // manual fix - override def value: Rep[Any] = { + override def value: Ref[Any] = { asRep[Any](mkMethodCall(self, AnyValueClass.getMethod("value"), - List(), + WrappedArray.empty, true, false, AnyElement)) } - override def tVal: Rep[WRType[Any]] = { + override def tVal: Ref[WRType[Any]] = { asRep[WRType[Any]](mkMethodCall(self, AnyValueClass.getMethod("tVal"), - List(), + WrappedArray.empty, true, false, element[WRType[Any]])) } } @@ -1734,40 +1390,42 @@ object AnyValue extends EntityObject("AnyValue") { lazy val sourceType: RType[SAnyValue] = { RType[SAnyValue] } - def lift(x: SAnyValue): Rep[AnyValue] = AnyValueConst(x) - def unlift(w: Rep[AnyValue]): SAnyValue = w match { + def lift(x: SAnyValue): Ref[AnyValue] = AnyValueConst(x) + def unlift(w: Ref[AnyValue]): SAnyValue = w match { case Def(AnyValueConst(x: SAnyValue)) => x.asInstanceOf[SAnyValue] case _ => unliftError(w) } } + private val AnyValueClass = classOf[AnyValue] + // entityAdapter for AnyValue trait - case class AnyValueAdapter(source: Rep[AnyValue]) - extends AnyValue with Def[AnyValue] { - val selfType: Elem[AnyValue] = element[AnyValue] + case class AnyValueAdapter(source: Ref[AnyValue]) + extends Node with AnyValue + with Def[AnyValue] { + val resultType: Elem[AnyValue] = element[AnyValue] override def transform(t: Transformer) = AnyValueAdapter(t(source)) - private val thisClass = classOf[AnyValue] // manual fix - def value: Rep[Any] = { + def value: Ref[Any] = { asRep[Any](mkMethodCall(source, - thisClass.getMethod("value"), - List(), + AnyValueClass.getMethod("value"), + WrappedArray.empty, true, true, AnyElement)) } - def tVal: Rep[WRType[Any]] = { + def tVal: Ref[WRType[Any]] = { asRep[WRType[Any]](mkMethodCall(source, - thisClass.getMethod("tVal"), - List(), + AnyValueClass.getMethod("tVal"), + WrappedArray.empty, true, true, element[WRType[Any]])) } } - // entityProxy: single proxy for each type family - implicit def proxyAnyValue(p: Rep[AnyValue]): AnyValue = { - if (p.rhs.isInstanceOf[AnyValue@unchecked]) p.rhs.asInstanceOf[AnyValue] + // entityUnref: single unref method for each type family + implicit final def unrefAnyValue(p: Ref[AnyValue]): AnyValue = { + if (p.node.isInstanceOf[AnyValue]) p.node.asInstanceOf[AnyValue] else AnyValueAdapter(p) } @@ -1775,7 +1433,7 @@ object AnyValue extends EntityObject("AnyValue") { // familyElem class AnyValueElem[To <: AnyValue] extends EntityElem[To] { - override val liftable: Liftables.Liftable[_, To] = LiftableAnyValue.asLiftable[SAnyValue, To] + override val liftable: Liftables.Liftable[_, To] = asLiftable[SAnyValue, To](LiftableAnyValue) override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { super.collectMethods ++ @@ -1783,70 +1441,43 @@ object AnyValue extends EntityObject("AnyValue") { "value", "tVal" )) } - - lazy val parent: Option[Elem[_]] = None - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override lazy val tag = { - weakTypeTag[AnyValue].asInstanceOf[WeakTypeTag[To]] - } - override def convert(x: Rep[Def[_]]) = { - val conv = fun {x: Rep[AnyValue] => convertAnyValue(x) } - tryConvert(element[AnyValue], this, x, conv) - } - - def convertAnyValue(x: Rep[AnyValue]): Rep[To] = { - x.elem match { - case _: AnyValueElem[_] => asRep[To](x) - case e => !!!(s"Expected $x to have AnyValueElem[_], but got $e", x) - } - } - override def getDefaultRep: Rep[To] = ??? } implicit lazy val anyValueElement: Elem[AnyValue] = new AnyValueElem[AnyValue] - implicit case object AnyValueCompanionElem extends CompanionElem[AnyValueCompanionCtor] { - lazy val tag = weakTypeTag[AnyValueCompanionCtor] - protected def getDefaultRep = RAnyValue - } + implicit case object AnyValueCompanionElem extends CompanionElem[AnyValueCompanionCtor] abstract class AnyValueCompanionCtor extends CompanionDef[AnyValueCompanionCtor] with AnyValueCompanion { - def selfType = AnyValueCompanionElem + def resultType = AnyValueCompanionElem override def toString = "AnyValue" } - implicit def proxyAnyValueCompanionCtor(p: Rep[AnyValueCompanionCtor]): AnyValueCompanionCtor = - proxyOps[AnyValueCompanionCtor](p) + implicit final def unrefAnyValueCompanionCtor(p: Ref[AnyValueCompanionCtor]): AnyValueCompanionCtor = + p.node.asInstanceOf[AnyValueCompanionCtor] - lazy val RAnyValue: Rep[AnyValueCompanionCtor] = new AnyValueCompanionCtor { + lazy val RAnyValue: MutableLazy[AnyValueCompanionCtor] = MutableLazy(new AnyValueCompanionCtor { private val thisClass = classOf[AnyValueCompanion] - } + }) object AnyValueMethods { object value { - def unapply(d: Def[_]): Nullable[Rep[AnyValue]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[AnyValueElem[_]] && method.getName == "value" => + def unapply(d: Def[_]): Nullable[Ref[AnyValue]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "value" && receiver.elem.isInstanceOf[AnyValueElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[AnyValue]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[AnyValue]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[AnyValue]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[AnyValue]] = unapply(exp.node) } object tVal { - def unapply(d: Def[_]): Nullable[Rep[AnyValue]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[AnyValueElem[_]] && method.getName == "tVal" => + def unapply(d: Def[_]): Nullable[Ref[AnyValue]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "tVal" && receiver.elem.isInstanceOf[AnyValueElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[AnyValue]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[AnyValue]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[AnyValue]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[AnyValue]] = unapply(exp.node) } } @@ -1862,83 +1493,83 @@ object Box extends EntityObject("Box") { type SBox = special.sigma.Box case class BoxConst( constValue: SBox - ) extends Box with LiftedConst[SBox, Box] + ) extends LiftedConst[SBox, Box] with Box with Def[Box] with BoxConstMethods { val liftable: Liftable[SBox, Box] = LiftableBox - val selfType: Elem[Box] = liftable.eW + val resultType: Elem[Box] = liftable.eW } trait BoxConstMethods extends Box { thisConst: Def[_] => private val BoxClass = classOf[Box] - override def id: Rep[Coll[Byte]] = { + override def id: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(self, BoxClass.getMethod("id"), - List(), + WrappedArray.empty, true, false, element[Coll[Byte]])) } - override def value: Rep[Long] = { + override def value: Ref[Long] = { asRep[Long](mkMethodCall(self, BoxClass.getMethod("value"), - List(), + WrappedArray.empty, true, false, element[Long])) } - override def propositionBytes: Rep[Coll[Byte]] = { + override def propositionBytes: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(self, BoxClass.getMethod("propositionBytes"), - List(), + WrappedArray.empty, true, false, element[Coll[Byte]])) } - override def bytes: Rep[Coll[Byte]] = { + override def bytes: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(self, BoxClass.getMethod("bytes"), - List(), + WrappedArray.empty, true, false, element[Coll[Byte]])) } - override def bytesWithoutRef: Rep[Coll[Byte]] = { + override def bytesWithoutRef: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(self, BoxClass.getMethod("bytesWithoutRef"), - List(), + WrappedArray.empty, true, false, element[Coll[Byte]])) } - override def registers: Rep[Coll[AnyValue]] = { + override def registers: Ref[Coll[AnyValue]] = { asRep[Coll[AnyValue]](mkMethodCall(self, BoxClass.getMethod("registers"), - List(), + WrappedArray.empty, true, false, element[Coll[AnyValue]])) } - override def getReg[T](i: Rep[Int])(implicit cT: Elem[T]): Rep[WOption[T]] = { + override def getReg[T](i: Ref[Int])(implicit cT: Elem[T]): Ref[WOption[T]] = { asRep[WOption[T]](mkMethodCall(self, BoxClass.getMethod("getReg", classOf[Sym], classOf[Elem[_]]), - List(i, cT), + Array[AnyRef](i, cT), true, false, element[WOption[T]])) } - override def tokens: Rep[Coll[(Coll[Byte], Long)]] = { + override def tokens: Ref[Coll[(Coll[Byte], Long)]] = { asRep[Coll[(Coll[Byte], Long)]](mkMethodCall(self, BoxClass.getMethod("tokens"), - List(), + WrappedArray.empty, true, false, element[Coll[(Coll[Byte], Long)]])) } - override def creationInfo: Rep[(Int, Coll[Byte])] = { + override def creationInfo: Ref[(Int, Coll[Byte])] = { asRep[(Int, Coll[Byte])](mkMethodCall(self, BoxClass.getMethod("creationInfo"), - List(), + WrappedArray.empty, true, false, element[(Int, Coll[Byte])])) } - override def executeFromRegister[T](regId: Rep[Byte])(implicit cT: Elem[T]): Rep[T] = { + override def executeFromRegister[T](regId: Ref[Byte])(implicit cT: Elem[T]): Ref[T] = { asRep[T](mkMethodCall(self, BoxClass.getMethod("executeFromRegister", classOf[Sym], classOf[Elem[_]]), - List(regId, cT), + Array[AnyRef](regId, cT), true, false, element[T])) } } @@ -1949,95 +1580,97 @@ object Box extends EntityObject("Box") { lazy val sourceType: RType[SBox] = { RType[SBox] } - def lift(x: SBox): Rep[Box] = BoxConst(x) - def unlift(w: Rep[Box]): SBox = w match { + def lift(x: SBox): Ref[Box] = BoxConst(x) + def unlift(w: Ref[Box]): SBox = w match { case Def(BoxConst(x: SBox)) => x.asInstanceOf[SBox] case _ => unliftError(w) } } + private val BoxClass = classOf[Box] + // entityAdapter for Box trait - case class BoxAdapter(source: Rep[Box]) - extends Box with Def[Box] { - val selfType: Elem[Box] = element[Box] + case class BoxAdapter(source: Ref[Box]) + extends Node with Box + with Def[Box] { + val resultType: Elem[Box] = element[Box] override def transform(t: Transformer) = BoxAdapter(t(source)) - private val thisClass = classOf[Box] - def id: Rep[Coll[Byte]] = { + def id: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(source, - thisClass.getMethod("id"), - List(), + BoxClass.getMethod("id"), + WrappedArray.empty, true, true, element[Coll[Byte]])) } - def value: Rep[Long] = { + def value: Ref[Long] = { asRep[Long](mkMethodCall(source, - thisClass.getMethod("value"), - List(), + BoxClass.getMethod("value"), + WrappedArray.empty, true, true, element[Long])) } - def propositionBytes: Rep[Coll[Byte]] = { + def propositionBytes: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(source, - thisClass.getMethod("propositionBytes"), - List(), + BoxClass.getMethod("propositionBytes"), + WrappedArray.empty, true, true, element[Coll[Byte]])) } - def bytes: Rep[Coll[Byte]] = { + def bytes: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(source, - thisClass.getMethod("bytes"), - List(), + BoxClass.getMethod("bytes"), + WrappedArray.empty, true, true, element[Coll[Byte]])) } - def bytesWithoutRef: Rep[Coll[Byte]] = { + def bytesWithoutRef: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(source, - thisClass.getMethod("bytesWithoutRef"), - List(), + BoxClass.getMethod("bytesWithoutRef"), + WrappedArray.empty, true, true, element[Coll[Byte]])) } - def registers: Rep[Coll[AnyValue]] = { + def registers: Ref[Coll[AnyValue]] = { asRep[Coll[AnyValue]](mkMethodCall(source, - thisClass.getMethod("registers"), - List(), + BoxClass.getMethod("registers"), + WrappedArray.empty, true, true, element[Coll[AnyValue]])) } - def getReg[T](i: Rep[Int])(implicit cT: Elem[T]): Rep[WOption[T]] = { + def getReg[T](i: Ref[Int])(implicit cT: Elem[T]): Ref[WOption[T]] = { asRep[WOption[T]](mkMethodCall(source, - thisClass.getMethod("getReg", classOf[Sym], classOf[Elem[_]]), - List(i, cT), + BoxClass.getMethod("getReg", classOf[Sym], classOf[Elem[_]]), + Array[AnyRef](i, cT), true, true, element[WOption[T]])) } - def tokens: Rep[Coll[(Coll[Byte], Long)]] = { + def tokens: Ref[Coll[(Coll[Byte], Long)]] = { asRep[Coll[(Coll[Byte], Long)]](mkMethodCall(source, - thisClass.getMethod("tokens"), - List(), + BoxClass.getMethod("tokens"), + WrappedArray.empty, true, true, element[Coll[(Coll[Byte], Long)]])) } - def creationInfo: Rep[(Int, Coll[Byte])] = { + def creationInfo: Ref[(Int, Coll[Byte])] = { asRep[(Int, Coll[Byte])](mkMethodCall(source, - thisClass.getMethod("creationInfo"), - List(), + BoxClass.getMethod("creationInfo"), + WrappedArray.empty, true, true, element[(Int, Coll[Byte])])) } - def executeFromRegister[T](regId: Rep[Byte])(implicit cT: Elem[T]): Rep[T] = { + def executeFromRegister[T](regId: Ref[Byte])(implicit cT: Elem[T]): Ref[T] = { asRep[T](mkMethodCall(source, - thisClass.getMethod("executeFromRegister", classOf[Sym], classOf[Elem[_]]), - List(regId, cT), + BoxClass.getMethod("executeFromRegister", classOf[Sym], classOf[Elem[_]]), + Array[AnyRef](regId, cT), true, true, element[T])) } } - // entityProxy: single proxy for each type family - implicit def proxyBox(p: Rep[Box]): Box = { - if (p.rhs.isInstanceOf[Box@unchecked]) p.rhs.asInstanceOf[Box] + // entityUnref: single unref method for each type family + implicit final def unrefBox(p: Ref[Box]): Box = { + if (p.node.isInstanceOf[Box]) p.node.asInstanceOf[Box] else BoxAdapter(p) } @@ -2045,7 +1678,7 @@ object Box extends EntityObject("Box") { // familyElem class BoxElem[To <: Box] extends EntityElem[To] { - override val liftable: Liftables.Liftable[_, To] = LiftableBox.asLiftable[SBox, To] + override val liftable: Liftables.Liftable[_, To] = asLiftable[SBox, To](LiftableBox) override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { super.collectMethods ++ @@ -2053,304 +1686,223 @@ object Box extends EntityObject("Box") { "id", "value", "propositionBytes", "bytes", "bytesWithoutRef", "registers", "getReg", "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "tokens", "creationInfo", "executeFromRegister" )) } - - lazy val parent: Option[Elem[_]] = None - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override lazy val tag = { - weakTypeTag[Box].asInstanceOf[WeakTypeTag[To]] - } - override def convert(x: Rep[Def[_]]) = { - val conv = fun {x: Rep[Box] => convertBox(x) } - tryConvert(element[Box], this, x, conv) - } - - def convertBox(x: Rep[Box]): Rep[To] = { - x.elem match { - case _: BoxElem[_] => asRep[To](x) - case e => !!!(s"Expected $x to have BoxElem[_], but got $e", x) - } - } - override def getDefaultRep: Rep[To] = ??? } implicit lazy val boxElement: Elem[Box] = new BoxElem[Box] - implicit case object BoxCompanionElem extends CompanionElem[BoxCompanionCtor] { - lazy val tag = weakTypeTag[BoxCompanionCtor] - protected def getDefaultRep = RBox - } + implicit case object BoxCompanionElem extends CompanionElem[BoxCompanionCtor] abstract class BoxCompanionCtor extends CompanionDef[BoxCompanionCtor] with BoxCompanion { - def selfType = BoxCompanionElem + def resultType = BoxCompanionElem override def toString = "Box" } - implicit def proxyBoxCompanionCtor(p: Rep[BoxCompanionCtor]): BoxCompanionCtor = - proxyOps[BoxCompanionCtor](p) + implicit final def unrefBoxCompanionCtor(p: Ref[BoxCompanionCtor]): BoxCompanionCtor = + p.node.asInstanceOf[BoxCompanionCtor] - lazy val RBox: Rep[BoxCompanionCtor] = new BoxCompanionCtor { + lazy val RBox: MutableLazy[BoxCompanionCtor] = MutableLazy(new BoxCompanionCtor { private val thisClass = classOf[BoxCompanion] - } + }) object BoxMethods { object id { - def unapply(d: Def[_]): Nullable[Rep[Box]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[BoxElem[_]] && method.getName == "id" => + def unapply(d: Def[_]): Nullable[Ref[Box]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "id" && receiver.elem.isInstanceOf[BoxElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Box]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Box]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[Box]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[Box]] = unapply(exp.node) } object value { - def unapply(d: Def[_]): Nullable[Rep[Box]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[BoxElem[_]] && method.getName == "value" => + def unapply(d: Def[_]): Nullable[Ref[Box]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "value" && receiver.elem.isInstanceOf[BoxElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Box]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Box]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[Box]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[Box]] = unapply(exp.node) } object propositionBytes { - def unapply(d: Def[_]): Nullable[Rep[Box]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[BoxElem[_]] && method.getName == "propositionBytes" => + def unapply(d: Def[_]): Nullable[Ref[Box]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "propositionBytes" && receiver.elem.isInstanceOf[BoxElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Box]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Box]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[Box]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[Box]] = unapply(exp.node) } object bytes { - def unapply(d: Def[_]): Nullable[Rep[Box]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[BoxElem[_]] && method.getName == "bytes" => + def unapply(d: Def[_]): Nullable[Ref[Box]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "bytes" && receiver.elem.isInstanceOf[BoxElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Box]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Box]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[Box]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[Box]] = unapply(exp.node) } object bytesWithoutRef { - def unapply(d: Def[_]): Nullable[Rep[Box]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[BoxElem[_]] && method.getName == "bytesWithoutRef" => + def unapply(d: Def[_]): Nullable[Ref[Box]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "bytesWithoutRef" && receiver.elem.isInstanceOf[BoxElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Box]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Box]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[Box]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[Box]] = unapply(exp.node) } object registers { - def unapply(d: Def[_]): Nullable[Rep[Box]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[BoxElem[_]] && method.getName == "registers" => + def unapply(d: Def[_]): Nullable[Ref[Box]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "registers" && receiver.elem.isInstanceOf[BoxElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Box]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Box]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[Box]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[Box]] = unapply(exp.node) } object getReg { - def unapply(d: Def[_]): Nullable[(Rep[Box], Rep[Int], Elem[T]) forSome {type T}] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BoxElem[_]] && method.getName == "getReg" => + def unapply(d: Def[_]): Nullable[(Ref[Box], Ref[Int], Elem[T]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "getReg" && receiver.elem.isInstanceOf[BoxElem[_]] => val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[Box], Rep[Int], Elem[T]) forSome {type T}]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[Box], Rep[Int], Elem[T]) forSome {type T}] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[Box], Ref[Int], Elem[T]) forSome {type T}]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[Box], Ref[Int], Elem[T]) forSome {type T}] = unapply(exp.node) } object R0 { - def unapply(d: Def[_]): Nullable[(Rep[Box], Elem[T]) forSome {type T}] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BoxElem[_]] && method.getName == "R0" => + def unapply(d: Def[_]): Nullable[(Ref[Box], Elem[T]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "R0" && receiver.elem.isInstanceOf[BoxElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[Box], Elem[T]) forSome {type T}]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[Box], Elem[T]) forSome {type T}] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[Box], Elem[T]) forSome {type T}]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[Box], Elem[T]) forSome {type T}] = unapply(exp.node) } object R1 { - def unapply(d: Def[_]): Nullable[(Rep[Box], Elem[T]) forSome {type T}] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BoxElem[_]] && method.getName == "R1" => + def unapply(d: Def[_]): Nullable[(Ref[Box], Elem[T]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "R1" && receiver.elem.isInstanceOf[BoxElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[Box], Elem[T]) forSome {type T}]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[Box], Elem[T]) forSome {type T}] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[Box], Elem[T]) forSome {type T}]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[Box], Elem[T]) forSome {type T}] = unapply(exp.node) } object R2 { - def unapply(d: Def[_]): Nullable[(Rep[Box], Elem[T]) forSome {type T}] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BoxElem[_]] && method.getName == "R2" => + def unapply(d: Def[_]): Nullable[(Ref[Box], Elem[T]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "R2" && receiver.elem.isInstanceOf[BoxElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[Box], Elem[T]) forSome {type T}]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[Box], Elem[T]) forSome {type T}] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[Box], Elem[T]) forSome {type T}]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[Box], Elem[T]) forSome {type T}] = unapply(exp.node) } object R3 { - def unapply(d: Def[_]): Nullable[(Rep[Box], Elem[T]) forSome {type T}] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BoxElem[_]] && method.getName == "R3" => + def unapply(d: Def[_]): Nullable[(Ref[Box], Elem[T]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "R3" && receiver.elem.isInstanceOf[BoxElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[Box], Elem[T]) forSome {type T}]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[Box], Elem[T]) forSome {type T}] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[Box], Elem[T]) forSome {type T}]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[Box], Elem[T]) forSome {type T}] = unapply(exp.node) } object R4 { - def unapply(d: Def[_]): Nullable[(Rep[Box], Elem[T]) forSome {type T}] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BoxElem[_]] && method.getName == "R4" => + def unapply(d: Def[_]): Nullable[(Ref[Box], Elem[T]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "R4" && receiver.elem.isInstanceOf[BoxElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[Box], Elem[T]) forSome {type T}]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[Box], Elem[T]) forSome {type T}] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[Box], Elem[T]) forSome {type T}]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[Box], Elem[T]) forSome {type T}] = unapply(exp.node) } object R5 { - def unapply(d: Def[_]): Nullable[(Rep[Box], Elem[T]) forSome {type T}] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BoxElem[_]] && method.getName == "R5" => + def unapply(d: Def[_]): Nullable[(Ref[Box], Elem[T]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "R5" && receiver.elem.isInstanceOf[BoxElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[Box], Elem[T]) forSome {type T}]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[Box], Elem[T]) forSome {type T}] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[Box], Elem[T]) forSome {type T}]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[Box], Elem[T]) forSome {type T}] = unapply(exp.node) } object R6 { - def unapply(d: Def[_]): Nullable[(Rep[Box], Elem[T]) forSome {type T}] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BoxElem[_]] && method.getName == "R6" => + def unapply(d: Def[_]): Nullable[(Ref[Box], Elem[T]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "R6" && receiver.elem.isInstanceOf[BoxElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[Box], Elem[T]) forSome {type T}]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[Box], Elem[T]) forSome {type T}] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[Box], Elem[T]) forSome {type T}]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[Box], Elem[T]) forSome {type T}] = unapply(exp.node) } object R7 { - def unapply(d: Def[_]): Nullable[(Rep[Box], Elem[T]) forSome {type T}] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BoxElem[_]] && method.getName == "R7" => + def unapply(d: Def[_]): Nullable[(Ref[Box], Elem[T]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "R7" && receiver.elem.isInstanceOf[BoxElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[Box], Elem[T]) forSome {type T}]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[Box], Elem[T]) forSome {type T}] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[Box], Elem[T]) forSome {type T}]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[Box], Elem[T]) forSome {type T}] = unapply(exp.node) } object R8 { - def unapply(d: Def[_]): Nullable[(Rep[Box], Elem[T]) forSome {type T}] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BoxElem[_]] && method.getName == "R8" => + def unapply(d: Def[_]): Nullable[(Ref[Box], Elem[T]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "R8" && receiver.elem.isInstanceOf[BoxElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[Box], Elem[T]) forSome {type T}]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[Box], Elem[T]) forSome {type T}] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[Box], Elem[T]) forSome {type T}]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[Box], Elem[T]) forSome {type T}] = unapply(exp.node) } object R9 { - def unapply(d: Def[_]): Nullable[(Rep[Box], Elem[T]) forSome {type T}] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BoxElem[_]] && method.getName == "R9" => + def unapply(d: Def[_]): Nullable[(Ref[Box], Elem[T]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "R9" && receiver.elem.isInstanceOf[BoxElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[Box], Elem[T]) forSome {type T}]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[Box], Elem[T]) forSome {type T}] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[Box], Elem[T]) forSome {type T}]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[Box], Elem[T]) forSome {type T}] = unapply(exp.node) } object tokens { - def unapply(d: Def[_]): Nullable[Rep[Box]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[BoxElem[_]] && method.getName == "tokens" => + def unapply(d: Def[_]): Nullable[Ref[Box]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "tokens" && receiver.elem.isInstanceOf[BoxElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Box]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Box]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[Box]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[Box]] = unapply(exp.node) } object creationInfo { - def unapply(d: Def[_]): Nullable[Rep[Box]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[BoxElem[_]] && method.getName == "creationInfo" => + def unapply(d: Def[_]): Nullable[Ref[Box]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "creationInfo" && receiver.elem.isInstanceOf[BoxElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Box]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Box]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[Box]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[Box]] = unapply(exp.node) } object executeFromRegister { - def unapply(d: Def[_]): Nullable[(Rep[Box], Rep[Byte], Elem[T]) forSome {type T}] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BoxElem[_]] && method.getName == "executeFromRegister" => + def unapply(d: Def[_]): Nullable[(Ref[Box], Ref[Byte], Elem[T]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "executeFromRegister" && receiver.elem.isInstanceOf[BoxElem[_]] => val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[Box], Rep[Byte], Elem[T]) forSome {type T}]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[Box], Rep[Byte], Elem[T]) forSome {type T}] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[Box], Ref[Byte], Elem[T]) forSome {type T}]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[Box], Ref[Byte], Elem[T]) forSome {type T}] = unapply(exp.node) } } @@ -2366,118 +1918,118 @@ object AvlTree extends EntityObject("AvlTree") { type SAvlTree = special.sigma.AvlTree case class AvlTreeConst( constValue: SAvlTree - ) extends AvlTree with LiftedConst[SAvlTree, AvlTree] + ) extends LiftedConst[SAvlTree, AvlTree] with AvlTree with Def[AvlTree] with AvlTreeConstMethods { val liftable: Liftable[SAvlTree, AvlTree] = LiftableAvlTree - val selfType: Elem[AvlTree] = liftable.eW + val resultType: Elem[AvlTree] = liftable.eW } trait AvlTreeConstMethods extends AvlTree { thisConst: Def[_] => private val AvlTreeClass = classOf[AvlTree] - override def digest: Rep[Coll[Byte]] = { + override def digest: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(self, AvlTreeClass.getMethod("digest"), - List(), + WrappedArray.empty, true, false, element[Coll[Byte]])) } - override def enabledOperations: Rep[Byte] = { + override def enabledOperations: Ref[Byte] = { asRep[Byte](mkMethodCall(self, AvlTreeClass.getMethod("enabledOperations"), - List(), + WrappedArray.empty, true, false, element[Byte])) } - override def keyLength: Rep[Int] = { + override def keyLength: Ref[Int] = { asRep[Int](mkMethodCall(self, AvlTreeClass.getMethod("keyLength"), - List(), + WrappedArray.empty, true, false, element[Int])) } - override def valueLengthOpt: Rep[WOption[Int]] = { + override def valueLengthOpt: Ref[WOption[Int]] = { asRep[WOption[Int]](mkMethodCall(self, AvlTreeClass.getMethod("valueLengthOpt"), - List(), + WrappedArray.empty, true, false, element[WOption[Int]])) } - override def isInsertAllowed: Rep[Boolean] = { + override def isInsertAllowed: Ref[Boolean] = { asRep[Boolean](mkMethodCall(self, AvlTreeClass.getMethod("isInsertAllowed"), - List(), + WrappedArray.empty, true, false, element[Boolean])) } - override def isUpdateAllowed: Rep[Boolean] = { + override def isUpdateAllowed: Ref[Boolean] = { asRep[Boolean](mkMethodCall(self, AvlTreeClass.getMethod("isUpdateAllowed"), - List(), + WrappedArray.empty, true, false, element[Boolean])) } - override def isRemoveAllowed: Rep[Boolean] = { + override def isRemoveAllowed: Ref[Boolean] = { asRep[Boolean](mkMethodCall(self, AvlTreeClass.getMethod("isRemoveAllowed"), - List(), + WrappedArray.empty, true, false, element[Boolean])) } - override def updateDigest(newDigest: Rep[Coll[Byte]]): Rep[AvlTree] = { + override def updateDigest(newDigest: Ref[Coll[Byte]]): Ref[AvlTree] = { asRep[AvlTree](mkMethodCall(self, AvlTreeClass.getMethod("updateDigest", classOf[Sym]), - List(newDigest), + Array[AnyRef](newDigest), true, false, element[AvlTree])) } - override def updateOperations(newOperations: Rep[Byte]): Rep[AvlTree] = { + override def updateOperations(newOperations: Ref[Byte]): Ref[AvlTree] = { asRep[AvlTree](mkMethodCall(self, AvlTreeClass.getMethod("updateOperations", classOf[Sym]), - List(newOperations), + Array[AnyRef](newOperations), true, false, element[AvlTree])) } - override def contains(key: Rep[Coll[Byte]], proof: Rep[Coll[Byte]]): Rep[Boolean] = { + override def contains(key: Ref[Coll[Byte]], proof: Ref[Coll[Byte]]): Ref[Boolean] = { asRep[Boolean](mkMethodCall(self, AvlTreeClass.getMethod("contains", classOf[Sym], classOf[Sym]), - List(key, proof), + Array[AnyRef](key, proof), true, false, element[Boolean])) } - override def get(key: Rep[Coll[Byte]], proof: Rep[Coll[Byte]]): Rep[WOption[Coll[Byte]]] = { + override def get(key: Ref[Coll[Byte]], proof: Ref[Coll[Byte]]): Ref[WOption[Coll[Byte]]] = { asRep[WOption[Coll[Byte]]](mkMethodCall(self, AvlTreeClass.getMethod("get", classOf[Sym], classOf[Sym]), - List(key, proof), + Array[AnyRef](key, proof), true, false, element[WOption[Coll[Byte]]])) } - override def getMany(keys: Rep[Coll[Coll[Byte]]], proof: Rep[Coll[Byte]]): Rep[Coll[WOption[Coll[Byte]]]] = { + override def getMany(keys: Ref[Coll[Coll[Byte]]], proof: Ref[Coll[Byte]]): Ref[Coll[WOption[Coll[Byte]]]] = { asRep[Coll[WOption[Coll[Byte]]]](mkMethodCall(self, AvlTreeClass.getMethod("getMany", classOf[Sym], classOf[Sym]), - List(keys, proof), + Array[AnyRef](keys, proof), true, false, element[Coll[WOption[Coll[Byte]]]])) } - override def insert(operations: Rep[Coll[(Coll[Byte], Coll[Byte])]], proof: Rep[Coll[Byte]]): Rep[WOption[AvlTree]] = { + override def insert(operations: Ref[Coll[(Coll[Byte], Coll[Byte])]], proof: Ref[Coll[Byte]]): Ref[WOption[AvlTree]] = { asRep[WOption[AvlTree]](mkMethodCall(self, AvlTreeClass.getMethod("insert", classOf[Sym], classOf[Sym]), - List(operations, proof), + Array[AnyRef](operations, proof), true, false, element[WOption[AvlTree]])) } - override def update(operations: Rep[Coll[(Coll[Byte], Coll[Byte])]], proof: Rep[Coll[Byte]]): Rep[WOption[AvlTree]] = { + override def update(operations: Ref[Coll[(Coll[Byte], Coll[Byte])]], proof: Ref[Coll[Byte]]): Ref[WOption[AvlTree]] = { asRep[WOption[AvlTree]](mkMethodCall(self, AvlTreeClass.getMethod("update", classOf[Sym], classOf[Sym]), - List(operations, proof), + Array[AnyRef](operations, proof), true, false, element[WOption[AvlTree]])) } - override def remove(operations: Rep[Coll[Coll[Byte]]], proof: Rep[Coll[Byte]]): Rep[WOption[AvlTree]] = { + override def remove(operations: Ref[Coll[Coll[Byte]]], proof: Ref[Coll[Byte]]): Ref[WOption[AvlTree]] = { asRep[WOption[AvlTree]](mkMethodCall(self, AvlTreeClass.getMethod("remove", classOf[Sym], classOf[Sym]), - List(operations, proof), + Array[AnyRef](operations, proof), true, false, element[WOption[AvlTree]])) } } @@ -2488,130 +2040,132 @@ object AvlTree extends EntityObject("AvlTree") { lazy val sourceType: RType[SAvlTree] = { RType[SAvlTree] } - def lift(x: SAvlTree): Rep[AvlTree] = AvlTreeConst(x) - def unlift(w: Rep[AvlTree]): SAvlTree = w match { + def lift(x: SAvlTree): Ref[AvlTree] = AvlTreeConst(x) + def unlift(w: Ref[AvlTree]): SAvlTree = w match { case Def(AvlTreeConst(x: SAvlTree)) => x.asInstanceOf[SAvlTree] case _ => unliftError(w) } } + private val AvlTreeClass = classOf[AvlTree] + // entityAdapter for AvlTree trait - case class AvlTreeAdapter(source: Rep[AvlTree]) - extends AvlTree with Def[AvlTree] { - val selfType: Elem[AvlTree] = element[AvlTree] + case class AvlTreeAdapter(source: Ref[AvlTree]) + extends Node with AvlTree + with Def[AvlTree] { + val resultType: Elem[AvlTree] = element[AvlTree] override def transform(t: Transformer) = AvlTreeAdapter(t(source)) - private val thisClass = classOf[AvlTree] - def digest: Rep[Coll[Byte]] = { + def digest: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(source, - thisClass.getMethod("digest"), - List(), + AvlTreeClass.getMethod("digest"), + WrappedArray.empty, true, true, element[Coll[Byte]])) } - def enabledOperations: Rep[Byte] = { + def enabledOperations: Ref[Byte] = { asRep[Byte](mkMethodCall(source, - thisClass.getMethod("enabledOperations"), - List(), + AvlTreeClass.getMethod("enabledOperations"), + WrappedArray.empty, true, true, element[Byte])) } - def keyLength: Rep[Int] = { + def keyLength: Ref[Int] = { asRep[Int](mkMethodCall(source, - thisClass.getMethod("keyLength"), - List(), + AvlTreeClass.getMethod("keyLength"), + WrappedArray.empty, true, true, element[Int])) } - def valueLengthOpt: Rep[WOption[Int]] = { + def valueLengthOpt: Ref[WOption[Int]] = { asRep[WOption[Int]](mkMethodCall(source, - thisClass.getMethod("valueLengthOpt"), - List(), + AvlTreeClass.getMethod("valueLengthOpt"), + WrappedArray.empty, true, true, element[WOption[Int]])) } - def isInsertAllowed: Rep[Boolean] = { + def isInsertAllowed: Ref[Boolean] = { asRep[Boolean](mkMethodCall(source, - thisClass.getMethod("isInsertAllowed"), - List(), + AvlTreeClass.getMethod("isInsertAllowed"), + WrappedArray.empty, true, true, element[Boolean])) } - def isUpdateAllowed: Rep[Boolean] = { + def isUpdateAllowed: Ref[Boolean] = { asRep[Boolean](mkMethodCall(source, - thisClass.getMethod("isUpdateAllowed"), - List(), + AvlTreeClass.getMethod("isUpdateAllowed"), + WrappedArray.empty, true, true, element[Boolean])) } - def isRemoveAllowed: Rep[Boolean] = { + def isRemoveAllowed: Ref[Boolean] = { asRep[Boolean](mkMethodCall(source, - thisClass.getMethod("isRemoveAllowed"), - List(), + AvlTreeClass.getMethod("isRemoveAllowed"), + WrappedArray.empty, true, true, element[Boolean])) } - def updateDigest(newDigest: Rep[Coll[Byte]]): Rep[AvlTree] = { + def updateDigest(newDigest: Ref[Coll[Byte]]): Ref[AvlTree] = { asRep[AvlTree](mkMethodCall(source, - thisClass.getMethod("updateDigest", classOf[Sym]), - List(newDigest), + AvlTreeClass.getMethod("updateDigest", classOf[Sym]), + Array[AnyRef](newDigest), true, true, element[AvlTree])) } - def updateOperations(newOperations: Rep[Byte]): Rep[AvlTree] = { + def updateOperations(newOperations: Ref[Byte]): Ref[AvlTree] = { asRep[AvlTree](mkMethodCall(source, - thisClass.getMethod("updateOperations", classOf[Sym]), - List(newOperations), + AvlTreeClass.getMethod("updateOperations", classOf[Sym]), + Array[AnyRef](newOperations), true, true, element[AvlTree])) } - def contains(key: Rep[Coll[Byte]], proof: Rep[Coll[Byte]]): Rep[Boolean] = { + def contains(key: Ref[Coll[Byte]], proof: Ref[Coll[Byte]]): Ref[Boolean] = { asRep[Boolean](mkMethodCall(source, - thisClass.getMethod("contains", classOf[Sym], classOf[Sym]), - List(key, proof), + AvlTreeClass.getMethod("contains", classOf[Sym], classOf[Sym]), + Array[AnyRef](key, proof), true, true, element[Boolean])) } - def get(key: Rep[Coll[Byte]], proof: Rep[Coll[Byte]]): Rep[WOption[Coll[Byte]]] = { + def get(key: Ref[Coll[Byte]], proof: Ref[Coll[Byte]]): Ref[WOption[Coll[Byte]]] = { asRep[WOption[Coll[Byte]]](mkMethodCall(source, - thisClass.getMethod("get", classOf[Sym], classOf[Sym]), - List(key, proof), + AvlTreeClass.getMethod("get", classOf[Sym], classOf[Sym]), + Array[AnyRef](key, proof), true, true, element[WOption[Coll[Byte]]])) } - def getMany(keys: Rep[Coll[Coll[Byte]]], proof: Rep[Coll[Byte]]): Rep[Coll[WOption[Coll[Byte]]]] = { + def getMany(keys: Ref[Coll[Coll[Byte]]], proof: Ref[Coll[Byte]]): Ref[Coll[WOption[Coll[Byte]]]] = { asRep[Coll[WOption[Coll[Byte]]]](mkMethodCall(source, - thisClass.getMethod("getMany", classOf[Sym], classOf[Sym]), - List(keys, proof), + AvlTreeClass.getMethod("getMany", classOf[Sym], classOf[Sym]), + Array[AnyRef](keys, proof), true, true, element[Coll[WOption[Coll[Byte]]]])) } - def insert(operations: Rep[Coll[(Coll[Byte], Coll[Byte])]], proof: Rep[Coll[Byte]]): Rep[WOption[AvlTree]] = { + def insert(operations: Ref[Coll[(Coll[Byte], Coll[Byte])]], proof: Ref[Coll[Byte]]): Ref[WOption[AvlTree]] = { asRep[WOption[AvlTree]](mkMethodCall(source, - thisClass.getMethod("insert", classOf[Sym], classOf[Sym]), - List(operations, proof), + AvlTreeClass.getMethod("insert", classOf[Sym], classOf[Sym]), + Array[AnyRef](operations, proof), true, true, element[WOption[AvlTree]])) } - def update(operations: Rep[Coll[(Coll[Byte], Coll[Byte])]], proof: Rep[Coll[Byte]]): Rep[WOption[AvlTree]] = { + def update(operations: Ref[Coll[(Coll[Byte], Coll[Byte])]], proof: Ref[Coll[Byte]]): Ref[WOption[AvlTree]] = { asRep[WOption[AvlTree]](mkMethodCall(source, - thisClass.getMethod("update", classOf[Sym], classOf[Sym]), - List(operations, proof), + AvlTreeClass.getMethod("update", classOf[Sym], classOf[Sym]), + Array[AnyRef](operations, proof), true, true, element[WOption[AvlTree]])) } - def remove(operations: Rep[Coll[Coll[Byte]]], proof: Rep[Coll[Byte]]): Rep[WOption[AvlTree]] = { + def remove(operations: Ref[Coll[Coll[Byte]]], proof: Ref[Coll[Byte]]): Ref[WOption[AvlTree]] = { asRep[WOption[AvlTree]](mkMethodCall(source, - thisClass.getMethod("remove", classOf[Sym], classOf[Sym]), - List(operations, proof), + AvlTreeClass.getMethod("remove", classOf[Sym], classOf[Sym]), + Array[AnyRef](operations, proof), true, true, element[WOption[AvlTree]])) } } - // entityProxy: single proxy for each type family - implicit def proxyAvlTree(p: Rep[AvlTree]): AvlTree = { - if (p.rhs.isInstanceOf[AvlTree@unchecked]) p.rhs.asInstanceOf[AvlTree] + // entityUnref: single unref method for each type family + implicit final def unrefAvlTree(p: Ref[AvlTree]): AvlTree = { + if (p.node.isInstanceOf[AvlTree]) p.node.asInstanceOf[AvlTree] else AvlTreeAdapter(p) } @@ -2619,7 +2173,7 @@ object AvlTree extends EntityObject("AvlTree") { // familyElem class AvlTreeElem[To <: AvlTree] extends EntityElem[To] { - override val liftable: Liftables.Liftable[_, To] = LiftableAvlTree.asLiftable[SAvlTree, To] + override val liftable: Liftables.Liftable[_, To] = asLiftable[SAvlTree, To](LiftableAvlTree) override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { super.collectMethods ++ @@ -2627,244 +2181,23 @@ object AvlTree extends EntityObject("AvlTree") { "digest", "enabledOperations", "keyLength", "valueLengthOpt", "isInsertAllowed", "isUpdateAllowed", "isRemoveAllowed", "updateDigest", "updateOperations", "contains", "get", "getMany", "insert", "update", "remove" )) } - - lazy val parent: Option[Elem[_]] = None - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override lazy val tag = { - weakTypeTag[AvlTree].asInstanceOf[WeakTypeTag[To]] - } - override def convert(x: Rep[Def[_]]) = { - val conv = fun {x: Rep[AvlTree] => convertAvlTree(x) } - tryConvert(element[AvlTree], this, x, conv) - } - - def convertAvlTree(x: Rep[AvlTree]): Rep[To] = { - x.elem match { - case _: AvlTreeElem[_] => asRep[To](x) - case e => !!!(s"Expected $x to have AvlTreeElem[_], but got $e", x) - } - } - override def getDefaultRep: Rep[To] = ??? } implicit lazy val avlTreeElement: Elem[AvlTree] = new AvlTreeElem[AvlTree] - implicit case object AvlTreeCompanionElem extends CompanionElem[AvlTreeCompanionCtor] { - lazy val tag = weakTypeTag[AvlTreeCompanionCtor] - protected def getDefaultRep = RAvlTree - } + implicit case object AvlTreeCompanionElem extends CompanionElem[AvlTreeCompanionCtor] abstract class AvlTreeCompanionCtor extends CompanionDef[AvlTreeCompanionCtor] with AvlTreeCompanion { - def selfType = AvlTreeCompanionElem + def resultType = AvlTreeCompanionElem override def toString = "AvlTree" } - implicit def proxyAvlTreeCompanionCtor(p: Rep[AvlTreeCompanionCtor]): AvlTreeCompanionCtor = - proxyOps[AvlTreeCompanionCtor](p) + implicit final def unrefAvlTreeCompanionCtor(p: Ref[AvlTreeCompanionCtor]): AvlTreeCompanionCtor = + p.node.asInstanceOf[AvlTreeCompanionCtor] - lazy val RAvlTree: Rep[AvlTreeCompanionCtor] = new AvlTreeCompanionCtor { + lazy val RAvlTree: MutableLazy[AvlTreeCompanionCtor] = MutableLazy(new AvlTreeCompanionCtor { private val thisClass = classOf[AvlTreeCompanion] - } - - object AvlTreeMethods { - object digest { - def unapply(d: Def[_]): Nullable[Rep[AvlTree]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[AvlTreeElem[_]] && method.getName == "digest" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[AvlTree]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[AvlTree]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object enabledOperations { - def unapply(d: Def[_]): Nullable[Rep[AvlTree]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[AvlTreeElem[_]] && method.getName == "enabledOperations" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[AvlTree]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[AvlTree]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object keyLength { - def unapply(d: Def[_]): Nullable[Rep[AvlTree]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[AvlTreeElem[_]] && method.getName == "keyLength" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[AvlTree]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[AvlTree]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object valueLengthOpt { - def unapply(d: Def[_]): Nullable[Rep[AvlTree]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[AvlTreeElem[_]] && method.getName == "valueLengthOpt" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[AvlTree]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[AvlTree]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object isInsertAllowed { - def unapply(d: Def[_]): Nullable[Rep[AvlTree]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[AvlTreeElem[_]] && method.getName == "isInsertAllowed" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[AvlTree]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[AvlTree]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object isUpdateAllowed { - def unapply(d: Def[_]): Nullable[Rep[AvlTree]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[AvlTreeElem[_]] && method.getName == "isUpdateAllowed" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[AvlTree]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[AvlTree]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object isRemoveAllowed { - def unapply(d: Def[_]): Nullable[Rep[AvlTree]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[AvlTreeElem[_]] && method.getName == "isRemoveAllowed" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[AvlTree]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[AvlTree]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object updateDigest { - def unapply(d: Def[_]): Nullable[(Rep[AvlTree], Rep[Coll[Byte]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[AvlTreeElem[_]] && method.getName == "updateDigest" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[AvlTree], Rep[Coll[Byte]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[AvlTree], Rep[Coll[Byte]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object updateOperations { - def unapply(d: Def[_]): Nullable[(Rep[AvlTree], Rep[Byte])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[AvlTreeElem[_]] && method.getName == "updateOperations" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[AvlTree], Rep[Byte])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[AvlTree], Rep[Byte])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object contains { - def unapply(d: Def[_]): Nullable[(Rep[AvlTree], Rep[Coll[Byte]], Rep[Coll[Byte]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[AvlTreeElem[_]] && method.getName == "contains" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[AvlTree], Rep[Coll[Byte]], Rep[Coll[Byte]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[AvlTree], Rep[Coll[Byte]], Rep[Coll[Byte]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object get { - def unapply(d: Def[_]): Nullable[(Rep[AvlTree], Rep[Coll[Byte]], Rep[Coll[Byte]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[AvlTreeElem[_]] && method.getName == "get" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[AvlTree], Rep[Coll[Byte]], Rep[Coll[Byte]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[AvlTree], Rep[Coll[Byte]], Rep[Coll[Byte]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object getMany { - def unapply(d: Def[_]): Nullable[(Rep[AvlTree], Rep[Coll[Coll[Byte]]], Rep[Coll[Byte]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[AvlTreeElem[_]] && method.getName == "getMany" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[AvlTree], Rep[Coll[Coll[Byte]]], Rep[Coll[Byte]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[AvlTree], Rep[Coll[Coll[Byte]]], Rep[Coll[Byte]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object insert { - def unapply(d: Def[_]): Nullable[(Rep[AvlTree], Rep[Coll[(Coll[Byte], Coll[Byte])]], Rep[Coll[Byte]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[AvlTreeElem[_]] && method.getName == "insert" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[AvlTree], Rep[Coll[(Coll[Byte], Coll[Byte])]], Rep[Coll[Byte]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[AvlTree], Rep[Coll[(Coll[Byte], Coll[Byte])]], Rep[Coll[Byte]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object update { - def unapply(d: Def[_]): Nullable[(Rep[AvlTree], Rep[Coll[(Coll[Byte], Coll[Byte])]], Rep[Coll[Byte]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[AvlTreeElem[_]] && method.getName == "update" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[AvlTree], Rep[Coll[(Coll[Byte], Coll[Byte])]], Rep[Coll[Byte]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[AvlTree], Rep[Coll[(Coll[Byte], Coll[Byte])]], Rep[Coll[Byte]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object remove { - def unapply(d: Def[_]): Nullable[(Rep[AvlTree], Rep[Coll[Coll[Byte]]], Rep[Coll[Byte]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[AvlTreeElem[_]] && method.getName == "remove" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[AvlTree], Rep[Coll[Coll[Byte]]], Rep[Coll[Byte]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[AvlTree], Rep[Coll[Coll[Byte]]], Rep[Coll[Byte]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - } - - object AvlTreeCompanionMethods { - } + }) } // of object AvlTree registerEntityObject("AvlTree", AvlTree) @@ -2875,62 +2208,62 @@ object PreHeader extends EntityObject("PreHeader") { type SPreHeader = special.sigma.PreHeader case class PreHeaderConst( constValue: SPreHeader - ) extends PreHeader with LiftedConst[SPreHeader, PreHeader] + ) extends LiftedConst[SPreHeader, PreHeader] with PreHeader with Def[PreHeader] with PreHeaderConstMethods { val liftable: Liftable[SPreHeader, PreHeader] = LiftablePreHeader - val selfType: Elem[PreHeader] = liftable.eW + val resultType: Elem[PreHeader] = liftable.eW } trait PreHeaderConstMethods extends PreHeader { thisConst: Def[_] => private val PreHeaderClass = classOf[PreHeader] - override def version: Rep[Byte] = { + override def version: Ref[Byte] = { asRep[Byte](mkMethodCall(self, PreHeaderClass.getMethod("version"), - List(), + WrappedArray.empty, true, false, element[Byte])) } - override def parentId: Rep[Coll[Byte]] = { + override def parentId: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(self, PreHeaderClass.getMethod("parentId"), - List(), + WrappedArray.empty, true, false, element[Coll[Byte]])) } - override def timestamp: Rep[Long] = { + override def timestamp: Ref[Long] = { asRep[Long](mkMethodCall(self, PreHeaderClass.getMethod("timestamp"), - List(), + WrappedArray.empty, true, false, element[Long])) } - override def nBits: Rep[Long] = { + override def nBits: Ref[Long] = { asRep[Long](mkMethodCall(self, PreHeaderClass.getMethod("nBits"), - List(), + WrappedArray.empty, true, false, element[Long])) } - override def height: Rep[Int] = { + override def height: Ref[Int] = { asRep[Int](mkMethodCall(self, PreHeaderClass.getMethod("height"), - List(), + WrappedArray.empty, true, false, element[Int])) } - override def minerPk: Rep[GroupElement] = { + override def minerPk: Ref[GroupElement] = { asRep[GroupElement](mkMethodCall(self, PreHeaderClass.getMethod("minerPk"), - List(), + WrappedArray.empty, true, false, element[GroupElement])) } - override def votes: Rep[Coll[Byte]] = { + override def votes: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(self, PreHeaderClass.getMethod("votes"), - List(), + WrappedArray.empty, true, false, element[Coll[Byte]])) } } @@ -2941,74 +2274,76 @@ object PreHeader extends EntityObject("PreHeader") { lazy val sourceType: RType[SPreHeader] = { RType[SPreHeader] } - def lift(x: SPreHeader): Rep[PreHeader] = PreHeaderConst(x) - def unlift(w: Rep[PreHeader]): SPreHeader = w match { + def lift(x: SPreHeader): Ref[PreHeader] = PreHeaderConst(x) + def unlift(w: Ref[PreHeader]): SPreHeader = w match { case Def(PreHeaderConst(x: SPreHeader)) => x.asInstanceOf[SPreHeader] case _ => unliftError(w) } } + private val PreHeaderClass = classOf[PreHeader] + // entityAdapter for PreHeader trait - case class PreHeaderAdapter(source: Rep[PreHeader]) - extends PreHeader with Def[PreHeader] { - val selfType: Elem[PreHeader] = element[PreHeader] + case class PreHeaderAdapter(source: Ref[PreHeader]) + extends Node with PreHeader + with Def[PreHeader] { + val resultType: Elem[PreHeader] = element[PreHeader] override def transform(t: Transformer) = PreHeaderAdapter(t(source)) - private val thisClass = classOf[PreHeader] - def version: Rep[Byte] = { + def version: Ref[Byte] = { asRep[Byte](mkMethodCall(source, - thisClass.getMethod("version"), - List(), + PreHeaderClass.getMethod("version"), + WrappedArray.empty, true, true, element[Byte])) } - def parentId: Rep[Coll[Byte]] = { + def parentId: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(source, - thisClass.getMethod("parentId"), - List(), + PreHeaderClass.getMethod("parentId"), + WrappedArray.empty, true, true, element[Coll[Byte]])) } - def timestamp: Rep[Long] = { + def timestamp: Ref[Long] = { asRep[Long](mkMethodCall(source, - thisClass.getMethod("timestamp"), - List(), + PreHeaderClass.getMethod("timestamp"), + WrappedArray.empty, true, true, element[Long])) } - def nBits: Rep[Long] = { + def nBits: Ref[Long] = { asRep[Long](mkMethodCall(source, - thisClass.getMethod("nBits"), - List(), + PreHeaderClass.getMethod("nBits"), + WrappedArray.empty, true, true, element[Long])) } - def height: Rep[Int] = { + def height: Ref[Int] = { asRep[Int](mkMethodCall(source, - thisClass.getMethod("height"), - List(), + PreHeaderClass.getMethod("height"), + WrappedArray.empty, true, true, element[Int])) } - def minerPk: Rep[GroupElement] = { + def minerPk: Ref[GroupElement] = { asRep[GroupElement](mkMethodCall(source, - thisClass.getMethod("minerPk"), - List(), + PreHeaderClass.getMethod("minerPk"), + WrappedArray.empty, true, true, element[GroupElement])) } - def votes: Rep[Coll[Byte]] = { + def votes: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(source, - thisClass.getMethod("votes"), - List(), + PreHeaderClass.getMethod("votes"), + WrappedArray.empty, true, true, element[Coll[Byte]])) } } - // entityProxy: single proxy for each type family - implicit def proxyPreHeader(p: Rep[PreHeader]): PreHeader = { - if (p.rhs.isInstanceOf[PreHeader@unchecked]) p.rhs.asInstanceOf[PreHeader] + // entityUnref: single unref method for each type family + implicit final def unrefPreHeader(p: Ref[PreHeader]): PreHeader = { + if (p.node.isInstanceOf[PreHeader]) p.node.asInstanceOf[PreHeader] else PreHeaderAdapter(p) } @@ -3016,7 +2351,7 @@ object PreHeader extends EntityObject("PreHeader") { // familyElem class PreHeaderElem[To <: PreHeader] extends EntityElem[To] { - override val liftable: Liftables.Liftable[_, To] = LiftablePreHeader.asLiftable[SPreHeader, To] + override val liftable: Liftables.Liftable[_, To] = asLiftable[SPreHeader, To](LiftablePreHeader) override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { super.collectMethods ++ @@ -3024,140 +2359,23 @@ object PreHeader extends EntityObject("PreHeader") { "version", "parentId", "timestamp", "nBits", "height", "minerPk", "votes" )) } - - lazy val parent: Option[Elem[_]] = None - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override lazy val tag = { - weakTypeTag[PreHeader].asInstanceOf[WeakTypeTag[To]] - } - override def convert(x: Rep[Def[_]]) = { - val conv = fun {x: Rep[PreHeader] => convertPreHeader(x) } - tryConvert(element[PreHeader], this, x, conv) - } - - def convertPreHeader(x: Rep[PreHeader]): Rep[To] = { - x.elem match { - case _: PreHeaderElem[_] => asRep[To](x) - case e => !!!(s"Expected $x to have PreHeaderElem[_], but got $e", x) - } - } - override def getDefaultRep: Rep[To] = ??? } implicit lazy val preHeaderElement: Elem[PreHeader] = new PreHeaderElem[PreHeader] - implicit case object PreHeaderCompanionElem extends CompanionElem[PreHeaderCompanionCtor] { - lazy val tag = weakTypeTag[PreHeaderCompanionCtor] - protected def getDefaultRep = RPreHeader - } + implicit case object PreHeaderCompanionElem extends CompanionElem[PreHeaderCompanionCtor] abstract class PreHeaderCompanionCtor extends CompanionDef[PreHeaderCompanionCtor] with PreHeaderCompanion { - def selfType = PreHeaderCompanionElem + def resultType = PreHeaderCompanionElem override def toString = "PreHeader" } - implicit def proxyPreHeaderCompanionCtor(p: Rep[PreHeaderCompanionCtor]): PreHeaderCompanionCtor = - proxyOps[PreHeaderCompanionCtor](p) + implicit final def unrefPreHeaderCompanionCtor(p: Ref[PreHeaderCompanionCtor]): PreHeaderCompanionCtor = + p.node.asInstanceOf[PreHeaderCompanionCtor] - lazy val RPreHeader: Rep[PreHeaderCompanionCtor] = new PreHeaderCompanionCtor { + lazy val RPreHeader: MutableLazy[PreHeaderCompanionCtor] = MutableLazy(new PreHeaderCompanionCtor { private val thisClass = classOf[PreHeaderCompanion] - } - - object PreHeaderMethods { - object version { - def unapply(d: Def[_]): Nullable[Rep[PreHeader]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[PreHeaderElem[_]] && method.getName == "version" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[PreHeader]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[PreHeader]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object parentId { - def unapply(d: Def[_]): Nullable[Rep[PreHeader]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[PreHeaderElem[_]] && method.getName == "parentId" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[PreHeader]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[PreHeader]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object timestamp { - def unapply(d: Def[_]): Nullable[Rep[PreHeader]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[PreHeaderElem[_]] && method.getName == "timestamp" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[PreHeader]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[PreHeader]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object nBits { - def unapply(d: Def[_]): Nullable[Rep[PreHeader]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[PreHeaderElem[_]] && method.getName == "nBits" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[PreHeader]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[PreHeader]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object height { - def unapply(d: Def[_]): Nullable[Rep[PreHeader]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[PreHeaderElem[_]] && method.getName == "height" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[PreHeader]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[PreHeader]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object minerPk { - def unapply(d: Def[_]): Nullable[Rep[PreHeader]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[PreHeaderElem[_]] && method.getName == "minerPk" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[PreHeader]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[PreHeader]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object votes { - def unapply(d: Def[_]): Nullable[Rep[PreHeader]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[PreHeaderElem[_]] && method.getName == "votes" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[PreHeader]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[PreHeader]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - } - - object PreHeaderCompanionMethods { - } + }) } // of object PreHeader registerEntityObject("PreHeader", PreHeader) @@ -3168,118 +2386,118 @@ object Header extends EntityObject("Header") { type SHeader = special.sigma.Header case class HeaderConst( constValue: SHeader - ) extends Header with LiftedConst[SHeader, Header] + ) extends LiftedConst[SHeader, Header] with Header with Def[Header] with HeaderConstMethods { val liftable: Liftable[SHeader, Header] = LiftableHeader - val selfType: Elem[Header] = liftable.eW + val resultType: Elem[Header] = liftable.eW } trait HeaderConstMethods extends Header { thisConst: Def[_] => private val HeaderClass = classOf[Header] - override def id: Rep[Coll[Byte]] = { + override def id: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(self, HeaderClass.getMethod("id"), - List(), + WrappedArray.empty, true, false, element[Coll[Byte]])) } - override def version: Rep[Byte] = { + override def version: Ref[Byte] = { asRep[Byte](mkMethodCall(self, HeaderClass.getMethod("version"), - List(), + WrappedArray.empty, true, false, element[Byte])) } - override def parentId: Rep[Coll[Byte]] = { + override def parentId: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(self, HeaderClass.getMethod("parentId"), - List(), + WrappedArray.empty, true, false, element[Coll[Byte]])) } - override def ADProofsRoot: Rep[Coll[Byte]] = { + override def ADProofsRoot: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(self, HeaderClass.getMethod("ADProofsRoot"), - List(), + WrappedArray.empty, true, false, element[Coll[Byte]])) } - override def stateRoot: Rep[AvlTree] = { + override def stateRoot: Ref[AvlTree] = { asRep[AvlTree](mkMethodCall(self, HeaderClass.getMethod("stateRoot"), - List(), + WrappedArray.empty, true, false, element[AvlTree])) } - override def transactionsRoot: Rep[Coll[Byte]] = { + override def transactionsRoot: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(self, HeaderClass.getMethod("transactionsRoot"), - List(), + WrappedArray.empty, true, false, element[Coll[Byte]])) } - override def timestamp: Rep[Long] = { + override def timestamp: Ref[Long] = { asRep[Long](mkMethodCall(self, HeaderClass.getMethod("timestamp"), - List(), + WrappedArray.empty, true, false, element[Long])) } - override def nBits: Rep[Long] = { + override def nBits: Ref[Long] = { asRep[Long](mkMethodCall(self, HeaderClass.getMethod("nBits"), - List(), + WrappedArray.empty, true, false, element[Long])) } - override def height: Rep[Int] = { + override def height: Ref[Int] = { asRep[Int](mkMethodCall(self, HeaderClass.getMethod("height"), - List(), + WrappedArray.empty, true, false, element[Int])) } - override def extensionRoot: Rep[Coll[Byte]] = { + override def extensionRoot: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(self, HeaderClass.getMethod("extensionRoot"), - List(), + WrappedArray.empty, true, false, element[Coll[Byte]])) } - override def minerPk: Rep[GroupElement] = { + override def minerPk: Ref[GroupElement] = { asRep[GroupElement](mkMethodCall(self, HeaderClass.getMethod("minerPk"), - List(), + WrappedArray.empty, true, false, element[GroupElement])) } - override def powOnetimePk: Rep[GroupElement] = { + override def powOnetimePk: Ref[GroupElement] = { asRep[GroupElement](mkMethodCall(self, HeaderClass.getMethod("powOnetimePk"), - List(), + WrappedArray.empty, true, false, element[GroupElement])) } - override def powNonce: Rep[Coll[Byte]] = { + override def powNonce: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(self, HeaderClass.getMethod("powNonce"), - List(), + WrappedArray.empty, true, false, element[Coll[Byte]])) } - override def powDistance: Rep[BigInt] = { + override def powDistance: Ref[BigInt] = { asRep[BigInt](mkMethodCall(self, HeaderClass.getMethod("powDistance"), - List(), + WrappedArray.empty, true, false, element[BigInt])) } - override def votes: Rep[Coll[Byte]] = { + override def votes: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(self, HeaderClass.getMethod("votes"), - List(), + WrappedArray.empty, true, false, element[Coll[Byte]])) } } @@ -3290,130 +2508,132 @@ object Header extends EntityObject("Header") { lazy val sourceType: RType[SHeader] = { RType[SHeader] } - def lift(x: SHeader): Rep[Header] = HeaderConst(x) - def unlift(w: Rep[Header]): SHeader = w match { + def lift(x: SHeader): Ref[Header] = HeaderConst(x) + def unlift(w: Ref[Header]): SHeader = w match { case Def(HeaderConst(x: SHeader)) => x.asInstanceOf[SHeader] case _ => unliftError(w) } } + private val HeaderClass = classOf[Header] + // entityAdapter for Header trait - case class HeaderAdapter(source: Rep[Header]) - extends Header with Def[Header] { - val selfType: Elem[Header] = element[Header] + case class HeaderAdapter(source: Ref[Header]) + extends Node with Header + with Def[Header] { + val resultType: Elem[Header] = element[Header] override def transform(t: Transformer) = HeaderAdapter(t(source)) - private val thisClass = classOf[Header] - def id: Rep[Coll[Byte]] = { + def id: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(source, - thisClass.getMethod("id"), - List(), + HeaderClass.getMethod("id"), + WrappedArray.empty, true, true, element[Coll[Byte]])) } - def version: Rep[Byte] = { + def version: Ref[Byte] = { asRep[Byte](mkMethodCall(source, - thisClass.getMethod("version"), - List(), + HeaderClass.getMethod("version"), + WrappedArray.empty, true, true, element[Byte])) } - def parentId: Rep[Coll[Byte]] = { + def parentId: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(source, - thisClass.getMethod("parentId"), - List(), + HeaderClass.getMethod("parentId"), + WrappedArray.empty, true, true, element[Coll[Byte]])) } - def ADProofsRoot: Rep[Coll[Byte]] = { + def ADProofsRoot: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(source, - thisClass.getMethod("ADProofsRoot"), - List(), + HeaderClass.getMethod("ADProofsRoot"), + WrappedArray.empty, true, true, element[Coll[Byte]])) } - def stateRoot: Rep[AvlTree] = { + def stateRoot: Ref[AvlTree] = { asRep[AvlTree](mkMethodCall(source, - thisClass.getMethod("stateRoot"), - List(), + HeaderClass.getMethod("stateRoot"), + WrappedArray.empty, true, true, element[AvlTree])) } - def transactionsRoot: Rep[Coll[Byte]] = { + def transactionsRoot: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(source, - thisClass.getMethod("transactionsRoot"), - List(), + HeaderClass.getMethod("transactionsRoot"), + WrappedArray.empty, true, true, element[Coll[Byte]])) } - def timestamp: Rep[Long] = { + def timestamp: Ref[Long] = { asRep[Long](mkMethodCall(source, - thisClass.getMethod("timestamp"), - List(), + HeaderClass.getMethod("timestamp"), + WrappedArray.empty, true, true, element[Long])) } - def nBits: Rep[Long] = { + def nBits: Ref[Long] = { asRep[Long](mkMethodCall(source, - thisClass.getMethod("nBits"), - List(), + HeaderClass.getMethod("nBits"), + WrappedArray.empty, true, true, element[Long])) } - def height: Rep[Int] = { + def height: Ref[Int] = { asRep[Int](mkMethodCall(source, - thisClass.getMethod("height"), - List(), + HeaderClass.getMethod("height"), + WrappedArray.empty, true, true, element[Int])) } - def extensionRoot: Rep[Coll[Byte]] = { + def extensionRoot: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(source, - thisClass.getMethod("extensionRoot"), - List(), + HeaderClass.getMethod("extensionRoot"), + WrappedArray.empty, true, true, element[Coll[Byte]])) } - def minerPk: Rep[GroupElement] = { + def minerPk: Ref[GroupElement] = { asRep[GroupElement](mkMethodCall(source, - thisClass.getMethod("minerPk"), - List(), + HeaderClass.getMethod("minerPk"), + WrappedArray.empty, true, true, element[GroupElement])) } - def powOnetimePk: Rep[GroupElement] = { + def powOnetimePk: Ref[GroupElement] = { asRep[GroupElement](mkMethodCall(source, - thisClass.getMethod("powOnetimePk"), - List(), + HeaderClass.getMethod("powOnetimePk"), + WrappedArray.empty, true, true, element[GroupElement])) } - def powNonce: Rep[Coll[Byte]] = { + def powNonce: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(source, - thisClass.getMethod("powNonce"), - List(), + HeaderClass.getMethod("powNonce"), + WrappedArray.empty, true, true, element[Coll[Byte]])) } - def powDistance: Rep[BigInt] = { + def powDistance: Ref[BigInt] = { asRep[BigInt](mkMethodCall(source, - thisClass.getMethod("powDistance"), - List(), + HeaderClass.getMethod("powDistance"), + WrappedArray.empty, true, true, element[BigInt])) } - def votes: Rep[Coll[Byte]] = { + def votes: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(source, - thisClass.getMethod("votes"), - List(), + HeaderClass.getMethod("votes"), + WrappedArray.empty, true, true, element[Coll[Byte]])) } } - // entityProxy: single proxy for each type family - implicit def proxyHeader(p: Rep[Header]): Header = { - if (p.rhs.isInstanceOf[Header@unchecked]) p.rhs.asInstanceOf[Header] + // entityUnref: single unref method for each type family + implicit final def unrefHeader(p: Ref[Header]): Header = { + if (p.node.isInstanceOf[Header]) p.node.asInstanceOf[Header] else HeaderAdapter(p) } @@ -3421,7 +2641,7 @@ object Header extends EntityObject("Header") { // familyElem class HeaderElem[To <: Header] extends EntityElem[To] { - override val liftable: Liftables.Liftable[_, To] = LiftableHeader.asLiftable[SHeader, To] + override val liftable: Liftables.Liftable[_, To] = asLiftable[SHeader, To](LiftableHeader) override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { super.collectMethods ++ @@ -3429,244 +2649,23 @@ object Header extends EntityObject("Header") { "id", "version", "parentId", "ADProofsRoot", "stateRoot", "transactionsRoot", "timestamp", "nBits", "height", "extensionRoot", "minerPk", "powOnetimePk", "powNonce", "powDistance", "votes" )) } - - lazy val parent: Option[Elem[_]] = None - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override lazy val tag = { - weakTypeTag[Header].asInstanceOf[WeakTypeTag[To]] - } - override def convert(x: Rep[Def[_]]) = { - val conv = fun {x: Rep[Header] => convertHeader(x) } - tryConvert(element[Header], this, x, conv) - } - - def convertHeader(x: Rep[Header]): Rep[To] = { - x.elem match { - case _: HeaderElem[_] => asRep[To](x) - case e => !!!(s"Expected $x to have HeaderElem[_], but got $e", x) - } - } - override def getDefaultRep: Rep[To] = ??? } implicit lazy val headerElement: Elem[Header] = new HeaderElem[Header] - implicit case object HeaderCompanionElem extends CompanionElem[HeaderCompanionCtor] { - lazy val tag = weakTypeTag[HeaderCompanionCtor] - protected def getDefaultRep = RHeader - } + implicit case object HeaderCompanionElem extends CompanionElem[HeaderCompanionCtor] abstract class HeaderCompanionCtor extends CompanionDef[HeaderCompanionCtor] with HeaderCompanion { - def selfType = HeaderCompanionElem + def resultType = HeaderCompanionElem override def toString = "Header" } - implicit def proxyHeaderCompanionCtor(p: Rep[HeaderCompanionCtor]): HeaderCompanionCtor = - proxyOps[HeaderCompanionCtor](p) + implicit final def unrefHeaderCompanionCtor(p: Ref[HeaderCompanionCtor]): HeaderCompanionCtor = + p.node.asInstanceOf[HeaderCompanionCtor] - lazy val RHeader: Rep[HeaderCompanionCtor] = new HeaderCompanionCtor { + lazy val RHeader: MutableLazy[HeaderCompanionCtor] = MutableLazy(new HeaderCompanionCtor { private val thisClass = classOf[HeaderCompanion] - } - - object HeaderMethods { - object id { - def unapply(d: Def[_]): Nullable[Rep[Header]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[HeaderElem[_]] && method.getName == "id" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Header]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Header]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object version { - def unapply(d: Def[_]): Nullable[Rep[Header]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[HeaderElem[_]] && method.getName == "version" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Header]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Header]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object parentId { - def unapply(d: Def[_]): Nullable[Rep[Header]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[HeaderElem[_]] && method.getName == "parentId" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Header]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Header]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object ADProofsRoot { - def unapply(d: Def[_]): Nullable[Rep[Header]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[HeaderElem[_]] && method.getName == "ADProofsRoot" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Header]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Header]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object stateRoot { - def unapply(d: Def[_]): Nullable[Rep[Header]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[HeaderElem[_]] && method.getName == "stateRoot" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Header]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Header]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object transactionsRoot { - def unapply(d: Def[_]): Nullable[Rep[Header]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[HeaderElem[_]] && method.getName == "transactionsRoot" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Header]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Header]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object timestamp { - def unapply(d: Def[_]): Nullable[Rep[Header]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[HeaderElem[_]] && method.getName == "timestamp" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Header]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Header]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object nBits { - def unapply(d: Def[_]): Nullable[Rep[Header]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[HeaderElem[_]] && method.getName == "nBits" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Header]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Header]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object height { - def unapply(d: Def[_]): Nullable[Rep[Header]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[HeaderElem[_]] && method.getName == "height" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Header]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Header]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object extensionRoot { - def unapply(d: Def[_]): Nullable[Rep[Header]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[HeaderElem[_]] && method.getName == "extensionRoot" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Header]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Header]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object minerPk { - def unapply(d: Def[_]): Nullable[Rep[Header]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[HeaderElem[_]] && method.getName == "minerPk" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Header]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Header]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object powOnetimePk { - def unapply(d: Def[_]): Nullable[Rep[Header]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[HeaderElem[_]] && method.getName == "powOnetimePk" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Header]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Header]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object powNonce { - def unapply(d: Def[_]): Nullable[Rep[Header]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[HeaderElem[_]] && method.getName == "powNonce" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Header]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Header]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object powDistance { - def unapply(d: Def[_]): Nullable[Rep[Header]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[HeaderElem[_]] && method.getName == "powDistance" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Header]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Header]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object votes { - def unapply(d: Def[_]): Nullable[Rep[Header]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[HeaderElem[_]] && method.getName == "votes" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Header]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Header]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - } - - object HeaderCompanionMethods { - } + }) } // of object Header registerEntityObject("Header", Header) @@ -3677,104 +2676,104 @@ object Context extends EntityObject("Context") { type SContext = special.sigma.Context case class ContextConst( constValue: SContext - ) extends Context with LiftedConst[SContext, Context] + ) extends LiftedConst[SContext, Context] with Context with Def[Context] with ContextConstMethods { val liftable: Liftable[SContext, Context] = LiftableContext - val selfType: Elem[Context] = liftable.eW + val resultType: Elem[Context] = liftable.eW } trait ContextConstMethods extends Context { thisConst: Def[_] => private val ContextClass = classOf[Context] - override def builder: Rep[SigmaDslBuilder] = { + override def builder: Ref[SigmaDslBuilder] = { asRep[SigmaDslBuilder](mkMethodCall(self, ContextClass.getMethod("builder"), - List(), + WrappedArray.empty, true, false, element[SigmaDslBuilder])) } - override def OUTPUTS: Rep[Coll[Box]] = { + override def OUTPUTS: Ref[Coll[Box]] = { asRep[Coll[Box]](mkMethodCall(self, ContextClass.getMethod("OUTPUTS"), - List(), + WrappedArray.empty, true, false, element[Coll[Box]])) } - override def INPUTS: Rep[Coll[Box]] = { + override def INPUTS: Ref[Coll[Box]] = { asRep[Coll[Box]](mkMethodCall(self, ContextClass.getMethod("INPUTS"), - List(), + WrappedArray.empty, true, false, element[Coll[Box]])) } - override def dataInputs: Rep[Coll[Box]] = { + override def dataInputs: Ref[Coll[Box]] = { asRep[Coll[Box]](mkMethodCall(self, ContextClass.getMethod("dataInputs"), - List(), + WrappedArray.empty, true, false, element[Coll[Box]])) } - override def HEIGHT: Rep[Int] = { + override def HEIGHT: Ref[Int] = { asRep[Int](mkMethodCall(self, ContextClass.getMethod("HEIGHT"), - List(), + WrappedArray.empty, true, false, element[Int])) } - override def SELF: Rep[Box] = { + override def SELF: Ref[Box] = { asRep[Box](mkMethodCall(self, ContextClass.getMethod("SELF"), - List(), + WrappedArray.empty, true, false, element[Box])) } - override def selfBoxIndex: Rep[Int] = { + override def selfBoxIndex: Ref[Int] = { asRep[Int](mkMethodCall(self, ContextClass.getMethod("selfBoxIndex"), - List(), + WrappedArray.empty, true, false, element[Int])) } - override def LastBlockUtxoRootHash: Rep[AvlTree] = { + override def LastBlockUtxoRootHash: Ref[AvlTree] = { asRep[AvlTree](mkMethodCall(self, ContextClass.getMethod("LastBlockUtxoRootHash"), - List(), + WrappedArray.empty, true, false, element[AvlTree])) } - override def headers: Rep[Coll[Header]] = { + override def headers: Ref[Coll[Header]] = { asRep[Coll[Header]](mkMethodCall(self, ContextClass.getMethod("headers"), - List(), + WrappedArray.empty, true, false, element[Coll[Header]])) } - override def preHeader: Rep[PreHeader] = { + override def preHeader: Ref[PreHeader] = { asRep[PreHeader](mkMethodCall(self, ContextClass.getMethod("preHeader"), - List(), + WrappedArray.empty, true, false, element[PreHeader])) } - override def minerPubKey: Rep[Coll[Byte]] = { + override def minerPubKey: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(self, ContextClass.getMethod("minerPubKey"), - List(), + WrappedArray.empty, true, false, element[Coll[Byte]])) } - override def getVar[T](id: Rep[Byte])(implicit cT: Elem[T]): Rep[WOption[T]] = { + override def getVar[T](id: Ref[Byte])(implicit cT: Elem[T]): Ref[WOption[T]] = { asRep[WOption[T]](mkMethodCall(self, ContextClass.getMethod("getVar", classOf[Sym], classOf[Elem[_]]), - List(id, cT), + Array[AnyRef](id, cT), true, false, element[WOption[T]])) } - override def vars: Rep[Coll[AnyValue]] = { + override def vars: Ref[Coll[AnyValue]] = { asRep[Coll[AnyValue]](mkMethodCall(self, ContextClass.getMethod("vars"), - List(), + WrappedArray.empty, true, false, element[Coll[AnyValue]])) } } @@ -3785,116 +2784,118 @@ object Context extends EntityObject("Context") { lazy val sourceType: RType[SContext] = { RType[SContext] } - def lift(x: SContext): Rep[Context] = ContextConst(x) - def unlift(w: Rep[Context]): SContext = w match { + def lift(x: SContext): Ref[Context] = ContextConst(x) + def unlift(w: Ref[Context]): SContext = w match { case Def(ContextConst(x: SContext)) => x.asInstanceOf[SContext] case _ => unliftError(w) } } + private val ContextClass = classOf[Context] + // entityAdapter for Context trait - case class ContextAdapter(source: Rep[Context]) - extends Context with Def[Context] { - val selfType: Elem[Context] = element[Context] + case class ContextAdapter(source: Ref[Context]) + extends Node with Context + with Def[Context] { + val resultType: Elem[Context] = element[Context] override def transform(t: Transformer) = ContextAdapter(t(source)) - private val thisClass = classOf[Context] - def builder: Rep[SigmaDslBuilder] = { + def builder: Ref[SigmaDslBuilder] = { asRep[SigmaDslBuilder](mkMethodCall(source, - thisClass.getMethod("builder"), - List(), + ContextClass.getMethod("builder"), + WrappedArray.empty, true, true, element[SigmaDslBuilder])) } - def OUTPUTS: Rep[Coll[Box]] = { + def OUTPUTS: Ref[Coll[Box]] = { asRep[Coll[Box]](mkMethodCall(source, - thisClass.getMethod("OUTPUTS"), - List(), + ContextClass.getMethod("OUTPUTS"), + WrappedArray.empty, true, true, element[Coll[Box]])) } - def INPUTS: Rep[Coll[Box]] = { + def INPUTS: Ref[Coll[Box]] = { asRep[Coll[Box]](mkMethodCall(source, - thisClass.getMethod("INPUTS"), - List(), + ContextClass.getMethod("INPUTS"), + WrappedArray.empty, true, true, element[Coll[Box]])) } - def dataInputs: Rep[Coll[Box]] = { + def dataInputs: Ref[Coll[Box]] = { asRep[Coll[Box]](mkMethodCall(source, - thisClass.getMethod("dataInputs"), - List(), + ContextClass.getMethod("dataInputs"), + WrappedArray.empty, true, true, element[Coll[Box]])) } - def HEIGHT: Rep[Int] = { + def HEIGHT: Ref[Int] = { asRep[Int](mkMethodCall(source, - thisClass.getMethod("HEIGHT"), - List(), + ContextClass.getMethod("HEIGHT"), + WrappedArray.empty, true, true, element[Int])) } - def SELF: Rep[Box] = { + def SELF: Ref[Box] = { asRep[Box](mkMethodCall(source, - thisClass.getMethod("SELF"), - List(), + ContextClass.getMethod("SELF"), + WrappedArray.empty, true, true, element[Box])) } - def selfBoxIndex: Rep[Int] = { + def selfBoxIndex: Ref[Int] = { asRep[Int](mkMethodCall(source, - thisClass.getMethod("selfBoxIndex"), - List(), + ContextClass.getMethod("selfBoxIndex"), + WrappedArray.empty, true, true, element[Int])) } - def LastBlockUtxoRootHash: Rep[AvlTree] = { + def LastBlockUtxoRootHash: Ref[AvlTree] = { asRep[AvlTree](mkMethodCall(source, - thisClass.getMethod("LastBlockUtxoRootHash"), - List(), + ContextClass.getMethod("LastBlockUtxoRootHash"), + WrappedArray.empty, true, true, element[AvlTree])) } - def headers: Rep[Coll[Header]] = { + def headers: Ref[Coll[Header]] = { asRep[Coll[Header]](mkMethodCall(source, - thisClass.getMethod("headers"), - List(), + ContextClass.getMethod("headers"), + WrappedArray.empty, true, true, element[Coll[Header]])) } - def preHeader: Rep[PreHeader] = { + def preHeader: Ref[PreHeader] = { asRep[PreHeader](mkMethodCall(source, - thisClass.getMethod("preHeader"), - List(), + ContextClass.getMethod("preHeader"), + WrappedArray.empty, true, true, element[PreHeader])) } - def minerPubKey: Rep[Coll[Byte]] = { + def minerPubKey: Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(source, - thisClass.getMethod("minerPubKey"), - List(), + ContextClass.getMethod("minerPubKey"), + WrappedArray.empty, true, true, element[Coll[Byte]])) } - def getVar[T](id: Rep[Byte])(implicit cT: Elem[T]): Rep[WOption[T]] = { + def getVar[T](id: Ref[Byte])(implicit cT: Elem[T]): Ref[WOption[T]] = { asRep[WOption[T]](mkMethodCall(source, - thisClass.getMethod("getVar", classOf[Sym], classOf[Elem[_]]), - List(id, cT), + ContextClass.getMethod("getVar", classOf[Sym], classOf[Elem[_]]), + Array[AnyRef](id, cT), true, true, element[WOption[T]])) } - def vars: Rep[Coll[AnyValue]] = { + def vars: Ref[Coll[AnyValue]] = { asRep[Coll[AnyValue]](mkMethodCall(source, - thisClass.getMethod("vars"), - List(), + ContextClass.getMethod("vars"), + WrappedArray.empty, true, true, element[Coll[AnyValue]])) } } - // entityProxy: single proxy for each type family - implicit def proxyContext(p: Rep[Context]): Context = { - if (p.rhs.isInstanceOf[Context@unchecked]) p.rhs.asInstanceOf[Context] + // entityUnref: single unref method for each type family + implicit final def unrefContext(p: Ref[Context]): Context = { + if (p.node.isInstanceOf[Context]) p.node.asInstanceOf[Context] else ContextAdapter(p) } @@ -3902,7 +2903,7 @@ object Context extends EntityObject("Context") { // familyElem class ContextElem[To <: Context] extends EntityElem[To] { - override val liftable: Liftables.Liftable[_, To] = LiftableContext.asLiftable[SContext, To] + override val liftable: Liftables.Liftable[_, To] = asLiftable[SContext, To](LiftableContext) override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { super.collectMethods ++ @@ -3910,213 +2911,153 @@ object Context extends EntityObject("Context") { "builder", "OUTPUTS", "INPUTS", "dataInputs", "HEIGHT", "SELF", "selfBoxIndex", "LastBlockUtxoRootHash", "headers", "preHeader", "minerPubKey", "getVar", "vars" )) } - - lazy val parent: Option[Elem[_]] = None - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override lazy val tag = { - weakTypeTag[Context].asInstanceOf[WeakTypeTag[To]] - } - override def convert(x: Rep[Def[_]]) = { - val conv = fun {x: Rep[Context] => convertContext(x) } - tryConvert(element[Context], this, x, conv) - } - - def convertContext(x: Rep[Context]): Rep[To] = { - x.elem match { - case _: ContextElem[_] => asRep[To](x) - case e => !!!(s"Expected $x to have ContextElem[_], but got $e", x) - } - } - override def getDefaultRep: Rep[To] = ??? } implicit lazy val contextElement: Elem[Context] = new ContextElem[Context] - implicit case object ContextCompanionElem extends CompanionElem[ContextCompanionCtor] { - lazy val tag = weakTypeTag[ContextCompanionCtor] - protected def getDefaultRep = RContext - } + implicit case object ContextCompanionElem extends CompanionElem[ContextCompanionCtor] abstract class ContextCompanionCtor extends CompanionDef[ContextCompanionCtor] with ContextCompanion { - def selfType = ContextCompanionElem + def resultType = ContextCompanionElem override def toString = "Context" } - implicit def proxyContextCompanionCtor(p: Rep[ContextCompanionCtor]): ContextCompanionCtor = - proxyOps[ContextCompanionCtor](p) + implicit final def unrefContextCompanionCtor(p: Ref[ContextCompanionCtor]): ContextCompanionCtor = + p.node.asInstanceOf[ContextCompanionCtor] - lazy val RContext: Rep[ContextCompanionCtor] = new ContextCompanionCtor { + lazy val RContext: MutableLazy[ContextCompanionCtor] = MutableLazy(new ContextCompanionCtor { private val thisClass = classOf[ContextCompanion] - } + }) object ContextMethods { object builder { - def unapply(d: Def[_]): Nullable[Rep[Context]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[ContextElem[_]] && method.getName == "builder" => + def unapply(d: Def[_]): Nullable[Ref[Context]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "builder" && receiver.elem.isInstanceOf[ContextElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Context]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Context]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[Context]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[Context]] = unapply(exp.node) } object OUTPUTS { - def unapply(d: Def[_]): Nullable[Rep[Context]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[ContextElem[_]] && method.getName == "OUTPUTS" => + def unapply(d: Def[_]): Nullable[Ref[Context]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "OUTPUTS" && receiver.elem.isInstanceOf[ContextElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Context]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Context]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[Context]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[Context]] = unapply(exp.node) } object INPUTS { - def unapply(d: Def[_]): Nullable[Rep[Context]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[ContextElem[_]] && method.getName == "INPUTS" => + def unapply(d: Def[_]): Nullable[Ref[Context]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "INPUTS" && receiver.elem.isInstanceOf[ContextElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Context]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Context]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[Context]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[Context]] = unapply(exp.node) } object dataInputs { - def unapply(d: Def[_]): Nullable[Rep[Context]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[ContextElem[_]] && method.getName == "dataInputs" => + def unapply(d: Def[_]): Nullable[Ref[Context]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "dataInputs" && receiver.elem.isInstanceOf[ContextElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Context]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Context]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[Context]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[Context]] = unapply(exp.node) } object HEIGHT { - def unapply(d: Def[_]): Nullable[Rep[Context]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[ContextElem[_]] && method.getName == "HEIGHT" => + def unapply(d: Def[_]): Nullable[Ref[Context]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "HEIGHT" && receiver.elem.isInstanceOf[ContextElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Context]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Context]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[Context]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[Context]] = unapply(exp.node) } object SELF { - def unapply(d: Def[_]): Nullable[Rep[Context]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[ContextElem[_]] && method.getName == "SELF" => + def unapply(d: Def[_]): Nullable[Ref[Context]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "SELF" && receiver.elem.isInstanceOf[ContextElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Context]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Context]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[Context]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[Context]] = unapply(exp.node) } object selfBoxIndex { - def unapply(d: Def[_]): Nullable[Rep[Context]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[ContextElem[_]] && method.getName == "selfBoxIndex" => + def unapply(d: Def[_]): Nullable[Ref[Context]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "selfBoxIndex" && receiver.elem.isInstanceOf[ContextElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Context]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Context]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[Context]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[Context]] = unapply(exp.node) } object LastBlockUtxoRootHash { - def unapply(d: Def[_]): Nullable[Rep[Context]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[ContextElem[_]] && method.getName == "LastBlockUtxoRootHash" => + def unapply(d: Def[_]): Nullable[Ref[Context]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "LastBlockUtxoRootHash" && receiver.elem.isInstanceOf[ContextElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Context]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Context]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[Context]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[Context]] = unapply(exp.node) } object headers { - def unapply(d: Def[_]): Nullable[Rep[Context]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[ContextElem[_]] && method.getName == "headers" => + def unapply(d: Def[_]): Nullable[Ref[Context]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "headers" && receiver.elem.isInstanceOf[ContextElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Context]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Context]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[Context]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[Context]] = unapply(exp.node) } object preHeader { - def unapply(d: Def[_]): Nullable[Rep[Context]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[ContextElem[_]] && method.getName == "preHeader" => + def unapply(d: Def[_]): Nullable[Ref[Context]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "preHeader" && receiver.elem.isInstanceOf[ContextElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Context]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Context]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[Context]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[Context]] = unapply(exp.node) } object minerPubKey { - def unapply(d: Def[_]): Nullable[Rep[Context]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[ContextElem[_]] && method.getName == "minerPubKey" => + def unapply(d: Def[_]): Nullable[Ref[Context]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "minerPubKey" && receiver.elem.isInstanceOf[ContextElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Context]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Context]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[Context]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[Context]] = unapply(exp.node) } object getVar { - def unapply(d: Def[_]): Nullable[(Rep[Context], Rep[Byte], Elem[T]) forSome {type T}] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[ContextElem[_]] && method.getName == "getVar" => + def unapply(d: Def[_]): Nullable[(Ref[Context], Ref[Byte], Elem[T]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "getVar" && receiver.elem.isInstanceOf[ContextElem[_]] => val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[Context], Rep[Byte], Elem[T]) forSome {type T}]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[Context], Rep[Byte], Elem[T]) forSome {type T}] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[Context], Ref[Byte], Elem[T]) forSome {type T}]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[Context], Ref[Byte], Elem[T]) forSome {type T}] = unapply(exp.node) } object vars { - def unapply(d: Def[_]): Nullable[Rep[Context]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[ContextElem[_]] && method.getName == "vars" => + def unapply(d: Def[_]): Nullable[Ref[Context]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "vars" && receiver.elem.isInstanceOf[ContextElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[Context]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Context]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[Context]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[Context]] = unapply(exp.node) } } @@ -4132,36 +3073,29 @@ object SigmaContract extends EntityObject("SigmaContract") { type SSigmaContract = special.sigma.SigmaContract case class SigmaContractConst( constValue: SSigmaContract - ) extends SigmaContract with LiftedConst[SSigmaContract, SigmaContract] + ) extends LiftedConst[SSigmaContract, SigmaContract] with SigmaContract with Def[SigmaContract] with SigmaContractConstMethods { val liftable: Liftable[SSigmaContract, SigmaContract] = LiftableSigmaContract - val selfType: Elem[SigmaContract] = liftable.eW + val resultType: Elem[SigmaContract] = liftable.eW } trait SigmaContractConstMethods extends SigmaContract { thisConst: Def[_] => private val SigmaContractClass = classOf[SigmaContract] - override def builder: Rep[SigmaDslBuilder] = { + override def builder: Ref[SigmaDslBuilder] = { asRep[SigmaDslBuilder](mkMethodCall(self, SigmaContractClass.getMethod("builder"), - List(), + WrappedArray.empty, true, false, element[SigmaDslBuilder])) } - override def Collection[T](items: Rep[T]*)(implicit cT: Elem[T]): Rep[Coll[T]] = { + override def Collection[T](items: Ref[T]*)(implicit cT: Elem[T]): Ref[Coll[T]] = { asRep[Coll[T]](mkMethodCall(self, SigmaContractClass.getMethod("Collection", classOf[Seq[_]], classOf[Elem[_]]), - List(items, cT), + Array[AnyRef](items, cT), true, false, element[Coll[T]])) } - - override def canOpen(ctx: Rep[Context]): Rep[Boolean] = { - asRep[Boolean](mkMethodCall(self, - SigmaContractClass.getMethod("canOpen", classOf[Sym]), - List(ctx), - true, false, element[Boolean])) - } } implicit object LiftableSigmaContract @@ -4170,46 +3104,41 @@ object SigmaContract extends EntityObject("SigmaContract") { lazy val sourceType: RType[SSigmaContract] = { RType[SSigmaContract] } - def lift(x: SSigmaContract): Rep[SigmaContract] = SigmaContractConst(x) - def unlift(w: Rep[SigmaContract]): SSigmaContract = w match { + def lift(x: SSigmaContract): Ref[SigmaContract] = SigmaContractConst(x) + def unlift(w: Ref[SigmaContract]): SSigmaContract = w match { case Def(SigmaContractConst(x: SSigmaContract)) => x.asInstanceOf[SSigmaContract] case _ => unliftError(w) } } + private val SigmaContractClass = classOf[SigmaContract] + // entityAdapter for SigmaContract trait - case class SigmaContractAdapter(source: Rep[SigmaContract]) - extends SigmaContract with Def[SigmaContract] { - val selfType: Elem[SigmaContract] = element[SigmaContract] + case class SigmaContractAdapter(source: Ref[SigmaContract]) + extends Node with SigmaContract + with Def[SigmaContract] { + val resultType: Elem[SigmaContract] = element[SigmaContract] override def transform(t: Transformer) = SigmaContractAdapter(t(source)) - private val thisClass = classOf[SigmaContract] - def builder: Rep[SigmaDslBuilder] = { + def builder: Ref[SigmaDslBuilder] = { asRep[SigmaDslBuilder](mkMethodCall(source, - thisClass.getMethod("builder"), - List(), + SigmaContractClass.getMethod("builder"), + WrappedArray.empty, true, true, element[SigmaDslBuilder])) } - override def Collection[T](items: Rep[T]*)(implicit cT: Elem[T]): Rep[Coll[T]] = { + override def Collection[T](items: Ref[T]*)(implicit cT: Elem[T]): Ref[Coll[T]] = { asRep[Coll[T]](mkMethodCall(source, - thisClass.getMethod("Collection", classOf[Seq[_]], classOf[Elem[_]]), - List(items, cT), + SigmaContractClass.getMethod("Collection", classOf[Seq[_]], classOf[Elem[_]]), + Array[AnyRef](items, cT), true, true, element[Coll[T]])) } - - def canOpen(ctx: Rep[Context]): Rep[Boolean] = { - asRep[Boolean](mkMethodCall(source, - thisClass.getMethod("canOpen", classOf[Sym]), - List(ctx), - true, true, element[Boolean])) - } } - // entityProxy: single proxy for each type family - implicit def proxySigmaContract(p: Rep[SigmaContract]): SigmaContract = { - if (p.rhs.isInstanceOf[SigmaContract@unchecked]) p.rhs.asInstanceOf[SigmaContract] + // entityUnref: single unref method for each type family + implicit final def unrefSigmaContract(p: Ref[SigmaContract]): SigmaContract = { + if (p.node.isInstanceOf[SigmaContract]) p.node.asInstanceOf[SigmaContract] else SigmaContractAdapter(p) } @@ -4217,330 +3146,31 @@ object SigmaContract extends EntityObject("SigmaContract") { // familyElem class SigmaContractElem[To <: SigmaContract] extends EntityElem[To] { - override val liftable: Liftables.Liftable[_, To] = LiftableSigmaContract.asLiftable[SSigmaContract, To] + override val liftable: Liftables.Liftable[_, To] = asLiftable[SSigmaContract, To](LiftableSigmaContract) override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { super.collectMethods ++ Elem.declaredMethods(classOf[SigmaContract], classOf[SSigmaContract], Set( - "builder", "Collection", "verifyZK", "atLeast", "allOf", "allZK", "anyOf", "anyZK", "xorOf", "PubKey", "sigmaProp", "blake2b256", "sha256", "byteArrayToBigInt", "longToByteArray", "byteArrayToLong", "proveDlog", "proveDHTuple", "groupGenerator", "canOpen", "asFunction" + "builder", "Collection", "verifyZK", "atLeast", "allOf", "allZK", "anyOf", "anyZK", "xorOf", "PubKey", "sigmaProp", "blake2b256", "sha256", "byteArrayToBigInt", "longToByteArray", "byteArrayToLong", "proveDlog", "proveDHTuple", "groupGenerator", "decodePoint", "substConstants" )) } - - lazy val parent: Option[Elem[_]] = None - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override lazy val tag = { - weakTypeTag[SigmaContract].asInstanceOf[WeakTypeTag[To]] - } - override def convert(x: Rep[Def[_]]) = { - val conv = fun {x: Rep[SigmaContract] => convertSigmaContract(x) } - tryConvert(element[SigmaContract], this, x, conv) - } - - def convertSigmaContract(x: Rep[SigmaContract]): Rep[To] = { - x.elem match { - case _: SigmaContractElem[_] => asRep[To](x) - case e => !!!(s"Expected $x to have SigmaContractElem[_], but got $e", x) - } - } - override def getDefaultRep: Rep[To] = ??? } implicit lazy val sigmaContractElement: Elem[SigmaContract] = new SigmaContractElem[SigmaContract] - implicit case object SigmaContractCompanionElem extends CompanionElem[SigmaContractCompanionCtor] { - lazy val tag = weakTypeTag[SigmaContractCompanionCtor] - protected def getDefaultRep = RSigmaContract - } + implicit case object SigmaContractCompanionElem extends CompanionElem[SigmaContractCompanionCtor] abstract class SigmaContractCompanionCtor extends CompanionDef[SigmaContractCompanionCtor] with SigmaContractCompanion { - def selfType = SigmaContractCompanionElem + def resultType = SigmaContractCompanionElem override def toString = "SigmaContract" } - implicit def proxySigmaContractCompanionCtor(p: Rep[SigmaContractCompanionCtor]): SigmaContractCompanionCtor = - proxyOps[SigmaContractCompanionCtor](p) + implicit final def unrefSigmaContractCompanionCtor(p: Ref[SigmaContractCompanionCtor]): SigmaContractCompanionCtor = + p.node.asInstanceOf[SigmaContractCompanionCtor] - lazy val RSigmaContract: Rep[SigmaContractCompanionCtor] = new SigmaContractCompanionCtor { + lazy val RSigmaContract: MutableLazy[SigmaContractCompanionCtor] = MutableLazy(new SigmaContractCompanionCtor { private val thisClass = classOf[SigmaContractCompanion] - } - - object SigmaContractMethods { - object builder { - def unapply(d: Def[_]): Nullable[Rep[SigmaContract]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[SigmaContractElem[_]] && method.getName == "builder" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[SigmaContract]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[SigmaContract]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object Collection { - def unapply(d: Def[_]): Nullable[(Rep[SigmaContract], Seq[Rep[T]], Elem[T]) forSome {type T}] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaContractElem[_]] && method.getName == "Collection" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaContract], Seq[Rep[T]], Elem[T]) forSome {type T}]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaContract], Seq[Rep[T]], Elem[T]) forSome {type T}] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object verifyZK { - def unapply(d: Def[_]): Nullable[(Rep[SigmaContract], Rep[Thunk[SigmaProp]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaContractElem[_]] && method.getName == "verifyZK" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaContract], Rep[Thunk[SigmaProp]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaContract], Rep[Thunk[SigmaProp]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object atLeast { - def unapply(d: Def[_]): Nullable[(Rep[SigmaContract], Rep[Int], Rep[Coll[SigmaProp]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaContractElem[_]] && method.getName == "atLeast" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaContract], Rep[Int], Rep[Coll[SigmaProp]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaContract], Rep[Int], Rep[Coll[SigmaProp]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object allOf { - def unapply(d: Def[_]): Nullable[(Rep[SigmaContract], Rep[Coll[Boolean]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaContractElem[_]] && method.getName == "allOf" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaContract], Rep[Coll[Boolean]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaContract], Rep[Coll[Boolean]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object allZK { - def unapply(d: Def[_]): Nullable[(Rep[SigmaContract], Rep[Coll[SigmaProp]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaContractElem[_]] && method.getName == "allZK" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaContract], Rep[Coll[SigmaProp]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaContract], Rep[Coll[SigmaProp]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object anyOf { - def unapply(d: Def[_]): Nullable[(Rep[SigmaContract], Rep[Coll[Boolean]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaContractElem[_]] && method.getName == "anyOf" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaContract], Rep[Coll[Boolean]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaContract], Rep[Coll[Boolean]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object anyZK { - def unapply(d: Def[_]): Nullable[(Rep[SigmaContract], Rep[Coll[SigmaProp]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaContractElem[_]] && method.getName == "anyZK" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaContract], Rep[Coll[SigmaProp]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaContract], Rep[Coll[SigmaProp]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object xorOf { - def unapply(d: Def[_]): Nullable[(Rep[SigmaContract], Rep[Coll[Boolean]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaContractElem[_]] && method.getName == "xorOf" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaContract], Rep[Coll[Boolean]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaContract], Rep[Coll[Boolean]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object PubKey { - def unapply(d: Def[_]): Nullable[(Rep[SigmaContract], Rep[String])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaContractElem[_]] && method.getName == "PubKey" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaContract], Rep[String])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaContract], Rep[String])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object sigmaProp { - def unapply(d: Def[_]): Nullable[(Rep[SigmaContract], Rep[Boolean])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaContractElem[_]] && method.getName == "sigmaProp" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaContract], Rep[Boolean])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaContract], Rep[Boolean])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object blake2b256 { - def unapply(d: Def[_]): Nullable[(Rep[SigmaContract], Rep[Coll[Byte]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaContractElem[_]] && method.getName == "blake2b256" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaContract], Rep[Coll[Byte]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaContract], Rep[Coll[Byte]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object sha256 { - def unapply(d: Def[_]): Nullable[(Rep[SigmaContract], Rep[Coll[Byte]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaContractElem[_]] && method.getName == "sha256" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaContract], Rep[Coll[Byte]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaContract], Rep[Coll[Byte]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object byteArrayToBigInt { - def unapply(d: Def[_]): Nullable[(Rep[SigmaContract], Rep[Coll[Byte]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaContractElem[_]] && method.getName == "byteArrayToBigInt" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaContract], Rep[Coll[Byte]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaContract], Rep[Coll[Byte]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object longToByteArray { - def unapply(d: Def[_]): Nullable[(Rep[SigmaContract], Rep[Long])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaContractElem[_]] && method.getName == "longToByteArray" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaContract], Rep[Long])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaContract], Rep[Long])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object byteArrayToLong { - def unapply(d: Def[_]): Nullable[(Rep[SigmaContract], Rep[Coll[Byte]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaContractElem[_]] && method.getName == "byteArrayToLong" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaContract], Rep[Coll[Byte]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaContract], Rep[Coll[Byte]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object proveDlog { - def unapply(d: Def[_]): Nullable[(Rep[SigmaContract], Rep[GroupElement])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaContractElem[_]] && method.getName == "proveDlog" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaContract], Rep[GroupElement])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaContract], Rep[GroupElement])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object proveDHTuple { - def unapply(d: Def[_]): Nullable[(Rep[SigmaContract], Rep[GroupElement], Rep[GroupElement], Rep[GroupElement], Rep[GroupElement])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaContractElem[_]] && method.getName == "proveDHTuple" => - val res = (receiver, args(0), args(1), args(2), args(3)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaContract], Rep[GroupElement], Rep[GroupElement], Rep[GroupElement], Rep[GroupElement])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaContract], Rep[GroupElement], Rep[GroupElement], Rep[GroupElement], Rep[GroupElement])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object groupGenerator { - def unapply(d: Def[_]): Nullable[Rep[SigmaContract]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[SigmaContractElem[_]] && method.getName == "groupGenerator" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[SigmaContract]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[SigmaContract]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object canOpen { - def unapply(d: Def[_]): Nullable[(Rep[SigmaContract], Rep[Context])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaContractElem[_]] && method.getName == "canOpen" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaContract], Rep[Context])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaContract], Rep[Context])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object asFunction { - def unapply(d: Def[_]): Nullable[Rep[SigmaContract]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[SigmaContractElem[_]] && method.getName == "asFunction" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[SigmaContract]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[SigmaContract]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - } - - object SigmaContractCompanionMethods { - } + }) } // of object SigmaContract registerEntityObject("SigmaContract", SigmaContract) @@ -4551,198 +3181,191 @@ object SigmaDslBuilder extends EntityObject("SigmaDslBuilder") { type SSigmaDslBuilder = special.sigma.SigmaDslBuilder case class SigmaDslBuilderConst( constValue: SSigmaDslBuilder - ) extends SigmaDslBuilder with LiftedConst[SSigmaDslBuilder, SigmaDslBuilder] + ) extends LiftedConst[SSigmaDslBuilder, SigmaDslBuilder] with SigmaDslBuilder with Def[SigmaDslBuilder] with SigmaDslBuilderConstMethods { val liftable: Liftable[SSigmaDslBuilder, SigmaDslBuilder] = LiftableSigmaDslBuilder - val selfType: Elem[SigmaDslBuilder] = liftable.eW + val resultType: Elem[SigmaDslBuilder] = liftable.eW } trait SigmaDslBuilderConstMethods extends SigmaDslBuilder { thisConst: Def[_] => private val SigmaDslBuilderClass = classOf[SigmaDslBuilder] - override def Colls: Rep[CollBuilder] = { + override def Colls: Ref[CollBuilder] = { asRep[CollBuilder](mkMethodCall(self, SigmaDslBuilderClass.getMethod("Colls"), - List(), + WrappedArray.empty, true, false, element[CollBuilder])) } - override def Monoids: Rep[MonoidBuilder] = { + override def Monoids: Ref[MonoidBuilder] = { asRep[MonoidBuilder](mkMethodCall(self, SigmaDslBuilderClass.getMethod("Monoids"), - List(), + WrappedArray.empty, true, false, element[MonoidBuilder])) } - override def Costing: Rep[CostedBuilder] = { + override def Costing: Ref[CostedBuilder] = { asRep[CostedBuilder](mkMethodCall(self, SigmaDslBuilderClass.getMethod("Costing"), - List(), + WrappedArray.empty, true, false, element[CostedBuilder])) } - override def CostModel: Rep[CostModel] = { + override def CostModel: Ref[CostModel] = { asRep[CostModel](mkMethodCall(self, SigmaDslBuilderClass.getMethod("CostModel"), - List(), + WrappedArray.empty, true, false, element[CostModel])) } - override def verifyZK(cond: Rep[Thunk[SigmaProp]]): Rep[Boolean] = { + override def verifyZK(cond: Ref[Thunk[SigmaProp]]): Ref[Boolean] = { asRep[Boolean](mkMethodCall(self, SigmaDslBuilderClass.getMethod("verifyZK", classOf[Sym]), - List(cond), + Array[AnyRef](cond), true, false, element[Boolean])) } - override def atLeast(bound: Rep[Int], props: Rep[Coll[SigmaProp]]): Rep[SigmaProp] = { + override def atLeast(bound: Ref[Int], props: Ref[Coll[SigmaProp]]): Ref[SigmaProp] = { asRep[SigmaProp](mkMethodCall(self, SigmaDslBuilderClass.getMethod("atLeast", classOf[Sym], classOf[Sym]), - List(bound, props), + Array[AnyRef](bound, props), true, false, element[SigmaProp])) } - override def allOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean] = { + override def allOf(conditions: Ref[Coll[Boolean]]): Ref[Boolean] = { asRep[Boolean](mkMethodCall(self, SigmaDslBuilderClass.getMethod("allOf", classOf[Sym]), - List(conditions), + Array[AnyRef](conditions), true, false, element[Boolean])) } - override def allZK(conditions: Rep[Coll[SigmaProp]]): Rep[SigmaProp] = { + override def allZK(conditions: Ref[Coll[SigmaProp]]): Ref[SigmaProp] = { asRep[SigmaProp](mkMethodCall(self, SigmaDslBuilderClass.getMethod("allZK", classOf[Sym]), - List(conditions), + Array[AnyRef](conditions), true, false, element[SigmaProp])) } - override def anyOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean] = { + override def anyOf(conditions: Ref[Coll[Boolean]]): Ref[Boolean] = { asRep[Boolean](mkMethodCall(self, SigmaDslBuilderClass.getMethod("anyOf", classOf[Sym]), - List(conditions), + Array[AnyRef](conditions), true, false, element[Boolean])) } - override def anyZK(conditions: Rep[Coll[SigmaProp]]): Rep[SigmaProp] = { + override def anyZK(conditions: Ref[Coll[SigmaProp]]): Ref[SigmaProp] = { asRep[SigmaProp](mkMethodCall(self, SigmaDslBuilderClass.getMethod("anyZK", classOf[Sym]), - List(conditions), + Array[AnyRef](conditions), true, false, element[SigmaProp])) } - override def xorOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean] = { + override def xorOf(conditions: Ref[Coll[Boolean]]): Ref[Boolean] = { asRep[Boolean](mkMethodCall(self, SigmaDslBuilderClass.getMethod("xorOf", classOf[Sym]), - List(conditions), + Array[AnyRef](conditions), true, false, element[Boolean])) } - override def PubKey(base64String: Rep[String]): Rep[SigmaProp] = { + override def PubKey(base64String: Ref[String]): Ref[SigmaProp] = { asRep[SigmaProp](mkMethodCall(self, SigmaDslBuilderClass.getMethod("PubKey", classOf[Sym]), - List(base64String), + Array[AnyRef](base64String), true, false, element[SigmaProp])) } - override def sigmaProp(b: Rep[Boolean]): Rep[SigmaProp] = { + override def sigmaProp(b: Ref[Boolean]): Ref[SigmaProp] = { asRep[SigmaProp](mkMethodCall(self, SigmaDslBuilderClass.getMethod("sigmaProp", classOf[Sym]), - List(b), + Array[AnyRef](b), true, false, element[SigmaProp])) } - override def blake2b256(bytes: Rep[Coll[Byte]]): Rep[Coll[Byte]] = { + override def blake2b256(bytes: Ref[Coll[Byte]]): Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(self, SigmaDslBuilderClass.getMethod("blake2b256", classOf[Sym]), - List(bytes), + Array[AnyRef](bytes), true, false, element[Coll[Byte]])) } - override def sha256(bytes: Rep[Coll[Byte]]): Rep[Coll[Byte]] = { + override def sha256(bytes: Ref[Coll[Byte]]): Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(self, SigmaDslBuilderClass.getMethod("sha256", classOf[Sym]), - List(bytes), + Array[AnyRef](bytes), true, false, element[Coll[Byte]])) } - override def byteArrayToBigInt(bytes: Rep[Coll[Byte]]): Rep[BigInt] = { + override def byteArrayToBigInt(bytes: Ref[Coll[Byte]]): Ref[BigInt] = { asRep[BigInt](mkMethodCall(self, SigmaDslBuilderClass.getMethod("byteArrayToBigInt", classOf[Sym]), - List(bytes), + Array[AnyRef](bytes), true, false, element[BigInt])) } - override def longToByteArray(l: Rep[Long]): Rep[Coll[Byte]] = { + override def longToByteArray(l: Ref[Long]): Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(self, SigmaDslBuilderClass.getMethod("longToByteArray", classOf[Sym]), - List(l), + Array[AnyRef](l), true, false, element[Coll[Byte]])) } - override def byteArrayToLong(bytes: Rep[Coll[Byte]]): Rep[Long] = { + override def byteArrayToLong(bytes: Ref[Coll[Byte]]): Ref[Long] = { asRep[Long](mkMethodCall(self, SigmaDslBuilderClass.getMethod("byteArrayToLong", classOf[Sym]), - List(bytes), + Array[AnyRef](bytes), true, false, element[Long])) } - override def proveDlog(g: Rep[GroupElement]): Rep[SigmaProp] = { + override def proveDlog(g: Ref[GroupElement]): Ref[SigmaProp] = { asRep[SigmaProp](mkMethodCall(self, SigmaDslBuilderClass.getMethod("proveDlog", classOf[Sym]), - List(g), + Array[AnyRef](g), true, false, element[SigmaProp])) } - override def proveDHTuple(g: Rep[GroupElement], h: Rep[GroupElement], u: Rep[GroupElement], v: Rep[GroupElement]): Rep[SigmaProp] = { + override def proveDHTuple(g: Ref[GroupElement], h: Ref[GroupElement], u: Ref[GroupElement], v: Ref[GroupElement]): Ref[SigmaProp] = { asRep[SigmaProp](mkMethodCall(self, SigmaDslBuilderClass.getMethod("proveDHTuple", classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym]), - List(g, h, u, v), + Array[AnyRef](g, h, u, v), true, false, element[SigmaProp])) } - override def groupGenerator: Rep[GroupElement] = { + override def groupGenerator: Ref[GroupElement] = { asRep[GroupElement](mkMethodCall(self, SigmaDslBuilderClass.getMethod("groupGenerator"), - List(), + WrappedArray.empty, true, false, element[GroupElement])) } - override def substConstants[T](scriptBytes: Rep[Coll[Byte]], positions: Rep[Coll[Int]], newValues: Rep[Coll[T]])(implicit cT: Elem[T]): Rep[Coll[Byte]] = { + override def substConstants[T](scriptBytes: Ref[Coll[Byte]], positions: Ref[Coll[Int]], newValues: Ref[Coll[T]])(implicit cT: Elem[T]): Ref[Coll[Byte]] = { implicit val eT = newValues.eA asRep[Coll[Byte]](mkMethodCall(self, SigmaDslBuilderClass.getMethod("substConstants", classOf[Sym], classOf[Sym], classOf[Sym], classOf[Elem[_]]), - List(scriptBytes, positions, newValues, cT), + Array[AnyRef](scriptBytes, positions, newValues, cT), true, false, element[Coll[Byte]])) } - override def decodePoint(encoded: Rep[Coll[Byte]]): Rep[GroupElement] = { + override def decodePoint(encoded: Ref[Coll[Byte]]): Ref[GroupElement] = { asRep[GroupElement](mkMethodCall(self, SigmaDslBuilderClass.getMethod("decodePoint", classOf[Sym]), - List(encoded), + Array[AnyRef](encoded), true, false, element[GroupElement])) } - override def BigInt(n: Rep[WBigInteger]): Rep[BigInt] = { - asRep[BigInt](mkMethodCall(self, - SigmaDslBuilderClass.getMethod("BigInt", classOf[Sym]), - List(n), - true, false, element[BigInt])) - } - - override def toBigInteger(n: Rep[BigInt]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - SigmaDslBuilderClass.getMethod("toBigInteger", classOf[Sym]), - List(n), - true, false, element[WBigInteger])) - } - - override def avlTree(operationFlags: Rep[Byte], digest: Rep[Coll[Byte]], keyLength: Rep[Int], valueLengthOpt: Rep[WOption[Int]]): Rep[AvlTree] = { + override def avlTree(operationFlags: Ref[Byte], digest: Ref[Coll[Byte]], keyLength: Ref[Int], valueLengthOpt: Ref[WOption[Int]]): Ref[AvlTree] = { asRep[AvlTree](mkMethodCall(self, SigmaDslBuilderClass.getMethod("avlTree", classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym]), - List(operationFlags, digest, keyLength, valueLengthOpt), + Array[AnyRef](operationFlags, digest, keyLength, valueLengthOpt), true, false, element[AvlTree])) } + + override def xor(l: Ref[Coll[Byte]], r: Ref[Coll[Byte]]): Ref[Coll[Byte]] = { + asRep[Coll[Byte]](mkMethodCall(self, + SigmaDslBuilderClass.getMethod("xor", classOf[Sym], classOf[Sym]), + Array[AnyRef](l, r), + true, false, element[Coll[Byte]])) + } } implicit object LiftableSigmaDslBuilder @@ -4751,208 +3374,203 @@ object SigmaDslBuilder extends EntityObject("SigmaDslBuilder") { lazy val sourceType: RType[SSigmaDslBuilder] = { RType[SSigmaDslBuilder] } - def lift(x: SSigmaDslBuilder): Rep[SigmaDslBuilder] = SigmaDslBuilderConst(x) - def unlift(w: Rep[SigmaDslBuilder]): SSigmaDslBuilder = w match { + def lift(x: SSigmaDslBuilder): Ref[SigmaDslBuilder] = SigmaDslBuilderConst(x) + def unlift(w: Ref[SigmaDslBuilder]): SSigmaDslBuilder = w match { case Def(SigmaDslBuilderConst(x: SSigmaDslBuilder)) => x.asInstanceOf[SSigmaDslBuilder] case _ => unliftError(w) } } + private val SigmaDslBuilderClass = classOf[SigmaDslBuilder] + // entityAdapter for SigmaDslBuilder trait - case class SigmaDslBuilderAdapter(source: Rep[SigmaDslBuilder]) - extends SigmaDslBuilder with Def[SigmaDslBuilder] { - val selfType: Elem[SigmaDslBuilder] = element[SigmaDslBuilder] + case class SigmaDslBuilderAdapter(source: Ref[SigmaDslBuilder]) + extends Node with SigmaDslBuilder + with Def[SigmaDslBuilder] { + val resultType: Elem[SigmaDslBuilder] = element[SigmaDslBuilder] override def transform(t: Transformer) = SigmaDslBuilderAdapter(t(source)) - private val thisClass = classOf[SigmaDslBuilder] - def Colls: Rep[CollBuilder] = { + def Colls: Ref[CollBuilder] = { asRep[CollBuilder](mkMethodCall(source, - thisClass.getMethod("Colls"), - List(), + SigmaDslBuilderClass.getMethod("Colls"), + WrappedArray.empty, true, true, element[CollBuilder])) } - def Monoids: Rep[MonoidBuilder] = { + def Monoids: Ref[MonoidBuilder] = { asRep[MonoidBuilder](mkMethodCall(source, - thisClass.getMethod("Monoids"), - List(), + SigmaDslBuilderClass.getMethod("Monoids"), + WrappedArray.empty, true, true, element[MonoidBuilder])) } - def Costing: Rep[CostedBuilder] = { + def Costing: Ref[CostedBuilder] = { asRep[CostedBuilder](mkMethodCall(source, - thisClass.getMethod("Costing"), - List(), + SigmaDslBuilderClass.getMethod("Costing"), + WrappedArray.empty, true, true, element[CostedBuilder])) } - def CostModel: Rep[CostModel] = { + def CostModel: Ref[CostModel] = { asRep[CostModel](mkMethodCall(source, - thisClass.getMethod("CostModel"), - List(), + SigmaDslBuilderClass.getMethod("CostModel"), + WrappedArray.empty, true, true, element[CostModel])) } - def verifyZK(cond: Rep[Thunk[SigmaProp]]): Rep[Boolean] = { + def verifyZK(cond: Ref[Thunk[SigmaProp]]): Ref[Boolean] = { asRep[Boolean](mkMethodCall(source, - thisClass.getMethod("verifyZK", classOf[Sym]), - List(cond), + SigmaDslBuilderClass.getMethod("verifyZK", classOf[Sym]), + Array[AnyRef](cond), true, true, element[Boolean])) } - def atLeast(bound: Rep[Int], props: Rep[Coll[SigmaProp]]): Rep[SigmaProp] = { + def atLeast(bound: Ref[Int], props: Ref[Coll[SigmaProp]]): Ref[SigmaProp] = { asRep[SigmaProp](mkMethodCall(source, - thisClass.getMethod("atLeast", classOf[Sym], classOf[Sym]), - List(bound, props), + SigmaDslBuilderClass.getMethod("atLeast", classOf[Sym], classOf[Sym]), + Array[AnyRef](bound, props), true, true, element[SigmaProp])) } - def allOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean] = { + def allOf(conditions: Ref[Coll[Boolean]]): Ref[Boolean] = { asRep[Boolean](mkMethodCall(source, - thisClass.getMethod("allOf", classOf[Sym]), - List(conditions), + SigmaDslBuilderClass.getMethod("allOf", classOf[Sym]), + Array[AnyRef](conditions), true, true, element[Boolean])) } - def allZK(conditions: Rep[Coll[SigmaProp]]): Rep[SigmaProp] = { + def allZK(conditions: Ref[Coll[SigmaProp]]): Ref[SigmaProp] = { asRep[SigmaProp](mkMethodCall(source, - thisClass.getMethod("allZK", classOf[Sym]), - List(conditions), + SigmaDslBuilderClass.getMethod("allZK", classOf[Sym]), + Array[AnyRef](conditions), true, true, element[SigmaProp])) } - def anyOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean] = { + def anyOf(conditions: Ref[Coll[Boolean]]): Ref[Boolean] = { asRep[Boolean](mkMethodCall(source, - thisClass.getMethod("anyOf", classOf[Sym]), - List(conditions), + SigmaDslBuilderClass.getMethod("anyOf", classOf[Sym]), + Array[AnyRef](conditions), true, true, element[Boolean])) } - def anyZK(conditions: Rep[Coll[SigmaProp]]): Rep[SigmaProp] = { + def anyZK(conditions: Ref[Coll[SigmaProp]]): Ref[SigmaProp] = { asRep[SigmaProp](mkMethodCall(source, - thisClass.getMethod("anyZK", classOf[Sym]), - List(conditions), + SigmaDslBuilderClass.getMethod("anyZK", classOf[Sym]), + Array[AnyRef](conditions), true, true, element[SigmaProp])) } - def xorOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean] = { + def xorOf(conditions: Ref[Coll[Boolean]]): Ref[Boolean] = { asRep[Boolean](mkMethodCall(source, - thisClass.getMethod("xorOf", classOf[Sym]), - List(conditions), + SigmaDslBuilderClass.getMethod("xorOf", classOf[Sym]), + Array[AnyRef](conditions), true, true, element[Boolean])) } - def PubKey(base64String: Rep[String]): Rep[SigmaProp] = { + def PubKey(base64String: Ref[String]): Ref[SigmaProp] = { asRep[SigmaProp](mkMethodCall(source, - thisClass.getMethod("PubKey", classOf[Sym]), - List(base64String), + SigmaDslBuilderClass.getMethod("PubKey", classOf[Sym]), + Array[AnyRef](base64String), true, true, element[SigmaProp])) } - def sigmaProp(b: Rep[Boolean]): Rep[SigmaProp] = { + def sigmaProp(b: Ref[Boolean]): Ref[SigmaProp] = { asRep[SigmaProp](mkMethodCall(source, - thisClass.getMethod("sigmaProp", classOf[Sym]), - List(b), + SigmaDslBuilderClass.getMethod("sigmaProp", classOf[Sym]), + Array[AnyRef](b), true, true, element[SigmaProp])) } - def blake2b256(bytes: Rep[Coll[Byte]]): Rep[Coll[Byte]] = { + def blake2b256(bytes: Ref[Coll[Byte]]): Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(source, - thisClass.getMethod("blake2b256", classOf[Sym]), - List(bytes), + SigmaDslBuilderClass.getMethod("blake2b256", classOf[Sym]), + Array[AnyRef](bytes), true, true, element[Coll[Byte]])) } - def sha256(bytes: Rep[Coll[Byte]]): Rep[Coll[Byte]] = { + def sha256(bytes: Ref[Coll[Byte]]): Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(source, - thisClass.getMethod("sha256", classOf[Sym]), - List(bytes), + SigmaDslBuilderClass.getMethod("sha256", classOf[Sym]), + Array[AnyRef](bytes), true, true, element[Coll[Byte]])) } - def byteArrayToBigInt(bytes: Rep[Coll[Byte]]): Rep[BigInt] = { + def byteArrayToBigInt(bytes: Ref[Coll[Byte]]): Ref[BigInt] = { asRep[BigInt](mkMethodCall(source, - thisClass.getMethod("byteArrayToBigInt", classOf[Sym]), - List(bytes), + SigmaDslBuilderClass.getMethod("byteArrayToBigInt", classOf[Sym]), + Array[AnyRef](bytes), true, true, element[BigInt])) } - def longToByteArray(l: Rep[Long]): Rep[Coll[Byte]] = { + def longToByteArray(l: Ref[Long]): Ref[Coll[Byte]] = { asRep[Coll[Byte]](mkMethodCall(source, - thisClass.getMethod("longToByteArray", classOf[Sym]), - List(l), + SigmaDslBuilderClass.getMethod("longToByteArray", classOf[Sym]), + Array[AnyRef](l), true, true, element[Coll[Byte]])) } - def byteArrayToLong(bytes: Rep[Coll[Byte]]): Rep[Long] = { + def byteArrayToLong(bytes: Ref[Coll[Byte]]): Ref[Long] = { asRep[Long](mkMethodCall(source, - thisClass.getMethod("byteArrayToLong", classOf[Sym]), - List(bytes), + SigmaDslBuilderClass.getMethod("byteArrayToLong", classOf[Sym]), + Array[AnyRef](bytes), true, true, element[Long])) } - def proveDlog(g: Rep[GroupElement]): Rep[SigmaProp] = { + def proveDlog(g: Ref[GroupElement]): Ref[SigmaProp] = { asRep[SigmaProp](mkMethodCall(source, - thisClass.getMethod("proveDlog", classOf[Sym]), - List(g), + SigmaDslBuilderClass.getMethod("proveDlog", classOf[Sym]), + Array[AnyRef](g), true, true, element[SigmaProp])) } - def proveDHTuple(g: Rep[GroupElement], h: Rep[GroupElement], u: Rep[GroupElement], v: Rep[GroupElement]): Rep[SigmaProp] = { + def proveDHTuple(g: Ref[GroupElement], h: Ref[GroupElement], u: Ref[GroupElement], v: Ref[GroupElement]): Ref[SigmaProp] = { asRep[SigmaProp](mkMethodCall(source, - thisClass.getMethod("proveDHTuple", classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym]), - List(g, h, u, v), + SigmaDslBuilderClass.getMethod("proveDHTuple", classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym]), + Array[AnyRef](g, h, u, v), true, true, element[SigmaProp])) } - def groupGenerator: Rep[GroupElement] = { + def groupGenerator: Ref[GroupElement] = { asRep[GroupElement](mkMethodCall(source, - thisClass.getMethod("groupGenerator"), - List(), + SigmaDslBuilderClass.getMethod("groupGenerator"), + WrappedArray.empty, true, true, element[GroupElement])) } - def substConstants[T](scriptBytes: Rep[Coll[Byte]], positions: Rep[Coll[Int]], newValues: Rep[Coll[T]])(implicit cT: Elem[T]): Rep[Coll[Byte]] = { + def substConstants[T](scriptBytes: Ref[Coll[Byte]], positions: Ref[Coll[Int]], newValues: Ref[Coll[T]])(implicit cT: Elem[T]): Ref[Coll[Byte]] = { implicit val eT = newValues.eA asRep[Coll[Byte]](mkMethodCall(source, - thisClass.getMethod("substConstants", classOf[Sym], classOf[Sym], classOf[Sym], classOf[Elem[_]]), - List(scriptBytes, positions, newValues, cT), + SigmaDslBuilderClass.getMethod("substConstants", classOf[Sym], classOf[Sym], classOf[Sym], classOf[Elem[_]]), + Array[AnyRef](scriptBytes, positions, newValues, cT), true, true, element[Coll[Byte]])) } - def decodePoint(encoded: Rep[Coll[Byte]]): Rep[GroupElement] = { + def decodePoint(encoded: Ref[Coll[Byte]]): Ref[GroupElement] = { asRep[GroupElement](mkMethodCall(source, - thisClass.getMethod("decodePoint", classOf[Sym]), - List(encoded), + SigmaDslBuilderClass.getMethod("decodePoint", classOf[Sym]), + Array[AnyRef](encoded), true, true, element[GroupElement])) } - def BigInt(n: Rep[WBigInteger]): Rep[BigInt] = { - asRep[BigInt](mkMethodCall(source, - thisClass.getMethod("BigInt", classOf[Sym]), - List(n), - true, true, element[BigInt])) - } - - def toBigInteger(n: Rep[BigInt]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(source, - thisClass.getMethod("toBigInteger", classOf[Sym]), - List(n), - true, true, element[WBigInteger])) - } - - def avlTree(operationFlags: Rep[Byte], digest: Rep[Coll[Byte]], keyLength: Rep[Int], valueLengthOpt: Rep[WOption[Int]]): Rep[AvlTree] = { + def avlTree(operationFlags: Ref[Byte], digest: Ref[Coll[Byte]], keyLength: Ref[Int], valueLengthOpt: Ref[WOption[Int]]): Ref[AvlTree] = { asRep[AvlTree](mkMethodCall(source, - thisClass.getMethod("avlTree", classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym]), - List(operationFlags, digest, keyLength, valueLengthOpt), + SigmaDslBuilderClass.getMethod("avlTree", classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym]), + Array[AnyRef](operationFlags, digest, keyLength, valueLengthOpt), true, true, element[AvlTree])) } + + def xor(l: Ref[Coll[Byte]], r: Ref[Coll[Byte]]): Ref[Coll[Byte]] = { + asRep[Coll[Byte]](mkMethodCall(source, + SigmaDslBuilderClass.getMethod("xor", classOf[Sym], classOf[Sym]), + Array[AnyRef](l, r), + true, true, element[Coll[Byte]])) + } } - // entityProxy: single proxy for each type family - implicit def proxySigmaDslBuilder(p: Rep[SigmaDslBuilder]): SigmaDslBuilder = { - if (p.rhs.isInstanceOf[SigmaDslBuilder@unchecked]) p.rhs.asInstanceOf[SigmaDslBuilder] + // entityUnref: single unref method for each type family + implicit final def unrefSigmaDslBuilder(p: Ref[SigmaDslBuilder]): SigmaDslBuilder = { + if (p.node.isInstanceOf[SigmaDslBuilder]) p.node.asInstanceOf[SigmaDslBuilder] else SigmaDslBuilderAdapter(p) } @@ -4960,390 +3578,281 @@ object SigmaDslBuilder extends EntityObject("SigmaDslBuilder") { // familyElem class SigmaDslBuilderElem[To <: SigmaDslBuilder] extends EntityElem[To] { - override val liftable: Liftables.Liftable[_, To] = LiftableSigmaDslBuilder.asLiftable[SSigmaDslBuilder, To] + override val liftable: Liftables.Liftable[_, To] = asLiftable[SSigmaDslBuilder, To](LiftableSigmaDslBuilder) override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { super.collectMethods ++ Elem.declaredMethods(classOf[SigmaDslBuilder], classOf[SSigmaDslBuilder], Set( - "Colls", "Monoids", "Costing", "CostModel", "verifyZK", "atLeast", "allOf", "allZK", "anyOf", "anyZK", "xorOf", "PubKey", "sigmaProp", "blake2b256", "sha256", "byteArrayToBigInt", "longToByteArray", "byteArrayToLong", "proveDlog", "proveDHTuple", "groupGenerator", "substConstants", "decodePoint", "BigInt", "toBigInteger", "avlTree" + "Colls", "Monoids", "Costing", "CostModel", "verifyZK", "atLeast", "allOf", "allZK", "anyOf", "anyZK", "xorOf", "PubKey", "sigmaProp", "blake2b256", "sha256", "byteArrayToBigInt", "longToByteArray", "byteArrayToLong", "proveDlog", "proveDHTuple", "groupGenerator", "substConstants", "decodePoint", "avlTree", "xor" )) } - - lazy val parent: Option[Elem[_]] = None - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override lazy val tag = { - weakTypeTag[SigmaDslBuilder].asInstanceOf[WeakTypeTag[To]] - } - override def convert(x: Rep[Def[_]]) = { - val conv = fun {x: Rep[SigmaDslBuilder] => convertSigmaDslBuilder(x) } - tryConvert(element[SigmaDslBuilder], this, x, conv) - } - - def convertSigmaDslBuilder(x: Rep[SigmaDslBuilder]): Rep[To] = { - x.elem match { - case _: SigmaDslBuilderElem[_] => asRep[To](x) - case e => !!!(s"Expected $x to have SigmaDslBuilderElem[_], but got $e", x) - } - } - override def getDefaultRep: Rep[To] = ??? } implicit lazy val sigmaDslBuilderElement: Elem[SigmaDslBuilder] = new SigmaDslBuilderElem[SigmaDslBuilder] - implicit case object SigmaDslBuilderCompanionElem extends CompanionElem[SigmaDslBuilderCompanionCtor] { - lazy val tag = weakTypeTag[SigmaDslBuilderCompanionCtor] - protected def getDefaultRep = RSigmaDslBuilder - } + implicit case object SigmaDslBuilderCompanionElem extends CompanionElem[SigmaDslBuilderCompanionCtor] abstract class SigmaDslBuilderCompanionCtor extends CompanionDef[SigmaDslBuilderCompanionCtor] with SigmaDslBuilderCompanion { - def selfType = SigmaDslBuilderCompanionElem + def resultType = SigmaDslBuilderCompanionElem override def toString = "SigmaDslBuilder" } - implicit def proxySigmaDslBuilderCompanionCtor(p: Rep[SigmaDslBuilderCompanionCtor]): SigmaDslBuilderCompanionCtor = - proxyOps[SigmaDslBuilderCompanionCtor](p) + implicit final def unrefSigmaDslBuilderCompanionCtor(p: Ref[SigmaDslBuilderCompanionCtor]): SigmaDslBuilderCompanionCtor = + p.node.asInstanceOf[SigmaDslBuilderCompanionCtor] - lazy val RSigmaDslBuilder: Rep[SigmaDslBuilderCompanionCtor] = new SigmaDslBuilderCompanionCtor { + lazy val RSigmaDslBuilder: MutableLazy[SigmaDslBuilderCompanionCtor] = MutableLazy(new SigmaDslBuilderCompanionCtor { private val thisClass = classOf[SigmaDslBuilderCompanion] - } + }) object SigmaDslBuilderMethods { object Colls { - def unapply(d: Def[_]): Nullable[Rep[SigmaDslBuilder]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] && method.getName == "Colls" => + def unapply(d: Def[_]): Nullable[Ref[SigmaDslBuilder]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "Colls" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[SigmaDslBuilder]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[SigmaDslBuilder]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[SigmaDslBuilder]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[SigmaDslBuilder]] = unapply(exp.node) } object Monoids { - def unapply(d: Def[_]): Nullable[Rep[SigmaDslBuilder]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] && method.getName == "Monoids" => + def unapply(d: Def[_]): Nullable[Ref[SigmaDslBuilder]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "Monoids" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[SigmaDslBuilder]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[SigmaDslBuilder]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[SigmaDslBuilder]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[SigmaDslBuilder]] = unapply(exp.node) } object Costing { - def unapply(d: Def[_]): Nullable[Rep[SigmaDslBuilder]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] && method.getName == "Costing" => + def unapply(d: Def[_]): Nullable[Ref[SigmaDslBuilder]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "Costing" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[SigmaDslBuilder]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[SigmaDslBuilder]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[SigmaDslBuilder]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[SigmaDslBuilder]] = unapply(exp.node) } object CostModel { - def unapply(d: Def[_]): Nullable[Rep[SigmaDslBuilder]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] && method.getName == "CostModel" => + def unapply(d: Def[_]): Nullable[Ref[SigmaDslBuilder]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "CostModel" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[SigmaDslBuilder]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[SigmaDslBuilder]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[SigmaDslBuilder]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[SigmaDslBuilder]] = unapply(exp.node) } object verifyZK { - def unapply(d: Def[_]): Nullable[(Rep[SigmaDslBuilder], Rep[Thunk[SigmaProp]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] && method.getName == "verifyZK" => + def unapply(d: Def[_]): Nullable[(Ref[SigmaDslBuilder], Ref[Thunk[SigmaProp]])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "verifyZK" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaDslBuilder], Rep[Thunk[SigmaProp]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaDslBuilder], Rep[Thunk[SigmaProp]])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[SigmaDslBuilder], Ref[Thunk[SigmaProp]])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[SigmaDslBuilder], Ref[Thunk[SigmaProp]])] = unapply(exp.node) } object atLeast { - def unapply(d: Def[_]): Nullable[(Rep[SigmaDslBuilder], Rep[Int], Rep[Coll[SigmaProp]])] = d match { + def unapply(d: Def[_]): Nullable[(Ref[SigmaDslBuilder], Ref[Int], Ref[Coll[SigmaProp]])] = d match { case MethodCall(receiver, method, args, _) if method.getName == "atLeast" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaDslBuilder], Rep[Int], Rep[Coll[SigmaProp]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaDslBuilder], Rep[Int], Rep[Coll[SigmaProp]])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[SigmaDslBuilder], Ref[Int], Ref[Coll[SigmaProp]])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[SigmaDslBuilder], Ref[Int], Ref[Coll[SigmaProp]])] = unapply(exp.node) } object allOf { - def unapply(d: Def[_]): Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Boolean]])] = d match { + def unapply(d: Def[_]): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Boolean]])] = d match { case MethodCall(receiver, method, args, _) if method.getName == "allOf" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Boolean]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Boolean]])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Boolean]])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Boolean]])] = unapply(exp.node) } object allZK { - def unapply(d: Def[_]): Nullable[(Rep[SigmaDslBuilder], Rep[Coll[SigmaProp]])] = d match { + def unapply(d: Def[_]): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[SigmaProp]])] = d match { case MethodCall(receiver, method, args, _) if method.getName == "allZK" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaDslBuilder], Rep[Coll[SigmaProp]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaDslBuilder], Rep[Coll[SigmaProp]])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[SigmaDslBuilder], Ref[Coll[SigmaProp]])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[SigmaProp]])] = unapply(exp.node) } object anyOf { - def unapply(d: Def[_]): Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Boolean]])] = d match { + def unapply(d: Def[_]): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Boolean]])] = d match { case MethodCall(receiver, method, args, _) if method.getName == "anyOf" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Boolean]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Boolean]])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Boolean]])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Boolean]])] = unapply(exp.node) } object anyZK { - def unapply(d: Def[_]): Nullable[(Rep[SigmaDslBuilder], Rep[Coll[SigmaProp]])] = d match { + def unapply(d: Def[_]): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[SigmaProp]])] = d match { case MethodCall(receiver, method, args, _) if method.getName == "anyZK" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaDslBuilder], Rep[Coll[SigmaProp]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaDslBuilder], Rep[Coll[SigmaProp]])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[SigmaDslBuilder], Ref[Coll[SigmaProp]])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[SigmaProp]])] = unapply(exp.node) } object xorOf { - def unapply(d: Def[_]): Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Boolean]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] && method.getName == "xorOf" => + def unapply(d: Def[_]): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Boolean]])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "xorOf" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Boolean]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Boolean]])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Boolean]])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Boolean]])] = unapply(exp.node) } object PubKey { - def unapply(d: Def[_]): Nullable[(Rep[SigmaDslBuilder], Rep[String])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] && method.getName == "PubKey" => + def unapply(d: Def[_]): Nullable[(Ref[SigmaDslBuilder], Ref[String])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "PubKey" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaDslBuilder], Rep[String])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaDslBuilder], Rep[String])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[SigmaDslBuilder], Ref[String])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[SigmaDslBuilder], Ref[String])] = unapply(exp.node) } object sigmaProp { - def unapply(d: Def[_]): Nullable[(Rep[SigmaDslBuilder], Rep[Boolean])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] && method.getName == "sigmaProp" => + def unapply(d: Def[_]): Nullable[(Ref[SigmaDslBuilder], Ref[Boolean])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "sigmaProp" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaDslBuilder], Rep[Boolean])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaDslBuilder], Rep[Boolean])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[SigmaDslBuilder], Ref[Boolean])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[SigmaDslBuilder], Ref[Boolean])] = unapply(exp.node) } object blake2b256 { - def unapply(d: Def[_]): Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Byte]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] && method.getName == "blake2b256" => + def unapply(d: Def[_]): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "blake2b256" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Byte]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Byte]])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]])] = unapply(exp.node) } object sha256 { - def unapply(d: Def[_]): Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Byte]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] && method.getName == "sha256" => + def unapply(d: Def[_]): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "sha256" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Byte]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Byte]])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]])] = unapply(exp.node) } object byteArrayToBigInt { - def unapply(d: Def[_]): Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Byte]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] && method.getName == "byteArrayToBigInt" => + def unapply(d: Def[_]): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "byteArrayToBigInt" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Byte]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Byte]])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]])] = unapply(exp.node) } object longToByteArray { - def unapply(d: Def[_]): Nullable[(Rep[SigmaDslBuilder], Rep[Long])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] && method.getName == "longToByteArray" => + def unapply(d: Def[_]): Nullable[(Ref[SigmaDslBuilder], Ref[Long])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "longToByteArray" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaDslBuilder], Rep[Long])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaDslBuilder], Rep[Long])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[SigmaDslBuilder], Ref[Long])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[SigmaDslBuilder], Ref[Long])] = unapply(exp.node) } object byteArrayToLong { - def unapply(d: Def[_]): Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Byte]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] && method.getName == "byteArrayToLong" => + def unapply(d: Def[_]): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "byteArrayToLong" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Byte]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Byte]])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]])] = unapply(exp.node) } object proveDlog { - def unapply(d: Def[_]): Nullable[(Rep[SigmaDslBuilder], Rep[GroupElement])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] && method.getName == "proveDlog" => + def unapply(d: Def[_]): Nullable[(Ref[SigmaDslBuilder], Ref[GroupElement])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "proveDlog" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaDslBuilder], Rep[GroupElement])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaDslBuilder], Rep[GroupElement])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[SigmaDslBuilder], Ref[GroupElement])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[SigmaDslBuilder], Ref[GroupElement])] = unapply(exp.node) } object proveDHTuple { - def unapply(d: Def[_]): Nullable[(Rep[SigmaDslBuilder], Rep[GroupElement], Rep[GroupElement], Rep[GroupElement], Rep[GroupElement])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] && method.getName == "proveDHTuple" => + def unapply(d: Def[_]): Nullable[(Ref[SigmaDslBuilder], Ref[GroupElement], Ref[GroupElement], Ref[GroupElement], Ref[GroupElement])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "proveDHTuple" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => val res = (receiver, args(0), args(1), args(2), args(3)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaDslBuilder], Rep[GroupElement], Rep[GroupElement], Rep[GroupElement], Rep[GroupElement])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaDslBuilder], Rep[GroupElement], Rep[GroupElement], Rep[GroupElement], Rep[GroupElement])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[SigmaDslBuilder], Ref[GroupElement], Ref[GroupElement], Ref[GroupElement], Ref[GroupElement])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[SigmaDslBuilder], Ref[GroupElement], Ref[GroupElement], Ref[GroupElement], Ref[GroupElement])] = unapply(exp.node) } object groupGenerator { - def unapply(d: Def[_]): Nullable[Rep[SigmaDslBuilder]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] && method.getName == "groupGenerator" => + def unapply(d: Def[_]): Nullable[Ref[SigmaDslBuilder]] = d match { + case MethodCall(receiver, method, _, _) if method.getName == "groupGenerator" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[SigmaDslBuilder]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[SigmaDslBuilder]] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[Ref[SigmaDslBuilder]]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[Ref[SigmaDslBuilder]] = unapply(exp.node) } object substConstants { - def unapply(d: Def[_]): Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Byte]], Rep[Coll[Int]], Rep[Coll[T]], Elem[T]) forSome {type T}] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] && method.getName == "substConstants" => + def unapply(d: Def[_]): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]], Ref[Coll[Int]], Ref[Coll[T]], Elem[T]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "substConstants" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => val res = (receiver, args(0), args(1), args(2), args(3)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Byte]], Rep[Coll[Int]], Rep[Coll[T]], Elem[T]) forSome {type T}]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Byte]], Rep[Coll[Int]], Rep[Coll[T]], Elem[T]) forSome {type T}] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]], Ref[Coll[Int]], Ref[Coll[T]], Elem[T]) forSome {type T}]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]], Ref[Coll[Int]], Ref[Coll[T]], Elem[T]) forSome {type T}] = unapply(exp.node) } object decodePoint { - def unapply(d: Def[_]): Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Byte]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] && method.getName == "decodePoint" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Byte]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaDslBuilder], Rep[Coll[Byte]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object BigInt { - def unapply(d: Def[_]): Nullable[(Rep[SigmaDslBuilder], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] && method.getName == "BigInt" => + def unapply(d: Def[_]): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "decodePoint" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaDslBuilder], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaDslBuilder], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object toBigInteger { - def unapply(d: Def[_]): Nullable[(Rep[SigmaDslBuilder], Rep[BigInt])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] && method.getName == "toBigInteger" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaDslBuilder], Rep[BigInt])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaDslBuilder], Rep[BigInt])] = exp match { - case Def(d) => unapply(d) + Nullable(res).asInstanceOf[Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]])] = unapply(exp.node) } object avlTree { - def unapply(d: Def[_]): Nullable[(Rep[SigmaDslBuilder], Rep[Byte], Rep[Coll[Byte]], Rep[Int], Rep[WOption[Int]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] && method.getName == "avlTree" => + def unapply(d: Def[_]): Nullable[(Ref[SigmaDslBuilder], Ref[Byte], Ref[Coll[Byte]], Ref[Int], Ref[WOption[Int]])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "avlTree" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => val res = (receiver, args(0), args(1), args(2), args(3)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaDslBuilder], Rep[Byte], Rep[Coll[Byte]], Rep[Int], Rep[WOption[Int]])]] + Nullable(res).asInstanceOf[Nullable[(Ref[SigmaDslBuilder], Ref[Byte], Ref[Coll[Byte]], Ref[Int], Ref[WOption[Int]])]] case _ => Nullable.None } - def unapply(exp: Sym): Nullable[(Rep[SigmaDslBuilder], Rep[Byte], Rep[Coll[Byte]], Rep[Int], Rep[WOption[Int]])] = exp match { - case Def(d) => unapply(d) + def unapply(exp: Sym): Nullable[(Ref[SigmaDslBuilder], Ref[Byte], Ref[Coll[Byte]], Ref[Int], Ref[WOption[Int]])] = unapply(exp.node) + } + + object xor { + def unapply(d: Def[_]): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]], Ref[Coll[Byte]])] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "xor" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => + val res = (receiver, args(0), args(1)) + Nullable(res).asInstanceOf[Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]], Ref[Coll[Byte]])]] case _ => Nullable.None } + def unapply(exp: Sym): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]], Ref[Coll[Byte]])] = unapply(exp.node) } } @@ -5352,6 +3861,22 @@ object SigmaDslBuilder extends EntityObject("SigmaDslBuilder") { } // of object SigmaDslBuilder registerEntityObject("SigmaDslBuilder", SigmaDslBuilder) + override def resetContext(): Unit = { + super.resetContext() + RCostModel.reset() + RBigInt.reset() + RGroupElement.reset() + RSigmaProp.reset() + RAnyValue.reset() + RBox.reset() + RAvlTree.reset() + RPreHeader.reset() + RHeader.reset() + RContext.reset() + RSigmaContract.reset() + RSigmaDslBuilder.reset() + } + registerModule(SigmaDslModule) } diff --git a/sigma-library/src/main/scala/special/sigma/impl/SigmaDslOverArraysImpl.scala b/sigma-library/src/main/scala/special/sigma/impl/SigmaDslOverArraysImpl.scala deleted file mode 100644 index e4a9a7aa5b..0000000000 --- a/sigma-library/src/main/scala/special/sigma/impl/SigmaDslOverArraysImpl.scala +++ /dev/null @@ -1,685 +0,0 @@ -package special.sigma - -import scalan._ -import scala.reflect.runtime.universe._ -import scala.reflect._ - -package impl { -// Abs ----------------------------------- -trait SigmaDslOverArraysDefs extends scalan.Scalan with SigmaDslOverArrays { - self: SigmaLibrary => -import IsoUR._ -import Converter._ -import AvlTree._ -import BigInt._ -import CCostedBuilder._ -import Coll._ -import CollBuilder._ -import CollOverArrayBuilder._ -import CostModel._ -import CostedBuilder._ -import GroupElement._ -import MonoidBuilder._ -import MonoidBuilderInst._ -import SigmaDslBuilder._ -import SigmaProp._ -import WBigInteger._ -import WECPoint._ -import WOption._ -import TestSigmaDslBuilder._ - -object TestSigmaDslBuilder extends EntityObject("TestSigmaDslBuilder") { - case class TestSigmaDslBuilderCtor - () - extends TestSigmaDslBuilder() with Def[TestSigmaDslBuilder] { - lazy val selfType = element[TestSigmaDslBuilder] - override def transform(t: Transformer) = TestSigmaDslBuilderCtor() - private val thisClass = classOf[SigmaDslBuilder] - - override def CostModel: Rep[CostModel] = { - asRep[CostModel](mkMethodCall(self, - thisClass.getMethod("CostModel"), - List(), - true, false, element[CostModel])) - } - - override def verifyZK(proof: Rep[Thunk[SigmaProp]]): Rep[Boolean] = { - asRep[Boolean](mkMethodCall(self, - thisClass.getMethod("verifyZK", classOf[Sym]), - List(proof), - true, false, element[Boolean])) - } - - override def atLeast(bound: Rep[Int], props: Rep[Coll[SigmaProp]]): Rep[SigmaProp] = { - asRep[SigmaProp](mkMethodCall(self, - thisClass.getMethod("atLeast", classOf[Sym], classOf[Sym]), - List(bound, props), - true, false, element[SigmaProp])) - } - - override def allOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean] = { - asRep[Boolean](mkMethodCall(self, - thisClass.getMethod("allOf", classOf[Sym]), - List(conditions), - true, false, element[Boolean])) - } - - override def anyOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean] = { - asRep[Boolean](mkMethodCall(self, - thisClass.getMethod("anyOf", classOf[Sym]), - List(conditions), - true, false, element[Boolean])) - } - - override def allZK(props: Rep[Coll[SigmaProp]]): Rep[SigmaProp] = { - asRep[SigmaProp](mkMethodCall(self, - thisClass.getMethod("allZK", classOf[Sym]), - List(props), - true, false, element[SigmaProp])) - } - - override def anyZK(props: Rep[Coll[SigmaProp]]): Rep[SigmaProp] = { - asRep[SigmaProp](mkMethodCall(self, - thisClass.getMethod("anyZK", classOf[Sym]), - List(props), - true, false, element[SigmaProp])) - } - - override def xorOf(conditions: Rep[Coll[Boolean]]): Rep[Boolean] = { - asRep[Boolean](mkMethodCall(self, - thisClass.getMethod("xorOf", classOf[Sym]), - List(conditions), - true, false, element[Boolean])) - } - - override def sigmaProp(b: Rep[Boolean]): Rep[SigmaProp] = { - asRep[SigmaProp](mkMethodCall(self, - thisClass.getMethod("sigmaProp", classOf[Sym]), - List(b), - true, false, element[SigmaProp])) - } - - override def blake2b256(bytes: Rep[Coll[Byte]]): Rep[Coll[Byte]] = { - asRep[Coll[Byte]](mkMethodCall(self, - thisClass.getMethod("blake2b256", classOf[Sym]), - List(bytes), - true, false, element[Coll[Byte]])) - } - - override def sha256(bytes: Rep[Coll[Byte]]): Rep[Coll[Byte]] = { - asRep[Coll[Byte]](mkMethodCall(self, - thisClass.getMethod("sha256", classOf[Sym]), - List(bytes), - true, false, element[Coll[Byte]])) - } - - override def PubKey(base64String: Rep[String]): Rep[SigmaProp] = { - asRep[SigmaProp](mkMethodCall(self, - thisClass.getMethod("PubKey", classOf[Sym]), - List(base64String), - true, false, element[SigmaProp])) - } - - override def byteArrayToBigInt(bytes: Rep[Coll[Byte]]): Rep[BigInt] = { - asRep[BigInt](mkMethodCall(self, - thisClass.getMethod("byteArrayToBigInt", classOf[Sym]), - List(bytes), - true, false, element[BigInt])) - } - - override def longToByteArray(l: Rep[Long]): Rep[Coll[Byte]] = { - asRep[Coll[Byte]](mkMethodCall(self, - thisClass.getMethod("longToByteArray", classOf[Sym]), - List(l), - true, false, element[Coll[Byte]])) - } - - override def byteArrayToLong(bytes: Rep[Coll[Byte]]): Rep[Long] = { - asRep[Long](mkMethodCall(self, - thisClass.getMethod("byteArrayToLong", classOf[Sym]), - List(bytes), - true, false, element[Long])) - } - - override def proveDlog(g: Rep[GroupElement]): Rep[SigmaProp] = { - asRep[SigmaProp](mkMethodCall(self, - thisClass.getMethod("proveDlog", classOf[Sym]), - List(g), - true, false, element[SigmaProp])) - } - - override def proveDHTuple(g: Rep[GroupElement], h: Rep[GroupElement], u: Rep[GroupElement], v: Rep[GroupElement]): Rep[SigmaProp] = { - asRep[SigmaProp](mkMethodCall(self, - thisClass.getMethod("proveDHTuple", classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym]), - List(g, h, u, v), - true, false, element[SigmaProp])) - } - - override def groupGenerator: Rep[GroupElement] = { - asRep[GroupElement](mkMethodCall(self, - thisClass.getMethod("groupGenerator"), - List(), - true, false, element[GroupElement])) - } - - override def substConstants[T](scriptBytes: Rep[Coll[Byte]], positions: Rep[Coll[Int]], newValues: Rep[Coll[T]])(implicit cT: Elem[T]): Rep[Coll[Byte]] = { - implicit val eT = newValues.eA - asRep[Coll[Byte]](mkMethodCall(self, - thisClass.getMethod("substConstants", classOf[Sym], classOf[Sym], classOf[Sym], classOf[Elem[_]]), - List(scriptBytes, positions, newValues, cT), - true, false, element[Coll[Byte]])) - } - - override def decodePoint(encoded: Rep[Coll[Byte]]): Rep[GroupElement] = { - asRep[GroupElement](mkMethodCall(self, - thisClass.getMethod("decodePoint", classOf[Sym]), - List(encoded), - true, false, element[GroupElement])) - } - - override def BigInt(n: Rep[WBigInteger]): Rep[BigInt] = { - asRep[BigInt](mkMethodCall(self, - thisClass.getMethod("BigInt", classOf[Sym]), - List(n), - true, false, element[BigInt])) - } - - override def toBigInteger(n: Rep[BigInt]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - thisClass.getMethod("toBigInteger", classOf[Sym]), - List(n), - true, false, element[WBigInteger])) - } - - override def GroupElement(p: Rep[WECPoint]): Rep[GroupElement] = { - asRep[GroupElement](mkMethodCall(self, - thisClass.getMethod("GroupElement", classOf[Sym]), - List(p), - true, false, element[GroupElement])) - } - - override def toECPoint(ge: Rep[GroupElement]): Rep[WECPoint] = { - asRep[WECPoint](mkMethodCall(self, - thisClass.getMethod("toECPoint", classOf[Sym]), - List(ge), - true, false, element[WECPoint])) - } - - override def avlTree(operationFlags: Rep[Byte], digest: Rep[Coll[Byte]], keyLength: Rep[Int], valueLengthOpt: Rep[WOption[Int]]): Rep[AvlTree] = { - asRep[AvlTree](mkMethodCall(self, - thisClass.getMethod("avlTree", classOf[Sym], classOf[Sym], classOf[Sym], classOf[Sym]), - List(operationFlags, digest, keyLength, valueLengthOpt), - true, false, element[AvlTree])) - } - } - // elem for concrete class - class TestSigmaDslBuilderElem(val iso: Iso[TestSigmaDslBuilderData, TestSigmaDslBuilder]) - extends SigmaDslBuilderElem[TestSigmaDslBuilder] - with ConcreteElem[TestSigmaDslBuilderData, TestSigmaDslBuilder] { - override lazy val parent: Option[Elem[_]] = Some(sigmaDslBuilderElement) - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override def convertSigmaDslBuilder(x: Rep[SigmaDslBuilder]) = RTestSigmaDslBuilder() - override def getDefaultRep = RTestSigmaDslBuilder() - override lazy val tag = { - weakTypeTag[TestSigmaDslBuilder] - } - } - - // state representation type - type TestSigmaDslBuilderData = Unit - - // 3) Iso for concrete class - class TestSigmaDslBuilderIso - extends EntityIso[TestSigmaDslBuilderData, TestSigmaDslBuilder] with Def[TestSigmaDslBuilderIso] { - override def transform(t: Transformer) = new TestSigmaDslBuilderIso() - private lazy val _safeFrom = fun { p: Rep[TestSigmaDslBuilder] => () } - override def from(p: Rep[TestSigmaDslBuilder]) = - tryConvert[TestSigmaDslBuilder, Unit](eTo, eFrom, p, _safeFrom) - override def to(p: Rep[Unit]) = { - val unit = p - RTestSigmaDslBuilder() - } - lazy val eFrom = UnitElement - lazy val eTo = new TestSigmaDslBuilderElem(self) - lazy val selfType = new TestSigmaDslBuilderIsoElem - def productArity = 0 - def productElement(n: Int) = ??? - } - case class TestSigmaDslBuilderIsoElem() extends Elem[TestSigmaDslBuilderIso] { - def getDefaultRep = reifyObject(new TestSigmaDslBuilderIso()) - lazy val tag = { - weakTypeTag[TestSigmaDslBuilderIso] - } - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - } - // 4) constructor and deconstructor - class TestSigmaDslBuilderCompanionCtor extends CompanionDef[TestSigmaDslBuilderCompanionCtor] with TestSigmaDslBuilderCompanion { - def selfType = TestSigmaDslBuilderCompanionElem - override def toString = "TestSigmaDslBuilderCompanion" - @scalan.OverloadId("fromData") - def apply(p: Rep[TestSigmaDslBuilderData]): Rep[TestSigmaDslBuilder] = { - isoTestSigmaDslBuilder.to(p) - } - - @scalan.OverloadId("fromFields") - def apply(): Rep[TestSigmaDslBuilder] = - mkTestSigmaDslBuilder() - - def unapply(p: Rep[SigmaDslBuilder]) = unmkTestSigmaDslBuilder(p) - } - lazy val TestSigmaDslBuilderRep: Rep[TestSigmaDslBuilderCompanionCtor] = new TestSigmaDslBuilderCompanionCtor - lazy val RTestSigmaDslBuilder: TestSigmaDslBuilderCompanionCtor = proxyTestSigmaDslBuilderCompanion(TestSigmaDslBuilderRep) - implicit def proxyTestSigmaDslBuilderCompanion(p: Rep[TestSigmaDslBuilderCompanionCtor]): TestSigmaDslBuilderCompanionCtor = { - if (p.rhs.isInstanceOf[TestSigmaDslBuilderCompanionCtor]) - p.rhs.asInstanceOf[TestSigmaDslBuilderCompanionCtor] - else - proxyOps[TestSigmaDslBuilderCompanionCtor](p) - } - - implicit case object TestSigmaDslBuilderCompanionElem extends CompanionElem[TestSigmaDslBuilderCompanionCtor] { - lazy val tag = weakTypeTag[TestSigmaDslBuilderCompanionCtor] - protected def getDefaultRep = TestSigmaDslBuilderRep - } - - implicit def proxyTestSigmaDslBuilder(p: Rep[TestSigmaDslBuilder]): TestSigmaDslBuilder = - proxyOps[TestSigmaDslBuilder](p) - - implicit class ExtendedTestSigmaDslBuilder(p: Rep[TestSigmaDslBuilder]) { - def toData: Rep[TestSigmaDslBuilderData] = { - isoTestSigmaDslBuilder.from(p) - } - } - - // 5) implicit resolution of Iso - implicit def isoTestSigmaDslBuilder: Iso[TestSigmaDslBuilderData, TestSigmaDslBuilder] = - reifyObject(new TestSigmaDslBuilderIso()) - - def mkTestSigmaDslBuilder - (): Rep[TestSigmaDslBuilder] = { - new TestSigmaDslBuilderCtor() - } - def unmkTestSigmaDslBuilder(p: Rep[SigmaDslBuilder]) = p.elem.asInstanceOf[Elem[_]] match { - case _: TestSigmaDslBuilderElem @unchecked => - Some(()) - case _ => - None - } - - object TestSigmaDslBuilderMethods { - object Colls { - def unapply(d: Def[_]): Nullable[Rep[TestSigmaDslBuilder]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "Colls" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[TestSigmaDslBuilder]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[TestSigmaDslBuilder]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object Monoids { - def unapply(d: Def[_]): Nullable[Rep[TestSigmaDslBuilder]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "Monoids" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[TestSigmaDslBuilder]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[TestSigmaDslBuilder]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object Costing { - def unapply(d: Def[_]): Nullable[Rep[TestSigmaDslBuilder]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "Costing" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[TestSigmaDslBuilder]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[TestSigmaDslBuilder]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object CostModel { - def unapply(d: Def[_]): Nullable[Rep[TestSigmaDslBuilder]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "CostModel" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[TestSigmaDslBuilder]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[TestSigmaDslBuilder]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object verifyZK { - def unapply(d: Def[_]): Nullable[(Rep[TestSigmaDslBuilder], Rep[Thunk[SigmaProp]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "verifyZK" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[TestSigmaDslBuilder], Rep[Thunk[SigmaProp]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[TestSigmaDslBuilder], Rep[Thunk[SigmaProp]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object atLeast { - def unapply(d: Def[_]): Nullable[(Rep[TestSigmaDslBuilder], Rep[Int], Rep[Coll[SigmaProp]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "atLeast" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[TestSigmaDslBuilder], Rep[Int], Rep[Coll[SigmaProp]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[TestSigmaDslBuilder], Rep[Int], Rep[Coll[SigmaProp]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object allOf { - def unapply(d: Def[_]): Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Boolean]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "allOf" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Boolean]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Boolean]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object anyOf { - def unapply(d: Def[_]): Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Boolean]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "anyOf" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Boolean]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Boolean]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object allZK { - def unapply(d: Def[_]): Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[SigmaProp]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "allZK" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[SigmaProp]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[SigmaProp]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object anyZK { - def unapply(d: Def[_]): Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[SigmaProp]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "anyZK" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[SigmaProp]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[SigmaProp]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object xorOf { - def unapply(d: Def[_]): Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Boolean]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "xorOf" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Boolean]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Boolean]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object sigmaProp { - def unapply(d: Def[_]): Nullable[(Rep[TestSigmaDslBuilder], Rep[Boolean])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "sigmaProp" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[TestSigmaDslBuilder], Rep[Boolean])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[TestSigmaDslBuilder], Rep[Boolean])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object blake2b256 { - def unapply(d: Def[_]): Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Byte]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "blake2b256" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Byte]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Byte]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object sha256 { - def unapply(d: Def[_]): Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Byte]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "sha256" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Byte]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Byte]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object PubKey { - def unapply(d: Def[_]): Nullable[(Rep[TestSigmaDslBuilder], Rep[String])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "PubKey" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[TestSigmaDslBuilder], Rep[String])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[TestSigmaDslBuilder], Rep[String])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object byteArrayToBigInt { - def unapply(d: Def[_]): Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Byte]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "byteArrayToBigInt" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Byte]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Byte]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object longToByteArray { - def unapply(d: Def[_]): Nullable[(Rep[TestSigmaDslBuilder], Rep[Long])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "longToByteArray" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[TestSigmaDslBuilder], Rep[Long])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[TestSigmaDslBuilder], Rep[Long])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object byteArrayToLong { - def unapply(d: Def[_]): Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Byte]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "byteArrayToLong" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Byte]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Byte]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object proveDlog { - def unapply(d: Def[_]): Nullable[(Rep[TestSigmaDslBuilder], Rep[GroupElement])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "proveDlog" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[TestSigmaDslBuilder], Rep[GroupElement])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[TestSigmaDslBuilder], Rep[GroupElement])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object proveDHTuple { - def unapply(d: Def[_]): Nullable[(Rep[TestSigmaDslBuilder], Rep[GroupElement], Rep[GroupElement], Rep[GroupElement], Rep[GroupElement])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "proveDHTuple" => - val res = (receiver, args(0), args(1), args(2), args(3)) - Nullable(res).asInstanceOf[Nullable[(Rep[TestSigmaDslBuilder], Rep[GroupElement], Rep[GroupElement], Rep[GroupElement], Rep[GroupElement])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[TestSigmaDslBuilder], Rep[GroupElement], Rep[GroupElement], Rep[GroupElement], Rep[GroupElement])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object groupGenerator { - def unapply(d: Def[_]): Nullable[Rep[TestSigmaDslBuilder]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "groupGenerator" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[TestSigmaDslBuilder]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[TestSigmaDslBuilder]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object substConstants { - def unapply(d: Def[_]): Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Byte]], Rep[Coll[Int]], Rep[Coll[T]], Elem[T]) forSome {type T}] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "substConstants" => - val res = (receiver, args(0), args(1), args(2), args(3)) - Nullable(res).asInstanceOf[Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Byte]], Rep[Coll[Int]], Rep[Coll[T]], Elem[T]) forSome {type T}]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Byte]], Rep[Coll[Int]], Rep[Coll[T]], Elem[T]) forSome {type T}] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object decodePoint { - def unapply(d: Def[_]): Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Byte]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "decodePoint" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Byte]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[TestSigmaDslBuilder], Rep[Coll[Byte]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object BigInt { - def unapply(d: Def[_]): Nullable[(Rep[TestSigmaDslBuilder], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "BigInt" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[TestSigmaDslBuilder], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[TestSigmaDslBuilder], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object toBigInteger { - def unapply(d: Def[_]): Nullable[(Rep[TestSigmaDslBuilder], Rep[BigInt])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "toBigInteger" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[TestSigmaDslBuilder], Rep[BigInt])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[TestSigmaDslBuilder], Rep[BigInt])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object GroupElement { - def unapply(d: Def[_]): Nullable[(Rep[TestSigmaDslBuilder], Rep[WECPoint])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "GroupElement" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[TestSigmaDslBuilder], Rep[WECPoint])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[TestSigmaDslBuilder], Rep[WECPoint])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object toECPoint { - def unapply(d: Def[_]): Nullable[(Rep[TestSigmaDslBuilder], Rep[GroupElement])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "toECPoint" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[TestSigmaDslBuilder], Rep[GroupElement])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[TestSigmaDslBuilder], Rep[GroupElement])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object avlTree { - def unapply(d: Def[_]): Nullable[(Rep[TestSigmaDslBuilder], Rep[Byte], Rep[Coll[Byte]], Rep[Int], Rep[WOption[Int]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[TestSigmaDslBuilderElem] && method.getName == "avlTree" => - val res = (receiver, args(0), args(1), args(2), args(3)) - Nullable(res).asInstanceOf[Nullable[(Rep[TestSigmaDslBuilder], Rep[Byte], Rep[Coll[Byte]], Rep[Int], Rep[WOption[Int]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[TestSigmaDslBuilder], Rep[Byte], Rep[Coll[Byte]], Rep[Int], Rep[WOption[Int]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - } - - object TestSigmaDslBuilderCompanionMethods { - } -} // of object TestSigmaDslBuilder - registerEntityObject("TestSigmaDslBuilder", TestSigmaDslBuilder) - - registerModule(SigmaDslOverArraysModule) -} - -object SigmaDslOverArraysModule extends scalan.ModuleInfo("special.sigma", "SigmaDslOverArrays") -} - -trait SigmaDslOverArraysModule extends special.sigma.impl.SigmaDslOverArraysDefs {self: SigmaLibrary =>} diff --git a/sigma-library/src/main/scala/special/sigma/wrappers/WrappersModule.scala b/sigma-library/src/main/scala/special/sigma/wrappers/WrappersModule.scala index 6d57a4ea32..84fc0abdd3 100644 --- a/sigma-library/src/main/scala/special/sigma/wrappers/WrappersModule.scala +++ b/sigma-library/src/main/scala/special/sigma/wrappers/WrappersModule.scala @@ -1,11 +1,4 @@ package special.sigma.wrappers -import wrappers.java.math.WBigIntegersModule -import wrappers.org.bouncycastle.math.ec.WECPointsModule -import wrappers.special.sigma.WSigmaPredefsModule - trait WrappersModule extends special.wrappers.WrappersModule - with WSigmaPredefsModule - with WECPointsModule - with WBigIntegersModule diff --git a/sigma-library/src/main/scala/special/sigma/wrappers/WrappersSpec.scala b/sigma-library/src/main/scala/special/sigma/wrappers/WrappersSpec.scala deleted file mode 100644 index a456948701..0000000000 --- a/sigma-library/src/main/scala/special/sigma/wrappers/WrappersSpec.scala +++ /dev/null @@ -1,67 +0,0 @@ -package special.sigma.wrappers { - import scalan._ - - trait WrappersSpec extends Base { self: SigmaLibrary => - import WArray._; - import WBigInteger._; - import WECPoint._; - import WSigmaPredef._; - import WrapSpecBase._; - trait ECPointWrapSpec extends WrapSpecBase { - def getEncoded[A](g: Rep[WECPoint], compressed: Rep[Boolean]): Rep[WArray[Byte]] = g.getEncoded(compressed); - def multiply(l: Rep[WECPoint], r: Rep[WBigInteger]): Rep[WECPoint] = l.multiply(r); - def add(l: Rep[WECPoint], r: Rep[WECPoint]): Rep[WECPoint] = l.add(r) - }; - trait BigIntegerWrapSpec extends WrapSpecBase { - def fromString(s: Rep[String]): Rep[WBigInteger] = RWBigInteger(s); - def fromArray(sig: Rep[Int], arr: Rep[WArray[Byte]]): Rep[WBigInteger] = RWBigInteger(sig, arr); - def valueOf(l: Rep[Long]): Rep[WBigInteger] = RWBigInteger.valueOf(l); - def toByteArray(l: Rep[WBigInteger]): Rep[WArray[Byte]] = l.toByteArray; - def add(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.add(r); - def subtract(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.subtract(r); - def multiply(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.multiply(r); - def mod(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.mod(r); - def modInverse(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.modInverse(r); - def modPow(l: Rep[WBigInteger], exponent: Rep[WBigInteger], m: Rep[WBigInteger]): Rep[WBigInteger] = l.modPow(exponent, m); - def remainder(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.remainder(r); - def divide(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.divide(r); - def compareTo(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[Int] = l.compareTo(r); - def min(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.min(r); - def max(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.max(r); - def gcd(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.gcd(r); - def and(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.and(r); - def or(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.or(r); - def xor(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.xor(r); - def not(l: Rep[WBigInteger]): Rep[WBigInteger] = l.not; - def andNot(l: Rep[WBigInteger], r: Rep[WBigInteger]): Rep[WBigInteger] = l.andNot(r); - def pow(l: Rep[WBigInteger], r: Rep[Int]): Rep[WBigInteger] = l.pow(r); - def testBit(l: Rep[WBigInteger], r: Rep[Int]): Rep[Boolean] = l.testBit(r); - def setBit(l: Rep[WBigInteger], r: Rep[Int]): Rep[WBigInteger] = l.setBit(r); - def clearBit(l: Rep[WBigInteger], r: Rep[Int]): Rep[WBigInteger] = l.clearBit(r); - def flipBit(l: Rep[WBigInteger], r: Rep[Int]): Rep[WBigInteger] = l.flipBit(r); - def getLowestSetBit(l: Rep[WBigInteger]): Rep[Int] = l.getLowestSetBit; - def bitCount(l: Rep[WBigInteger]): Rep[Int] = l.bitCount; - def bitLength(l: Rep[WBigInteger]): Rep[Int] = l.bitLength; - def isProbablePrime(l: Rep[WBigInteger], r: Rep[Int]): Rep[Boolean] = l.isProbablePrime(r); - def shiftLeft(l: Rep[WBigInteger], r: Rep[Int]): Rep[WBigInteger] = l.shiftLeft(r); - def shiftRight(l: Rep[WBigInteger], r: Rep[Int]): Rep[WBigInteger] = l.shiftRight(r); - def abs(l: Rep[WBigInteger]): Rep[WBigInteger] = l.abs; - def negate(l: Rep[WBigInteger]): Rep[WBigInteger] = l.negate; - def signum(l: Rep[WBigInteger]): Rep[Int] = l.signum; - def byteValue(l: Rep[WBigInteger]): Rep[Byte] = l.byteValue; - def shortValue(l: Rep[WBigInteger]): Rep[Short] = l.shortValue; - def intValue(l: Rep[WBigInteger]): Rep[Int] = l.intValue; - def longValue(l: Rep[WBigInteger]): Rep[Long] = l.longValue; - def byteValueExact(l: Rep[WBigInteger]): Rep[Byte] = l.byteValueExact; - def shortValueExact(l: Rep[WBigInteger]): Rep[Short] = l.shortValueExact; - def intValueExact(l: Rep[WBigInteger]): Rep[Int] = l.intValueExact; - def longValueExact(l: Rep[WBigInteger]): Rep[Long] = l.longValueExact - }; - trait SigmaPredefWrapSpec extends WrapSpecBase { - def dataSize(v: Rep[Any]): Rep[Long] = RWSigmaPredef.dataSize[Any](v) - }; - trait ECPointWrapSpecCompanion; - trait BigIntegerWrapSpecCompanion; - trait SigmaPredefWrapSpecCompanion - } -} \ No newline at end of file diff --git a/sigma-library/src/main/scala/special/sigma/wrappers/impl/WrappersSpecImpl.scala b/sigma-library/src/main/scala/special/sigma/wrappers/impl/WrappersSpecImpl.scala deleted file mode 100644 index f22878117c..0000000000 --- a/sigma-library/src/main/scala/special/sigma/wrappers/impl/WrappersSpecImpl.scala +++ /dev/null @@ -1,828 +0,0 @@ -package special.sigma.wrappers - -import scalan._ -import scala.reflect.runtime.universe._ -import scala.reflect._ - -package impl { -// Abs ----------------------------------- -trait WrappersSpecDefs extends scalan.Scalan with WrappersSpec { - self: SigmaLibrary => -import IsoUR._ -import Converter._ -import WArray._ -import WBigInteger._ -import WECPoint._ -import WSigmaPredef._ -import WrapSpecBase._ -import BigIntegerWrapSpec._ -import ECPointWrapSpec._ -import SigmaPredefWrapSpec._ - -object ECPointWrapSpec extends EntityObject("ECPointWrapSpec") { - // entityAdapter for ECPointWrapSpec trait - case class ECPointWrapSpecAdapter(source: Rep[ECPointWrapSpec]) - extends ECPointWrapSpec with Def[ECPointWrapSpec] { - val selfType: Elem[ECPointWrapSpec] = element[ECPointWrapSpec] - override def transform(t: Transformer) = ECPointWrapSpecAdapter(t(source)) - } - - // entityProxy: single proxy for each type family - implicit def proxyECPointWrapSpec(p: Rep[ECPointWrapSpec]): ECPointWrapSpec = { - if (p.rhs.isInstanceOf[ECPointWrapSpec@unchecked]) p.rhs.asInstanceOf[ECPointWrapSpec] - else - ECPointWrapSpecAdapter(p) - } - - // familyElem - class ECPointWrapSpecElem[To <: ECPointWrapSpec] - extends WrapSpecBaseElem[To] { - override lazy val parent: Option[Elem[_]] = Some(wrapSpecBaseElement) - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override lazy val tag = { - weakTypeTag[ECPointWrapSpec].asInstanceOf[WeakTypeTag[To]] - } - override def convert(x: Rep[Def[_]]) = { - val conv = fun {x: Rep[ECPointWrapSpec] => convertECPointWrapSpec(x) } - tryConvert(element[ECPointWrapSpec], this, x, conv) - } - - def convertECPointWrapSpec(x: Rep[ECPointWrapSpec]): Rep[To] = { - x.elem match { - case _: ECPointWrapSpecElem[_] => asRep[To](x) - case e => !!!(s"Expected $x to have ECPointWrapSpecElem[_], but got $e", x) - } - } - override def getDefaultRep: Rep[To] = ??? - } - - implicit lazy val eCPointWrapSpecElement: Elem[ECPointWrapSpec] = - new ECPointWrapSpecElem[ECPointWrapSpec] - - implicit case object ECPointWrapSpecCompanionElem extends CompanionElem[ECPointWrapSpecCompanionCtor] { - lazy val tag = weakTypeTag[ECPointWrapSpecCompanionCtor] - protected def getDefaultRep = RECPointWrapSpec - } - - abstract class ECPointWrapSpecCompanionCtor extends CompanionDef[ECPointWrapSpecCompanionCtor] with ECPointWrapSpecCompanion { - def selfType = ECPointWrapSpecCompanionElem - override def toString = "ECPointWrapSpec" - } - implicit def proxyECPointWrapSpecCompanionCtor(p: Rep[ECPointWrapSpecCompanionCtor]): ECPointWrapSpecCompanionCtor = - proxyOps[ECPointWrapSpecCompanionCtor](p) - - lazy val RECPointWrapSpec: Rep[ECPointWrapSpecCompanionCtor] = new ECPointWrapSpecCompanionCtor { - private val thisClass = classOf[ECPointWrapSpecCompanion] - } - - object ECPointWrapSpecMethods { - object getEncoded { - def unapply(d: Def[_]): Nullable[(Rep[ECPointWrapSpec], Rep[WECPoint], Rep[Boolean], Elem[A]) forSome {type A}] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[ECPointWrapSpecElem[_]] && method.getName == "getEncoded" => - val res = (receiver, args(0), args(1), args(2)) - Nullable(res).asInstanceOf[Nullable[(Rep[ECPointWrapSpec], Rep[WECPoint], Rep[Boolean], Elem[A]) forSome {type A}]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[ECPointWrapSpec], Rep[WECPoint], Rep[Boolean], Elem[A]) forSome {type A}] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object multiply { - def unapply(d: Def[_]): Nullable[(Rep[ECPointWrapSpec], Rep[WECPoint], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[ECPointWrapSpecElem[_]] && method.getName == "multiply" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[ECPointWrapSpec], Rep[WECPoint], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[ECPointWrapSpec], Rep[WECPoint], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object add { - def unapply(d: Def[_]): Nullable[(Rep[ECPointWrapSpec], Rep[WECPoint], Rep[WECPoint])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[ECPointWrapSpecElem[_]] && method.getName == "add" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[ECPointWrapSpec], Rep[WECPoint], Rep[WECPoint])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[ECPointWrapSpec], Rep[WECPoint], Rep[WECPoint])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - } - - object ECPointWrapSpecCompanionMethods { - } -} // of object ECPointWrapSpec - registerEntityObject("ECPointWrapSpec", ECPointWrapSpec) - -object BigIntegerWrapSpec extends EntityObject("BigIntegerWrapSpec") { - // entityAdapter for BigIntegerWrapSpec trait - case class BigIntegerWrapSpecAdapter(source: Rep[BigIntegerWrapSpec]) - extends BigIntegerWrapSpec with Def[BigIntegerWrapSpec] { - val selfType: Elem[BigIntegerWrapSpec] = element[BigIntegerWrapSpec] - override def transform(t: Transformer) = BigIntegerWrapSpecAdapter(t(source)) - } - - // entityProxy: single proxy for each type family - implicit def proxyBigIntegerWrapSpec(p: Rep[BigIntegerWrapSpec]): BigIntegerWrapSpec = { - if (p.rhs.isInstanceOf[BigIntegerWrapSpec@unchecked]) p.rhs.asInstanceOf[BigIntegerWrapSpec] - else - BigIntegerWrapSpecAdapter(p) - } - - // familyElem - class BigIntegerWrapSpecElem[To <: BigIntegerWrapSpec] - extends WrapSpecBaseElem[To] { - override lazy val parent: Option[Elem[_]] = Some(wrapSpecBaseElement) - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override lazy val tag = { - weakTypeTag[BigIntegerWrapSpec].asInstanceOf[WeakTypeTag[To]] - } - override def convert(x: Rep[Def[_]]) = { - val conv = fun {x: Rep[BigIntegerWrapSpec] => convertBigIntegerWrapSpec(x) } - tryConvert(element[BigIntegerWrapSpec], this, x, conv) - } - - def convertBigIntegerWrapSpec(x: Rep[BigIntegerWrapSpec]): Rep[To] = { - x.elem match { - case _: BigIntegerWrapSpecElem[_] => asRep[To](x) - case e => !!!(s"Expected $x to have BigIntegerWrapSpecElem[_], but got $e", x) - } - } - override def getDefaultRep: Rep[To] = ??? - } - - implicit lazy val bigIntegerWrapSpecElement: Elem[BigIntegerWrapSpec] = - new BigIntegerWrapSpecElem[BigIntegerWrapSpec] - - implicit case object BigIntegerWrapSpecCompanionElem extends CompanionElem[BigIntegerWrapSpecCompanionCtor] { - lazy val tag = weakTypeTag[BigIntegerWrapSpecCompanionCtor] - protected def getDefaultRep = RBigIntegerWrapSpec - } - - abstract class BigIntegerWrapSpecCompanionCtor extends CompanionDef[BigIntegerWrapSpecCompanionCtor] with BigIntegerWrapSpecCompanion { - def selfType = BigIntegerWrapSpecCompanionElem - override def toString = "BigIntegerWrapSpec" - } - implicit def proxyBigIntegerWrapSpecCompanionCtor(p: Rep[BigIntegerWrapSpecCompanionCtor]): BigIntegerWrapSpecCompanionCtor = - proxyOps[BigIntegerWrapSpecCompanionCtor](p) - - lazy val RBigIntegerWrapSpec: Rep[BigIntegerWrapSpecCompanionCtor] = new BigIntegerWrapSpecCompanionCtor { - private val thisClass = classOf[BigIntegerWrapSpecCompanion] - } - - object BigIntegerWrapSpecMethods { - object fromString { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[String])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "fromString" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[String])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[String])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object fromArray { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[Int], Rep[WArray[Byte]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "fromArray" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[Int], Rep[WArray[Byte]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[Int], Rep[WArray[Byte]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object valueOf { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[Long])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "valueOf" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[Long])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[Long])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object toByteArray { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "toByteArray" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object add { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "add" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object subtract { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "subtract" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object multiply { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "multiply" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object mod { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "mod" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object modInverse { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "modInverse" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object modPow { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "modPow" => - val res = (receiver, args(0), args(1), args(2)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object remainder { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "remainder" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object divide { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "divide" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object compareTo { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "compareTo" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object min { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "min" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object max { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "max" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object gcd { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "gcd" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object and { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "and" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object or { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "or" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object xor { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "xor" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object not { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "not" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object andNot { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "andNot" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object pow { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[Int])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "pow" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[Int])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[Int])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object testBit { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[Int])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "testBit" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[Int])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[Int])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object setBit { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[Int])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "setBit" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[Int])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[Int])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object clearBit { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[Int])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "clearBit" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[Int])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[Int])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object flipBit { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[Int])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "flipBit" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[Int])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[Int])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object getLowestSetBit { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "getLowestSetBit" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object bitCount { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "bitCount" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object bitLength { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "bitLength" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object isProbablePrime { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[Int])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "isProbablePrime" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[Int])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[Int])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object shiftLeft { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[Int])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "shiftLeft" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[Int])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[Int])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object shiftRight { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[Int])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "shiftRight" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[Int])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger], Rep[Int])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object abs { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "abs" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object negate { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "negate" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object signum { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "signum" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object byteValue { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "byteValue" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object shortValue { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "shortValue" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object intValue { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "intValue" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object longValue { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "longValue" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object byteValueExact { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "byteValueExact" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object shortValueExact { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "shortValueExact" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object intValueExact { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "intValueExact" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object longValueExact { - def unapply(d: Def[_]): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[BigIntegerWrapSpecElem[_]] && method.getName == "longValueExact" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[BigIntegerWrapSpec], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - } - - object BigIntegerWrapSpecCompanionMethods { - } -} // of object BigIntegerWrapSpec - registerEntityObject("BigIntegerWrapSpec", BigIntegerWrapSpec) - -object SigmaPredefWrapSpec extends EntityObject("SigmaPredefWrapSpec") { - // entityAdapter for SigmaPredefWrapSpec trait - case class SigmaPredefWrapSpecAdapter(source: Rep[SigmaPredefWrapSpec]) - extends SigmaPredefWrapSpec with Def[SigmaPredefWrapSpec] { - val selfType: Elem[SigmaPredefWrapSpec] = element[SigmaPredefWrapSpec] - override def transform(t: Transformer) = SigmaPredefWrapSpecAdapter(t(source)) - } - - // entityProxy: single proxy for each type family - implicit def proxySigmaPredefWrapSpec(p: Rep[SigmaPredefWrapSpec]): SigmaPredefWrapSpec = { - if (p.rhs.isInstanceOf[SigmaPredefWrapSpec@unchecked]) p.rhs.asInstanceOf[SigmaPredefWrapSpec] - else - SigmaPredefWrapSpecAdapter(p) - } - - // familyElem - class SigmaPredefWrapSpecElem[To <: SigmaPredefWrapSpec] - extends WrapSpecBaseElem[To] { - override lazy val parent: Option[Elem[_]] = Some(wrapSpecBaseElement) - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override lazy val tag = { - weakTypeTag[SigmaPredefWrapSpec].asInstanceOf[WeakTypeTag[To]] - } - override def convert(x: Rep[Def[_]]) = { - val conv = fun {x: Rep[SigmaPredefWrapSpec] => convertSigmaPredefWrapSpec(x) } - tryConvert(element[SigmaPredefWrapSpec], this, x, conv) - } - - def convertSigmaPredefWrapSpec(x: Rep[SigmaPredefWrapSpec]): Rep[To] = { - x.elem match { - case _: SigmaPredefWrapSpecElem[_] => asRep[To](x) - case e => !!!(s"Expected $x to have SigmaPredefWrapSpecElem[_], but got $e", x) - } - } - override def getDefaultRep: Rep[To] = ??? - } - - implicit lazy val sigmaPredefWrapSpecElement: Elem[SigmaPredefWrapSpec] = - new SigmaPredefWrapSpecElem[SigmaPredefWrapSpec] - - implicit case object SigmaPredefWrapSpecCompanionElem extends CompanionElem[SigmaPredefWrapSpecCompanionCtor] { - lazy val tag = weakTypeTag[SigmaPredefWrapSpecCompanionCtor] - protected def getDefaultRep = RSigmaPredefWrapSpec - } - - abstract class SigmaPredefWrapSpecCompanionCtor extends CompanionDef[SigmaPredefWrapSpecCompanionCtor] with SigmaPredefWrapSpecCompanion { - def selfType = SigmaPredefWrapSpecCompanionElem - override def toString = "SigmaPredefWrapSpec" - } - implicit def proxySigmaPredefWrapSpecCompanionCtor(p: Rep[SigmaPredefWrapSpecCompanionCtor]): SigmaPredefWrapSpecCompanionCtor = - proxyOps[SigmaPredefWrapSpecCompanionCtor](p) - - lazy val RSigmaPredefWrapSpec: Rep[SigmaPredefWrapSpecCompanionCtor] = new SigmaPredefWrapSpecCompanionCtor { - private val thisClass = classOf[SigmaPredefWrapSpecCompanion] - } - - object SigmaPredefWrapSpecMethods { - object dataSize { - def unapply(d: Def[_]): Nullable[(Rep[SigmaPredefWrapSpec], Rep[Any])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[SigmaPredefWrapSpecElem[_]] && method.getName == "dataSize" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[SigmaPredefWrapSpec], Rep[Any])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[SigmaPredefWrapSpec], Rep[Any])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - } - - object SigmaPredefWrapSpecCompanionMethods { - } -} // of object SigmaPredefWrapSpec - registerEntityObject("SigmaPredefWrapSpec", SigmaPredefWrapSpec) - - registerModule(WrappersSpecModule) -} - -object WrappersSpecModule extends scalan.ModuleInfo("special.sigma.wrappers", "WrappersSpec") -} - -trait WrappersSpecModule extends special.sigma.wrappers.impl.WrappersSpecDefs {self: SigmaLibrary =>} diff --git a/sigma-library/src/main/scala/wrappers/java/math/WBigIntegers.scala b/sigma-library/src/main/scala/wrappers/java/math/WBigIntegers.scala deleted file mode 100644 index 5c17b70661..0000000000 --- a/sigma-library/src/main/scala/wrappers/java/math/WBigIntegers.scala +++ /dev/null @@ -1,61 +0,0 @@ -package wrappers.java.math { - import scalan._ - - import impl._ - - import special.sigma.wrappers.WrappersModule - - import special.sigma.wrappers.BigIntegerWrapSpec - - trait WBigIntegers extends Base { self: WrappersModule => - import WArray._; - import WBigInteger._; - @External("BigInteger") @Liftable trait WBigInteger extends Def[WBigInteger] { - @External def longValueExact: Rep[Long]; - @External def intValueExact: Rep[Int]; - @External def shortValueExact: Rep[Short]; - @External def byteValueExact: Rep[Byte]; - @External def longValue: Rep[Long]; - @External def intValue: Rep[Int]; - @External def shortValue: Rep[Short]; - @External def byteValue: Rep[Byte]; - @External def signum: Rep[Int]; - @External def negate: Rep[WBigInteger]; - @External def abs: Rep[WBigInteger]; - @External def shiftRight(x$1: Rep[Int]): Rep[WBigInteger]; - @External def shiftLeft(x$1: Rep[Int]): Rep[WBigInteger]; - @External def isProbablePrime(x$1: Rep[Int]): Rep[Boolean]; - @External def bitLength: Rep[Int]; - @External def bitCount: Rep[Int]; - @External def getLowestSetBit: Rep[Int]; - @External def flipBit(x$1: Rep[Int]): Rep[WBigInteger]; - @External def clearBit(x$1: Rep[Int]): Rep[WBigInteger]; - @External def setBit(x$1: Rep[Int]): Rep[WBigInteger]; - @External def testBit(x$1: Rep[Int]): Rep[Boolean]; - @External def pow(x$1: Rep[Int]): Rep[WBigInteger]; - @External def andNot(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def not: Rep[WBigInteger]; - @External def xor(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def or(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def and(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def gcd(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def max(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def min(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def compareTo(x$1: Rep[WBigInteger]): Rep[Int]; - @External def divide(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def remainder(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def modPow(x$1: Rep[WBigInteger], x$2: Rep[WBigInteger]): Rep[WBigInteger]; - @External def modInverse(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def mod(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def multiply(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def subtract(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def add(x$1: Rep[WBigInteger]): Rep[WBigInteger]; - @External def toByteArray: Rep[WArray[Byte]] - }; - trait WBigIntegerCompanion { - @Constructor @OverloadId(value = "constructor_1") def apply(x$1: Rep[Int], x$2: Rep[WArray[Byte]]): Rep[WBigInteger]; - @Constructor @OverloadId(value = "constructor_2") def apply(x$1: Rep[String]): Rep[WBigInteger]; - @External def valueOf(x$1: Rep[Long]): Rep[WBigInteger] - } - } -} \ No newline at end of file diff --git a/sigma-library/src/main/scala/wrappers/java/math/impl/WBigIntegersImpl.scala b/sigma-library/src/main/scala/wrappers/java/math/impl/WBigIntegersImpl.scala deleted file mode 100644 index f157b166fc..0000000000 --- a/sigma-library/src/main/scala/wrappers/java/math/impl/WBigIntegersImpl.scala +++ /dev/null @@ -1,1265 +0,0 @@ -package wrappers.java.math - -import scalan._ -import impl._ -import special.sigma.wrappers.WrappersModule -import special.sigma.wrappers.BigIntegerWrapSpec -import scala.reflect.runtime.universe._ -import scala.reflect._ -import java.lang.reflect.Method // manual fix -import java.math.BigInteger // manual fix -import org.bouncycastle.math.ec.ECPoint // manual fix - -package impl { -// Abs ----------------------------------- -trait WBigIntegersDefs extends scalan.Scalan with WBigIntegers { - self: WrappersModule => -import special.sigma._ // manual fix -import IsoUR._ -import Converter._ -import WArray._ -import WBigInteger._ - -object WBigInteger extends EntityObject("WBigInteger") { - // entityConst: single const for each entity - import Liftables._ - import scala.reflect.{ClassTag, classTag} - - case class WBigIntegerConst( - constValue: BigInteger - ) extends WBigInteger with LiftedConst[BigInteger, WBigInteger] - with Def[WBigInteger] with WBigIntegerConstMethods { - val liftable: Liftable[BigInteger, WBigInteger] = LiftableBigInteger - val selfType: Elem[WBigInteger] = liftable.eW - } - - trait WBigIntegerConstMethods extends WBigInteger { thisConst: Def[_] => - - private val WBigIntegerClass = classOf[WBigInteger] - - override def longValueExact: Rep[Long] = { - asRep[Long](mkMethodCall(self, - WBigIntegerClass.getMethod("longValueExact"), - List(), - true, false, element[Long])) - } - - override def intValueExact: Rep[Int] = { - asRep[Int](mkMethodCall(self, - WBigIntegerClass.getMethod("intValueExact"), - List(), - true, false, element[Int])) - } - - override def shortValueExact: Rep[Short] = { - asRep[Short](mkMethodCall(self, - WBigIntegerClass.getMethod("shortValueExact"), - List(), - true, false, element[Short])) - } - - override def byteValueExact: Rep[Byte] = { - asRep[Byte](mkMethodCall(self, - WBigIntegerClass.getMethod("byteValueExact"), - List(), - true, false, element[Byte])) - } - - override def longValue: Rep[Long] = { - asRep[Long](mkMethodCall(self, - WBigIntegerClass.getMethod("longValue"), - List(), - true, false, element[Long])) - } - - override def intValue: Rep[Int] = { - asRep[Int](mkMethodCall(self, - WBigIntegerClass.getMethod("intValue"), - List(), - true, false, element[Int])) - } - - override def shortValue: Rep[Short] = { - asRep[Short](mkMethodCall(self, - WBigIntegerClass.getMethod("shortValue"), - List(), - true, false, element[Short])) - } - - override def byteValue: Rep[Byte] = { - asRep[Byte](mkMethodCall(self, - WBigIntegerClass.getMethod("byteValue"), - List(), - true, false, element[Byte])) - } - - override def signum: Rep[Int] = { - asRep[Int](mkMethodCall(self, - WBigIntegerClass.getMethod("signum"), - List(), - true, false, element[Int])) - } - - override def negate: Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - WBigIntegerClass.getMethod("negate"), - List(), - true, false, element[WBigInteger])) - } - - override def abs: Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - WBigIntegerClass.getMethod("abs"), - List(), - true, false, element[WBigInteger])) - } - - override def shiftRight(x$1: Rep[Int]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - WBigIntegerClass.getMethod("shiftRight", classOf[Sym]), - List(x$1), - true, false, element[WBigInteger])) - } - - override def shiftLeft(x$1: Rep[Int]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - WBigIntegerClass.getMethod("shiftLeft", classOf[Sym]), - List(x$1), - true, false, element[WBigInteger])) - } - - override def isProbablePrime(x$1: Rep[Int]): Rep[Boolean] = { - asRep[Boolean](mkMethodCall(self, - WBigIntegerClass.getMethod("isProbablePrime", classOf[Sym]), - List(x$1), - true, false, element[Boolean])) - } - - override def bitLength: Rep[Int] = { - asRep[Int](mkMethodCall(self, - WBigIntegerClass.getMethod("bitLength"), - List(), - true, false, element[Int])) - } - - override def bitCount: Rep[Int] = { - asRep[Int](mkMethodCall(self, - WBigIntegerClass.getMethod("bitCount"), - List(), - true, false, element[Int])) - } - - override def getLowestSetBit: Rep[Int] = { - asRep[Int](mkMethodCall(self, - WBigIntegerClass.getMethod("getLowestSetBit"), - List(), - true, false, element[Int])) - } - - override def flipBit(x$1: Rep[Int]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - WBigIntegerClass.getMethod("flipBit", classOf[Sym]), - List(x$1), - true, false, element[WBigInteger])) - } - - override def clearBit(x$1: Rep[Int]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - WBigIntegerClass.getMethod("clearBit", classOf[Sym]), - List(x$1), - true, false, element[WBigInteger])) - } - - override def setBit(x$1: Rep[Int]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - WBigIntegerClass.getMethod("setBit", classOf[Sym]), - List(x$1), - true, false, element[WBigInteger])) - } - - override def testBit(x$1: Rep[Int]): Rep[Boolean] = { - asRep[Boolean](mkMethodCall(self, - WBigIntegerClass.getMethod("testBit", classOf[Sym]), - List(x$1), - true, false, element[Boolean])) - } - - override def pow(x$1: Rep[Int]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - WBigIntegerClass.getMethod("pow", classOf[Sym]), - List(x$1), - true, false, element[WBigInteger])) - } - - override def andNot(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - WBigIntegerClass.getMethod("andNot", classOf[Sym]), - List(x$1), - true, false, element[WBigInteger])) - } - - override def not: Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - WBigIntegerClass.getMethod("not"), - List(), - true, false, element[WBigInteger])) - } - - override def xor(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - WBigIntegerClass.getMethod("xor", classOf[Sym]), - List(x$1), - true, false, element[WBigInteger])) - } - - override def or(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - WBigIntegerClass.getMethod("or", classOf[Sym]), - List(x$1), - true, false, element[WBigInteger])) - } - - override def and(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - WBigIntegerClass.getMethod("and", classOf[Sym]), - List(x$1), - true, false, element[WBigInteger])) - } - - override def gcd(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - WBigIntegerClass.getMethod("gcd", classOf[Sym]), - List(x$1), - true, false, element[WBigInteger])) - } - - override def max(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - WBigIntegerClass.getMethod("max", classOf[Sym]), - List(x$1), - true, false, element[WBigInteger])) - } - - override def min(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - WBigIntegerClass.getMethod("min", classOf[Sym]), - List(x$1), - true, false, element[WBigInteger])) - } - - override def compareTo(x$1: Rep[WBigInteger]): Rep[Int] = { - asRep[Int](mkMethodCall(self, - WBigIntegerClass.getMethod("compareTo", classOf[Sym]), - List(x$1), - true, false, element[Int])) - } - - override def divide(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - WBigIntegerClass.getMethod("divide", classOf[Sym]), - List(x$1), - true, false, element[WBigInteger])) - } - - override def remainder(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - WBigIntegerClass.getMethod("remainder", classOf[Sym]), - List(x$1), - true, false, element[WBigInteger])) - } - - override def modPow(x$1: Rep[WBigInteger], x$2: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - WBigIntegerClass.getMethod("modPow", classOf[Sym], classOf[Sym]), - List(x$1, x$2), - true, false, element[WBigInteger])) - } - - override def modInverse(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - WBigIntegerClass.getMethod("modInverse", classOf[Sym]), - List(x$1), - true, false, element[WBigInteger])) - } - - override def mod(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - WBigIntegerClass.getMethod("mod", classOf[Sym]), - List(x$1), - true, false, element[WBigInteger])) - } - - override def multiply(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - WBigIntegerClass.getMethod("multiply", classOf[Sym]), - List(x$1), - true, false, element[WBigInteger])) - } - - override def subtract(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - WBigIntegerClass.getMethod("subtract", classOf[Sym]), - List(x$1), - true, false, element[WBigInteger])) - } - - override def add(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - WBigIntegerClass.getMethod("add", classOf[Sym]), - List(x$1), - true, false, element[WBigInteger])) - } - - override def toByteArray: Rep[WArray[Byte]] = { - asRep[WArray[Byte]](mkMethodCall(self, - WBigIntegerClass.getMethod("toByteArray"), - List(), - true, false, element[WArray[Byte]])) - } - } - - implicit object LiftableBigInteger - extends Liftable[BigInteger, WBigInteger] { - lazy val eW: Elem[WBigInteger] = wBigIntegerElement - lazy val sourceType: RType[BigInteger] = { - RType[BigInteger] - } - def lift(x: BigInteger): Rep[WBigInteger] = WBigIntegerConst(x) - def unlift(w: Rep[WBigInteger]): BigInteger = w match { - case Def(WBigIntegerConst(x: BigInteger)) - => x.asInstanceOf[BigInteger] - case _ => unliftError(w) - } - } - - private val _BigIntegerWrapSpec = new BigIntegerWrapSpec {} - // entityAdapter for WBigInteger trait - case class WBigIntegerAdapter(source: Rep[WBigInteger]) - extends WBigInteger with Def[WBigInteger] { - val selfType: Elem[WBigInteger] = element[WBigInteger] - override def transform(t: Transformer) = WBigIntegerAdapter(t(source)) - private val thisClass = classOf[WBigInteger] - - def longValueExact: Rep[Long] = { - asRep[Long](mkMethodCall(source, - thisClass.getMethod("longValueExact"), - List(), - true, true, element[Long])) - } - - def intValueExact: Rep[Int] = { - asRep[Int](mkMethodCall(source, - thisClass.getMethod("intValueExact"), - List(), - true, true, element[Int])) - } - - def shortValueExact: Rep[Short] = { - asRep[Short](mkMethodCall(source, - thisClass.getMethod("shortValueExact"), - List(), - true, true, element[Short])) - } - - def byteValueExact: Rep[Byte] = { - asRep[Byte](mkMethodCall(source, - thisClass.getMethod("byteValueExact"), - List(), - true, true, element[Byte])) - } - - def longValue: Rep[Long] = { - asRep[Long](mkMethodCall(source, - thisClass.getMethod("longValue"), - List(), - true, true, element[Long])) - } - - def intValue: Rep[Int] = { - asRep[Int](mkMethodCall(source, - thisClass.getMethod("intValue"), - List(), - true, true, element[Int])) - } - - def shortValue: Rep[Short] = { - asRep[Short](mkMethodCall(source, - thisClass.getMethod("shortValue"), - List(), - true, true, element[Short])) - } - - def byteValue: Rep[Byte] = { - asRep[Byte](mkMethodCall(source, - thisClass.getMethod("byteValue"), - List(), - true, true, element[Byte])) - } - - def signum: Rep[Int] = { - asRep[Int](mkMethodCall(source, - thisClass.getMethod("signum"), - List(), - true, true, element[Int])) - } - - def negate: Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(source, - thisClass.getMethod("negate"), - List(), - true, true, element[WBigInteger])) - } - - def abs: Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(source, - thisClass.getMethod("abs"), - List(), - true, true, element[WBigInteger])) - } - - def shiftRight(x$1: Rep[Int]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(source, - thisClass.getMethod("shiftRight", classOf[Sym]), - List(x$1), - true, true, element[WBigInteger])) - } - - def shiftLeft(x$1: Rep[Int]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(source, - thisClass.getMethod("shiftLeft", classOf[Sym]), - List(x$1), - true, true, element[WBigInteger])) - } - - def isProbablePrime(x$1: Rep[Int]): Rep[Boolean] = { - asRep[Boolean](mkMethodCall(source, - thisClass.getMethod("isProbablePrime", classOf[Sym]), - List(x$1), - true, true, element[Boolean])) - } - - def bitLength: Rep[Int] = { - asRep[Int](mkMethodCall(source, - thisClass.getMethod("bitLength"), - List(), - true, true, element[Int])) - } - - def bitCount: Rep[Int] = { - asRep[Int](mkMethodCall(source, - thisClass.getMethod("bitCount"), - List(), - true, true, element[Int])) - } - - def getLowestSetBit: Rep[Int] = { - asRep[Int](mkMethodCall(source, - thisClass.getMethod("getLowestSetBit"), - List(), - true, true, element[Int])) - } - - def flipBit(x$1: Rep[Int]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(source, - thisClass.getMethod("flipBit", classOf[Sym]), - List(x$1), - true, true, element[WBigInteger])) - } - - def clearBit(x$1: Rep[Int]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(source, - thisClass.getMethod("clearBit", classOf[Sym]), - List(x$1), - true, true, element[WBigInteger])) - } - - def setBit(x$1: Rep[Int]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(source, - thisClass.getMethod("setBit", classOf[Sym]), - List(x$1), - true, true, element[WBigInteger])) - } - - def testBit(x$1: Rep[Int]): Rep[Boolean] = { - asRep[Boolean](mkMethodCall(source, - thisClass.getMethod("testBit", classOf[Sym]), - List(x$1), - true, true, element[Boolean])) - } - - def pow(x$1: Rep[Int]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(source, - thisClass.getMethod("pow", classOf[Sym]), - List(x$1), - true, true, element[WBigInteger])) - } - - def andNot(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(source, - thisClass.getMethod("andNot", classOf[Sym]), - List(x$1), - true, true, element[WBigInteger])) - } - - def not: Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(source, - thisClass.getMethod("not"), - List(), - true, true, element[WBigInteger])) - } - - def xor(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(source, - thisClass.getMethod("xor", classOf[Sym]), - List(x$1), - true, true, element[WBigInteger])) - } - - def or(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(source, - thisClass.getMethod("or", classOf[Sym]), - List(x$1), - true, true, element[WBigInteger])) - } - - def and(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(source, - thisClass.getMethod("and", classOf[Sym]), - List(x$1), - true, true, element[WBigInteger])) - } - - def gcd(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(source, - thisClass.getMethod("gcd", classOf[Sym]), - List(x$1), - true, true, element[WBigInteger])) - } - - def max(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(source, - thisClass.getMethod("max", classOf[Sym]), - List(x$1), - true, true, element[WBigInteger])) - } - - def min(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(source, - thisClass.getMethod("min", classOf[Sym]), - List(x$1), - true, true, element[WBigInteger])) - } - - def compareTo(x$1: Rep[WBigInteger]): Rep[Int] = { - asRep[Int](mkMethodCall(source, - thisClass.getMethod("compareTo", classOf[Sym]), - List(x$1), - true, true, element[Int])) - } - - def divide(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(source, - thisClass.getMethod("divide", classOf[Sym]), - List(x$1), - true, true, element[WBigInteger])) - } - - def remainder(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(source, - thisClass.getMethod("remainder", classOf[Sym]), - List(x$1), - true, true, element[WBigInteger])) - } - - def modPow(x$1: Rep[WBigInteger], x$2: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(source, - thisClass.getMethod("modPow", classOf[Sym], classOf[Sym]), - List(x$1, x$2), - true, true, element[WBigInteger])) - } - - def modInverse(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(source, - thisClass.getMethod("modInverse", classOf[Sym]), - List(x$1), - true, true, element[WBigInteger])) - } - - def mod(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(source, - thisClass.getMethod("mod", classOf[Sym]), - List(x$1), - true, true, element[WBigInteger])) - } - - def multiply(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(source, - thisClass.getMethod("multiply", classOf[Sym]), - List(x$1), - true, true, element[WBigInteger])) - } - - def subtract(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(source, - thisClass.getMethod("subtract", classOf[Sym]), - List(x$1), - true, true, element[WBigInteger])) - } - - def add(x$1: Rep[WBigInteger]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(source, - thisClass.getMethod("add", classOf[Sym]), - List(x$1), - true, true, element[WBigInteger])) - } - - def toByteArray: Rep[WArray[Byte]] = { - asRep[WArray[Byte]](mkMethodCall(source, - thisClass.getMethod("toByteArray"), - List(), - true, true, element[WArray[Byte]])) - } - } - - // entityProxy: single proxy for each type family - implicit def proxyWBigInteger(p: Rep[WBigInteger]): WBigInteger = { - if (p.rhs.isInstanceOf[WBigInteger@unchecked]) p.rhs.asInstanceOf[WBigInteger] - else - WBigIntegerAdapter(p) - } - - // familyElem - class WBigIntegerElem[To <: WBigInteger] - extends EntityElem[To] { - override val liftable: Liftables.Liftable[_, To] = LiftableBigInteger.asLiftable[BigInteger, To] - - override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { - super.collectMethods ++ - Elem.declaredWrapperMethods(_BigIntegerWrapSpec, classOf[WBigInteger], Set( - "longValueExact", "intValueExact", "shortValueExact", "byteValueExact", "longValue", "intValue", "shortValue", "byteValue", "signum", "negate", "abs", "shiftRight", "shiftLeft", "isProbablePrime", "bitLength", "bitCount", "getLowestSetBit", "flipBit", "clearBit", "setBit", "testBit", "pow", "andNot", "not", "xor", "or", "and", "gcd", "max", "min", "compareTo", "divide", "remainder", "modPow", "modInverse", "mod", "multiply", "subtract", "add", "toByteArray" - )) - } - - lazy val parent: Option[Elem[_]] = None - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override lazy val tag = { - weakTypeTag[WBigInteger].asInstanceOf[WeakTypeTag[To]] - } - override def convert(x: Rep[Def[_]]) = { - val conv = fun {x: Rep[WBigInteger] => convertWBigInteger(x) } - tryConvert(element[WBigInteger], this, x, conv) - } - - def convertWBigInteger(x: Rep[WBigInteger]): Rep[To] = { - x.elem match { - case _: WBigIntegerElem[_] => asRep[To](x) - case e => !!!(s"Expected $x to have WBigIntegerElem[_], but got $e", x) - } - } - override def getDefaultRep: Rep[To] = ??? - } - - implicit lazy val wBigIntegerElement: Elem[WBigInteger] = - new WBigIntegerElem[WBigInteger] - - implicit case object WBigIntegerCompanionElem extends CompanionElem[WBigIntegerCompanionCtor] { - lazy val tag = weakTypeTag[WBigIntegerCompanionCtor] - protected def getDefaultRep = RWBigInteger - } - - abstract class WBigIntegerCompanionCtor extends CompanionDef[WBigIntegerCompanionCtor] with WBigIntegerCompanion { - def selfType = WBigIntegerCompanionElem - override def toString = "WBigInteger" - } - implicit def proxyWBigIntegerCompanionCtor(p: Rep[WBigIntegerCompanionCtor]): WBigIntegerCompanionCtor = - proxyOps[WBigIntegerCompanionCtor](p) - - lazy val RWBigInteger: Rep[WBigIntegerCompanionCtor] = new WBigIntegerCompanionCtor { - private val thisClass = classOf[WBigIntegerCompanion] - - def apply(x$1: Rep[Int], x$2: Rep[WArray[Byte]]): Rep[WBigInteger] = - newObjEx[WBigInteger](x$1, x$2) - - def apply(x$1: Rep[String]): Rep[WBigInteger] = - newObjEx[WBigInteger](x$1) - - def valueOf(x$1: Rep[Long]): Rep[WBigInteger] = { - asRep[WBigInteger](mkMethodCall(self, - thisClass.getMethod("valueOf", classOf[Sym]), - List(x$1), - true, false, element[WBigInteger])) - } - } - - object WBigIntegerMethods { - object longValueExact { - def unapply(d: Def[_]): Nullable[Rep[WBigInteger]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "longValueExact" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[WBigInteger]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[WBigInteger]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object intValueExact { - def unapply(d: Def[_]): Nullable[Rep[WBigInteger]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "intValueExact" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[WBigInteger]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[WBigInteger]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object shortValueExact { - def unapply(d: Def[_]): Nullable[Rep[WBigInteger]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "shortValueExact" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[WBigInteger]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[WBigInteger]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object byteValueExact { - def unapply(d: Def[_]): Nullable[Rep[WBigInteger]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "byteValueExact" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[WBigInteger]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[WBigInteger]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object longValue { - def unapply(d: Def[_]): Nullable[Rep[WBigInteger]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "longValue" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[WBigInteger]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[WBigInteger]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object intValue { - def unapply(d: Def[_]): Nullable[Rep[WBigInteger]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "intValue" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[WBigInteger]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[WBigInteger]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object shortValue { - def unapply(d: Def[_]): Nullable[Rep[WBigInteger]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "shortValue" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[WBigInteger]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[WBigInteger]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object byteValue { - def unapply(d: Def[_]): Nullable[Rep[WBigInteger]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "byteValue" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[WBigInteger]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[WBigInteger]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object signum { - def unapply(d: Def[_]): Nullable[Rep[WBigInteger]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "signum" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[WBigInteger]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[WBigInteger]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object negate { - def unapply(d: Def[_]): Nullable[Rep[WBigInteger]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "negate" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[WBigInteger]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[WBigInteger]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object abs { - def unapply(d: Def[_]): Nullable[Rep[WBigInteger]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "abs" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[WBigInteger]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[WBigInteger]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object shiftRight { - def unapply(d: Def[_]): Nullable[(Rep[WBigInteger], Rep[Int])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "shiftRight" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[WBigInteger], Rep[Int])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WBigInteger], Rep[Int])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object shiftLeft { - def unapply(d: Def[_]): Nullable[(Rep[WBigInteger], Rep[Int])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "shiftLeft" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[WBigInteger], Rep[Int])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WBigInteger], Rep[Int])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object isProbablePrime { - def unapply(d: Def[_]): Nullable[(Rep[WBigInteger], Rep[Int])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "isProbablePrime" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[WBigInteger], Rep[Int])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WBigInteger], Rep[Int])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object bitLength { - def unapply(d: Def[_]): Nullable[Rep[WBigInteger]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "bitLength" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[WBigInteger]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[WBigInteger]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object bitCount { - def unapply(d: Def[_]): Nullable[Rep[WBigInteger]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "bitCount" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[WBigInteger]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[WBigInteger]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object getLowestSetBit { - def unapply(d: Def[_]): Nullable[Rep[WBigInteger]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "getLowestSetBit" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[WBigInteger]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[WBigInteger]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object flipBit { - def unapply(d: Def[_]): Nullable[(Rep[WBigInteger], Rep[Int])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "flipBit" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[WBigInteger], Rep[Int])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WBigInteger], Rep[Int])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object clearBit { - def unapply(d: Def[_]): Nullable[(Rep[WBigInteger], Rep[Int])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "clearBit" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[WBigInteger], Rep[Int])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WBigInteger], Rep[Int])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object setBit { - def unapply(d: Def[_]): Nullable[(Rep[WBigInteger], Rep[Int])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "setBit" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[WBigInteger], Rep[Int])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WBigInteger], Rep[Int])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object testBit { - def unapply(d: Def[_]): Nullable[(Rep[WBigInteger], Rep[Int])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "testBit" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[WBigInteger], Rep[Int])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WBigInteger], Rep[Int])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object pow { - def unapply(d: Def[_]): Nullable[(Rep[WBigInteger], Rep[Int])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "pow" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[WBigInteger], Rep[Int])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WBigInteger], Rep[Int])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object andNot { - def unapply(d: Def[_]): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "andNot" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object not { - def unapply(d: Def[_]): Nullable[Rep[WBigInteger]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "not" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[WBigInteger]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[WBigInteger]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object xor { - def unapply(d: Def[_]): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "xor" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object or { - def unapply(d: Def[_]): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "or" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object and { - def unapply(d: Def[_]): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "and" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object gcd { - def unapply(d: Def[_]): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "gcd" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object max { - def unapply(d: Def[_]): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "max" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object min { - def unapply(d: Def[_]): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "min" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object compareTo { - def unapply(d: Def[_]): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "compareTo" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object divide { - def unapply(d: Def[_]): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "divide" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object remainder { - def unapply(d: Def[_]): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "remainder" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object modPow { - def unapply(d: Def[_]): Nullable[(Rep[WBigInteger], Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "modPow" => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[WBigInteger], Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WBigInteger], Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object modInverse { - def unapply(d: Def[_]): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "modInverse" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object mod { - def unapply(d: Def[_]): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "mod" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object multiply { - def unapply(d: Def[_]): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "multiply" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object subtract { - def unapply(d: Def[_]): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "subtract" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object add { - def unapply(d: Def[_]): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "add" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[WBigInteger], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WBigInteger], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object toByteArray { - def unapply(d: Def[_]): Nullable[Rep[WBigInteger]] = d match { - case MethodCall(receiver, method, _, _) if receiver.elem.isInstanceOf[WBigIntegerElem[_]] && method.getName == "toByteArray" => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Rep[WBigInteger]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[WBigInteger]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - } - - object WBigIntegerCompanionMethods { - object apply_constructor_1 { - def unapply(d: Def[_]): Nullable[(Rep[Int], Rep[WArray[Byte]])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem == WBigIntegerCompanionElem && method.getName == "apply" && { val ann = method.getAnnotation(classOf[scalan.OverloadId]); ann != null && ann.value == "constructor_1" } => - val res = (args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Rep[Int], Rep[WArray[Byte]])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[Int], Rep[WArray[Byte]])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object apply_constructor_2 { - def unapply(d: Def[_]): Nullable[Rep[String]] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem == WBigIntegerCompanionElem && method.getName == "apply" && { val ann = method.getAnnotation(classOf[scalan.OverloadId]); ann != null && ann.value == "constructor_2" } => - val res = args(0) - Nullable(res).asInstanceOf[Nullable[Rep[String]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[String]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object valueOf { - def unapply(d: Def[_]): Nullable[Rep[Long]] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem == WBigIntegerCompanionElem && method.getName == "valueOf" => - val res = args(0) - Nullable(res).asInstanceOf[Nullable[Rep[Long]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[Long]] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - } -} // of object WBigInteger - registerEntityObject("WBigInteger", WBigInteger) - - registerModule(WBigIntegersModule) -} - -object WBigIntegersModule extends scalan.ModuleInfo("wrappers.java.math", "WBigIntegers") -} - -trait WBigIntegersModule extends wrappers.java.math.impl.WBigIntegersDefs {self: WrappersModule =>} diff --git a/sigma-library/src/main/scala/wrappers/org/bouncycastle/math/ec/WECPoints.scala b/sigma-library/src/main/scala/wrappers/org/bouncycastle/math/ec/WECPoints.scala deleted file mode 100644 index d7e022f173..0000000000 --- a/sigma-library/src/main/scala/wrappers/org/bouncycastle/math/ec/WECPoints.scala +++ /dev/null @@ -1,21 +0,0 @@ -package wrappers.org.bouncycastle.math.ec { - import scalan._ - - import impl._ - - import special.sigma.wrappers.WrappersModule - - import special.sigma.wrappers.ECPointWrapSpec - - trait WECPoints extends Base { self: WrappersModule => - import WArray._; - import WBigInteger._; - import WECPoint._; - @External("ECPoint") @Liftable trait WECPoint extends Def[WECPoint] { - @External def add(x$1: Rep[WECPoint]): Rep[WECPoint]; - @External def multiply(x$1: Rep[WBigInteger]): Rep[WECPoint]; - @External def getEncoded(x$1: Rep[Boolean]): Rep[WArray[Byte]] - }; - trait WECPointCompanion - } -} \ No newline at end of file diff --git a/sigma-library/src/main/scala/wrappers/org/bouncycastle/math/ec/impl/WECPointsImpl.scala b/sigma-library/src/main/scala/wrappers/org/bouncycastle/math/ec/impl/WECPointsImpl.scala deleted file mode 100644 index c760b8ed37..0000000000 --- a/sigma-library/src/main/scala/wrappers/org/bouncycastle/math/ec/impl/WECPointsImpl.scala +++ /dev/null @@ -1,217 +0,0 @@ -package wrappers.org.bouncycastle.math.ec - -import scalan._ -import impl._ -import special.sigma.wrappers.WrappersModule -import special.sigma.wrappers.ECPointWrapSpec -import java.lang.reflect.Method // manual fix -import java.math.BigInteger // manual fix - -import org.bouncycastle.math.ec.ECPoint // manual fix -import scala.reflect.runtime.universe._ -import scala.reflect._ - -package impl { -// Abs ----------------------------------- -trait WECPointsDefs extends scalan.Scalan with WECPoints { - self: WrappersModule => - import special.sigma._ // manual fix -import IsoUR._ -import Converter._ -import WArray._ -import WBigInteger._ -import WECPoint._ - -object WECPoint extends EntityObject("WECPoint") { - // entityConst: single const for each entity - import Liftables._ - import scala.reflect.{ClassTag, classTag} - - case class WECPointConst( - constValue: ECPoint - ) extends WECPoint with LiftedConst[ECPoint, WECPoint] - with Def[WECPoint] with WECPointConstMethods { - val liftable: Liftable[ECPoint, WECPoint] = LiftableECPoint - val selfType: Elem[WECPoint] = liftable.eW - } - - trait WECPointConstMethods extends WECPoint { thisConst: Def[_] => - - private val WECPointClass = classOf[WECPoint] - - override def add(x$1: Rep[WECPoint]): Rep[WECPoint] = { - asRep[WECPoint](mkMethodCall(self, - WECPointClass.getMethod("add", classOf[Sym]), - List(x$1), - true, false, element[WECPoint])) - } - - override def multiply(x$1: Rep[WBigInteger]): Rep[WECPoint] = { - asRep[WECPoint](mkMethodCall(self, - WECPointClass.getMethod("multiply", classOf[Sym]), - List(x$1), - true, false, element[WECPoint])) - } - - override def getEncoded(x$1: Rep[Boolean]): Rep[WArray[Byte]] = { - asRep[WArray[Byte]](mkMethodCall(self, - WECPointClass.getMethod("getEncoded", classOf[Sym]), - List(x$1), - true, false, element[WArray[Byte]])) - } - } - - implicit object LiftableECPoint - extends Liftable[ECPoint, WECPoint] { - lazy val eW: Elem[WECPoint] = wECPointElement - lazy val sourceType: RType[ECPoint] = { - RType[ECPoint] - } - def lift(x: ECPoint): Rep[WECPoint] = WECPointConst(x) - def unlift(w: Rep[WECPoint]): ECPoint = w match { - case Def(WECPointConst(x: ECPoint)) - => x.asInstanceOf[ECPoint] - case _ => unliftError(w) - } - } - - private val _ECPointWrapSpec = new ECPointWrapSpec {} - // entityAdapter for WECPoint trait - case class WECPointAdapter(source: Rep[WECPoint]) - extends WECPoint with Def[WECPoint] { - val selfType: Elem[WECPoint] = element[WECPoint] - override def transform(t: Transformer) = WECPointAdapter(t(source)) - private val thisClass = classOf[WECPoint] - - def add(x$1: Rep[WECPoint]): Rep[WECPoint] = { - asRep[WECPoint](mkMethodCall(source, - thisClass.getMethod("add", classOf[Sym]), - List(x$1), - true, true, element[WECPoint])) - } - - def multiply(x$1: Rep[WBigInteger]): Rep[WECPoint] = { - asRep[WECPoint](mkMethodCall(source, - thisClass.getMethod("multiply", classOf[Sym]), - List(x$1), - true, true, element[WECPoint])) - } - - def getEncoded(x$1: Rep[Boolean]): Rep[WArray[Byte]] = { - asRep[WArray[Byte]](mkMethodCall(source, - thisClass.getMethod("getEncoded", classOf[Sym]), - List(x$1), - true, true, element[WArray[Byte]])) - } - } - - // entityProxy: single proxy for each type family - implicit def proxyWECPoint(p: Rep[WECPoint]): WECPoint = { - if (p.rhs.isInstanceOf[WECPoint@unchecked]) p.rhs.asInstanceOf[WECPoint] - else - WECPointAdapter(p) - } - - // familyElem - class WECPointElem[To <: WECPoint] - extends EntityElem[To] { - override val liftable: Liftables.Liftable[_, To] = LiftableECPoint.asLiftable[ECPoint, To] - - override protected def collectMethods: Map[java.lang.reflect.Method, MethodDesc] = { - super.collectMethods ++ - Elem.declaredWrapperMethods(_ECPointWrapSpec, classOf[WECPoint], Set( - "add", "multiply", "getEncoded" - )) - } - - lazy val parent: Option[Elem[_]] = None - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override lazy val tag = { - weakTypeTag[WECPoint].asInstanceOf[WeakTypeTag[To]] - } - override def convert(x: Rep[Def[_]]) = { - val conv = fun {x: Rep[WECPoint] => convertWECPoint(x) } - tryConvert(element[WECPoint], this, x, conv) - } - - def convertWECPoint(x: Rep[WECPoint]): Rep[To] = { - x.elem match { - case _: WECPointElem[_] => asRep[To](x) - case e => !!!(s"Expected $x to have WECPointElem[_], but got $e", x) - } - } - override def getDefaultRep: Rep[To] = ??? - } - - implicit lazy val wECPointElement: Elem[WECPoint] = - new WECPointElem[WECPoint] - - implicit case object WECPointCompanionElem extends CompanionElem[WECPointCompanionCtor] { - lazy val tag = weakTypeTag[WECPointCompanionCtor] - protected def getDefaultRep = RWECPoint - } - - abstract class WECPointCompanionCtor extends CompanionDef[WECPointCompanionCtor] with WECPointCompanion { - def selfType = WECPointCompanionElem - override def toString = "WECPoint" - } - implicit def proxyWECPointCompanionCtor(p: Rep[WECPointCompanionCtor]): WECPointCompanionCtor = - proxyOps[WECPointCompanionCtor](p) - - lazy val RWECPoint: Rep[WECPointCompanionCtor] = new WECPointCompanionCtor { - private val thisClass = classOf[WECPointCompanion] - } - - object WECPointMethods { - object add { - def unapply(d: Def[_]): Nullable[(Rep[WECPoint], Rep[WECPoint])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WECPointElem[_]] && method.getName == "add" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[WECPoint], Rep[WECPoint])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WECPoint], Rep[WECPoint])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object multiply { - def unapply(d: Def[_]): Nullable[(Rep[WECPoint], Rep[WBigInteger])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WECPointElem[_]] && method.getName == "multiply" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[WECPoint], Rep[WBigInteger])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WECPoint], Rep[WBigInteger])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - - object getEncoded { - def unapply(d: Def[_]): Nullable[(Rep[WECPoint], Rep[Boolean])] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem.isInstanceOf[WECPointElem[_]] && method.getName == "getEncoded" => - val res = (receiver, args(0)) - Nullable(res).asInstanceOf[Nullable[(Rep[WECPoint], Rep[Boolean])]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Rep[WECPoint], Rep[Boolean])] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - } - - object WECPointCompanionMethods { - } -} // of object WECPoint - registerEntityObject("WECPoint", WECPoint) - - registerModule(WECPointsModule) -} - -object WECPointsModule extends scalan.ModuleInfo("wrappers.org.bouncycastle.math.ec", "WECPoints") -} - -trait WECPointsModule extends wrappers.org.bouncycastle.math.ec.impl.WECPointsDefs {self: WrappersModule =>} diff --git a/sigma-library/src/main/scala/wrappers/special/sigma/WSigmaPredefs.scala b/sigma-library/src/main/scala/wrappers/special/sigma/WSigmaPredefs.scala deleted file mode 100644 index e93616d340..0000000000 --- a/sigma-library/src/main/scala/wrappers/special/sigma/WSigmaPredefs.scala +++ /dev/null @@ -1,17 +0,0 @@ -package wrappers.special.sigma { - import scalan._ - - import impl._ - - import special.sigma.wrappers.WrappersModule - - import special.sigma.wrappers.SigmaPredefWrapSpec - - trait WSigmaPredefs extends Base { self: WrappersModule => - import WSigmaPredef._; - @External("SigmaPredef") trait WSigmaPredef extends Def[WSigmaPredef]; - trait WSigmaPredefCompanion { - @External def dataSize[T](v: Rep[T]): Rep[Long] - } - } -} \ No newline at end of file diff --git a/sigma-library/src/main/scala/wrappers/special/sigma/impl/WSigmaPredefsImpl.scala b/sigma-library/src/main/scala/wrappers/special/sigma/impl/WSigmaPredefsImpl.scala deleted file mode 100644 index 884f33142c..0000000000 --- a/sigma-library/src/main/scala/wrappers/special/sigma/impl/WSigmaPredefsImpl.scala +++ /dev/null @@ -1,108 +0,0 @@ -package wrappers.special.sigma - -import scalan._ -import impl._ -import special.sigma.wrappers.WrappersModule -import special.sigma.wrappers.SigmaPredefWrapSpec -import scala.reflect.runtime.universe._ -import scala.reflect._ - -package impl { -// Abs ----------------------------------- -trait WSigmaPredefsDefs extends scalan.Scalan with WSigmaPredefs { - self: WrappersModule => -import IsoUR._ -import Converter._ -import WSigmaPredef._ - -object WSigmaPredef extends EntityObject("WSigmaPredef") { - // entityAdapter for WSigmaPredef trait - case class WSigmaPredefAdapter(source: Rep[WSigmaPredef]) - extends WSigmaPredef with Def[WSigmaPredef] { - val selfType: Elem[WSigmaPredef] = element[WSigmaPredef] - override def transform(t: Transformer) = WSigmaPredefAdapter(t(source)) - } - - // entityProxy: single proxy for each type family - implicit def proxyWSigmaPredef(p: Rep[WSigmaPredef]): WSigmaPredef = { - if (p.rhs.isInstanceOf[WSigmaPredef@unchecked]) p.rhs.asInstanceOf[WSigmaPredef] - else - WSigmaPredefAdapter(p) - } - - // familyElem - class WSigmaPredefElem[To <: WSigmaPredef] - extends EntityElem[To] { - lazy val parent: Option[Elem[_]] = None - override def buildTypeArgs = super.buildTypeArgs ++ TypeArgs() - override lazy val tag = { - weakTypeTag[WSigmaPredef].asInstanceOf[WeakTypeTag[To]] - } - override def convert(x: Rep[Def[_]]) = { - val conv = fun {x: Rep[WSigmaPredef] => convertWSigmaPredef(x) } - tryConvert(element[WSigmaPredef], this, x, conv) - } - - def convertWSigmaPredef(x: Rep[WSigmaPredef]): Rep[To] = { - x.elem match { - case _: WSigmaPredefElem[_] => asRep[To](x) - case e => !!!(s"Expected $x to have WSigmaPredefElem[_], but got $e", x) - } - } - override def getDefaultRep: Rep[To] = ??? - } - - implicit lazy val wSigmaPredefElement: Elem[WSigmaPredef] = - new WSigmaPredefElem[WSigmaPredef] - - implicit case object WSigmaPredefCompanionElem extends CompanionElem[WSigmaPredefCompanionCtor] { - lazy val tag = weakTypeTag[WSigmaPredefCompanionCtor] - protected def getDefaultRep = RWSigmaPredef - } - - abstract class WSigmaPredefCompanionCtor extends CompanionDef[WSigmaPredefCompanionCtor] with WSigmaPredefCompanion { - def selfType = WSigmaPredefCompanionElem - override def toString = "WSigmaPredef" - } - implicit def proxyWSigmaPredefCompanionCtor(p: Rep[WSigmaPredefCompanionCtor]): WSigmaPredefCompanionCtor = - proxyOps[WSigmaPredefCompanionCtor](p) - - lazy val RWSigmaPredef: Rep[WSigmaPredefCompanionCtor] = new WSigmaPredefCompanionCtor { - private val thisClass = classOf[WSigmaPredefCompanion] - - def dataSize[T](v: Rep[T]): Rep[Long] = { - implicit val eT = v.elem - asRep[Long](mkMethodCall(self, - thisClass.getMethod("dataSize", classOf[Sym]), - List(v), - true, false, element[Long])) - } - } - - object WSigmaPredefMethods { - } - - object WSigmaPredefCompanionMethods { - object dataSize { - def unapply(d: Def[_]): Nullable[Rep[T] forSome {type T}] = d match { - case MethodCall(receiver, method, args, _) if receiver.elem == WSigmaPredefCompanionElem && method.getName == "dataSize" => - val res = args(0) - Nullable(res).asInstanceOf[Nullable[Rep[T] forSome {type T}]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Rep[T] forSome {type T}] = exp match { - case Def(d) => unapply(d) - case _ => Nullable.None - } - } - } -} // of object WSigmaPredef - registerEntityObject("WSigmaPredef", WSigmaPredef) - - registerModule(WSigmaPredefsModule) -} - -object WSigmaPredefsModule extends scalan.ModuleInfo("wrappers.special.sigma", "WSigmaPredefs") -} - -trait WSigmaPredefsModule extends wrappers.special.sigma.impl.WSigmaPredefsDefs {self: WrappersModule =>} diff --git a/sigma-library/src/test/scala/scalan/SigmaLibraryTests.scala b/sigma-library/src/test/scala/scalan/SigmaLibraryTests.scala deleted file mode 100644 index 94bb25a1c9..0000000000 --- a/sigma-library/src/test/scala/scalan/SigmaLibraryTests.scala +++ /dev/null @@ -1,27 +0,0 @@ -package scalan - -//private class TestSigmaLibrary extends SigmaLibrary { -// import TestSigmaDslBuilder._ -// import CollOverArrayBuilder._ -// import CCostedBuilder._ -// import CostedBuilder._ -// import MonoidBuilder._ -// -// lazy val colBuilder: Rep[CollBuilder] = RCollOverArrayBuilder() -// lazy val costedBuilder: Rep[CostedBuilder] = RCCostedBuilder() -// lazy val intPlusMonoid: Rep[Monoid[Int]] = costedBuilder.monoidBuilder.intPlusMonoid -// lazy val longPlusMonoid: Rep[Monoid[Long]] = costedBuilder.monoidBuilder.longPlusMonoid -// lazy val sigmaDslBuilder = RTestSigmaDslBuilder() -//} -// -//class SigmaLibraryTests extends BaseCtxTests { -// -// test("Benchmark SigmaLibrary creation time") { -// new Benchmark(new TestSigmaLibrary).run() -// } -//} -// -//object MeasureSigmaLibraryCreate extends App { -// new Benchmark(new TestSigmaLibrary).run() -//} - diff --git a/sigma-library/src/test/scala/special/sigma/wrappers/WBigIntegerTests.scala b/sigma-library/src/test/scala/special/sigma/wrappers/WBigIntegerTests.scala deleted file mode 100644 index e125a0bf57..0000000000 --- a/sigma-library/src/test/scala/special/sigma/wrappers/WBigIntegerTests.scala +++ /dev/null @@ -1,25 +0,0 @@ -package special.sigma.wrappers - -import java.math.BigInteger -import special.wrappers.WrappersTests -import scala.collection.mutable -import scala.language.reflectiveCalls - -class WBigIntegerTests extends WrappersTests { - class Ctx extends WrappersCtx with WrappersModule { - } - - test("invokeUnlifted") { - val ctx = new Ctx - import ctx._ - import Liftables._ - import WBigInteger._ - import EnvRep._ - - val obj = BigInteger.valueOf(10L) - - check(obj, { env: EnvRep[WBigInteger] => - for { xs <- env; one <- lifted(BigInteger.ONE) } yield xs.add(one) }, obj.add(BigInteger.ONE)) - check(obj, { env: EnvRep[WBigInteger] => for { xs <- env } yield xs.multiply(xs) }, obj.multiply(obj)) - } -} diff --git a/sigma-library/src/test/scala/special/sigma/wrappers/WECPointTests.scala b/sigma-library/src/test/scala/special/sigma/wrappers/WECPointTests.scala deleted file mode 100644 index 3324246e72..0000000000 --- a/sigma-library/src/test/scala/special/sigma/wrappers/WECPointTests.scala +++ /dev/null @@ -1,27 +0,0 @@ -package special.sigma.wrappers - -import java.math.BigInteger - -import org.bouncycastle.crypto.ec.CustomNamedCurves -import special.wrappers.WrappersTests -import scala.language.reflectiveCalls - -class WECPointTests extends WrappersTests { - class Ctx extends WrappersCtx with WrappersModule { - } - - test("invokeUnlifted") { - val ctx = new Ctx - import ctx._ - import WECPoint._ - import WBigInteger._ - import Liftables._ - import EnvRep._ - - val obj = CustomNamedCurves.getByName("secp256k1").getG - val ten = BigInteger.valueOf(10L) - check(obj, { env: EnvRep[WECPoint] => for { xs <- env } yield xs.add(xs) }, obj.add(obj)) - check(obj, { env: EnvRep[WECPoint] => for { xs <- env; tenL <- lifted(ten) } yield xs.multiply(tenL) }, obj.multiply(ten)) - check(obj, { env: EnvRep[WECPoint] => for { xs <- env; arg <- lifted(true) } yield xs.getEncoded(arg) }, obj.getEncoded(true)) - } -} diff --git a/src/main/java/gf2t/GF2_192.java b/sigmastate/src/main/java/gf2t/GF2_192.java similarity index 100% rename from src/main/java/gf2t/GF2_192.java rename to sigmastate/src/main/java/gf2t/GF2_192.java diff --git a/src/main/java/gf2t/GF2_192_Poly.java b/sigmastate/src/main/java/gf2t/GF2_192_Poly.java similarity index 100% rename from src/main/java/gf2t/GF2_192_Poly.java rename to sigmastate/src/main/java/gf2t/GF2_192_Poly.java diff --git a/src/main/scala/org/ergoplatform/ErgoAddress.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoAddress.scala similarity index 92% rename from src/main/scala/org/ergoplatform/ErgoAddress.scala rename to sigmastate/src/main/scala/org/ergoplatform/ErgoAddress.scala index f4f1c4a1a4..d992f382e0 100644 --- a/src/main/scala/org/ergoplatform/ErgoAddress.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/ErgoAddress.scala @@ -141,8 +141,19 @@ object Pay2SHAddress { val scriptId = 1: Byte val addressTypePrefix: Byte = 2: Byte + /** Create Pay-to-script-hash address with the given underlying script (ErgoTree). + * @param script ErgoTree representation of guarding script + * @param encoder address encoder which is used to encode address bytes as String */ def apply(script: ErgoTree)(implicit encoder: ErgoAddressEncoder): Pay2SHAddress = { - val sb = ErgoTreeSerializer.DefaultSerializer.serializeErgoTree(script) + val prop = script.toProposition(replaceConstants = script.isConstantSegregation) + apply(prop) + } + + /** Create Pay-to-script-hash address with the given underlying proposition (SigmaPropValue). + * @param prop Value representation of guarding script (aka proposition) + * @param encoder address encoder which is used to encode address bytes as String */ + def apply(prop: SigmaPropValue)(implicit encoder: ErgoAddressEncoder): Pay2SHAddress = { + val sb = ValueSerializer.serialize(prop) val sbh = ErgoAddressEncoder.hash192(sb) new Pay2SHAddress(sbh) } diff --git a/src/main/scala/org/ergoplatform/ErgoBox.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoBox.scala similarity index 100% rename from src/main/scala/org/ergoplatform/ErgoBox.scala rename to sigmastate/src/main/scala/org/ergoplatform/ErgoBox.scala diff --git a/src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala similarity index 100% rename from src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala rename to sigmastate/src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala diff --git a/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala similarity index 100% rename from src/main/scala/org/ergoplatform/ErgoLikeContext.scala rename to sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala diff --git a/src/main/scala/org/ergoplatform/ErgoLikeInterpreter.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeInterpreter.scala similarity index 100% rename from src/main/scala/org/ergoplatform/ErgoLikeInterpreter.scala rename to sigmastate/src/main/scala/org/ergoplatform/ErgoLikeInterpreter.scala diff --git a/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala similarity index 100% rename from src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala rename to sigmastate/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala diff --git a/src/main/scala/org/ergoplatform/ErgoScriptPredef.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoScriptPredef.scala similarity index 100% rename from src/main/scala/org/ergoplatform/ErgoScriptPredef.scala rename to sigmastate/src/main/scala/org/ergoplatform/ErgoScriptPredef.scala diff --git a/src/main/scala/org/ergoplatform/Input.scala b/sigmastate/src/main/scala/org/ergoplatform/Input.scala similarity index 100% rename from src/main/scala/org/ergoplatform/Input.scala rename to sigmastate/src/main/scala/org/ergoplatform/Input.scala diff --git a/src/main/scala/org/ergoplatform/JsonCodecs.scala b/sigmastate/src/main/scala/org/ergoplatform/JsonCodecs.scala similarity index 97% rename from src/main/scala/org/ergoplatform/JsonCodecs.scala rename to sigmastate/src/main/scala/org/ergoplatform/JsonCodecs.scala index 10dd58bff8..b76f393d36 100644 --- a/src/main/scala/org/ergoplatform/JsonCodecs.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/JsonCodecs.scala @@ -16,11 +16,10 @@ import sigmastate.eval.Extensions._ import sigmastate.eval.{CGroupElement, CPreHeader, WrapperOf, _} import sigmastate.interpreter.{ContextExtension, ProverResult} import sigmastate.lang.exceptions.SigmaException -import sigmastate.serialization.{ErgoTreeSerializer, ValueSerializer} +import sigmastate.serialization.{DataJsonEncoder, ErgoTreeSerializer, ValueSerializer} import sigmastate.{AvlTreeData, AvlTreeFlags, SType} import special.collection.Coll -import special.sigma.{Header, PreHeader} - +import special.sigma.{AnyValue, Header, PreHeader} import scala.util.Try trait JsonCodecs { @@ -44,6 +43,12 @@ trait JsonCodecs { } yield transform(bytes) } + implicit val anyValueEncoder: Encoder[AnyValue] = { anyval => DataJsonEncoder.encodeAnyValue(anyval) } + + implicit val anyValueDecoder: Decoder[AnyValue] = { implicit cursor => + fromTry(Try.apply(DataJsonEncoder.decodeAnyValue(cursor.value))) + } + implicit val sigmaBigIntEncoder: Encoder[special.sigma.BigInt] = { bigInt => JsonNumber.fromDecimalStringUnsafe(bigInt.asInstanceOf[WrapperOf[BigInteger]].wrappedValue.toString).asJson } diff --git a/src/main/scala/org/ergoplatform/SigmaConstants.scala b/sigmastate/src/main/scala/org/ergoplatform/SigmaConstants.scala similarity index 100% rename from src/main/scala/org/ergoplatform/SigmaConstants.scala rename to sigmastate/src/main/scala/org/ergoplatform/SigmaConstants.scala diff --git a/src/main/scala/org/ergoplatform/dsl/AvlTreeHelpers.scala b/sigmastate/src/main/scala/org/ergoplatform/dsl/AvlTreeHelpers.scala similarity index 100% rename from src/main/scala/org/ergoplatform/dsl/AvlTreeHelpers.scala rename to sigmastate/src/main/scala/org/ergoplatform/dsl/AvlTreeHelpers.scala diff --git a/src/main/scala/org/ergoplatform/dsl/ContractSpec.scala b/sigmastate/src/main/scala/org/ergoplatform/dsl/ContractSpec.scala similarity index 100% rename from src/main/scala/org/ergoplatform/dsl/ContractSpec.scala rename to sigmastate/src/main/scala/org/ergoplatform/dsl/ContractSpec.scala diff --git a/src/main/scala/org/ergoplatform/dsl/ContractSyntax.scala b/sigmastate/src/main/scala/org/ergoplatform/dsl/ContractSyntax.scala similarity index 96% rename from src/main/scala/org/ergoplatform/dsl/ContractSyntax.scala rename to sigmastate/src/main/scala/org/ergoplatform/dsl/ContractSyntax.scala index eb17ea217f..3c51834b85 100644 --- a/src/main/scala/org/ergoplatform/dsl/ContractSyntax.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/dsl/ContractSyntax.scala @@ -41,7 +41,6 @@ object ContractSyntax { } trait SigmaContractSyntax extends SigmaContract with ContractSyntax { - override def canOpen(ctx: Context): Boolean = ??? } diff --git a/src/main/scala/org/ergoplatform/dsl/ErgoContractSpec.scala b/sigmastate/src/main/scala/org/ergoplatform/dsl/ErgoContractSpec.scala similarity index 100% rename from src/main/scala/org/ergoplatform/dsl/ErgoContractSpec.scala rename to sigmastate/src/main/scala/org/ergoplatform/dsl/ErgoContractSpec.scala diff --git a/src/main/scala/org/ergoplatform/dsl/StdContracts.scala b/sigmastate/src/main/scala/org/ergoplatform/dsl/StdContracts.scala similarity index 100% rename from src/main/scala/org/ergoplatform/dsl/StdContracts.scala rename to sigmastate/src/main/scala/org/ergoplatform/dsl/StdContracts.scala diff --git a/src/main/scala/org/ergoplatform/mining/emission/EmissionRules.scala b/sigmastate/src/main/scala/org/ergoplatform/mining/emission/EmissionRules.scala similarity index 100% rename from src/main/scala/org/ergoplatform/mining/emission/EmissionRules.scala rename to sigmastate/src/main/scala/org/ergoplatform/mining/emission/EmissionRules.scala diff --git a/src/main/scala/org/ergoplatform/settings/ErgoAlgos.scala b/sigmastate/src/main/scala/org/ergoplatform/settings/ErgoAlgos.scala similarity index 100% rename from src/main/scala/org/ergoplatform/settings/ErgoAlgos.scala rename to sigmastate/src/main/scala/org/ergoplatform/settings/ErgoAlgos.scala diff --git a/src/main/scala/org/ergoplatform/settings/MonetarySettings.scala b/sigmastate/src/main/scala/org/ergoplatform/settings/MonetarySettings.scala similarity index 100% rename from src/main/scala/org/ergoplatform/settings/MonetarySettings.scala rename to sigmastate/src/main/scala/org/ergoplatform/settings/MonetarySettings.scala diff --git a/src/main/scala/org/ergoplatform/validation/RuleStatus.scala b/sigmastate/src/main/scala/org/ergoplatform/validation/RuleStatus.scala similarity index 100% rename from src/main/scala/org/ergoplatform/validation/RuleStatus.scala rename to sigmastate/src/main/scala/org/ergoplatform/validation/RuleStatus.scala diff --git a/src/main/scala/org/ergoplatform/validation/RuleStatusSerializer.scala b/sigmastate/src/main/scala/org/ergoplatform/validation/RuleStatusSerializer.scala similarity index 100% rename from src/main/scala/org/ergoplatform/validation/RuleStatusSerializer.scala rename to sigmastate/src/main/scala/org/ergoplatform/validation/RuleStatusSerializer.scala diff --git a/src/main/scala/org/ergoplatform/validation/SigmaValidationSettings.scala b/sigmastate/src/main/scala/org/ergoplatform/validation/SigmaValidationSettings.scala similarity index 100% rename from src/main/scala/org/ergoplatform/validation/SigmaValidationSettings.scala rename to sigmastate/src/main/scala/org/ergoplatform/validation/SigmaValidationSettings.scala diff --git a/src/main/scala/org/ergoplatform/validation/SigmaValidationSettingsSerializer.scala b/sigmastate/src/main/scala/org/ergoplatform/validation/SigmaValidationSettingsSerializer.scala similarity index 96% rename from src/main/scala/org/ergoplatform/validation/SigmaValidationSettingsSerializer.scala rename to sigmastate/src/main/scala/org/ergoplatform/validation/SigmaValidationSettingsSerializer.scala index 6d0e44253a..4f4a05280b 100644 --- a/src/main/scala/org/ergoplatform/validation/SigmaValidationSettingsSerializer.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/validation/SigmaValidationSettingsSerializer.scala @@ -2,7 +2,7 @@ package org.ergoplatform.validation import sigmastate.serialization.SigmaSerializer import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} -import sigma.util.Extensions.{IntOps,LongOps} +import scalan.util.Extensions.{IntOps,LongOps} /** The rules are serialized ordered by ruleId. * This serializer preserves roundtrip identity `deserialize(serialize(_)) = identity` diff --git a/src/main/scala/org/ergoplatform/validation/SoftForkChecker.scala b/sigmastate/src/main/scala/org/ergoplatform/validation/SoftForkChecker.scala similarity index 100% rename from src/main/scala/org/ergoplatform/validation/SoftForkChecker.scala rename to sigmastate/src/main/scala/org/ergoplatform/validation/SoftForkChecker.scala diff --git a/src/main/scala/org/ergoplatform/validation/ValidationRules.scala b/sigmastate/src/main/scala/org/ergoplatform/validation/ValidationRules.scala similarity index 98% rename from src/main/scala/org/ergoplatform/validation/ValidationRules.scala rename to sigmastate/src/main/scala/org/ergoplatform/validation/ValidationRules.scala index deb793a81e..5cc5ad4350 100644 --- a/src/main/scala/org/ergoplatform/validation/ValidationRules.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/validation/ValidationRules.scala @@ -6,7 +6,7 @@ import java.util import org.ergoplatform.SigmaConstants.MaxLoopLevelInCostFunction import scorex.util.ByteArrayBuilder import scorex.util.serialization.{VLQByteBufferReader, VLQByteBufferWriter} -import sigma.util.Extensions.toUByte +import scalan.util.Extensions.toUByte import sigmastate.Values.{ErgoTree, IntValue, SValue, Value} import sigmastate._ import sigmastate.eval.IRContext @@ -48,7 +48,7 @@ case class ValidationRule( * Should be used in all validation rules to unify ValidationException instances * which can be thrown (to simplify handling). */ - protected def throwValidationException(cause: Throwable, args: Seq[Any]) = { + def throwValidationException(cause: Throwable, args: Seq[Any]) = { if (cause.isInstanceOf[ValidationException]) { throw cause } @@ -119,7 +119,7 @@ object ValidationRules { object CheckIsSupportedIndexExpression extends ValidationRule(1003, "Check the index expression for accessing collection element is supported.") { - final def apply[Ctx <: IRContext, T](ctx: Ctx)(coll: Value[SCollection[_]], i: IntValue, iSym: ctx.Rep[Int]): Unit = { + final def apply[Ctx <: IRContext, T](ctx: Ctx)(coll: Value[SCollection[_]], i: IntValue, iSym: ctx.Ref[Int]): Unit = { checkRule() if (!ctx.isSupportedIndexExpression(iSym)) throwValidationException( @@ -130,7 +130,7 @@ object ValidationRules { object CheckCostFunc extends ValidationRule(1004, "Cost function should contain only operations from specified list.") { - final def apply[Ctx <: IRContext, T](ctx: Ctx)(costF: ctx.Rep[Any => Int]): Unit = { + final def apply[Ctx <: IRContext, T](ctx: Ctx)(costF: ctx.Ref[Any => Int]): Unit = { checkRule() val verification = ctx.verifyCostFunc(ctx.asRep[Any => Int](costF)) if (!verification.isSuccess) { @@ -141,7 +141,7 @@ object ValidationRules { object CheckCalcFunc extends ValidationRule(1005, "If SigmaProp.isProven method calls exists in the given function,\n then it is the last operation") { - final def apply[Ctx <: IRContext, T](ctx: Ctx)(calcF: ctx.Rep[ctx.Context => Any]): Unit = { + final def apply[Ctx <: IRContext, T](ctx: Ctx)(calcF: ctx.Ref[ctx.Context => Any]): Unit = { checkRule() val verification = ctx.verifyIsProven(calcF) if (!verification.isSuccess) { diff --git a/src/main/scala/sigmastate/AvlTreeData.scala b/sigmastate/src/main/scala/sigmastate/AvlTreeData.scala similarity index 100% rename from src/main/scala/sigmastate/AvlTreeData.scala rename to sigmastate/src/main/scala/sigmastate/AvlTreeData.scala diff --git a/src/main/scala/sigmastate/EcPointFunctions.scala b/sigmastate/src/main/scala/sigmastate/EcPointFunctions.scala similarity index 100% rename from src/main/scala/sigmastate/EcPointFunctions.scala rename to sigmastate/src/main/scala/sigmastate/EcPointFunctions.scala diff --git a/src/main/scala/sigmastate/Operations.scala b/sigmastate/src/main/scala/sigmastate/Operations.scala similarity index 100% rename from src/main/scala/sigmastate/Operations.scala rename to sigmastate/src/main/scala/sigmastate/Operations.scala diff --git a/src/main/scala/sigmastate/SigSerializer.scala b/sigmastate/src/main/scala/sigmastate/SigSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/SigSerializer.scala rename to sigmastate/src/main/scala/sigmastate/SigSerializer.scala diff --git a/src/main/scala/sigmastate/UncheckedTree.scala b/sigmastate/src/main/scala/sigmastate/UncheckedTree.scala similarity index 100% rename from src/main/scala/sigmastate/UncheckedTree.scala rename to sigmastate/src/main/scala/sigmastate/UncheckedTree.scala diff --git a/src/main/scala/sigmastate/UnprovenTree.scala b/sigmastate/src/main/scala/sigmastate/UnprovenTree.scala similarity index 100% rename from src/main/scala/sigmastate/UnprovenTree.scala rename to sigmastate/src/main/scala/sigmastate/UnprovenTree.scala diff --git a/src/main/scala/sigmastate/Values.scala b/sigmastate/src/main/scala/sigmastate/Values.scala similarity index 92% rename from src/main/scala/sigmastate/Values.scala rename to sigmastate/src/main/scala/sigmastate/Values.scala index ace5fb8e31..91b5eed9cd 100644 --- a/src/main/scala/sigmastate/Values.scala +++ b/sigmastate/src/main/scala/sigmastate/Values.scala @@ -13,7 +13,7 @@ import scorex.crypto.authds.{ADDigest, SerializedAdProof} import scorex.crypto.authds.avltree.batch.BatchAVLVerifier import scorex.crypto.hash.{Digest32, Blake2b256} import scalan.util.CollectionUtil._ -import sigmastate.SCollection.SByteArray +import sigmastate.SCollection.{SByteArray, SIntArray} import sigmastate.interpreter.CryptoConstants.EcPointType import sigmastate.interpreter.CryptoConstants import sigmastate.serialization.{OpCodes, ConstantStore, _} @@ -27,7 +27,7 @@ import sigmastate.utxo._ import special.sigma.Extensions._ import sigmastate.eval._ import sigmastate.eval.Extensions._ -import sigma.util.Extensions.ByteOps +import scalan.util.Extensions.ByteOps import spire.syntax.all.cfor import scala.language.implicitConversions @@ -49,9 +49,7 @@ object Values { type Idn = String trait Value[+S <: SType] extends SigmaNode { - def companion: ValueCompanion /*= - sys.error(s"Companion object is not defined for AST node ${this.getClass}")*/ - + def companion: ValueCompanion /** Unique id of the node class used in serialization of ErgoTree. */ def opCode: OpCode = companion.opCode @@ -73,8 +71,6 @@ object Values { def opName: String = this.getClass.getSimpleName - def opId: OperationId = OperationId(opName, opType) - /** Parser has some source information like line,column in the text. We need to keep it up until RuntimeCosting. * The way to do this is to add Nullable property to every Value. Since Parser is always using SigmaBuilder * to create nodes, @@ -117,8 +113,6 @@ object Values { implicit def liftSigmaProp(g: SigmaProp): Value[SSigmaProp.type] = SigmaPropConstant(g) implicit def liftSigmaBoolean(sb: SigmaBoolean): Value[SSigmaProp.type] = SigmaPropConstant(SigmaDsl.SigmaProp(sb)) - def apply[S <: SType](tS: S)(const: tS.WrappedType): Value[S] = tS.mkConstant(const) - object Typed { def unapply(v: SValue): Option[(SValue, SType)] = Some((v, v.tpe)) } @@ -299,17 +293,9 @@ object Values { object ByteConstant { def apply(value: Byte): Constant[SByte.type] = Constant[SByte.type](value, SByte) - def unapply(v: SValue): Option[Byte] = v match { - case Constant(value: Byte, SByte) => Some(value) - case _ => None - } } object ShortConstant { def apply(value: Short): Constant[SShort.type] = Constant[SShort.type](value, SShort) - def unapply(v: SValue): Option[Short] = v match { - case Constant(value: Short, SShort) => Some(value) - case _ => None - } } object IntConstant { def apply(value: Int): Constant[SInt.type] = Constant[SInt.type](value, SInt) @@ -319,7 +305,6 @@ object Values { } def Zero = IntConstant(0) - def One = IntConstant(1) } object LongConstant { def apply(value: Long): Constant[SLong.type] = Constant[SLong.type](value, SLong) @@ -332,10 +317,6 @@ object Values { def apply(value: BigInt): Constant[SBigInt.type] = Constant[SBigInt.type](value, SBigInt) def apply(value: BigInteger): Constant[SBigInt.type] = Constant[SBigInt.type](SigmaDsl.BigInt(value), SBigInt) def apply(value: Long): Constant[SBigInt.type] = Constant[SBigInt.type](SigmaDsl.BigInt(BigInteger.valueOf(value)), SBigInt) - def unapply(v: SValue): Option[BigInt] = v match { - case Constant(value: BigInt, SBigInt) => Some(value) - case _ => None - } } object StringConstant { @@ -344,15 +325,10 @@ object Values { case Constant(value: String, SString) => Some(value) case _ => None } - def Empty = StringConstant("") } object BoxConstant { def apply(value: Box): Constant[SBox.type] = Constant[SBox.type](value, SBox) - def unapply(v: SValue): Option[Box] = v match { - case Constant(value: Box, SBox) => Some(value) - case _ => None - } } object GroupElementConstant { @@ -379,27 +355,6 @@ object Values { object AvlTreeConstant { def apply(value: AvlTree): Constant[SAvlTree.type] = Constant[SAvlTree.type](value, SAvlTree) - def unapply(v: SValue): Option[AvlTree] = v match { - case Constant(value: AvlTree, SAvlTree) => Some(value) - case _ => None - } - } - - implicit class AvlTreeConstantOps(val c: AvlTreeConstant) extends AnyVal { - def createVerifier(proof: SerializedAdProof) = - new BatchAVLVerifier[Digest32, Blake2b256.type]( - ADDigest @@ c.value.digest.toArray, - proof, - c.value.keyLength, - c.value.valueLengthOpt) - } - - object ContextConstant { - def apply(value: ErgoLikeContext): Constant[SContext.type] = Constant[SContext.type](value, SContext) - def unapply(v: SValue): Option[ErgoLikeContext] = v match { - case Constant(value: ErgoLikeContext, SContext) => Some(value) - case _ => None - } } object PreHeaderConstant { @@ -418,14 +373,6 @@ object Values { } } - trait NotReadyValueByte extends NotReadyValue[SByte.type] { - override def tpe = SByte - } - - trait NotReadyValueShort extends NotReadyValue[SShort.type] { - override def tpe = SShort - } - trait NotReadyValueInt extends NotReadyValue[SInt.type] { override def tpe = SInt } @@ -450,37 +397,13 @@ object Values { type TaggedAvlTree = TaggedVariable[SAvlTree.type] type TaggedByteArray = TaggedVariable[SCollection[SByte.type]] - def TaggedBoolean(id: Byte): Value[SBoolean.type] = mkTaggedVariable(id, SBoolean) - def TaggedByte(id: Byte): Value[SByte.type] = mkTaggedVariable(id, SByte) - def TaggedShort(id: Byte): Value[SShort.type] = mkTaggedVariable(id, SShort) - def TaggedInt(id: Byte): Value[SInt.type] = mkTaggedVariable(id, SInt) - def TaggedLong(id: Byte): Value[SLong.type] = mkTaggedVariable(id, SLong) - def TaggedBigInt(id: Byte): Value[SBigInt.type] = mkTaggedVariable(id, SBigInt) def TaggedBox(id: Byte): Value[SBox.type] = mkTaggedVariable(id, SBox) - def TaggedGroupElement(id: Byte): Value[SGroupElement.type] = - mkTaggedVariable(id, SGroupElement) - def TaggedSigmaProp(id: Byte): TaggedSigmaProp = TaggedVariable(id, SSigmaProp) def TaggedAvlTree(id: Byte): Value[SAvlTree.type] = mkTaggedVariable(id, SAvlTree) - def TaggedByteArray (id: Byte): Value[SCollection[SByte.type]] = - mkTaggedVariable(id, SByteArray) trait EvaluatedCollection[T <: SType, C <: SCollection[T]] extends EvaluatedValue[C] { def elementType: T } - type OptionConstant[T <: SType] = Constant[SOption[T]] - object OptionConstant { - def apply[T <: SType](value: Option[T#WrappedType], elementType: T): Constant[SOption[T]] = - Constant[SOption[T]](value, SOption(elementType)) - def unapply[T <: SType](node: Value[SOption[T]]): Option[(Option[T#WrappedType], T)] = node match { - case opt: Constant[SOption[a]] @unchecked if opt.tpe.isOption => - val v = opt.value.asInstanceOf[Option[T#WrappedType]] - val t = opt.tpe.elemType.asInstanceOf[T] - Some((v, t)) - case _ => None - } - } - type CollectionConstant[T <: SType] = Constant[SCollection[T]] object CollectionConstant { @@ -495,14 +418,6 @@ object Values { } } - implicit class CollectionConstantOps[T <: SType](val c: CollectionConstant[T]) extends AnyVal { - def toConcreteCollection: ConcreteCollection[T] = { - val tElem = c.tpe.elemType - val items = c.value.toArray.map(v => tElem.mkConstant(v.asInstanceOf[tElem.WrappedType])) - ConcreteCollection(items, tElem) - } - } - val ByteArrayTypeCode = (SCollectionType.CollectionTypeCode + SByte.typeCode).toByte object ByteArrayConstant { @@ -784,12 +699,6 @@ object Values { case tuple: Tuple => whenTuple(tuple) case _ => sys.error(s"Unexpected node $coll") } - def toConcreteCollection: ConcreteCollection[T] = - matchCase( - cc => cc, - _.toConcreteCollection, - t => ConcreteCollection(t.items.map(_.asValue[T]), SAny.asInstanceOf[T]) - ) } implicit class SigmaPropValueOps(val p: Value[SSigmaProp.type]) extends AnyVal { @@ -909,6 +818,7 @@ object Values { def GetVarBox(varId: Byte): GetVar[SBox.type] = GetVar(varId, SBox) def GetVarSigmaProp(varId: Byte): GetVar[SSigmaProp.type] = GetVar(varId, SSigmaProp) def GetVarByteArray(varId: Byte): GetVar[SCollection[SByte.type]] = GetVar(varId, SByteArray) + def GetVarIntArray(varId: Byte): GetVar[SCollection[SInt.type]] = GetVar(varId, SIntArray) /** This is alternative representation of ErgoTree expression when it cannot be parsed * due to `error`. This is used by the nodes running old versions of code to recognize diff --git a/src/main/scala/sigmastate/basics/BcDlogGroup.scala b/sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala similarity index 100% rename from src/main/scala/sigmastate/basics/BcDlogGroup.scala rename to sigmastate/src/main/scala/sigmastate/basics/BcDlogGroup.scala diff --git a/src/main/scala/sigmastate/basics/DLogProtocol.scala b/sigmastate/src/main/scala/sigmastate/basics/DLogProtocol.scala similarity index 100% rename from src/main/scala/sigmastate/basics/DLogProtocol.scala rename to sigmastate/src/main/scala/sigmastate/basics/DLogProtocol.scala diff --git a/src/main/scala/sigmastate/basics/DiffieHellmanTupleProtocol.scala b/sigmastate/src/main/scala/sigmastate/basics/DiffieHellmanTupleProtocol.scala similarity index 100% rename from src/main/scala/sigmastate/basics/DiffieHellmanTupleProtocol.scala rename to sigmastate/src/main/scala/sigmastate/basics/DiffieHellmanTupleProtocol.scala diff --git a/src/main/scala/sigmastate/basics/DlogGroup.scala b/sigmastate/src/main/scala/sigmastate/basics/DlogGroup.scala similarity index 100% rename from src/main/scala/sigmastate/basics/DlogGroup.scala rename to sigmastate/src/main/scala/sigmastate/basics/DlogGroup.scala diff --git a/src/main/scala/sigmastate/basics/SigmaProtocolFunctions.scala b/sigmastate/src/main/scala/sigmastate/basics/SigmaProtocolFunctions.scala similarity index 100% rename from src/main/scala/sigmastate/basics/SigmaProtocolFunctions.scala rename to sigmastate/src/main/scala/sigmastate/basics/SigmaProtocolFunctions.scala diff --git a/src/main/scala/sigmastate/eval/BigIntegerOps.scala b/sigmastate/src/main/scala/sigmastate/eval/BigIntegerOps.scala similarity index 71% rename from src/main/scala/sigmastate/eval/BigIntegerOps.scala rename to sigmastate/src/main/scala/sigmastate/eval/BigIntegerOps.scala index 6b6a15cd07..6f50a7a729 100644 --- a/src/main/scala/sigmastate/eval/BigIntegerOps.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/BigIntegerOps.scala @@ -2,10 +2,13 @@ package sigmastate.eval import java.math.BigInteger -import scala.math.{LowPriorityOrderingImplicits,Integral, Ordering} +import scalan.{ExactNumeric, ExactIntegral, ExactOrderingImpl} + +import scala.math.{LowPriorityOrderingImplicits, Integral, Ordering} import special.sigma._ -import sigma.util.Extensions._ +import scalan.util.Extensions._ import sigmastate.eval.Extensions._ +import sigmastate.eval.NumericOps.BigIntIsExactNumeric.n object OrderingOps extends LowPriorityOrderingImplicits { def apply[T](implicit ord: Ordering[T]) = ord @@ -40,7 +43,6 @@ object NumericOps { implicit object BigIntegerIsIntegral extends BigIntegerIsIntegral with OrderingOps.BigIntegerOrdering trait BigIntIsIntegral extends Integral[BigInt] { -// private val BI = implicitly[Integral[BigInt]] def quot(x: BigInt, y: BigInt): BigInt = x.divide(y) def rem(x: BigInt, y: BigInt): BigInt = x.remainder(y) def plus(x: BigInt, y: BigInt): BigInt = x.add(y) @@ -55,5 +57,20 @@ object NumericOps { } implicit object BigIntIsIntegral extends BigIntIsIntegral with OrderingOps.BigIntOrdering + implicit object BigIntIsExactNumeric extends ExactNumeric[BigInt] { + val n = BigIntIsIntegral + override def plus(x: BigInt, y: BigInt): BigInt = n.plus(x, y) + override def minus(x: BigInt, y: BigInt): BigInt = n.minus(x, y) + override def times(x: BigInt, y: BigInt): BigInt = n.times(x, y) + } + + implicit object BigIntIsExactIntegral extends ExactIntegral[BigInt] { + val n = BigIntIsIntegral + override def plus(x: BigInt, y: BigInt): BigInt = n.plus(x, y) + override def minus(x: BigInt, y: BigInt): BigInt = n.minus(x, y) + override def times(x: BigInt, y: BigInt): BigInt = n.times(x, y) + } + + implicit object BigIntIsExactOrdering extends ExactOrderingImpl[BigInt](BigIntIsIntegral) } diff --git a/src/main/scala/sigmastate/eval/CompiletimeCosting.scala b/sigmastate/src/main/scala/sigmastate/eval/CompiletimeCosting.scala similarity index 84% rename from src/main/scala/sigmastate/eval/CompiletimeCosting.scala rename to sigmastate/src/main/scala/sigmastate/eval/CompiletimeCosting.scala index 2ac84d114c..c4ae6e1590 100644 --- a/src/main/scala/sigmastate/eval/CompiletimeCosting.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/CompiletimeCosting.scala @@ -12,10 +12,36 @@ import sigmastate.SCollection._ import sigmastate.SBigInt._ import sigmastate.Values.Value.Typed import sigmastate.lang.Terms -import sigma.util.Extensions._ +import scalan.util.Extensions._ trait CompiletimeCosting extends RuntimeCosting { IR: IRContext => import builder._ + import SigmaProp._ + import CollBuilder._ + import SigmaDslBuilder._ + + override def rewriteDef[T](d: Def[T]): Ref[_] = d match { + case AllOf(b, HasSigmas(bools, sigmas), _) => + val zkAll = sigmaDslBuilder.allZK(b.fromItems(sigmas:_*)) + if (bools.isEmpty) + zkAll.isValid + else + (sigmaDslBuilder.sigmaProp(sigmaDslBuilder.allOf(b.fromItems(bools:_*))) && zkAll).isValid + + case AnyOf(b, HasSigmas(bs, ss), _) => + val zkAny = sigmaDslBuilder.anyZK(b.fromItems(ss:_*)) + if (bs.isEmpty) + zkAny.isValid + else + (sigmaDslBuilder.sigmaProp(sigmaDslBuilder.anyOf(b.fromItems(bs:_*))) || zkAny).isValid + + case AllOf(_,items,_) if items.length == 1 => items(0) + case AnyOf(_,items,_) if items.length == 1 => items(0) + case AllZk(_,items,_) if items.length == 1 => items(0) + case AnyZk(_,items,_) if items.length == 1 => items(0) + + case _ => super.rewriteDef(d) + } override def evalNode[T <: SType](ctx: RCosted[Context], env: CostingEnv, node: Value[T]): RCosted[T#WrappedType] = { def eval[T <: SType](node: Value[T]): RCosted[T#WrappedType] = evalNode(ctx, env, node) diff --git a/src/main/scala/sigmastate/eval/CostingDataContext.scala b/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala similarity index 99% rename from src/main/scala/sigmastate/eval/CostingDataContext.scala rename to sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala index ab7156a562..6e8601bb35 100644 --- a/src/main/scala/sigmastate/eval/CostingDataContext.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala @@ -464,8 +464,6 @@ class CCostModel extends CostModel { def AccessKiloByteOfData: Int = costOf("AccessKiloByteOfData", SFunc(IndexedSeq(), SUnit)) - def dataSize[T](x: T)(implicit cT: ClassTag[T]): Long = SigmaPredef.dataSize(x) - def PubKeySize: Long = CryptoConstants.EncodedGroupElementLength } diff --git a/src/main/scala/sigmastate/eval/CostingRules.scala b/sigmastate/src/main/scala/sigmastate/eval/CostingRules.scala similarity index 89% rename from src/main/scala/sigmastate/eval/CostingRules.scala rename to sigmastate/src/main/scala/sigmastate/eval/CostingRules.scala index 3df3c9f14f..9d011e5a15 100644 --- a/src/main/scala/sigmastate/eval/CostingRules.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/CostingRules.scala @@ -6,8 +6,9 @@ import scalan.{SigmaLibrary, MutableLazy} import sigmastate._ import sigmastate.interpreter.CryptoConstants import sigmastate.utxo.CostTable +import spire.syntax.all.cfor -trait CostingRules extends SigmaLibrary { IR: RuntimeCosting => +trait CostingRules extends SigmaLibrary { IR: IRContext => import Coll._ import BigInt._ import SigmaProp._ @@ -108,12 +109,12 @@ trait CostingRules extends SigmaLibrary { IR: RuntimeCosting => @inline def SizeGroupElement: RSize[GroupElement] = _sizeGroupElement.value private val _wRTypeSigmaProp: LazyRep[WRType[SigmaProp]] = MutableLazy(liftElem(element[SigmaProp])) - @inline def WRTypeSigmaProp: Rep[WRType[SigmaProp]] = _wRTypeSigmaProp.value + @inline def WRTypeSigmaProp: Ref[WRType[SigmaProp]] = _wRTypeSigmaProp.value class KnownCollInfo[T](len: Int, itemSizeCreator: => RSize[T]) { - private val _length: LazyRep[Int] = MutableLazy { len: Rep[Int] } - def length: Rep[Int] = _length.value + private val _length: LazyRep[Int] = MutableLazy { len: Ref[Int] } + def length: Ref[Int] = _length.value private val _itemSize: LazyRep[Size[T]] = MutableLazy(itemSizeCreator) def itemSize: RSize[T] = _itemSize.value @@ -147,7 +148,7 @@ trait CostingRules extends SigmaLibrary { IR: RuntimeCosting => * @param valuesCost accumulated cost to be added to resulting node * @return Costed node representing cost information of the input collection `coll`. */ - def mkCostedColl(coll: Rep[Coll[T]], valuesCost: Rep[Int]): Rep[CostedColl[T]] = { + def mkCostedColl(coll: Ref[Coll[T]], valuesCost: Ref[Int]): Ref[CostedColl[T]] = { RCCostedColl(coll, costZeros, sizesColl, valuesCost) } } @@ -186,69 +187,69 @@ trait CostingRules extends SigmaLibrary { IR: RuntimeCosting => .foreach(_.reset()) } - case class Cast[To](eTo: Elem[To], x: Rep[Def[_]]) extends BaseDef[To]()(eTo) { + case class Cast[To](eTo: Elem[To], x: Ref[Def[_]]) extends BaseDef[To]()(eTo) { override def transform(t: Transformer) = Cast(eTo, t(x)) } - def tryCast[To](x: Rep[Def[_]])(implicit eTo: Elem[To]): Rep[To] = { - if (eTo.runtimeClass.isAssignableFrom(x.elem.runtimeClass)) - x.asRep[To] + def tryCast[To](x: Ref[Def[_]])(implicit eTo: Elem[To]): Ref[To] = { + if (eTo.getClass.isAssignableFrom(x.elem.getClass)) + asRep[To](x) else Cast(eTo, x) } - def asCostedColl[T](collC: RCosted[Coll[T]]): Rep[CostedColl[T]] = { + def asCostedColl[T](collC: RCosted[Coll[T]]): Ref[CostedColl[T]] = { implicit val eT = collC.elem.eVal.eItem tryCast[CostedColl[T]](collC) } - def asCostedPair[A,B](pC: RCosted[(A,B)]): Rep[CostedPair[A,B]] = { + def asCostedPair[A,B](pC: RCosted[(A,B)]): Ref[CostedPair[A,B]] = { implicit val eA = pC.elem.eVal.eFst implicit val eB = pC.elem.eVal.eSnd tryCast[CostedPair[A,B]](pC) } - def asCostedFunc[A,B](fC: RCosted[A => B]): Rep[CostedFunc[Unit,A,B]] = { + def asCostedFunc[A,B](fC: RCosted[A => B]): Ref[CostedFunc[Unit,A,B]] = { implicit val eA = fC.elem.eVal.eDom implicit val eB = fC.elem.eVal.eRange tryCast[CostedFunc[Unit, A, B]](fC)(costedFuncElement(UnitElement, eA, eB)) } - def asSizeColl[T](collS: RSize[Coll[T]]): Rep[SizeColl[T]] = { + def asSizeColl[T](collS: RSize[Coll[T]]): Ref[SizeColl[T]] = { implicit val eT = collS.elem.eVal.eItem tryCast[SizeColl[T]](collS) } - def asSizePair[A, B](s: RSize[(A,B)]): Rep[SizePair[A,B]] = { + def asSizePair[A, B](s: RSize[(A,B)]): Ref[SizePair[A,B]] = { implicit val eA = s.elem.eVal.eFst implicit val eB = s.elem.eVal.eSnd tryCast[SizePair[A,B]](s) } - def asSizeOption[T](optS: RSize[WOption[T]]): Rep[SizeOption[T]] = { + def asSizeOption[T](optS: RSize[WOption[T]]): Ref[SizeOption[T]] = { implicit val eA = optS.elem.eVal.eItem tryCast[SizeOption[T]](optS) } - def asSizeBox(ctx: RSize[Box]): Rep[SizeBox] = tryCast[SizeBox](ctx) - def asSizeContext(ctx: RSize[Context]): Rep[SizeContext] = tryCast[SizeContext](ctx) + def asSizeBox(ctx: RSize[Box]): Ref[SizeBox] = tryCast[SizeBox](ctx) + def asSizeContext(ctx: RSize[Context]): Ref[SizeContext] = tryCast[SizeContext](ctx) - def SOME[A](x: Rep[A]): Rep[WOption[A]] = specialPredef.some(x) + def SOME[A](x: Ref[A]): Ref[WOption[A]] = specialPredef.some(x) - def mkSizeColl[T:Elem](len: Rep[Int]): Rep[Size[Coll[T]]] = { + def mkSizeColl[T:Elem](len: Ref[Int]): Ref[Size[Coll[T]]] = { val sizes = colBuilder.replicate(len, costedBuilder.mkSizePrim(typeSize[T], element[T]): RSize[T]) costedBuilder.mkSizeColl(sizes) } - def mkSizeColl[T](len: Rep[Int], sItem: RSize[T]): Rep[Size[Coll[T]]] = { + def mkSizeColl[T](len: Ref[Int], sItem: RSize[T]): Ref[Size[Coll[T]]] = { val sizes = colBuilder.replicate(len, sItem) costedBuilder.mkSizeColl(sizes) } - def mkSizeOption[T](size: RSize[T]): Rep[Size[WOption[T]]] = costedBuilder.mkSizeOption(SOME(size)) - def mkSizePair[A, B](l: RSize[A], r: RSize[B]): Rep[Size[(A,B)]] = costedBuilder.mkSizePair(l, r) + def mkSizeOption[T](size: RSize[T]): Ref[Size[WOption[T]]] = costedBuilder.mkSizeOption(SOME(size)) + def mkSizePair[A, B](l: RSize[A], r: RSize[B]): Ref[Size[(A,B)]] = costedBuilder.mkSizePair(l, r) - def mkCostedColl[T](values: RColl[T], costs: RColl[Int], sizes: RColl[Size[T]], valuesCost: Rep[Int]): RCostedColl[T] = + def mkCostedColl[T](values: RColl[T], costs: RColl[Int], sizes: RColl[Size[T]], valuesCost: Ref[Int]): RCostedColl[T] = costedBuilder.mkCostedColl(values, costs, sizes, valuesCost) - def mkCostedOption[T](value: ROption[T], costOpt: ROption[Int], sizeOpt: ROption[Size[T]], accCost: Rep[Int]): RCostedOption[T] = + def mkCostedOption[T](value: ROption[T], costOpt: ROption[Int], sizeOpt: ROption[Size[T]], accCost: Ref[Int]): RCostedOption[T] = costedBuilder.mkCostedOption(value, costOpt, sizeOpt, accCost) - def mkCostedFunc[A,R](f: RFuncCosted[A,R], cost: Rep[Int], codeSize: Rep[Long], eArg: Elem[A], eRes: Elem[R]): Rep[CostedFunc[Unit, A, R]] = { + def mkCostedFunc[A,R](f: RFuncCosted[A,R], cost: Ref[Int], codeSize: Ref[Long], eArg: Elem[A], eRes: Elem[R]): Ref[CostedFunc[Unit, A, R]] = { val envC = RCCostedPrim((), IntZero, SizeUnit) val sFunc = costedBuilder.mkSizeFunc(SizeUnit, codeSize, eArg, eRes) RCCostedFunc(envC, f, cost, sFunc) @@ -260,45 +261,53 @@ trait CostingRules extends SigmaLibrary { IR: RuntimeCosting => * This class defines generic costing helpers, to unify and simplify costing rules of individual methods. */ abstract class Coster[T](obj: RCosted[T], method: SMethod, costedArgs: Seq[RCosted[_]], args: Seq[Sym]) { - def costOfArgs: Seq[Rep[Int]] = (obj +: costedArgs).map(_.cost) - def sizeOfArgs: Rep[Long] = costedArgs.foldLeft(obj.size.dataSize)({ case (s, e) => s + e.size.dataSize }) + def costOfArgs: Seq[Ref[Int]] = { + val len = costedArgs.length + val res = new Array[Ref[Int]](1 + len) + res(0) = obj.cost + cfor(0)(_ < len, _ + 1) { i => + res(i + 1) = costedArgs(i).asInstanceOf[Ref[Costed[Any]]].cost + } + res + } + def sizeOfArgs: Ref[Long] = costedArgs.foldLeft(obj.size.dataSize)((s, e) => s + e.size.dataSize) - def constantSizePropertyAccess[R](prop: Rep[T] => Rep[R]): RCosted[R] = { + def constantSizePropertyAccess[R](prop: Ref[T] => Ref[R]): RCosted[R] = { val value = prop(obj.value) withConstantSize(value, opCost(value, costOfArgs, selectFieldCost)) } - def knownSizePropertyAccess[R](prop: Rep[T] => Rep[R], size: RSize[R]): RCosted[R] = { + def knownSizePropertyAccess[R](prop: Ref[T] => Ref[R], size: RSize[R]): RCosted[R] = { val value = prop(obj.value) RCCostedPrim(value, opCost(value, costOfArgs, selectFieldCost), size) } - def knownLengthCollPropertyAccess[R](prop: Rep[T] => Rep[Coll[R]], info: KnownCollInfo[R]): Rep[CostedColl[R]] = { + def knownLengthCollPropertyAccess[R](prop: Ref[T] => Ref[Coll[R]], info: KnownCollInfo[R]): Ref[CostedColl[R]] = { val value = prop(obj.value) info.mkCostedColl(value, opCost(value, costOfArgs, selectFieldCost)) } - def digest32PropertyAccess(prop: Rep[T] => Rep[Coll[Byte]]): Rep[CostedColl[Byte]] = + def digest32PropertyAccess(prop: Ref[T] => Ref[Coll[Byte]]): Ref[CostedColl[Byte]] = knownLengthCollPropertyAccess(prop, HashInfo) - def groupElementPropertyAccess(prop: Rep[T] => Rep[GroupElement]): RCosted[GroupElement] = + def groupElementPropertyAccess(prop: Ref[T] => Ref[GroupElement]): RCosted[GroupElement] = knownSizePropertyAccess(prop, SizeGroupElement) - def bigIntPropertyAccess(prop: Rep[T] => Rep[BigInt]): RCosted[BigInt] = + def bigIntPropertyAccess(prop: Ref[T] => Ref[BigInt]): RCosted[BigInt] = knownSizePropertyAccess(prop, SizeBigInt) - def defaultPropertyAccess[R](prop: Rep[T] => Rep[R], propSize: RSize[T] => RSize[R]): RCosted[R] = { + def defaultPropertyAccess[R](prop: Ref[T] => Ref[R], propSize: RSize[T] => RSize[R]): RCosted[R] = { val value = prop(obj.value) RCCostedPrim(value, opCost(value, costOfArgs, selectFieldCost), propSize(obj.size)) } - def defaultOptionPropertyAccess[R: Elem](prop: Rep[T] => ROption[R], propSize: RSize[T] => RSize[WOption[R]], itemCost: Rep[Int]): RCostedOption[R] = { + def defaultOptionPropertyAccess[R: Elem](prop: Ref[T] => ROption[R], propSize: RSize[T] => RSize[WOption[R]], itemCost: Ref[Int]): RCostedOption[R] = { val v = prop(obj.value) val s = propSize(obj.size) RCCostedOption(v, SOME(itemCost), asSizeOption(s).sizeOpt, opCost(v, costOfArgs, selectFieldCost)) } - def defaultCollPropertyAccess[R: Elem](prop: Rep[T] => RColl[R], propSize: RSize[T] => RSize[Coll[R]], itemCost: Rep[Int]): RCostedColl[R] = { + def defaultCollPropertyAccess[R: Elem](prop: Ref[T] => RColl[R], propSize: RSize[T] => RSize[Coll[R]], itemCost: Ref[Int]): RCostedColl[R] = { val v = prop(obj.value) val s = propSize(obj.size) val sizes = asSizeColl(s).sizes @@ -306,7 +315,7 @@ trait CostingRules extends SigmaLibrary { IR: RuntimeCosting => RCCostedColl(v, costs, sizes, opCost(v, costOfArgs, selectFieldCost)) } - def boxPropertyAccess(prop: Rep[T] => Rep[Box], propSize: RSize[T] => RSize[Box]): RCosted[Box] = { + def boxPropertyAccess(prop: Ref[T] => Ref[Box], propSize: RSize[T] => RSize[Box]): RCosted[Box] = { val v = prop(obj.value) val c = opCost(v, costOfArgs, sigmaDslBuilder.CostModel.AccessBox) val s = propSize(obj.size) @@ -381,7 +390,7 @@ trait CostingRules extends SigmaLibrary { IR: RuntimeCosting => res } - private def treeModifierMethod(meth: Rep[AvlTree] => Rep[WOption[AvlTree]]): RCosted[WOption[AvlTree]] = { + private def treeModifierMethod(meth: Ref[AvlTree] => Ref[WOption[AvlTree]]): RCosted[WOption[AvlTree]] = { val value = meth(obj.value) val size = sizeOfArgs RCCostedOption(value, @@ -405,7 +414,7 @@ trait CostingRules extends SigmaLibrary { IR: RuntimeCosting => /** Costing rules for SContext methods */ class ContextCoster(obj: RCosted[Context], method: SMethod, costedArgs: Seq[RCosted[_]], args: Seq[Sym]) extends Coster[Context](obj, method, costedArgs, args){ import Context._ - def boxCollProperty(prop: Rep[Context] => Rep[Coll[Box]], propSize: Rep[SizeContext] => RSize[Coll[Box]]) = { + def boxCollProperty(prop: Ref[Context] => Ref[Coll[Box]], propSize: Ref[SizeContext] => RSize[Coll[Box]]) = { defaultCollPropertyAccess(prop, ctxS => propSize(asSizeContext(ctxS)), sigmaDslBuilder.CostModel.AccessBox) } def headers() = { @@ -435,7 +444,7 @@ trait CostingRules extends SigmaLibrary { IR: RuntimeCosting => def minerPubKey: RCostedColl[Byte] = knownLengthCollPropertyAccess(_.minerPubKey, EncodedGroupElementInfo) - def getVar[T](id: RCosted[Byte])(implicit tT: Rep[WRType[T]]): RCostedOption[T] = { ??? + def getVar[T](id: RCosted[Byte])(implicit tT: Ref[WRType[T]]): RCostedOption[T] = { ??? // defaultOptionPropertyAccess(_.getVar(id.value)(tT.eA), asSizeContext(_).reg) // val opt = ctx.getVar(id)(cT) // dsl.costOption(opt, dsl.CostModel.GetVar) @@ -464,7 +473,7 @@ trait CostingRules extends SigmaLibrary { IR: RuntimeCosting => TokensInfo.mkCostedColl(value, opCost(value, costOfArgs, costOf(method))) } - def getReg[T](i: RCosted[Int])(implicit tT: Rep[WRType[T]]): RCosted[WOption[T]] = { + def getReg[T](i: RCosted[Int])(implicit tT: Ref[WRType[T]]): RCosted[WOption[T]] = { val sBox = asSizeBox(obj.size) implicit val elem = tT.eA val valueOpt = obj.value.getReg(i.value)(elem) @@ -603,7 +612,7 @@ trait CostingRules extends SigmaLibrary { IR: RuntimeCosting => } val isConstSize = eT.sourceType.isConstantSize val mapperCost = if (isConstSize) { - val mcost: Rep[Int] = Apply(costF, Pair(IntZero, constantTypeSize(eT)), false) + val mcost: Ref[Int] = Apply(costF, Pair(IntZero, constantTypeSize(eT)), false) len * (mcost + CostTable.lambdaInvoke) } else { zeros.zip(sizes).map(costF).sum(intPlusMonoid) + len * CostTable.lambdaInvoke @@ -622,7 +631,7 @@ trait CostingRules extends SigmaLibrary { IR: RuntimeCosting => val zeros = colBuilder.replicate(len, IntZero) val isConstSize = eT.sourceType.isConstantSize val predicateCost = if (isConstSize) { - val predCost: Rep[Int] = Apply(costF, Pair(IntZero, constantTypeSize(eT)), false) + val predCost: Ref[Int] = Apply(costF, Pair(IntZero, constantTypeSize(eT)), false) len * (predCost + CostTable.lambdaInvoke) } else { zeros.zip(sizes).map(costF).sum(intPlusMonoid) + len * CostTable.lambdaInvoke @@ -649,7 +658,7 @@ trait CostingRules extends SigmaLibrary { IR: RuntimeCosting => val isConstSize = eT.sourceType.isConstantSize val mapperCost = if (isConstSize) { - val mcost: Rep[Int] = Apply(costF, Pair(IntZero, constantTypeSize(eT)), false) + val mcost: Ref[Int] = Apply(costF, Pair(IntZero, constantTypeSize(eT)), false) len * (mcost + CostTable.lambdaInvoke) } else { colBuilder.replicate(len, IntZero) @@ -676,8 +685,8 @@ trait CostingRules extends SigmaLibrary { IR: RuntimeCosting => val xsC = asCostedColl(obj) val ysC = asCostedColl(ys) // TODO optimize: it make sence to add more high level operations to avoid building large graphs - val costs = xsC.costs.zip(ysC.costs).map(fun { in: Rep[(Int,Int)] => in._1 + in._2 }) - val sizes = xsC.sizes.zip(ysC.sizes).map(fun { in: Rep[(Size[T],Size[B])] => RCSizePair(in._1, in._2): RSize[(T,B)] }) + val costs = xsC.costs.zip(ysC.costs).map(fun { in: Ref[(Int,Int)] => in._1 + in._2 }) + val sizes = xsC.sizes.zip(ysC.sizes).map(fun { in: Ref[(Size[T],Size[B])] => RCSizePair(in._1, in._2): RSize[(T,B)] }) val c = opCost(values, costOfArgs, costOf(method)) RCCostedColl(values, costs, sizes, c) } diff --git a/src/main/scala/sigmastate/eval/Evaluation.scala b/sigmastate/src/main/scala/sigmastate/eval/Evaluation.scala similarity index 87% rename from src/main/scala/sigmastate/eval/Evaluation.scala rename to sigmastate/src/main/scala/sigmastate/eval/Evaluation.scala index 84c2895046..1e3706952b 100644 --- a/src/main/scala/sigmastate/eval/Evaluation.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/Evaluation.scala @@ -36,15 +36,11 @@ trait Evaluation extends RuntimeCosting { IR: IRContext => import Context._ import SigmaProp._ import Coll._ - import CReplColl._ - import PairOfCols._ import AnyValue._ import Box._ import AvlTree._ import CollBuilder._ import SigmaDslBuilder._ - import WBigInteger._ - import WArray._ import WOption._ import WRType._ import GroupElement._ @@ -61,12 +57,13 @@ trait Evaluation extends RuntimeCosting { IR: IRContext => import SizeFunc._ import CSizeFunc._ import SizeAnyValue._ - import CSizeAnyValue._ +// import CSizeAnyValue._ import SizeSigmaProp._ import SizeBox._ - import CSizeBox._ +// import CSizeBox._ import SizeContext._ - import CSizeContext._ +// import CSizeContext._ + import MonoidBuilder._ import OpCodes._ private val SCM = SizeContextMethods @@ -82,13 +79,11 @@ trait Evaluation extends RuntimeCosting { IR: IRContext => private val SigmaM = SigmaPropMethods private val CollM = CollMethods private val BoxM = BoxMethods - private val AvlM = AvlTreeMethods private val CBM = CollBuilderMethods private val SDBM = SigmaDslBuilderMethods - private val AM = WArrayMethods private val OM = WOptionMethods - private val BIM = WBigIntegerMethods private val SPCM = WSpecialPredefCompanionMethods + private val MBM = MonoidBuilderMethods private val _allowedOpCodesInCosting: HashSet[OpCodeExtra] = HashSet[OpCode]( AppendCode, @@ -190,6 +185,7 @@ trait Evaluation extends RuntimeCosting { IR: IRContext => case _: IntPlusMonoid => IntPlusMonoidCode case _: ThunkDef[_] => ThunkDefCode case _: ThunkForce[_] => ThunkForceCode + case MBM.intPlusMonoid(_) => IntPlusMonoidCode // TODO no HF proof case SCM.inputs(_) => SCMInputsCode case SCM.outputs(_) => SCMOutputsCode case SCM.dataInputs(_) => SCMDataInputsCode @@ -217,11 +213,9 @@ trait Evaluation extends RuntimeCosting { IR: IRContext => case _: CSizeFuncCtor[_, _, _] => CSizeFuncCtorCode case _: CSizeOptionCtor[_] => CSizeOptionCtorCode case _: CSizeCollCtor[_] => CSizeCollCtorCode - case _: CSizeBoxCtor => CSizeBoxCtorCode - case _: CSizeContextCtor => CSizeContextCtorCode - case _: CSizeAnyValueCtor => CSizeAnyValueCtorCode - case _: CReplCollCtor[_] => CReplCollCtorCode - case _: PairOfColsCtor[_, _] => PairOfColsCtorCode +// case _: CSizeBoxCtor => CSizeBoxCtorCode +// case _: CSizeContextCtor => CSizeContextCtorCode +// case _: CSizeAnyValueCtor => CSizeAnyValueCtorCode case CollM.sum(_, _) => CollMSumCode case CBM.replicate(_, _, _) => CBMReplicateCode case CBM.fromItems(_, _, _) => CBMFromItemsCode @@ -232,7 +226,6 @@ trait Evaluation extends RuntimeCosting { IR: IRContext => case _: Const[_] => ConstantCode case _: Tup[_, _] => TupleCode case _: First[_, _] | _: Second[_, _] => SelectFieldCode - case _: FieldApply[_] => SelectFieldCode case _: Lambda[_, _] => FuncValueCode case _: Apply[_, _] => FuncApplyCode case _: Upcast[_, _] => UpcastCode @@ -329,8 +322,8 @@ trait Evaluation extends RuntimeCosting { IR: IRContext => /** Recursively traverse the hierarchy of loop operations. */ private def traverseScope(scope: AstGraph, level: Int): Unit = { - scope.schedule.foreach { te => - te.rhs match { + scope.schedule.foreach { sym => + sym.node match { case op @ LoopOperation(bodyLam) => CheckCostFuncOperation(this)(getOpCodeEx(op)) val nextLevel = level + 1 @@ -346,38 +339,39 @@ trait Evaluation extends RuntimeCosting { IR: IRContext => /** Checks if the function (Lambda node) given by the symbol `costF` contains only allowed operations * in the schedule. */ - def verifyCostFunc(costF: Rep[Any => Int]): Try[Unit] = { + def verifyCostFunc(costF: Ref[Any => Int]): Try[Unit] = { val Def(Lambda(lam,_,_,_)) = costF Try { traverseScope(lam, level = 0) if (debugModeSanityChecks) { val backDeps = mutable.HashMap.empty[Sym, ArrayBuffer[Sym]] - lam.scheduleAll.foreach { te => - getDeps(te.rhs).foreach { usedSym => + lam.flatSchedule.foreach { sym => + sym.node.deps.foreach { usedSym => val usages = backDeps.getOrElseUpdate(usedSym, new ArrayBuffer()) - usages += te.sym + usages += sym } } // println(backDeps) - lam.scheduleAll + lam.flatSchedule .filter { - case _ @ TableEntrySingle(_, op: OpCost, _) => + case Def(op: OpCost) => assert(!op.args.contains(op.opCost), s"Invalid $op") true case _ => false } - .foreach { te => - val usages = backDeps.getOrElse(te.sym, new ArrayBuffer()) + .foreach { sym => + val usages = backDeps.getOrElse(sym, new ArrayBuffer()) usages.foreach { usageSym => - usageSym.rhs match { - case l: Lambda[_,_] => //ok - case t: ThunkDef[_] => //ok - case OpCost(_, _, args, _) if args.contains(te.sym) => //ok - case OpCost(_, _, _, opCost) if opCost == te.sym => - println(s"INFO: OpCost usage of node $te in opCost poistion in $usageSym -> ${usageSym.rhs}") + usageSym.node match { + case _: Lambda[_,_] => //ok + case _: ThunkDef[_] => //ok + case OpCost(_, _, args, _) if args.contains(sym) => //ok + case OpCost(_, _, _, opCost) if opCost == sym => + println(s"INFO: OpCost usage of node $sym -> ${sym.node} in opCost poistion in $usageSym -> ${usageSym.node}") //ok + case _: Tup[_,_] => //ok case _ => - !!!(s"Non OpCost usage of node $te in $usageSym -> ${usageSym.rhs}: ${usageSym.elem}: (usages = ${usages.map(_.rhs)})") + !!!(s"Non OpCost usage of node $sym -> ${sym.node} in $usageSym -> ${usageSym.node}: ${usageSym.elem}: (usages = ${usages.map(_.node)})") } } } @@ -386,18 +380,18 @@ trait Evaluation extends RuntimeCosting { IR: IRContext => } /** Finds SigmaProp.isProven method calls in the given Lambda `f` */ - def findIsProven[T](f: Rep[Context => T]): Option[Sym] = { + def findIsProven[T](f: Ref[Context => T]): Option[Sym] = { val Def(Lambda(lam,_,_,_)) = f - val s = lam.scheduleAll.find(te => te.rhs match { + val s = lam.flatSchedule.find(sym => sym.node match { case SigmaM.isValid(_) => true case _ => false - }).map(_.sym) + }) s } /** Checks that if SigmaProp.isProven method calls exists in the given Lambda's schedule, * then it is the last operation. */ - def verifyIsProven[T](f: Rep[Context => T]): Try[Unit] = { + def verifyIsProven[T](f: Ref[Context => T]): Try[Unit] = { val isProvenOpt = findIsProven(f) Try { isProvenOpt match { @@ -518,8 +512,8 @@ trait Evaluation extends RuntimeCosting { IR: IRContext => * In the latter case we expect is has already been accumulated. */ @inline private def getArgCostFromEnv(op: OpCost, dataEnv: DataEnv, s: Sym): Int = { val res = getFromEnv(dataEnv, s).asInstanceOf[Int] - assert(!isVisited(s), s"Unexpected visited arg $s -> ${s.rhs} of $op") - assert(!s.rhs.isInstanceOf[OpCost], s"Unexpected not-visited OpCost arg $s -> ${s.rhs} of $op") + assert(!isVisited(s), s"Unexpected visited arg $s -> ${s.node} of $op") + assert(!s.node.isInstanceOf[OpCost], s"Unexpected not-visited OpCost arg $s -> ${s.node} of $op") res } @@ -627,17 +621,16 @@ trait Evaluation extends RuntimeCosting { IR: IRContext => /** Transform graph IR into the corresponding Scala function * @param f simbol of the graph representing function from type A to B * @param costLimit when Some(value) is specified, then OpCost nodes will be used to accumulate total cost of execution. */ - def compile[SA, SB, A, B](dataEnv: Map[Sym, AnyRef], f: Rep[A => B], costLimit: Option[Long] = None) + def compile[SA, SB, A, B](dataEnv: Map[Sym, AnyRef], f: Ref[A => B], costLimit: Option[Long] = None) (implicit lA: Liftable[SA, A], lB: Liftable[SB, B]): SA => (SB, Int) = { val costAccumulator = new CostAccumulator(0, costLimit) - def evaluate(te: TableEntry[_]): EnvRep[_] = EnvRep { dataEnv => + def evaluate(sym: Sym): EnvRep[_] = EnvRep { dataEnv => object In { def unapply(s: Sym): Option[Any] = Some(getFromEnv(dataEnv, s)) } - def out(v: Any): (DataEnv, Sym) = { val vBoxed = v.asInstanceOf[AnyRef]; (dataEnv + (te.sym -> vBoxed), te.sym) } + def out(v: Any): (DataEnv, Sym) = { val vBoxed = v.asInstanceOf[AnyRef]; (dataEnv + (sym -> vBoxed), sym) } try { - val startTime = if (okMeasureOperationTime) System.nanoTime() else 0L - val res: (DataEnv, Sym) = te.rhs match { + val res: (DataEnv, Sym) = sym.node match { case d @ ContextM.getVar(ctx @ In(ctxObj: CostingDataContext), _, elem) => val mc = d.asInstanceOf[MethodCall] val declaredTpe = elemToSType(elem) @@ -652,18 +645,14 @@ trait Evaluation extends RuntimeCosting { IR: IRContext => case Tup(In(a), In(b)) => out((a,b)) case First(In(p: Tuple2[_,_])) => out(p._1) case Second(In(p: Tuple2[_,_])) => out(p._2) - case FieldApply(In(data), IsTupleFN(i)) => data match { - case coll: special.collection.Coll[a] => - out(coll(i - 1)) - case tup: Product => - out(tup.productElement(i - 1)) - } case wc: LiftedConst[_,_] => out(wc.constValue) - case _: SigmaDslBuilder | _: CollBuilder | _: CostedBuilder | _: IntPlusMonoid | _: LongPlusMonoid | - _: WSpecialPredefCompanion => - out(dataEnv.getOrElse(te.sym, !!!(s"Cannot resolve companion instance for $te"))) + case _: SigmaDslBuilder | _: CollBuilder | _: CostedBuilder | + _: WSpecialPredefCompanion | + _: IntPlusMonoid | _: LongPlusMonoid | + MBM.intPlusMonoid(_) | MBM.longPlusMonoid(_) => // TODO no HF proof + out(dataEnv.getOrElse(sym, !!!(s"Cannot resolve companion instance for $sym -> ${sym.node}"))) case SigmaM.isValid(In(prop: AnyRef)) => out(prop) @@ -679,7 +668,6 @@ trait Evaluation extends RuntimeCosting { IR: IRContext => val byteArray = SubstConstants.eval(input.toArray, positions.toArray, typedNewVals)(sigmaDslBuilderValue.validationSettings) out(sigmaDslBuilderValue.Colls.fromArray(byteArray)) - case AM.length(In(arr: Array[_])) => out(arr.length) case CBM.replicate(In(b: special.collection.CollBuilder), In(n: Int), xSym @ In(x)) => out(b.replicate(n, x)(asType[Any](xSym.elem.sourceType))) @@ -691,7 +679,7 @@ trait Evaluation extends RuntimeCosting { IR: IRContext => val dataRes = obj.elem match { case _: CollElem[_, _] => mc match { case CollMethods.flatMap(_, f) => - val newMC = mc.copy(args = mc.args :+ f.elem.eRange.eItem)(mc.selfType, mc.isAdapterCall) + val newMC = mc.copy(args = mc.args :+ f.elem.eRange.eItem)(mc.resultType, mc.isAdapterCall) costAccumulator.startLoop(f) val res = invokeUnlifted(obj.elem, newMC, dataEnv) costAccumulator.endLoop() @@ -767,29 +755,27 @@ trait Evaluation extends RuntimeCosting { IR: IRContext => val f = (ctx: AnyRef) => { costAccumulator.startScope() // x is not yet in _visited set of the new scope, thus it will accumulated is necessary - val resEnv = l.schedule.foldLeft(dataEnv + (x -> ctx)) { (env, te) => - val (e, _) = evaluate(te).run(env) + val resEnv = l.schedule.foldLeft(dataEnv + (x -> ctx)) { (env, sym) => + val (e, _) = evaluate(sym).run(env) e } val res = resEnv(y) - costAccumulator.endScope(te.sym) + costAccumulator.endScope(sym) res } out(f) case Apply(In(_f), In(x: AnyRef), _) => val f = _f.asInstanceOf[AnyRef => Any] out(f(x)) - case First(In(p: Tuple2[_,_])) => out(p._1) - case Second(In(p: Tuple2[_,_])) => out(p._2) case ThunkDef(y, schedule) => val th = () => { costAccumulator.startScope() - val resEnv = schedule.foldLeft(dataEnv) { (env, te) => - val (e, _) = evaluate(te).run(env) + val resEnv = schedule.foldLeft(dataEnv) { (env, sym) => + val (e, _) = evaluate(sym).run(env) e } val res = resEnv(y) - costAccumulator.endScope(te.sym) + costAccumulator.endScope(sym) res } out(th) @@ -811,13 +797,13 @@ trait Evaluation extends RuntimeCosting { IR: IRContext => val res = sigmaDslBuilderValue.avlTree(flags, digest, keyLength, valueLengthOpt) out(res) - case CReplCollCtor(valueSym @ In(value), In(len: Int)) => - val res = sigmaDslBuilderValue.Colls.replicate(len, value)(asType[Any](valueSym.elem.sourceType)) - out(res) - - case PairOfColsCtor(In(ls: SColl[a]@unchecked), In(rs: SColl[b]@unchecked)) => - val res = sigmaDslBuilderValue.Colls.pairColl(ls, rs) - out(res) +// case CReplCollCtor(valueSym @ In(value), In(len: Int)) => +// val res = sigmaDslBuilderValue.Colls.replicate(len, value)(asType[Any](valueSym.elem.sourceType)) +// out(res) +// +// case PairOfColsCtor(In(ls: SColl[a]@unchecked), In(rs: SColl[b]@unchecked)) => +// val res = sigmaDslBuilderValue.Colls.pairColl(ls, rs) +// out(res) case CSizePrimCtor(In(dataSize: Long), tVal) => val res = new special.collection.CSizePrim(dataSize, tVal.eA.sourceType) @@ -831,22 +817,22 @@ trait Evaluation extends RuntimeCosting { IR: IRContext => case CSizeOptionCtor(In(optSize: Option[SSize[_]] @unchecked)) => val res = new special.collection.CSizeOption(optSize) out(res) - case CSizeAnyValueCtor(tVal, In(valueSize: SSize[Any] @unchecked)) => - val res = new special.sigma.CSizeAnyValue(tVal.eA.sourceType.asInstanceOf[RType[Any]], valueSize) - out(res) - case CSizeBoxCtor( - In(propBytes: SSize[SColl[Byte]]@unchecked), In(bytes: SSize[SColl[Byte]]@unchecked), - In(bytesWithoutRef: SSize[SColl[Byte]]@unchecked), In(regs: SSize[SColl[Option[SAnyValue]]]@unchecked), - In(tokens: SSize[SColl[(SColl[Byte], Long)]]@unchecked)) => - val res = new EvalSizeBox(propBytes, bytes, bytesWithoutRef, regs, tokens) - out(res) +// case CSizeAnyValueCtor(tVal, In(valueSize: SSize[Any] @unchecked)) => +// val res = new special.sigma.CSizeAnyValue(tVal.eA.sourceType.asInstanceOf[RType[Any]], valueSize) +// out(res) +// case CSizeBoxCtor( +// In(propBytes: SSize[SColl[Byte]]@unchecked), In(bytes: SSize[SColl[Byte]]@unchecked), +// In(bytesWithoutRef: SSize[SColl[Byte]]@unchecked), In(regs: SSize[SColl[Option[SAnyValue]]]@unchecked), +// In(tokens: SSize[SColl[(SColl[Byte], Long)]]@unchecked)) => +// val res = new EvalSizeBox(propBytes, bytes, bytesWithoutRef, regs, tokens) +// out(res) case costOp: CostOf => out(costOp.eval) case op @ PerKbCostOf(_,In(size: Long)) => out(op.eval(size)) case op: OpCost => - val c = costAccumulator.add(te.sym, op, dataEnv) + val c = costAccumulator.add(sym, op, dataEnv) out(c) case SizeOf(sym @ In(data)) => val tpe = elemToSType(sym.elem) @@ -861,10 +847,6 @@ trait Evaluation extends RuntimeCosting { IR: IRContext => } } out(size) - case TypeSize(tpe) => - assert(tpe.isConstantSize) - val size = tpe.dataSize(SType.DummyValue) - out(size) case c @ Cast(eTo, In(v)) => if (!eTo.sourceType.classTag.runtimeClass.isAssignableFrom(v.getClass)) { error(s"Invalid cast $c: ${eTo.sourceType.classTag.runtimeClass} is not assignable from ${v.getClass}") @@ -883,34 +865,15 @@ trait Evaluation extends RuntimeCosting { IR: IRContext => else out(tpe.upcast(from.asInstanceOf[AnyVal])) - case SimpleStruct(_, fields) => - val items = fields.map { case (_, In(fieldValue)) => fieldValue }.toArray - out(sigmaDslBuilderValue.Colls.fromArray(items)(AnyType)) - case _ => - !!!(s"Don't know how to evaluate($te)") - } - if (okMeasureOperationTime) { - val endTime = System.nanoTime() - val estimatedTime = endTime - startTime - te.sym.getMetadata(OperationIdKey) match { - case Some(opId: OperationId) => - if (opId.opType.tRange.isCollection) { - val col = res._1(res._2).asInstanceOf[SColl[Any]] - val colTime = if (col.length > 1) estimatedTime / col.length else estimatedTime - CostTableStat.addOpTime(opId, colTime, col.length) - } - else - CostTableStat.addOpTime(opId, estimatedTime, len = 1) - case _ => - } + !!!(s"Don't know how to evaluate($sym -> ${sym.node})") } onEvaluatedGraphNode(res._1, res._2, res._1(res._2)) res } catch { case e: Throwable => - !!!(s"Error in Evaluation.compile.evaluate($te)", e) + !!!(s"Error in Evaluation.compile.evaluate($sym -> ${sym.node})", e) } } diff --git a/src/main/scala/sigmastate/eval/Extensions.scala b/sigmastate/src/main/scala/sigmastate/eval/Extensions.scala similarity index 100% rename from src/main/scala/sigmastate/eval/Extensions.scala rename to sigmastate/src/main/scala/sigmastate/eval/Extensions.scala diff --git a/src/main/scala/sigmastate/eval/IRContext.scala b/sigmastate/src/main/scala/sigmastate/eval/IRContext.scala similarity index 92% rename from src/main/scala/sigmastate/eval/IRContext.scala rename to sigmastate/src/main/scala/sigmastate/eval/IRContext.scala index c787545457..61a2d11f6c 100644 --- a/src/main/scala/sigmastate/eval/IRContext.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/IRContext.scala @@ -24,13 +24,13 @@ trait IRContext extends Evaluation with TreeBuilding { override val costedBuilderValue = sigmaDslBuilderValue.Costing override val monoidBuilderValue = sigmaDslBuilderValue.Monoids - type RCostingResult[T] = Rep[(Context => T, ((Int, Size[Context])) => Int)] + type RCostingResult[T] = Ref[(Context => T, ((Int, Size[Context])) => Int)] case class RCostingResultEx[T]( - costedGraph: Rep[Costed[Context] => Costed[T]], - costF: Rep[((Context, (Int, Size[Context]))) => Int] + costedGraph: Ref[Costed[Context] => Costed[T]], + costF: Ref[((Context, (Int, Size[Context]))) => Int] ) { - lazy val calcF: Rep[Context => Any] = costedGraph.sliceCalc(true) + lazy val calcF: Ref[Context => Any] = costedGraph.sliceCalc(true) } def doCosting[T](env: ScriptEnv, typed: SValue): RCostingResult[T] = { @@ -88,7 +88,7 @@ trait IRContext extends Evaluation with TreeBuilding { import Context._; def checkCost(ctx: SContext, exp: Value[SType], - costF: Rep[Size[Context] => Int], maxCost: Long): Int = { + costF: Ref[Size[Context] => Int], maxCost: Long): Int = { val costFun = compile[SSize[SContext], Int, Size[Context], Int](getDataEnv, costF, Some(maxCost)) val (_, estimatedCost) = costFun(Sized.sizeOf(ctx)) if (estimatedCost > maxCost) { @@ -98,7 +98,7 @@ trait IRContext extends Evaluation with TreeBuilding { } def checkCostEx(ctx: SContext, exp: Value[SType], - costF: Rep[((Int, Size[Context])) => Int], maxCost: Long): Int = { + costF: Ref[((Int, Size[Context])) => Int], maxCost: Long): Int = { val costFun = compile[(Int, SSize[SContext]), Int, (Int, Size[Context]), Int](getDataEnv, costF, Some(maxCost)) val (_, estimatedCost) = costFun((0, Sized.sizeOf(ctx))) if (estimatedCost > maxCost) { @@ -126,7 +126,7 @@ trait IRContext extends Evaluation with TreeBuilding { * the old scripts at some point will die out of the blockchain. */ def checkCostWithContext(ctx: SContext, exp: Value[SType], - costF: Rep[((Context, (Int, Size[Context]))) => Int], maxCost: Long, initCost: Long): Try[Int] = Try { + costF: Ref[((Context, (Int, Size[Context]))) => Int], maxCost: Long, initCost: Long): Try[Int] = Try { val costFun = compile[(SContext, (Int, SSize[SContext])), Int, (Context, (Int, Size[Context])), Int]( getDataEnv, costF, Some(maxCost)) val (estimatedCost, accCost) = costFun((ctx, (0, Sized.sizeOf(ctx)))) @@ -147,7 +147,7 @@ trait IRContext extends Evaluation with TreeBuilding { } /** IR context to be used by blockchain nodes to validate transactions. */ -class RuntimeIRContext extends IRContext with CompiletimeCosting { +class RuntimeIRContext extends IRContext { } /** IR context to be used by script development tools to compile ErgoScript into ErgoTree bytecode. */ diff --git a/src/main/scala/sigmastate/eval/RuntimeCosting.scala b/sigmastate/src/main/scala/sigmastate/eval/RuntimeCosting.scala similarity index 75% rename from src/main/scala/sigmastate/eval/RuntimeCosting.scala rename to sigmastate/src/main/scala/sigmastate/eval/RuntimeCosting.scala index 2d87f8d821..8403e82abb 100644 --- a/src/main/scala/sigmastate/eval/RuntimeCosting.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/RuntimeCosting.scala @@ -1,10 +1,8 @@ package sigmastate.eval -import java.lang.reflect.Constructor - import scala.language.implicitConversions import scala.language.existentials -import scalan.{Lazy, MutableLazy, Nullable, RType} +import scalan.{ExactIntegral, ExactOrdering, Nullable, MutableLazy, Lazy, ExactNumeric, RType} import scalan.util.CollectionUtil.TraversableOps import org.ergoplatform._ import sigmastate._ @@ -22,7 +20,6 @@ import scalan.RType._ import scorex.crypto.hash.{Sha256, Blake2b256} import sigmastate.interpreter.Interpreter.ScriptEnv import sigmastate.lang.{Terms, SourceContext} -import scalan.staged.Slicing import sigma.types.PrimViewType import sigmastate.basics.DLogProtocol.ProveDlog import sigmastate.basics.ProveDHTuple @@ -33,18 +30,19 @@ import special.sigma.{GroupElementRType, AvlTreeRType, BigIntegerRType, BoxRType import special.sigma.Extensions._ import org.ergoplatform.validation.ValidationRules._ import scalan.util.ReflectionUtil -import sigmastate.eval.ExactNumeric._ +import scalan.ExactIntegral._ +import scalan.ExactNumeric._ +import scalan.ExactOrdering.{ShortIsExactOrdering, ByteIsExactOrdering, IntIsExactOrdering, LongIsExactOrdering} +import spire.syntax.all.cfor import scala.collection.mutable +import scala.collection.mutable.ArrayBuffer trait RuntimeCosting extends CostingRules { IR: IRContext => import Context._; import Header._; import PreHeader._; - import WArray._; - import WBigInteger._ - import WECPoint._ import GroupElement._; import BigInt._; import WOption._ @@ -52,9 +50,7 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => import CollBuilder._; import SigmaProp._; import Box._ - import CollOverArrayBuilder._; import CCostedBuilder._ - import CSizeBuilder._ import Size._; import SizeBox._; import SizeColl._; @@ -78,13 +74,9 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => import SigmaDslBuilder._ import MonoidBuilder._ import AvlTree._ - import IntPlusMonoid._ - import LongPlusMonoid._ import WSpecialPredef._ - import TestSigmaDslBuilder._ import CostModel._ - override val performViewsLifting = false val okMeasureOperationTime: Boolean = false this.isInlineThunksOnForce = true // this required for splitting of cost graph @@ -108,10 +100,6 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => /** Whether to output the computed results of the script. */ var outputComputedResults: Boolean = false - /** Whether to perform extended checks of correctness, expected invariants and data consistency. - * NOTE: Since it may add substantial overhead, set it to `false` before using in production. */ - val debugModeSanityChecks: Boolean = false - // /** Pass configuration which is used by default in IRContext. */ // val calcPass = new DefaultPass("calcPass", Pass.defaultPassConfig.copy(constantPropagation = true)) // @@ -123,7 +111,8 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => // beginPass(costPass) case class CostOf(opName: String, opType: SFunc) extends BaseDef[Int] { - override def transform(t: Transformer): Def[IntPlusMonoidData] = this + override def mirror(t: Transformer): Ref[Int] = self // TODO no HF proof + def eval: Int = { val operId = OperationId(opName, opType) val cost = CostTable.DefaultCosts(operId) @@ -135,8 +124,8 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => * @param operId id of the operation in CostTable * @param size size of the data which is used to compute operation cost */ - case class PerKbCostOf(operId: OperationId, size: Rep[Long]) extends BaseDef[Int] { - override def transform(t: Transformer): Def[IntPlusMonoidData] = PerKbCostOf(operId, t(size)) + case class PerKbCostOf(operId: OperationId, size: Ref[Long]) extends BaseDef[Int] { + override def transform(t: Transformer): Def[Int] = PerKbCostOf(operId, t(size)) /** Cost rule which is used to compute operation cost, depending on dataSize. * Per kilobite cost of the oparation is obtained from CostTable and multiplied on * the data size in Kb. */ @@ -146,7 +135,7 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => } } - def costOf(costOp: CostOf, doEval: Boolean): Rep[Int] = { + def costOf(costOp: CostOf, doEval: Boolean): Ref[Int] = { val res = if (doEval) { val c = Const(costOp.eval) // optimized hot-spot: here we avoid rewriting which is done by reifyObject @@ -159,22 +148,22 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => res } - def costOf(opName: String, opType: SFunc, doEval: Boolean): Rep[Int] = { + def costOf(opName: String, opType: SFunc, doEval: Boolean): Ref[Int] = { val costOp = CostOf(opName, opType) costOf(costOp, doEval) } - def costOf(opName: String, opType: SFunc): Rep[Int] = { + def costOf(opName: String, opType: SFunc): Ref[Int] = { costOf(opName, opType, substFromCostTable) } - def costOf(method: SMethod): Rep[Int] = { + def costOf(method: SMethod): Ref[Int] = { val methodTemplate = method.objType.methodById(method.methodId) val opId = methodTemplate.opId costOf(opId.name, opId.opType.copy(tpeParams = Nil), substFromCostTable) } - def perKbCostOf(method: SMethod, dataSize: Rep[Long]): Rep[Int] = { + def perKbCostOf(method: SMethod, dataSize: Ref[Long]): Ref[Int] = { val methodTemplate = method.objType.methodById(method.methodId) val opId = methodTemplate.opId perKbCostOf(opId.name, opId.opType.copy(tpeParams = Nil), dataSize) @@ -186,40 +175,34 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => def costOfSigmaTree(sigmaTree: SigmaBoolean): Int = sigmaTree match { case _: ProveDlog => _costOfProveDlogEval.eval case _: ProveDHTuple => _costOfProveDHTuple.eval - case CAND(children) => children.map(costOfSigmaTree(_)).sum - case COR(children) => children.map(costOfSigmaTree(_)).sum - case CTHRESHOLD(_, children) => children.map(costOfSigmaTree(_)).sum + case CAND(children) => Colls.fromArray(children.toArray).map(costOfSigmaTree(_)).sum(intPlusMonoidValue) + case COR(children) => Colls.fromArray(children.toArray).map(costOfSigmaTree(_)).sum(intPlusMonoidValue) + case CTHRESHOLD(_, children) => Colls.fromArray(children.toArray).map(costOfSigmaTree(_)).sum(intPlusMonoidValue) case _ => CostTable.MinimalCost } - case class ConstantPlaceholder[T](index: Int)(implicit eT: LElem[T]) extends Def[T] { - def selfType: Elem[T] = eT.value - } - - def constantPlaceholder[T](index: Int)(implicit eT: LElem[T]): Rep[T] = ConstantPlaceholder[T](index) - - def perKbCostOf(opName: String, opType: SFunc, dataSize: Rep[Long]): Rep[Int] = { + def perKbCostOf(opName: String, opType: SFunc, dataSize: Ref[Long]): Ref[Int] = { val opNamePerKb = s"${opName}_per_kb" PerKbCostOf(OperationId(opNamePerKb, opType), dataSize) } - def perKbCostOf(node: SValue, dataSize: Rep[Long]): Rep[Int] = { + def perKbCostOf(node: SValue, dataSize: Ref[Long]): Ref[Int] = { perKbCostOf(node.getClass.getSimpleName, node.opType, dataSize) } - def perItemCostOf(node: SValue, arrLength: Rep[Int]) = { + def perItemCostOf(node: SValue, arrLength: Ref[Int]) = { val opName = s"${node.getClass.getSimpleName}_per_item" costOf(opName, node.opType) * arrLength } - def constCost(tpe: SType): Rep[Int] = tpe match { + def constCost(tpe: SType): Ref[Int] = tpe match { case _: SFunc => costOf(s"Lambda", Constant[SType](SFunc.identity.asWrappedType, tpe).opType) case _ => costOf(s"Const", Constant[SType](SType.DummyValue, tpe).opType) } - def constCost[T: Elem]: Rep[Int] = { + def constCost[T: Elem]: Ref[Int] = { val tpe = elemToSType(element[T]) constCost(tpe) } @@ -227,7 +210,7 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => val UpcastBigIntOpType = SFunc(sigmastate.Upcast.tT, SBigInt) val DowncastBigIntOpType = SFunc(SBigInt, sigmastate.Upcast.tR) - def costOf(v: SValue): Rep[Int] = v match { + def costOf(v: SValue): Ref[Int] = v match { case l: Terms.Lambda => constCost(l.tpe) case l: FuncValue => @@ -240,107 +223,87 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => costOf(v.opName, v.opType) } - trait SizeStruct extends Size[Struct] { - def sizeFields: Rep[Struct] - } - case class SizeStructCtor(sizeFields: Rep[Struct]) extends SizeStruct { - override def transform(t: Transformer) = SizeStructCtor(t(sizeFields)) - - implicit val eVal: Elem[Struct] = { - val fields = sizeFields.elem.fields.map { case (fn, cE) => (fn, cE.asInstanceOf[SizeElem[_, _]].eVal) } - structElement(fields) - } - val selfType: Elem[Size[Struct]] = sizeElement(eVal) - - def dataSize: Rep[Long] = { - val sizes = sizeFields.fields.map { case (_, cf: RSize[a]@unchecked) => cf.dataSize } - val sizesColl = colBuilder.fromItems(sizes:_*) - sizesColl.sum(longPlusMonoid) - } - } - def RSizeStruct(sizeFields: Rep[Struct]): Rep[Size[Struct]] = SizeStructCtor(sizeFields) - - trait CostedStruct extends Costed[Struct] { } - - case class CostedStructCtor(costedFields: Rep[Struct], structCost: Rep[Int]) extends CostedStruct { - override def transform(t: Transformer) = CostedStructCtor(t(costedFields), t(structCost)) - - implicit val eVal: Elem[Struct] = { - val fields = costedFields.elem.fields.map { case (fn, cE) => (fn, cE.asInstanceOf[CostedElem[_, _]].eVal) } - structElement(fields) - } - val selfType: Elem[Costed[Struct]] = costedElement(eVal) - - def builder: Rep[CostedBuilder] = costedBuilder - - def value: Rep[Struct] = costedFields.mapFields { case cf: RCosted[a]@unchecked => cf.value } - - def cost: Rep[Int] = { - val costs = costedFields.fields.map { case (_, cf: RCosted[a]@unchecked) => cf.cost } - opCost(value, costs, structCost) - } - - override def size: Rep[Size[Struct]] = { - val sizeFields = costedFields.mapFields { case cf: RCosted[a]@unchecked => cf.size } - SizeStructCtor(sizeFields) - } - } +// trait SizeStruct extends Size[Struct] { +// def sizeFields: Ref[Struct] +// } +// case class SizeStructCtor(sizeFields: Ref[Struct]) extends SizeStruct { +// override def transform(t: Transformer) = SizeStructCtor(t(sizeFields)) +// +// implicit val eVal: Elem[Struct] = { +// val fields = sizeFields.elem.fields.map { case (fn, cE) => (fn, cE.asInstanceOf[SizeElem[_, _]].eVal) } +// structElement(fields) +// } +// val resultType: Elem[Size[Struct]] = sizeElement(eVal) +// +// def dataSize: Ref[Long] = { +// val sizes = sizeFields.fields.map { case (_, cf: RSize[a]@unchecked) => cf.dataSize } +// val sizesColl = colBuilder.fromItems(sizes:_*) +// sizesColl.sum(longPlusMonoid) +// } +// } +// def RSizeStruct(sizeFields: Ref[Struct]): Ref[Size[Struct]] = SizeStructCtor(sizeFields) + +// trait CostedStruct extends Costed[Struct] { } + +// case class CostedStructCtor(costedFields: Ref[Struct], structCost: Ref[Int]) extends CostedStruct { +// override def transform(t: Transformer) = CostedStructCtor(t(costedFields), t(structCost)) +// +// implicit val eVal: Elem[Struct] = { +// val fields = costedFields.elem.fields.map { case (fn, cE) => (fn, cE.asInstanceOf[CostedElem[_, _]].eVal) } +// structElement(fields) +// } +// val resultType: Elem[Costed[Struct]] = costedElement(eVal) +// +// def builder: Ref[CostedBuilder] = costedBuilder +// +// def value: Ref[Struct] = costedFields.mapFields { case cf: RCosted[a]@unchecked => cf.value } +// +// def cost: Ref[Int] = { +// val costs = costedFields.fields.map { case (_, cf: RCosted[a]@unchecked) => cf.cost } +// opCost(value, costs, structCost) +// } +// +// override def size: Ref[Size[Struct]] = { +// val sizeFields = costedFields.mapFields { case cf: RCosted[a]@unchecked => cf.size } +// SizeStructCtor(sizeFields) +// } +// } - def RCostedStruct(costedFields: Rep[Struct], structCost: Rep[Int]): Rep[Costed[Struct]] = CostedStructCtor(costedFields, structCost) +// def RCostedStruct(costedFields: Ref[Struct], structCost: Ref[Int]): Ref[Costed[Struct]] = CostedStructCtor(costedFields, structCost) // SizeThunk ============================================= trait SizeThunk[A] extends Size[Thunk[A]] { } - case class SizeThunkCtor[A](sizeBlock: Rep[Thunk[Size[A]]]) extends SizeThunk[A] { + case class SizeThunkCtor[A](sizeBlock: Ref[Thunk[Size[A]]]) extends SizeThunk[A] { override def transform(t: Transformer) = SizeThunkCtor(t(sizeBlock)) implicit val eVal: Elem[Thunk[A]] = thunkElement(sizeBlock.elem.eItem.eVal) - val selfType: Elem[Size[Thunk[A]]] = sizeElement(eVal) + val resultType: Elem[Size[Thunk[A]]] = sizeElement(eVal) - override def dataSize: Rep[Long] = sizeBlock.force().dataSize + override def dataSize: Ref[Long] = sizeBlock.force().dataSize } - def RSizeThunk[A](sizeBlock: Rep[Thunk[Size[A]]]): Rep[Size[Thunk[A]]] = SizeThunkCtor(sizeBlock) + def RSizeThunk[A](sizeBlock: Ref[Thunk[Size[A]]]): Ref[Size[Thunk[A]]] = SizeThunkCtor(sizeBlock) // --------------------------------------------------------- // CostedThunk ============================================= trait CostedThunk[A] extends Costed[Thunk[A]] { } - case class CostedThunkCtor[A](costedBlock: Rep[Thunk[Costed[A]]], thunkCost: Rep[Int]) extends CostedThunk[A] { + case class CostedThunkCtor[A](costedBlock: Ref[Thunk[Costed[A]]], thunkCost: Ref[Int]) extends CostedThunk[A] { override def transform(t: Transformer) = CostedThunkCtor(t(costedBlock), t(thunkCost)) implicit val eVal: Elem[Thunk[A]] = thunkElement(costedBlock.elem.eItem.eVal) - val selfType: Elem[Costed[Thunk[A]]] = costedElement(eVal) + val resultType: Elem[Costed[Thunk[A]]] = costedElement(eVal) - def builder: Rep[CostedBuilder] = costedBuilder - def value: Rep[Thunk[A]] = Thunk { costedBlock.force().value } - def cost: Rep[Int] = asRep[Int](ThunkForce(Thunk(costedBlock.force.cost))) + thunkCost + def builder: Ref[CostedBuilder] = costedBuilder + def value: Ref[Thunk[A]] = Thunk { costedBlock.force().value } + def cost: Ref[Int] = asRep[Int](ThunkForce(Thunk(costedBlock.force.cost))) + thunkCost override def size: RSize[Thunk[A]] = SizeThunkCtor(Thunk { costedBlock.force().size }) } - def RCostedThunk[A](costedBlock: Rep[Thunk[Costed[A]]], thunkCost: Rep[Int]): Rep[Costed[Thunk[A]]] = CostedThunkCtor(costedBlock, thunkCost) + def RCostedThunk[A](costedBlock: Ref[Thunk[Costed[A]]], thunkCost: Ref[Int]): Ref[Costed[Thunk[A]]] = CostedThunkCtor(costedBlock, thunkCost) // --------------------------------------------------------- - object ConstantSizeType { - def unapply(e: Elem[_]): Nullable[SType] = { - val tpe = elemToSType(e) - if (tpe.isConstantSize) Nullable(tpe) - else Nullable.None - } - } - - override def sizeOf[T](value: Rep[T]): Rep[Long] = value.elem match { - case ConstantSizeType(tpe) => - typeSize(tpe) - case _ => - !!!(s"Cannot get sizeOf($value: ${value.elem})", value) - } - - /** Graph node to represent computation of size for types with isConstantSize == true. */ - case class TypeSize(tpe: SType) extends BaseDef[Long] { - assert(tpe.isConstantSize, s"Expected isConstantSize type but was TypeSize($tpe)") - } - - def typeSize(tpe: SType): Rep[Long] = { + def typeSize(tpe: SType): Ref[Long] = { assert(tpe.isConstantSize, { s"Expected constant size type but was $tpe" }) @@ -348,7 +311,7 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => toRep(size) } - def typeSize[T: Elem]: Rep[Long] = { + def typeSize[T: Elem]: Ref[Long] = { val tpe = elemToSType(element[T]) typeSize(tpe) } @@ -357,36 +320,33 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => case CostOf(name, opType) => s"CostOf($name:$opType)" case GroupElementConst(p) => p.showToString case SigmaPropConst(sp) => sp.toString - case ac: WArrayConst[_,_] => - val trimmed = ac.constValue.take(ac.constValue.length min 10) - s"WArray(len=${ac.constValue.length}; ${trimmed.mkString(",")},...)" case _ => super.formatDef(d) } - type RColl[T] = Rep[Coll[T]] - type ROption[T] = Rep[WOption[T]] - type RCostedColl[T] = Rep[CostedColl[T]] - type RCostedOption[T] = Rep[CostedOption[T]] - type RFuncCosted[A,B] = Rep[Costed[A] => Costed[B]] + type RColl[T] = Ref[Coll[T]] + type ROption[T] = Ref[WOption[T]] + type RCostedColl[T] = Ref[CostedColl[T]] + type RCostedOption[T] = Ref[CostedOption[T]] + type RFuncCosted[A,B] = Ref[Costed[A] => Costed[B]] implicit class RFuncCostedOps[A,B](f: RFuncCosted[A,B]) { implicit val eA = f.elem.eDom.eVal /**NOTE: when removeIsValid == true the resulting type B may change from Boolean to SigmaProp * This should be kept in mind at call site */ - def sliceCalc(okRemoveIsProven: Boolean): Rep[A => Any] = { - val _f = { x: Rep[A] => f(RCCostedPrim(x, IntZero, zeroSize(x.elem))).value } + def sliceCalc(okRemoveIsProven: Boolean): Ref[A => Any] = { + val _f = { x: Ref[A] => f(RCCostedPrim(x, IntZero, zeroSize(x.elem))).value } val res = if (okRemoveIsProven) fun(removeIsProven(_f)) else fun(_f) res } - def sliceCalc: Rep[A => B] = fun { x: Rep[A] => f(RCCostedPrim(x, IntZero, zeroSize(x.elem))).value } + def sliceCalc: Ref[A => B] = fun { x: Ref[A] => f(RCCostedPrim(x, IntZero, zeroSize(x.elem))).value } - def sliceCost: Rep[((Int,Size[A])) => Int] = fun { in: Rep[(Int, Size[A])] => + def sliceCost: Ref[((Int,Size[A])) => Int] = fun { in: Ref[(Int, Size[A])] => val Pair(c, s) = in f(RCCostedPrim(placeholder[A], c, s)).cost } - def sliceCostEx: Rep[((A, (Int,Size[A]))) => Int] = fun { in: Rep[(A, (Int, Size[A]))] => + def sliceCostEx: Ref[((A, (Int,Size[A]))) => Int] = fun { in: Ref[(A, (Int, Size[A]))] => val Pair(ctx, Pair(c, s)) = in val oldFun = funUnderCosting @@ -399,7 +359,7 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => } } - def sliceSize: Rep[Size[A] => Size[B]] = fun { in: Rep[Size[A]] => + def sliceSize: Ref[Size[A] => Size[B]] = fun { in: Ref[Size[A]] => val s = in val arg = RCCostedPrim(placeholder[A], IntZero, s) f(arg).size @@ -408,18 +368,18 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => type CostedCollFunc[A,B] = Costed[A] => CostedColl[B] type CostedOptionFunc[A,B] = Costed[A] => CostedOption[B] - type RCostedCollFunc[A,B] = Rep[CostedCollFunc[A, B]] - type RCostedOptionFunc[A,B] = Rep[CostedOptionFunc[A, B]] + type RCostedCollFunc[A,B] = Ref[CostedCollFunc[A, B]] + type RCostedOptionFunc[A,B] = Ref[CostedOptionFunc[A, B]] implicit class RCostedCollFuncOps[A,B](f: RCostedCollFunc[A,B]) { implicit val eA = f.elem.eDom.eVal - def sliceValues: Rep[A => Coll[B]] = fun { x: Rep[A] => f(RCCostedPrim(x, IntZero, zeroSize(x.elem))).values } - def sliceCosts: Rep[((Int,Size[A])) => (Coll[Int], Int)] = fun { in: Rep[(Int, Size[A])] => + def sliceValues: Ref[A => Coll[B]] = fun { x: Ref[A] => f(RCCostedPrim(x, IntZero, zeroSize(x.elem))).values } + def sliceCosts: Ref[((Int,Size[A])) => (Coll[Int], Int)] = fun { in: Ref[(Int, Size[A])] => val Pair(c, s) = in val colC = f(RCCostedPrim(placeholder[A], c, s)) Pair(colC.costs, colC.valuesCost) } - def sliceSizes: Rep[Size[A] => Coll[Size[B]]] = fun { in: Rep[Size[A]] => + def sliceSizes: Ref[Size[A] => Coll[Size[B]]] = fun { in: Ref[Size[A]] => val s = in f(RCCostedPrim(placeholder[A], IntZero, s)).sizes } @@ -436,19 +396,19 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => implicit def extendCostedCollElem[A](elem: Elem[CostedColl[A]]): CostedCollElem[A, CostedColl[A]] = elem.asInstanceOf[CostedCollElem[A, CostedColl[A]]] - def splitCostedFunc2[A,B](f: RFuncCosted[A,B]): (Rep[A=>B], Rep[((Int, Size[A])) => Int]) = { + def splitCostedFunc2[A,B](f: RFuncCosted[A,B]): (Ref[A=>B], Ref[((Int, Size[A])) => Int]) = { implicit val eA = f.elem.eDom.eVal val calcF = f.sliceCalc val costF = f.sliceCost (calcF, costF) } - def splitCostedFunc2[A, B](f: RFuncCosted[A,B], okRemoveIsValid: Boolean): (Rep[A=>Any], Rep[((Int, Size[A])) => Int]) = { + def splitCostedFunc2[A, B](f: RFuncCosted[A,B], okRemoveIsValid: Boolean): (Ref[A=>Any], Ref[((Int, Size[A])) => Int]) = { implicit val eA = f.elem.eDom.eVal val calcF = f.sliceCalc(okRemoveIsValid) val costF = f.sliceCost (calcF, costF) } - def splitCostedFunc[A,B](f: RFuncCosted[A,B]): (Rep[A=>B], Rep[((Int, Size[A])) => Int], Rep[Size[A] => Size[B]]) = { + def splitCostedFunc[A,B](f: RFuncCosted[A,B]): (Ref[A=>B], Ref[((Int, Size[A])) => Int], Ref[Size[A] => Size[B]]) = { implicit val eA = f.elem.eDom.eVal val calcF = f.sliceCalc val costF = f.sliceCost @@ -456,7 +416,7 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => (calcF, costF, sizeF) } - def splitCostedCollFunc[A,B](f: RCostedCollFunc[A,B]): (Rep[A=>Coll[B]], Rep[((Int, Size[A])) => (Coll[Int], Int)], Rep[Size[A] => Coll[Size[B]]]) = { + def splitCostedCollFunc[A,B](f: RCostedCollFunc[A,B]): (Ref[A=>Coll[B]], Ref[((Int, Size[A])) => (Coll[Int], Int)], Ref[Size[A] => Coll[Size[B]]]) = { implicit val eA = f.elem.eDom.eVal val calcF = f.sliceValues val costF = f.sliceCosts @@ -465,18 +425,15 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => } object CostedFoldExtractors { - val CM = CostedMethods - val COM = CostedOptionMethods - val WOM = WOptionMethods type Result = (ROption[A], Th[B], RFunc[A, Costed[B]]) forSome {type A; type B} } object IsConstSizeCostedColl { - def unapply(d: Def[_]): Nullable[Rep[Costed[Coll[A]]] forSome {type A}] = d.selfType match { + def unapply(d: Def[_]): Nullable[Ref[Costed[Coll[A]]] forSome {type A}] = d.resultType match { case ce: CostedElem[_,_] if !ce.isInstanceOf[CostedCollElem[_, _]] => ce.eVal match { case colE: CollElem[a,_] if colE.eItem.isConstantSize => - val res = d.self.asInstanceOf[Rep[Costed[Coll[A]]] forSome {type A}] + val res = d.self.asInstanceOf[Ref[Costed[Coll[A]]] forSome {type A}] Nullable(res) case _ => Nullable.None } @@ -485,11 +442,11 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => } object IsCostedPair { - def unapply(d: Def[_]): Nullable[Rep[Costed[(A, B)]] forSome {type A; type B}] = d.selfType match { + def unapply(d: Def[_]): Nullable[Ref[Costed[(A, B)]] forSome {type A; type B}] = d.resultType match { case ce: CostedElem[_,_] if !ce.isInstanceOf[CostedPairElem[_, _, _]] => ce.eVal match { case _: PairElem[a,b] => - val res = d.self.asInstanceOf[Rep[Costed[(A, B)]] forSome {type A; type B}] + val res = d.self.asInstanceOf[Ref[Costed[(A, B)]] forSome {type A; type B}] Nullable(res) case _ => Nullable.None } @@ -503,61 +460,106 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => type CostedTh[T] = Th[Costed[T]] - class ElemAccessor[T](prop: Rep[T] => Elem[_]) { + class ElemAccessor[T](prop: Ref[T] => Elem[_]) { def unapply(s: Sym): Nullable[Elem[_]] = { val sR = asRep[T](s); Nullable(prop(sR)) } } object ElemAccessor { - def apply[T](prop: Rep[T] => Elem[_]): ElemAccessor[T] = new ElemAccessor(prop) + def apply[T](prop: Ref[T] => Elem[_]): ElemAccessor[T] = new ElemAccessor(prop) } val EValOfSizeColl = ElemAccessor[Coll[Size[Any]]](_.elem.eItem.eVal) - private object Methods { - val CBM = CollBuilderMethods - val SigmaM = SigmaPropMethods - val CCM = CostedCollMethods - val CostedM = CostedMethods - val CostedOptionM = CostedOptionMethods - val WOptionM = WOptionMethods - val WArrayM = WArrayMethods - val CM = CollMethods - val CostedBuilderM = CostedBuilderMethods - val SPCM = WSpecialPredefCompanionMethods - val SDBM = SigmaDslBuilderMethods - val SM = SizeMethods - val SBM = SizeBoxMethods - } + private val CBM = CollBuilderMethods + private val SigmaM = SigmaPropMethods + private val CCM = CostedCollMethods + private val CostedM = CostedMethods + private val WOptionM = WOptionMethods + private val SDBM = SigmaDslBuilderMethods + private val SM = SizeMethods - def mkNormalizedOpCost(costedValue: Sym, costs: Seq[Rep[Int]]): Rep[Int] = { - val (args, rests) = costs.partition(_.rhs.isInstanceOf[OpCost]) + def mkNormalizedOpCost(costedValue: Sym, costs: Seq[Ref[Int]]): Ref[Int] = { + val (args, rests) = costs.partition(_.node.isInstanceOf[OpCost]) val restSum = if (rests.isEmpty) IntZero else rests.reduce((x, y) => x + y) opCost(costedValue, args, restSum) } - override def rewriteDef[T](d: Def[T]): Rep[_] = { - import Methods._ + object AnyOf { + def unapply(d: Def[_]): Nullable[(Ref[CollBuilder], Seq[Ref[A]], Elem[A]) forSome {type A}] = d match { + case SDBM.anyOf(_, xs) => + CBM.fromItems.unapply(xs) + case _ => Nullable.None + } + } + object AllOf { + def unapply(d: Def[_]): Nullable[(Ref[CollBuilder], Seq[Ref[A]], Elem[A]) forSome {type A}] = d match { + case SDBM.allOf(_, xs) => + CBM.fromItems.unapply(xs) + case _ => Nullable.None + } + } + object AnyZk { + def unapply(d: Def[_]): Nullable[(Ref[CollBuilder], Seq[Ref[SigmaProp]], Elem[SigmaProp])] = d match { + case SDBM.anyZK(_, xs) => + CBM.fromItems.unapply(xs).asInstanceOf[Nullable[(Ref[CollBuilder], Seq[Ref[SigmaProp]], Elem[SigmaProp])]] + case _ => Nullable.None + } + } + object AllZk { + def unapply(d: Def[_]): Nullable[(Ref[CollBuilder], Seq[Ref[SigmaProp]], Elem[SigmaProp])] = d match { + case SDBM.allZK(_, xs) => + CBM.fromItems.unapply(xs).asInstanceOf[Nullable[(Ref[CollBuilder], Seq[Ref[SigmaProp]], Elem[SigmaProp])]] + case _ => Nullable.None + } + } + object HasSigmas { + def unapply(items: Seq[Sym]): Option[(Seq[Ref[Boolean]], Seq[Ref[SigmaProp]])] = { + val bs = ArrayBuffer.empty[Ref[Boolean]] + val ss = ArrayBuffer.empty[Ref[SigmaProp]] + for (i <- items) { + i match { + case SigmaM.isValid(s) => ss += s + case b => bs += asRep[Boolean](b) + } + } + assert(items.length == bs.length + ss.length) + if (ss.isEmpty) None + else Some((bs,ss)) + } + } + /** For performance reasons the patterns are organized in special (non-declarative) way. + * Unfortunately, this is less readable, but gives significant performance boost + * Look at comments to understand the logic of the rules. + * + * @hotspot executed for each node of the graph, don't beautify. + */ + override def rewriteDef[T](d: Def[T]): Ref[_] = { + // First we match on node type, and then depending on it, we have further branching logic. + // On each branching level each node type should be matched exactly once, + // for the rewriting to be sound. d match { // Rule: cast(eTo, x) if x.elem <:< eTo ==> x - case Cast(eTo: Elem[to], x) if eTo.runtimeClass.isAssignableFrom(x.elem.runtimeClass) => + case Cast(eTo: Elem[to], x) if eTo.getClass.isAssignableFrom(x.elem.getClass) => x // Rule: ThunkDef(x, Nil).force => x case ThunkForce(Def(ThunkDef(root, sch))) if sch.isEmpty => root - case SM.dataSize(Def(CSizeCollCtor(CBM.replicate(_, n, s: RSize[a]@unchecked)))) => s.dataSize * n.toLong - - case SM.dataSize(Def(CSizeCollCtor(sizes @ EValOfSizeColl(eVal)))) if eVal.isConstantSize => - sizes.length.toLong * typeSize(eVal) + case SM.dataSize(size) => size.node match { + case CSizeCollCtor(sizes) => sizes match { + case CBM.replicate(_, n, s: RSize[a]@unchecked) => s.dataSize * n.toLong + case EValOfSizeColl(eVal) if eVal.isConstantSize => sizes.length.toLong * typeSize(eVal) + case _ => super.rewriteDef(d) + } + case _ => super.rewriteDef(d) + } - case CM.map(CM.zip(CBM.replicate(_, n, x: Rep[a]), ys: RColl[b]@unchecked), _f) => + case CM.map(CM.zip(CBM.replicate(_, n, x: Ref[a]), ys: RColl[b]@unchecked), _f) => val f = asRep[((a,b)) => Any](_f) implicit val eb = ys.elem.eItem - ys.map(fun { y: Rep[b] => f(Pair(x, y))}) - - case WArrayM.length(Def(arrC: WArrayConst[_,_])) => arrC.constValue.length + ys.map(fun { y: Ref[b] => f(Pair(x, y))}) // Rule: l.isValid op Thunk {... root} => (l op TrivialSigma(root)).isValid case ApplyBinOpLazy(op, SigmaM.isValid(l), Def(ThunkDef(root, sch))) if root.elem == BooleanElement => @@ -579,13 +581,16 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => l1 || prop res.isValid + case SDBM.Colls(_) => colBuilder + case SDBM.sigmaProp(_, SigmaM.isValid(p)) => p + case SigmaM.isValid(SDBM.sigmaProp(_, bool)) => bool case CCM.foldCosted(xs: RCostedColl[a], zero: RCosted[b], _f) => val f = asRep[Costed[(b,a)] => Costed[b]](_f) - val (calcF/*: Rep[((b,a)) => b]*/, - costF/*: Rep[((Int, Size[(b,a)])) => Int]*/, - sizeF/*: Rep[Size[(b,a)] => Size[b]]*/) = splitCostedFunc[(b,a), b](f) + val (calcF/*: Ref[((b,a)) => b]*/, + costF/*: Ref[((Int, Size[(b,a)])) => Int]*/, + sizeF/*: Ref[Size[(b,a)] => Size[b]]*/) = splitCostedFunc[(b,a), b](f) val resV = xs.values.foldLeft(zero.value, calcF) @@ -599,11 +604,11 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => val preFoldCost = opCost(resV, Array(xs.cost, zero.cost), len * CostTable.lambdaInvoke + CostTable.lambdaCost) val Pair(resS, resC) = sizes.foldLeft(Pair(zero.size, preFoldCost), - fun { in: Rep[((Size[b], Int), Size[a])] => + fun { in: Ref[((Size[b], Int), Size[a])] => val Pair(Pair(accSizeB, accCost), xSize) = in val sBA = RCSizePair(accSizeB, xSize) val size = sizeF(sBA) // unfold sizeF - val cost: Rep[Int] = opCost(size, Array(accCost), asRep[Int](Apply(costF, Pair(IntZero, sBA), false)) + CostTable.lambdaInvoke) + val cost: Ref[Int] = opCost(size, Array(accCost), asRep[Int](Apply(costF, Pair(IntZero, sBA), false)) + CostTable.lambdaInvoke) val res = Pair(size, cost) res } @@ -612,50 +617,54 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => val cost = opCost(resV, Array(preFoldCost), resC) RCCostedPrim(resV, cost, resS) - case CostedM.cost(Def(CCostedCollCtor(values, costs, _, accCost))) => - accCost.rhs match { - case _: OpCost => - opCost(values, Array(accCost), costs.sum(intPlusMonoid)) // OpCost should be in args position - case _ => - opCost(values, Nil, costs.sum(intPlusMonoid) + accCost) - } - - case CostedM.cost(Def(CCostedOptionCtor(v, costOpt, _, accCost))) => - accCost.rhs match { - case _: OpCost => - opCost(v, Array(accCost), costOpt.getOrElse(Thunk(IntZero))) // OpCost should be in args position - case _ => - opCost(v, Nil, costOpt.getOrElse(Thunk(IntZero)) + accCost) - } - - case CostedM.cost(Def(CCostedPairCtor(l, r, accCost))) => - val costs = Array(l.cost, r.cost, accCost) - val v = Pair(l.value, r.value) - mkNormalizedOpCost(v, costs) + case CostedM.cost(costed) => costed.node match { + case CCostedCollCtor(values, costs, _, accCost) => + accCost.node match { + case _: OpCost => + opCost(values, Array(accCost), costs.sum(intPlusMonoid)) // OpCost should be in args position + case _ => + opCost(values, Nil, costs.sum(intPlusMonoid) + accCost) + } + case CCostedOptionCtor(v, costOpt, _, accCost) => + accCost.node match { + case _: OpCost => + opCost(v, Array(accCost), costOpt.getOrElse(Thunk(IntZero))) // OpCost should be in args position + case _ => + opCost(v, Nil, costOpt.getOrElse(Thunk(IntZero)) + accCost) + } + case CCostedPairCtor(l, r, accCost) => + val costs = Array(l.cost, r.cost, accCost) + val v = Pair(l.value, r.value) + mkNormalizedOpCost(v, costs) + + // Rule: opt.fold(default, f).cost ==> opt.fold(default.cost, x => f(x).cost) + case WOptionM.fold(opt, _th @ Def(ThunkDef(_, _)), _f) => + implicit val eA: Elem[Any] = opt.elem.eItem.asInstanceOf[Elem[Any]] + val th = asRep[Thunk[Costed[Any]]](_th) + val f = asRep[Any => Costed[Any]](_f) + opt.fold(Thunk(forceThunkByMirror(th).cost), fun { x: Ref[Any] => f(x).cost }) + case _ => super.rewriteDef(d) + } - case CostedM.value(Def(CCostedFuncCtor(_, func: RFuncCosted[a,b], _,_))) => - func.sliceCalc + case CostedM.value(costed) => costed.node match { + case CCostedFuncCtor(_, func: RFuncCosted[a,b], _,_) => func.sliceCalc - // Rule: opt.fold(default, f).value ==> opt.fold(default.value, x => f(x).value) - case CostedM.value(WOptionM.fold(opt, _th @ Def(ThunkDef(_, _)), _f)) => - implicit val eA: Elem[Any] = opt.elem.eItem.asElem[Any] - val th = asRep[Thunk[Costed[Any]]](_th) - val f = asRep[Any => Costed[Any]](_f) - opt.fold(Thunk(forceThunkByMirror(th).value), fun { x: Rep[Any] => f(x).value }) + // Rule: opt.fold(default, f).value ==> opt.fold(default.value, x => f(x).value) + case WOptionM.fold(opt, _th @ Def(ThunkDef(_, _)), _f) => + implicit val eA: Elem[Any] = opt.elem.eItem.asInstanceOf[Elem[Any]] + val th = asRep[Thunk[Costed[Any]]](_th) + val f = asRep[Any => Costed[Any]](_f) + opt.fold(Thunk(forceThunkByMirror(th).value), fun { x: Ref[Any] => f(x).value }) - // Rule: opt.fold(default, f).cost ==> opt.fold(default.cost, x => f(x).cost) - case CostedM.cost(WOptionM.fold(opt, _th @ Def(ThunkDef(_, _)), _f)) => - implicit val eA: Elem[Any] = opt.elem.eItem.asElem[Any] - val th = asRep[Thunk[Costed[Any]]](_th) - val f = asRep[Any => Costed[Any]](_f) - opt.fold(Thunk(forceThunkByMirror(th).cost), fun { x: Rep[Any] => f(x).cost }) + case _ => super.rewriteDef(d) + } // Rule: opt.fold(default, f).size ==> opt.fold(default.size, x => f(x).size) case CostedM.size(WOptionM.fold(opt, _th @ Def(ThunkDef(_, _)), _f)) => - implicit val eA: Elem[Any] = opt.elem.eItem.asElem[Any] + implicit val eA: Elem[Any] = opt.elem.eItem.asInstanceOf[Elem[Any]] val th = asRep[Thunk[Costed[Any]]](_th) val f = asRep[Any => Costed[Any]](_f) - opt.fold(Thunk(forceThunkByMirror(th).size), fun { x: Rep[Any] => f(x).size }) + opt.fold(Thunk(forceThunkByMirror(th).size), fun { x: Ref[Any] => f(x).size }) case CCostedPrimCtor(v, c, s) => val res = v.elem.asInstanceOf[Elem[_]] match { @@ -677,13 +686,13 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => case OpCost(_, id, args, cost) => val zero = IntZero - if (isCostingProcess && cost == zero && args.length == 1 && args(0).rhs.isInstanceOf[OpCost]) { + if (isCostingProcess && cost == zero && args.length == 1 && args(0).node.isInstanceOf[OpCost]) { args(0) // Rule: OpCode(_,_, Seq(x @ OpCode(...)), 0) ==> x, } else if (args.exists(_ == zero)) { val nonZeroArgs = args.filterNot(_ == zero) - val res: Rep[Int] = + val res: Ref[Int] = if (cost == zero && nonZeroArgs.isEmpty) zero else { val lamVar = lambdaStack.head.x @@ -697,29 +706,44 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => } super.rewriteDef(d) } + case _ => - super.rewriteDef(d) + if (currentPass.config.constantPropagation) { + // additional constant propagation rules (see other similar cases) + d match { + case AnyOf(_,items,_) if (items.forall(_.isConst)) => + val bs = items.map { case Def(Const(b: Boolean)) => b } + toRep(bs.exists(_ == true)) + case AllOf(_,items,_) if (items.forall(_.isConst)) => + val bs = items.map { case Def(Const(b: Boolean)) => b } + toRep(bs.forall(_ == true)) + case _ => + super.rewriteDef(d) + } + } + else + super.rewriteDef(d) } } - def costedPrimToColl[A](coll: Rep[Coll[A]], c: Rep[Int], s: RSize[Coll[A]]): RCostedColl[A] = s.elem.asInstanceOf[Any] match { + def costedPrimToColl[A](coll: Ref[Coll[A]], c: Ref[Int], s: RSize[Coll[A]]): RCostedColl[A] = s.elem.asInstanceOf[Any] match { case se: SizeElem[_,_] if se.eVal.isInstanceOf[CollElem[_,_]] => val sizes = asSizeColl(s).sizes val costs = colBuilder.replicate(sizes.length, IntZero) mkCostedColl(coll, costs, sizes, c) case _ => - !!!(s"Expected Size[Coll[A]] node but was $s -> ${s.rhs}") + !!!(s"Expected Size[Coll[A]] node but was $s -> ${s.node}") } - def costedPrimToOption[A](opt: Rep[WOption[A]], c: Rep[Int], s: RSize[WOption[A]]) = s.elem.asInstanceOf[Any] match { + def costedPrimToOption[A](opt: Ref[WOption[A]], c: Ref[Int], s: RSize[WOption[A]]) = s.elem.asInstanceOf[Any] match { case se: SizeElem[_,_] if se.eVal.isInstanceOf[WOptionElem[_,_]] => val sizeOpt = asSizeOption(s).sizeOpt mkCostedOption(opt, SomeIntZero, sizeOpt, c) case _ => - !!!(s"Expected RCSizeOption node but was $s -> ${s.rhs}") + !!!(s"Expected RCSizeOption node but was $s -> ${s.node}") } - def costedPrimToPair[A,B](p: Rep[(A,B)], c: Rep[Int], s: RSize[(A,B)]) = s.elem.asInstanceOf[Any] match { + def costedPrimToPair[A,B](p: Ref[(A,B)], c: Ref[Int], s: RSize[(A,B)]) = s.elem.asInstanceOf[Any] match { case se: SizeElem[_,_] if se.eVal.isInstanceOf[PairElem[_,_]] => val sPair = asSizePair(s) val zero = IntZero @@ -728,10 +752,10 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => val newCost = if (c == zero) zero else opCost(Pair(l, r), Array(c), zero) RCCostedPair(l, r, newCost) case _ => - !!!(s"Expected RCSizePair node but was $s -> ${s.rhs}") + !!!(s"Expected RCSizePair node but was $s -> ${s.node}") } - override def rewriteNonInvokableMethodCall(mc: MethodCall): Rep[_] = mc match { + override def rewriteNonInvokableMethodCall(mc: MethodCall): Ref[_] = mc match { case IsConstSizeCostedColl(col: RCosted[Coll[Any]]@unchecked) => costedPrimToColl(col.value, col.cost, asSizeColl(col.size)) case IsCostedPair(p) => @@ -743,56 +767,47 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => super.rewriteNonInvokableMethodCall(mc) } - override def transformDef[A](d: Def[A], t: Transformer): Rep[A] = d match { - case c: CostOf => c.self - case OpCost(_, id, args, cost) => - if (args.contains(cost)) - !!!(s"Invalid OpCost($id, $args, $cost)") - super.transformDef(d, t) - case _ => super.transformDef(d, t) - } - /** Should be specified in the final cake */ val builder: sigmastate.lang.SigmaBuilder import builder._ /** Lazy values, which are immutable, but can be reset, so that the next time they are accessed * the expression is re-evaluated. Each value should be reset in onReset() method. */ - private val _sigmaDslBuilder: LazyRep[SigmaDslBuilder] = MutableLazy(RTestSigmaDslBuilder()) - @inline def sigmaDslBuilder: Rep[SigmaDslBuilder] = _sigmaDslBuilder.value + private val _sigmaDslBuilder: LazyRep[SigmaDslBuilder] = MutableLazy(variable[SigmaDslBuilder]) + @inline def sigmaDslBuilder: Ref[SigmaDslBuilder] = _sigmaDslBuilder.value - private val _colBuilder: LazyRep[CollBuilder] = MutableLazy(sigmaDslBuilder.Colls) - @inline def colBuilder: Rep[CollBuilder] = _colBuilder.value + private val _colBuilder: LazyRep[CollBuilder] = MutableLazy(variable[CollBuilder]) + @inline def colBuilder: Ref[CollBuilder] = _colBuilder.value - private val _sizeBuilder: LazyRep[SizeBuilder] = MutableLazy(RCSizeBuilder()) - @inline def sizeBuilder: Rep[SizeBuilder] = _sizeBuilder.value +// private val _sizeBuilder: LazyRep[SizeBuilder] = MutableLazy(RCSizeBuilder()) +// @inline def sizeBuilder: Ref[SizeBuilder] = _sizeBuilder.value private val _costedBuilder: LazyRep[CostedBuilder] = MutableLazy(RCCostedBuilder()) - @inline def costedBuilder: Rep[CostedBuilder] = _costedBuilder.value + @inline def costedBuilder: Ref[CostedBuilder] = _costedBuilder.value private val _monoidBuilder: LazyRep[MonoidBuilder] = MutableLazy(costedBuilder.monoidBuilder) - @inline def monoidBuilder: Rep[MonoidBuilder] = _monoidBuilder.value + @inline def monoidBuilder: Ref[MonoidBuilder] = _monoidBuilder.value private val _intPlusMonoid: LazyRep[Monoid[Int]] = MutableLazy(monoidBuilder.intPlusMonoid) - @inline def intPlusMonoid: Rep[Monoid[Int]] = _intPlusMonoid.value + @inline def intPlusMonoid: Ref[Monoid[Int]] = _intPlusMonoid.value private val _longPlusMonoid: LazyRep[Monoid[Long]] = MutableLazy(monoidBuilder.longPlusMonoid) - @inline def longPlusMonoid: Rep[Monoid[Long]] = _longPlusMonoid.value + @inline def longPlusMonoid: Ref[Monoid[Long]] = _longPlusMonoid.value private val _costedGlobal: LazyRep[Costed[SigmaDslBuilder]] = MutableLazy(RCCostedPrim(sigmaDslBuilder, IntZero, costedBuilder.mkSizePrim(1L, sigmaDslBuilderElement))) @inline def costedGlobal: RCosted[SigmaDslBuilder] = _costedGlobal.value private val _costOfProveDlog: LazyRep[Int] = MutableLazy(costOf(_costOfProveDlogEval, substFromCostTable)) - @inline def CostOfProveDlog: Rep[Int] = _costOfProveDlog.value + @inline def CostOfProveDlog: Ref[Int] = _costOfProveDlog.value private val _costOfDHTuple: LazyRep[Int] = MutableLazy(costOf(_costOfProveDHTuple, substFromCostTable)) - @inline def CostOfDHTuple: Rep[Int] = _costOfDHTuple.value // see CostTable for how it relate to ProveDlogEval + @inline def CostOfDHTuple: Ref[Int] = _costOfDHTuple.value // see CostTable for how it relate to ProveDlogEval protected override def onReset(): Unit = { super.onReset() // WARNING: every lazy value should be listed here, otherwise bevavior after resetContext is undefined and may throw. - Array(_sigmaDslBuilder, _colBuilder, _sizeBuilder, _costedBuilder, + Array(_sigmaDslBuilder, _colBuilder, _costedBuilder, _monoidBuilder, _intPlusMonoid, _longPlusMonoid, _costedGlobal, _costOfProveDlog, _costOfDHTuple) .foreach(_.reset()) @@ -801,7 +816,7 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => import Cost._ - def removeIsProven[T,R](f: Rep[T] => Rep[Any]): Rep[T] => Rep[Any] = { x: Rep[T] => + def removeIsProven[T,R](f: Ref[T] => Ref[Any]): Ref[T] => Ref[Any] = { x: Ref[T] => val y = f(x); val res = y match { case SigmaPropMethods.isValid(p) => p @@ -831,12 +846,12 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => case SAvlTree => avlTreeElement case SSigmaProp => sigmaPropElement case STuple(Seq(a, b)) => pairElement(stypeToElem(a), stypeToElem(b)) - case STuple(items) => tupleStructElement(items.map(stypeToElem(_)):_*) +// case STuple(items) => tupleStructElement(items.map(stypeToElem(_)):_*) case c: SCollectionType[a] => collElement(stypeToElem(c.elemType)) case o: SOption[a] => wOptionElement(stypeToElem(o.elemType)) case SFunc(Seq(tpeArg), tpeRange, Nil) => funcElement(stypeToElem(tpeArg), stypeToElem(tpeRange)) case _ => error(s"Don't know how to convert SType $t to Elem") - }).asElem[T#WrappedType] + }).asInstanceOf[Elem[T#WrappedType]] def elemToSType[T](e: Elem[T]): SType = e match { case BooleanElement => SBoolean @@ -856,43 +871,15 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => case _: HeaderElem[_] => SHeader case _: PreHeaderElem[_] => SPreHeader case _: SigmaPropElem[_] => SSigmaProp - case se: StructElem[_] => - assert(se.fieldNames.zipWithIndex.forall { case (n,i) => n == s"_${i+1}" }) - STuple(se.fieldElems.map(elemToSType(_)).toIndexedSeq) +// case se: StructElem[_] => +// assert(se.fieldNames.zipWithIndex.forall { case (n,i) => n == s"_${i+1}" }) +// STuple(se.fieldElems.map(elemToSType(_)).toIndexedSeq) case ce: CollElem[_, _] => SCollection(elemToSType(ce.eItem)) case fe: FuncElem[_, _] => SFunc(elemToSType(fe.eDom), elemToSType(fe.eRange)) case pe: PairElem[_, _] => STuple(elemToSType(pe.eFst), elemToSType(pe.eSnd)) case _ => error(s"Don't know how to convert Elem $e to SType") } - def rtypeToElem(t: RType[_]): Elem[_] = t match { - case BooleanType => BooleanElement - case ByteType => ByteElement - case ShortType => ShortElement - case IntType => IntElement - case LongType => LongElement - case StringType => StringElement - case AnyType => AnyElement - - case BigIntegerRType => wBigIntegerElement - case BigIntRType => bigIntElement - - case ECPointRType => wECPointElement - case GroupElementRType => groupElementElement - - case AvlTreeRType => avlTreeElement - case ot: OptionType[_] => wOptionElement(rtypeToElem(ot.tA)) - case BoxRType => boxElement - case SigmaPropRType => sigmaPropElement - case tup: TupleType => tupleStructElement(tup.items.map(t => rtypeToElem(t)):_*) - case at: ArrayType[_] => wArrayElement(rtypeToElem(at.tA)) - case ct: CollType[_] => collElement(rtypeToElem(ct.tItem)) - case ft: FuncType[_,_] => funcElement(rtypeToElem(ft.tDom), rtypeToElem(ft.tRange)) - case pt: PairType[_,_] => pairElement(rtypeToElem(pt.tFst), rtypeToElem(pt.tSnd)) - case pvt: PrimViewType[_,_] => rtypeToElem(pvt.tVal) - case _ => sys.error(s"Don't know how to convert RType $t to Elem") - } - /** For a given data type returns the corresponding specific descendant of CostedElem[T] */ def elemToCostedElem[T](implicit e: Elem[T]): Elem[Costed[T]] = (e match { case oe: WOptionElem[a,_] => costedOptionElement(oe.eItem) @@ -913,9 +900,6 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => case UnitElement => UnitIsLiftable case e: BigIntElem[_] => LiftableBigInt case e: GroupElementElem[_] => LiftableGroupElement - case ae: WArrayElem[t,_] => - implicit val lt = liftableFromElem[t](ae.eItem) - liftableArray(lt) case ce: CollElem[t,_] => implicit val lt = liftableFromElem[t](ce.eItem) liftableColl(lt) @@ -930,57 +914,50 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => }).asInstanceOf[Liftable[_,WT]] import NumericOps._ - private lazy val elemToNumericMap = Map[Elem[_], Numeric[_]]( + private lazy val elemToExactNumericMap = Map[Elem[_], ExactNumeric[_]]( (ByteElement, ByteIsExactNumeric), (ShortElement, ShortIsExactNumeric), (IntElement, IntIsExactNumeric), (LongElement, LongIsExactNumeric), - (bigIntElement, numeric[SBigInt]) + (bigIntElement, BigIntIsExactNumeric) ) - private lazy val elemToIntegralMap = Map[Elem[_], Integral[_]]( - (ByteElement, integral[Byte]), - (ShortElement, integral[Short]), - (IntElement, integral[Int]), - (LongElement, integral[Long]), - (bigIntElement, integral[SBigInt]) + private lazy val elemToExactIntegralMap = Map[Elem[_], ExactIntegral[_]]( + (ByteElement, ByteIsExactIntegral), + (ShortElement, ShortIsExactIntegral), + (IntElement, IntIsExactIntegral), + (LongElement, LongIsExactIntegral), + (bigIntElement, BigIntIsExactIntegral) ) - private lazy val elemToOrderingMap = Map[Elem[_], Ordering[_]]( - (ByteElement, implicitly[Ordering[Byte]]), - (ShortElement, implicitly[Ordering[Short]]), - (IntElement, implicitly[Ordering[Int]]), - (LongElement, implicitly[Ordering[Long]]), - (bigIntElement, implicitly[Ordering[SBigInt]]) - ) - private lazy val elemToExactNumeric = Map[Elem[_], ExactNumeric[_]]( - (ByteElement, ByteIsExactNumeric), - (ShortElement, ShortIsExactNumeric), - (IntElement, IntIsExactNumeric), - (LongElement, LongIsExactNumeric), + private lazy val elemToExactOrderingMap = Map[Elem[_], ExactOrdering[_]]( + (ByteElement, ByteIsExactOrdering), + (ShortElement, ShortIsExactOrdering), + (IntElement, IntIsExactOrdering), + (LongElement, LongIsExactOrdering), + (bigIntElement, BigIntIsExactOrdering) ) - def elemToNumeric [T](e: Elem[T]): Numeric[T] = elemToNumericMap(e).asInstanceOf[Numeric[T]] - def elemToIntegral[T](e: Elem[T]): Integral[T] = elemToIntegralMap(e).asInstanceOf[Integral[T]] - def elemToOrdering[T](e: Elem[T]): Ordering[T] = elemToOrderingMap(e).asInstanceOf[Ordering[T]] - def elemToExactNumeric[T](e: Elem[T]): ExactNumeric[T] = elemToExactNumeric(e).asInstanceOf[ExactNumeric[T]] + def elemToExactNumeric [T](e: Elem[T]): ExactNumeric[T] = elemToExactNumericMap(e).asInstanceOf[ExactNumeric[T]] + def elemToExactIntegral[T](e: Elem[T]): ExactIntegral[T] = elemToExactIntegralMap(e).asInstanceOf[ExactIntegral[T]] + def elemToExactOrdering[T](e: Elem[T]): ExactOrdering[T] = elemToExactOrderingMap(e).asInstanceOf[ExactOrdering[T]] def opcodeToEndoBinOp[T](opCode: Byte, eT: Elem[T]): EndoBinOp[T] = opCode match { - case OpCodes.PlusCode => NumericPlus(elemToNumeric(eT))(eT) - case OpCodes.MinusCode => NumericMinus(elemToNumeric(eT))(eT) - case OpCodes.MultiplyCode => NumericTimes(elemToNumeric(eT))(eT) - case OpCodes.DivisionCode => IntegralDivide(elemToIntegral(eT))(eT) - case OpCodes.ModuloCode => IntegralMod(elemToIntegral(eT))(eT) - case OpCodes.MinCode => OrderingMin(elemToOrdering(eT))(eT) - case OpCodes.MaxCode => OrderingMax(elemToOrdering(eT))(eT) + case OpCodes.PlusCode => NumericPlus(elemToExactNumeric(eT))(eT) + case OpCodes.MinusCode => NumericMinus(elemToExactNumeric(eT))(eT) + case OpCodes.MultiplyCode => NumericTimes(elemToExactNumeric(eT))(eT) + case OpCodes.DivisionCode => IntegralDivide(elemToExactIntegral(eT))(eT) + case OpCodes.ModuloCode => IntegralMod(elemToExactIntegral(eT))(eT) + case OpCodes.MinCode => OrderingMin(elemToExactOrdering(eT))(eT) + case OpCodes.MaxCode => OrderingMax(elemToExactOrdering(eT))(eT) case _ => error(s"Cannot find EndoBinOp for opcode $opCode") } def opcodeToBinOp[A](opCode: Byte, eA: Elem[A]): BinOp[A,_] = opCode match { case OpCodes.EqCode => Equals[A]()(eA) case OpCodes.NeqCode => NotEquals[A]()(eA) - case OpCodes.GtCode => OrderingGT[A](elemToOrdering(eA)) - case OpCodes.LtCode => OrderingLT[A](elemToOrdering(eA)) - case OpCodes.GeCode => OrderingGTEQ[A](elemToOrdering(eA)) - case OpCodes.LeCode => OrderingLTEQ[A](elemToOrdering(eA)) + case OpCodes.GtCode => OrderingGT[A](elemToExactOrdering(eA)) + case OpCodes.LtCode => OrderingLT[A](elemToExactOrdering(eA)) + case OpCodes.GeCode => OrderingGTEQ[A](elemToExactOrdering(eA)) + case OpCodes.LeCode => OrderingLTEQ[A](elemToExactOrdering(eA)) case _ => error(s"Cannot find BinOp for opcode $opCode") } @@ -990,7 +967,7 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => } /** Helper to create costed collection of some constant size type T */ - def mkCostedColl[T](col: Rep[Coll[T]], len: Rep[Int], cost: Rep[Int]): Rep[CostedColl[T]] = { + def mkCostedColl[T](col: Ref[Coll[T]], len: Ref[Int], cost: Ref[Int]): Ref[CostedColl[T]] = { // TODO optimize: the method should be specialized on T so that mkSizePrim is not used val eT = col.elem.eItem val costs = colBuilder.replicate(len, IntZero) @@ -998,14 +975,12 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => RCCostedColl(col, costs, sizes, cost) } - @inline final def asCosted[T](x: Rep[_]): Rep[Costed[T]] = x.asInstanceOf[Rep[Costed[T]]] + @inline final def asCosted[T](x: Ref[_]): Ref[Costed[T]] = x.asInstanceOf[Ref[Costed[T]]] type CostingEnv = Map[Any, RCosted[_]] import sigmastate._ - val OperationIdKey = MetaKey[AnyRef]("OperationId")(AnyRefElement) - protected def isOperationNode(v: SValue): Boolean = v match { case _: Block | _: BlockValue | _: TaggedVariableNode[_] | _: ValNode | _: ValDef | _: ValUse[_] | _: FuncValue => false case _ => true @@ -1014,15 +989,6 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => protected def onTreeNodeCosted[T <: SType]( ctx: RCosted[Context], env: CostingEnv, node: Value[T], costed: RCosted[T#WrappedType]): Unit = { - if (okMeasureOperationTime && isOperationNode(node)) { - asRep[Any](costed) match { - case Def(CCostedPrimCtor(v, c, s)) => - v.setMetadata(OperationIdKey)(node.opId) - case Def(CCostedCollCtor(vs,_,_,_)) => - vs.setMetadata(OperationIdKey)(node.opId) - case _ => - } - } } @inline def SigmaDsl = sigmaDslBuilderValue @@ -1032,7 +998,7 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => def constantTypeSize[T](implicit eT: Elem[T]): RSize[T] = RCSizePrim(typeSize(eT), eT) - def withConstantSize[T](v: Rep[T], cost: Rep[Int]): RCosted[T] = RCCostedPrim(v, cost, constantTypeSize(v.elem)) + def withConstantSize[T](v: Ref[T], cost: Ref[Int]): RCosted[T] = RCCostedPrim(v, cost, constantTypeSize(v.elem)) def sizeOfData[ST,T](x: ST)(implicit lT: Liftable[ST,T]): RSize[T] = asRep[Size[T]](lT.sourceType match { case BooleanType => liftConst(Sized.sizeOf(x.asInstanceOf[Boolean])) @@ -1066,8 +1032,8 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => /** Build a new costed value with the given cost in a dependency list. * This is required to correctly handle tuple field accesses like `v._1` * and not to lose the cost of `v` in the cost of resulting value. */ - def attachCost[T](source: RCosted[T], accCost: Rep[Int], cost: Rep[Int]): RCosted[T] = asRep[Costed[T]] { - def newCost(v: Sym, c: Rep[Int]) = opCost(v, Array(accCost, c), cost) // put cost in dependency list + def attachCost[T](source: RCosted[T], accCost: Ref[Int], cost: Ref[Int]): RCosted[T] = asRep[Costed[T]] { + def newCost(v: Sym, c: Ref[Int]) = opCost(v, Array(accCost, c), cost) // put cost in dependency list source.elem.eVal match { case e: CollElem[a, _] => @@ -1092,11 +1058,20 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => /** Mutable IR context state, make sure it is reset in onReset() to its initial state. */ private[this] var _contextDependantNodes = debox.Set.ofSize[Int](InitDependantNodes) - def isContextDependant(sym: Sym): Boolean = + @inline final def isContextDependant(sym: Sym): Boolean = if (sym.isConst) true else { - _contextDependantNodes(sym.rhs.nodeId) + _contextDependantNodes(sym.node.nodeId) + } + + /** @hotspot don't beautify the code */ + @inline final def allContextDependant(syms: Array[Sym]): Boolean = { + val len = syms.length + cfor(0)(_ < len, _ + 1) { i => + if (!isContextDependant(syms(i))) return false } + true + } /** Here we hook into graph building process at the point where each new graph node is added to the graph. * First, we call `super.createDefinition`, which adds the new node `d` to the graph (`s` is the node's symbol). @@ -1107,26 +1082,24 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => * * @see super.createDefinition, isSupportedIndexExpression */ - override protected def createDefinition[T](optScope: Nullable[ThunkScope], s: Rep[T], d: Def[T]): TableEntry[T] = { + override protected def createDefinition[T](optScope: Nullable[ThunkScope], s: Ref[T], d: Def[T]): Ref[T] = { val res = super.createDefinition(optScope, s, d) - res.rhs match { - case d if d.selfType.isInstanceOf[ContextElem[_]] => - // the node is of Context type => `context-dependent` - _contextDependantNodes += (d.nodeId) - case d => - val allArgs = d.getDeps.forall(isContextDependant) - if (allArgs) { - // all arguments are `context-dependent` => d is `context-dependent` - _contextDependantNodes += (d.nodeId) - } - } + val d1 = res.node + // the node is of Context type => `context-dependent` + // all arguments are `context-dependent` => d is `context-dependent` + val isDependent = + d1.resultType.isInstanceOf[ContextElem[_]] || + allContextDependant(d1.deps) + if (isDependent) + _contextDependantNodes += (d1.nodeId) + else false // this is to avoid boxing in `then` branch res } /** Checks that index expression sub-graph (which root is `i`) consists of `context-dependent` nodes. * This is used in the validation rule for the costing of ByIndex operation. * @see RuntimeCosting, CheckIsSupportedIndexExpression */ - def isSupportedIndexExpression(i: Rep[Int]): Boolean = { + def isSupportedIndexExpression(i: Ref[Int]): Boolean = { isContextDependant(i) } @@ -1138,8 +1111,8 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => def costedBooleanTransformer[T](node: BooleanTransformer[_], xs: RCostedColl[T], condition: RCosted[T => SType#WrappedType], - calcF: Rep[T => Any], accCost: Rep[Int]) = { - val args: Seq[Rep[Int]] = Array(xs.cost, condition.cost) + calcF: Ref[T => Any], accCost: Ref[Int]) = { + val args: Seq[Ref[Int]] = Array(xs.cost, condition.cost) val res = calcF.elem.eRange.asInstanceOf[Elem[_]] match { case BooleanElement => node match { @@ -1177,7 +1150,7 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => import WOption._ def eval[T <: SType](node: Value[T]): RCosted[T#WrappedType] = evalNode(ctx, env, node) object In { def unapply(v: SValue): Nullable[RCosted[Any]] = Nullable(asRep[Costed[Any]](evalNode(ctx, env, v))) } - class InColl[T: Elem] { def unapply(v: SValue): Nullable[Rep[CostedColl[T]]] = Nullable(tryCast[CostedColl[T]](evalNode(ctx, env, v))) } + class InColl[T: Elem] { def unapply(v: SValue): Nullable[Ref[CostedColl[T]]] = Nullable(tryCast[CostedColl[T]](evalNode(ctx, env, v))) } val InCollByte = new InColl[Byte]; val InCollAny = new InColl[Any]()(AnyElement); val InCollInt = new InColl[Int] val InCollCollByte = new InColl[Coll[Byte]]()(eCollByte) @@ -1190,7 +1163,7 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => } Nullable(res) }} - object InSeqUnzipped { def unapply(items: Seq[SValue]): Nullable[(Seq[Rep[Any]], Seq[Rep[Int]], Seq[RSize[Any]])] = { + object InSeqUnzipped { def unapply(items: Seq[SValue]): Nullable[(Seq[Ref[Any]], Seq[Ref[Int]], Seq[RSize[Any]])] = { val res = items.mapUnzip { x: SValue => val xC = eval(x) (asRep[Any](xC.value), xC.cost, asRep[Size[Any]](xC.size)) @@ -1203,7 +1176,7 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => ruleStack = new CostingRuleStat(node, t, 0, t) :: ruleStack } - val res: Rep[Any] = node match { + val res: Ref[Any] = node match { case TaggedVariableNode(id, _) => env.getOrElse(id, !!!(s"TaggedVariable $id not found in environment $env")) @@ -1243,7 +1216,7 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => val treeV = liftConst(tree) RCCostedPrim(treeV, opCost(treeV, Nil, costOf(c)), SizeAvlTree) case s: String => - val resV = toRep(s)(stypeToElem(tpe).asElem[String]) + val resV = toRep(s)(stypeToElem(tpe).asInstanceOf[Elem[String]]) RCCostedPrim(resV, opCost(resV, Nil, costOf(c)), SizeString) case _ => val resV = toRep(v)(stypeToElem(tpe)) @@ -1291,7 +1264,7 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => case CreateProveDlog(In(_v)) => val vC = asRep[Costed[GroupElement]](_v) - val resV: Rep[SigmaProp] = sigmaDslBuilder.proveDlog(vC.value) + val resV: Ref[SigmaProp] = sigmaDslBuilder.proveDlog(vC.value) val cost = opCost(resV, Array(vC.cost), CostOfProveDlog) RCCostedPrim(resV, cost, SizeSigmaProposition) @@ -1300,7 +1273,7 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => val hvC = asRep[Costed[GroupElement]](_hv) val uvC = asRep[Costed[GroupElement]](_uv) val vvC = asRep[Costed[GroupElement]](_vv) - val resV: Rep[SigmaProp] = sigmaDslBuilder.proveDHTuple(gvC.value, hvC.value, uvC.value, vvC.value) + val resV: Ref[SigmaProp] = sigmaDslBuilder.proveDHTuple(gvC.value, hvC.value, uvC.value, vvC.value) val cost = opCost(resV, Array(gvC.cost, hvC.cost, uvC.cost, vvC.cost), CostOfDHTuple) RCCostedPrim(resV, cost, SizeSigmaProposition) @@ -1373,16 +1346,10 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => case Values.Tuple(InSeq(Seq(x, y))) => val v = Pair(x, y) - val costs = Array(x.cost, y.cost, CostTable.newPairValueCost: Rep[Int]) + val costs = Array(x.cost, y.cost, CostTable.newPairValueCost: Ref[Int]) val c = mkNormalizedOpCost(v, costs) RCCostedPair(x, y, c) - case Values.Tuple(InSeq(items)) => - val fields = items.zipWithIndex.map { case (x, i) => (s"_${i+1}", x)} - val value = struct(fields) - val cost = opCost(value, items.map(_.cost), costedBuilder.ConstructTupleCost) - RCostedStruct(value, cost) - case node: BooleanTransformer[_] => val tpeIn = node.input.tpe.elemType val eIn = stypeToElem(tpeIn) @@ -1396,7 +1363,7 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => val sizes = xs.sizes val len = sizes.length val cost = if (tpeIn.isConstantSize) { - val predicateCost: Rep[Int] = Apply(costF, Pair(IntZero, constantTypeSize(eAny)), false) + val predicateCost: Ref[Int] = Apply(costF, Pair(IntZero, constantTypeSize(eAny)), false) len * (predicateCost + CostTable.lambdaInvoke) } else { colBuilder.replicate(len, IntZero).zip(sizes).map(costF).sum(intPlusMonoid) + len * CostTable.lambdaInvoke @@ -1422,7 +1389,7 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => implicit val eS = zeroC.elem.eVal assert(eState == eS, s"Types should be equal: but $eState != $eS") - val foldOpC = fun { in: Rep[CostedPair[s, a]] => + val foldOpC = fun { in: Ref[CostedPair[s, a]] => val acc = in.l; val item = in.r val out = sfunc match { case Terms.Lambda(_, Seq((accN, _), (n, _)), _, Some(op)) => @@ -1469,24 +1436,24 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => val (calcF, costF, sizeF) = splitCostedCollFunc(asRep[CostedCollFunc[Any,Any]](fC.func)) val value = xC.value val values: RColl[Any] = Apply(calcF, value, false) - val costRes: Rep[(Coll[Int], Int)] = Apply(costF, Pair(xC.cost, xC.size), false) + val costRes: Ref[(Coll[Int], Int)] = Apply(costF, Pair(xC.cost, xC.size), false) val sizes: RColl[Size[Any]] = Apply(sizeF, xC.size, false) RCCostedColl(values, costRes._1, sizes, costRes._2) // case optTpe: SOption[_] => // val (calcF, costF, sizeF) = splitCostedOptionFunc(asRep[CostedOptionFunc[Any,Any]](fC.func)) // val value = xC.value -// val values: Rep[WOption[Any]] = Apply(calcF, value, false) -// val costRes: Rep[(WOption[Int], Int)] = Apply(costF, Pair(value, Pair(xC.cost, xC.dataSize)), false) -// val sizes: Rep[WOption[Long]]= Apply(sizeF, Pair(value, xC.dataSize), false) +// val values: Ref[WOption[Any]] = Apply(calcF, value, false) +// val costRes: Ref[(WOption[Int], Int)] = Apply(costF, Pair(value, Pair(xC.cost, xC.dataSize)), false) +// val sizes: Ref[WOption[Long]]= Apply(sizeF, Pair(value, xC.dataSize), false) // RCCostedOption(values, costRes._1, sizes, costRes._2) case _ => val calcF = fC.sliceCalc val costF = fC.sliceCost val sizeF = fC.sliceSize val value = xC.value - val y: Rep[Any] = Apply(calcF, value, false) - val c: Rep[Int] = opCost(y, Array(fC.cost, xC.cost), asRep[Int](Apply(costF, Pair(IntZero, xC.size), false)) + CostTable.lambdaInvoke) - val s: Rep[Size[Any]]= Apply(sizeF, xC.size, false) + val y: Ref[Any] = Apply(calcF, value, false) + val c: Ref[Int] = opCost(y, Array(fC.cost, xC.cost), asRep[Int](Apply(costF, Pair(IntZero, xC.size), false)) + CostTable.lambdaInvoke) + val s: Ref[Size[Any]]= Apply(sizeF, xC.size, false) RCCostedPrim(y, c, s) } @@ -1510,13 +1477,9 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => val xsC = asRep[Costed[Coll[a]]](xs) val v = xsC.value.length RCCostedPrim(v, opCost(v, Array(xsC.cost), costOf(node)), SizeInt) - case se: StructElem[_] => - val xsC = asRep[Costed[Struct]](xs) - val v = se.fields.length - RCCostedPrim(v, opCost(v, Array(xsC.cost), costOf(node)), SizeInt) case pe: PairElem[a,b] => val xsC = asRep[Costed[(a,b)]](xs) - val v: Rep[Int] = 2 + val v: Ref[Int] = 2 RCCostedPrim(v, opCost(v, Array(xsC.cost), costOf(node)), SizeInt) } @@ -1577,7 +1540,7 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => case utxo.ExtractCreationInfo(In(box)) => BoxCoster(box, SBox.creationInfoMethod, Nil) case utxo.ExtractRegisterAs(In(box), regId, optTpe) => - implicit val elem = stypeToElem(optTpe.elemType).asElem[Any] + implicit val elem = stypeToElem(optTpe.elemType).asInstanceOf[Elem[Any]] val i: RCosted[Int] = RCCostedPrim(regId.number.toInt, IntZero, SizeInt) BoxCoster(box, SBox.getRegMethod, Array(i), Array(liftElem(elem))) @@ -1590,7 +1553,7 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => case AtLeast(bound, input) => val inputC = asRep[CostedColl[SigmaProp]](evalNode(ctx, env, input)) if (inputC.values.length.isConst) { - val inputCount = inputC.values.length.asValue + val inputCount = valueFromRep(inputC.values.length) if (inputCount > AtLeast.MaxChildrenCount) error(s"Expected input elements count should not exceed ${AtLeast.MaxChildrenCount}, actual: $inputCount", node.sourceContext.toOption) } @@ -1604,7 +1567,7 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => val xC = asRep[Costed[BigInt]](eval(op.left)) val yC = asRep[Costed[BigInt]](eval(op.right)) val opName = op.opName - var v: Rep[BigInt] = null; + var v: Ref[BigInt] = null; op.opCode match { case PlusCode => v = xC.value.add(yC.value) @@ -1728,7 +1691,7 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => case neg: Negation[SNumericType]@unchecked => val tpe = neg.input.tpe val et = stypeToElem(tpe) - val op = NumericNegate(elemToNumeric(et))(et) + val op = NumericNegate(elemToExactNumeric(et))(et) val inputC = evalNode(ctx, env, neg.input) inputC match { case x: RCosted[a] => val v = ApplyUnOp(op, x.value) @@ -1779,33 +1742,33 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => } case l @ Terms.Lambda(_, Seq((n, argTpe)), tpe, Some(body)) => - val eArg = stypeToElem(argTpe).asElem[Any] + val eArg = stypeToElem(argTpe).asInstanceOf[Elem[Any]] val eCostedArg = elemToCostedElem(eArg) - val f = fun { x: Rep[Costed[Any]] => + val f = fun { x: Ref[Costed[Any]] => evalNode(ctx, env + (n -> x), body) }(Lazy(eCostedArg)) val eRes = f.elem.eRange.eVal mkCostedFunc(f, opCost(f, Nil, costOf(node)), l.tpe.dataSize(SType.DummyValue), eArg, eRes) case l @ FuncValue(Seq((n, argTpe)), body) => - val eArg = stypeToElem(argTpe).asElem[Any] + val eArg = stypeToElem(argTpe).asInstanceOf[Elem[Any]] val xElem = elemToCostedElem(eArg) - val f = fun { x: Rep[Costed[Any]] => + val f = fun { x: Ref[Costed[Any]] => evalNode(ctx, env + (n -> x), body) }(Lazy(xElem)) val eRes = f.elem.eRange.eVal mkCostedFunc(f, opCost(f, Nil, costOf(node)), l.tpe.dataSize(SType.DummyValue), eArg, eRes) case col @ ConcreteCollection(InSeqUnzipped(vs, cs, ss), elemType) => - implicit val eAny = stypeToElem(elemType).asElem[Any] + implicit val eAny = stypeToElem(elemType).asInstanceOf[Elem[Any]] val values = colBuilder.fromItems(vs: _*)(eAny) val costs = colBuilder.replicate(cs.length, IntZero) val sizes = colBuilder.fromItems(ss: _*)(sizeElement(eAny)) // val args = vs.zip(cs).map { case (v,c) => -// if (c.rhs.isInstanceOf[OpCost]) c else opCost(v, Nil, c) +// if (c.node.isInstanceOf[OpCost]) c else opCost(v, Nil, c) // } - val args = mutable.ArrayBuilder.make[Rep[Int]] - val uniqueArgs = scalan.AVHashMap[Rep[Any], (Rep[Any], Rep[Int])](10) + val args = mutable.ArrayBuilder.make[Ref[Int]] + val uniqueArgs = scalan.AVHashMap[Ref[Any], (Ref[Any], Ref[Int])](10) vs.zip(cs).foreach { vc => uniqueArgs.get(vc._1) match { case Nullable((v, c)) => @@ -1814,7 +1777,7 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => val v = vc._1 val c = vc._2 uniqueArgs.put(v, vc) - val arg = if (c.rhs.isInstanceOf[OpCost]) c else opCost(v, Nil, c) + val arg = if (c.node.isInstanceOf[OpCost]) c else opCost(v, Nil, c) args += arg } } @@ -1859,7 +1822,7 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => case Terms.MethodCall(obj, method, args, typeSubst) if method.objType.coster.isDefined => val objC = eval(obj) val argsC = args.map(eval) - val elems = typeSubst.values.toSeq.map(tpe => liftElem(stypeToElem(tpe).asElem[Any])) + val elems = typeSubst.values.toSeq.map(tpe => liftElem(stypeToElem(tpe).asInstanceOf[Elem[Any]])) method.objType.coster.get(IR)(objC, method, argsC, elems) case _ => @@ -1898,7 +1861,7 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => resC } - def buildCostedGraph[T](envVals: Map[Any, SValue], tree: SValue): Rep[Costed[Context] => Costed[T]] = { + def buildCostedGraph[T](envVals: Map[Any, SValue], tree: SValue): Ref[Costed[Context] => Costed[T]] = { try { assert(ruleStack.isEmpty) fun { ctxC: RCosted[Context] => @@ -1913,7 +1876,7 @@ trait RuntimeCosting extends CostingRules { IR: IRContext => } } - def cost[T](env: ScriptEnv, typed: SValue): Rep[Costed[Context] => Costed[T]] = { + def cost[T](env: ScriptEnv, typed: SValue): Ref[Costed[Context] => Costed[T]] = { val cg = buildCostedGraph[T](env.map { case (k, v) => (k: Any, builder.liftAny(v).get) }, typed) cg } diff --git a/src/main/scala/sigmastate/eval/SigmaCoster.scala b/sigmastate/src/main/scala/sigmastate/eval/SigmaCoster.scala similarity index 100% rename from src/main/scala/sigmastate/eval/SigmaCoster.scala rename to sigmastate/src/main/scala/sigmastate/eval/SigmaCoster.scala diff --git a/src/main/scala/sigmastate/eval/Sized.scala b/sigmastate/src/main/scala/sigmastate/eval/Sized.scala similarity index 100% rename from src/main/scala/sigmastate/eval/Sized.scala rename to sigmastate/src/main/scala/sigmastate/eval/Sized.scala diff --git a/src/main/scala/sigmastate/eval/TreeBuilding.scala b/sigmastate/src/main/scala/sigmastate/eval/TreeBuilding.scala similarity index 88% rename from src/main/scala/sigmastate/eval/TreeBuilding.scala rename to sigmastate/src/main/scala/sigmastate/eval/TreeBuilding.scala index 70a733d4a6..71c0f32fed 100644 --- a/src/main/scala/sigmastate/eval/TreeBuilding.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/TreeBuilding.scala @@ -25,11 +25,8 @@ trait TreeBuilding extends RuntimeCosting { IR: IRContext => import CollBuilder._ import SigmaDslBuilder._ import CCostedBuilder._ - import MonoidBuilderInst._ import BigInt._ - import WArray._ import WOption._ - import WECPoint._ import AvlTree._ import GroupElement._ @@ -39,10 +36,8 @@ trait TreeBuilding extends RuntimeCosting { IR: IRContext => private val BoxM = BoxMethods private val CBM = CollBuilderMethods private val SDBM = SigmaDslBuilderMethods - private val AM = WArrayMethods private val OM = WOptionMethods private val BIM = BigIntMethods - private val AvlM = AvlTreeMethods private val GM = GroupElementMethods /** Describes assignment of valIds for symbols which become ValDefs. @@ -114,27 +109,20 @@ trait TreeBuilding extends RuntimeCosting { IR: IRContext => } } - object IsNonConstantDef { + object IsConstantDef { def unapply(d: Def[_]): Option[Def[_]] = d match { - // in case of GroupElement constant (ProveDlog) different constants have different meaning, - // thus it is ok for them to create ValDef -// case c: Const[_] if c.elem.isInstanceOf[WECPointElem[_]] => Some(d) - // to increase effect of constant segregation we need to treat the constants specially - // and don't create ValDef even if the constant is used more than one time, - // because two equal constants don't always have the same meaning. - case _: Const[_] => None - case _ => Some(d) + case _: Const[_] => Some(d) + case _ => None } } - def buildValue(ctx: Rep[Context], + def buildValue(ctx: Ref[Context], mainG: PGraph, env: DefEnv, s: Sym, defId: Int, constantsProcessing: Option[ConstantStore]): SValue = { import builder._ - import TestSigmaDslBuilder._ def recurse[T <: SType](s: Sym) = buildValue(ctx, mainG, env, s, defId, constantsProcessing).asValue[T] object In { def unapply(s: Sym): Option[SValue] = Some(buildValue(ctx, mainG, env, s, defId, constantsProcessing)) } s match { @@ -169,7 +157,7 @@ trait TreeBuilding extends RuntimeCosting { IR: IRContext => mkConstant[tpe.type](wc.constValue.asInstanceOf[tpe.WrappedType], tpe) case Def(IsContextProperty(v)) => v - case Def(TestSigmaDslBuilderCtor()) => Global + case s if s == sigmaDslBuilder => Global case Def(ApplyBinOp(IsArithOp(opCode), xSym, ySym)) => val Seq(x, y) = Seq(xSym, ySym).map(recurse) @@ -186,9 +174,6 @@ trait TreeBuilding extends RuntimeCosting { IR: IRContext => case Def(ApplyUnOp(IsLogicalUnOp(mkNode), xSym)) => mkNode(recurse(xSym)) - case CBM.fromArray(_, arr @ Def(wc: LiftedConst[a,_])) => - val colTpe = elemToSType(s.elem) - mkConstant[colTpe.type](wc.constValue.asInstanceOf[colTpe.WrappedType], colTpe) case CBM.fromItems(_, colSyms, elemT) => val elemTpe = elemToSType(elemT) val col = colSyms.map(recurse(_).asValue[elemTpe.type]) @@ -265,7 +250,7 @@ trait TreeBuilding extends RuntimeCosting { IR: IRContext => mkFilter(col.asCollection[SType], p.asFunc) case Def(MethodCall(receiver, m, argsSyms, _)) if receiver.elem.isInstanceOf[CollElem[_, _]] => - val colSym = receiver.asInstanceOf[Rep[Coll[Any]]] + val colSym = receiver.asInstanceOf[Ref[Coll[Any]]] val args = argsSyms.map(_.asInstanceOf[Sym]).map(recurse) val col = recurse(colSym).asCollection[SType] val colTpe = col.tpe @@ -289,9 +274,9 @@ trait TreeBuilding extends RuntimeCosting { IR: IRContext => case BoxM.getReg(In(box), regId, _) => val tpe = elemToSType(s.elem).asOption if (regId.isConst) - mkExtractRegisterAs(box.asBox, ErgoBox.allRegisters(regId.asValue), tpe) + mkExtractRegisterAs(box.asBox, ErgoBox.allRegisters(valueFromRep(regId)), tpe) else - error(s"Non constant expressions (${regId.rhs}) are not supported in getReg") + error(s"Non constant expressions (${regId.node}) are not supported in getReg") case BoxM.creationInfo(In(box)) => mkExtractCreationInfo(box.asBox) case BoxM.id(In(box)) => @@ -316,8 +301,6 @@ trait TreeBuilding extends RuntimeCosting { IR: IRContext => SigmaAnd(Seq(p1.asSigmaProp, p2.asSigmaProp)) case SigmaM.or_sigma_||(In(p1), In(p2)) => SigmaOr(Seq(p1.asSigmaProp, p2.asSigmaProp)) - case SigmaM.isValid(In(prop)) => - mkSigmaPropIsProven(prop.asSigmaProp) case SigmaM.propBytes(In(prop)) => mkSigmaPropBytes(prop.asSigmaProp) @@ -375,6 +358,8 @@ trait TreeBuilding extends RuntimeCosting { IR: IRContext => mkByteArrayToLong(recurse(colSym)) case SDBM.decodePoint(_, colSym) => mkDecodePoint(recurse(colSym)) + case SDBM.substConstants(_, In(scriptBytes), In(positions), In(newValues), _) => + mkSubstConst(scriptBytes.asByteArray, positions.asIntArray, newValues.asCollection[SType]) case Def(IfThenElseLazy(condSym, thenPSym, elsePSym)) => val Seq(cond, thenP, elseP) = Seq(condSym, thenPSym, elsePSym).map(recurse) @@ -386,18 +371,12 @@ trait TreeBuilding extends RuntimeCosting { IR: IRContext => mkSelectField(recurse(pair), 1) case Def(Second(pair)) => mkSelectField(recurse(pair), 2) - case Def(FieldApply(In(data), IsTupleFN(i))) => - mkSelectField(data.asTuple, i) case Def(Downcast(inputSym, toSym)) => mkDowncast(recurse(inputSym).asNumValue, elemToSType(toSym).asNumType) case Def(Upcast(inputSym, toSym)) => mkUpcast(recurse(inputSym).asNumValue, elemToSType(toSym).asNumType) - case Def(SimpleStruct(_, fields)) => - val items = fields.map { case (n, v) => recurse(v) } - mkTuple(items) - case GM.exp(In(obj), In(arg)) => mkExponentiate(obj.asGroupElement, arg.asBigInt) @@ -409,19 +388,13 @@ trait TreeBuilding extends RuntimeCosting { IR: IRContext => .getOrElse(error(s"Cannot find method ${m.getName} in object $obj")) val specMethod = method.specializeFor(obj.tpe, args.map(_.tpe)) builder.mkMethodCall(obj, specMethod, args.toIndexedSeq, Map()) -// val method = ((SCollection.methods.find(_.name == m.getName), args) match { -// case (Some(mth @ SCollection.FlatMapMethod), Seq(f)) => -// mth.withConcreteTypes(Map(SCollection.tOV -> f.asFunc.tpe.tRange.asCollection.elemType)) -// case (Some(mth), _) => mth -// case (None, _) => error(s"unknown method Coll.${m.getName}") -// }).withConcreteTypes(Map(SCollection.tIV -> colTpe.elemType)) case Def(d) => !!!(s"Don't know how to buildValue($mainG, $s -> $d, $env, $defId)") } } - private def processAstGraph(ctx: Rep[Context], + private def processAstGraph(ctx: Ref[Context], mainG: PGraph, env: DefEnv, subG: AstGraph, @@ -430,12 +403,16 @@ trait TreeBuilding extends RuntimeCosting { IR: IRContext => val valdefs = new ArrayBuffer[ValDef] var curId = defId var curEnv = env - for (te <- subG.schedule) { - val s = te.sym; val d = te.rhs - if (mainG.hasManyUsagesGlobal(s) + for (s <- subG.schedule) { + val d = s.node +// val nonRootLoop = LoopOperation.unapply(d).isDefined && !subG.roots.contains(s) + if ((mainG.hasManyUsagesGlobal(s)/* || nonRootLoop*/) && IsContextProperty.unapply(d).isEmpty && IsInternalDef.unapply(d).isEmpty - && IsNonConstantDef.unapply(d).nonEmpty) + // to increase effect of constant segregation we need to treat the constants specially + // and don't create ValDef even if the constant is used more than one time, + // because two equal constants don't always have the same meaning. + && IsConstantDef.unapply(d).isEmpty) { val rhs = buildValue(ctx, mainG, curEnv, s, curId, constantsProcessing) curId += 1 @@ -450,7 +427,7 @@ trait TreeBuilding extends RuntimeCosting { IR: IRContext => res } - def buildTree[T <: SType](f: Rep[Context => Any], + def buildTree[T <: SType](f: Ref[Context => Any], constantsProcessing: Option[ConstantStore] = None): Value[T] = { val Def(Lambda(lam,_,_,_)) = f val mainG = new PGraph(lam.y) diff --git a/src/main/scala/sigmastate/eval/Zero.scala b/sigmastate/src/main/scala/sigmastate/eval/Zero.scala similarity index 100% rename from src/main/scala/sigmastate/eval/Zero.scala rename to sigmastate/src/main/scala/sigmastate/eval/Zero.scala diff --git a/src/main/scala/sigmastate/eval/package.scala b/sigmastate/src/main/scala/sigmastate/eval/package.scala similarity index 100% rename from src/main/scala/sigmastate/eval/package.scala rename to sigmastate/src/main/scala/sigmastate/eval/package.scala diff --git a/src/main/scala/sigmastate/interpreter/CryptoConstants.scala b/sigmastate/src/main/scala/sigmastate/interpreter/CryptoConstants.scala similarity index 100% rename from src/main/scala/sigmastate/interpreter/CryptoConstants.scala rename to sigmastate/src/main/scala/sigmastate/interpreter/CryptoConstants.scala diff --git a/src/main/scala/sigmastate/interpreter/CryptoFunctions.scala b/sigmastate/src/main/scala/sigmastate/interpreter/CryptoFunctions.scala similarity index 100% rename from src/main/scala/sigmastate/interpreter/CryptoFunctions.scala rename to sigmastate/src/main/scala/sigmastate/interpreter/CryptoFunctions.scala diff --git a/src/main/scala/sigmastate/interpreter/Interpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala similarity index 94% rename from src/main/scala/sigmastate/interpreter/Interpreter.scala rename to sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala index 91690f502f..429a48b8ca 100644 --- a/src/main/scala/sigmastate/interpreter/Interpreter.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala @@ -33,10 +33,19 @@ trait Interpreter extends ScorexLogging { val IR: IRContext import IR._ - def deserializeMeasured(context: CTX, scriptBytes: Array[Byte]) = { + /** Deserializes given script bytes using ValueSerializer (i.e. assuming expression tree format). + * It also measures tree complexity adding to the total estimated cost of script execution. + * The new returned context contains increased `initCost` and should be used for further processing. + * + * The method SHOULD be called only inside trySoftForkable scope, to make deserialization soft-forkable. + * + * NOTE: While ErgoTree is always of type SigmaProp, ValueSerializer can serialize expression of any type. + * So it cannot be replaced with ErgoTreeSerializer here. + */ + def deserializeMeasured(context: CTX, scriptBytes: Array[Byte]): (CTX, Value[SType]) = { val r = SigmaSerializer.startReader(scriptBytes) r.complexity = 0 - val script = ValueSerializer.deserialize(r) + val script = ValueSerializer.deserialize(r) // Why ValueSerializer? read NOTE above val scriptComplexity = r.complexity val currCost = JMath.addExact(context.initCost, scriptComplexity) @@ -87,7 +96,7 @@ trait Interpreter extends ScorexLogging { (res, currContext.value) } - def checkCost(context: CTX, exp: Value[SType], costF: Rep[((Int, IR.Size[IR.Context])) => Int]): Int = { + def checkCost(context: CTX, exp: Value[SType], costF: Ref[((Int, IR.Size[IR.Context])) => Int]): Int = { import IR.Size._ import IR.Context._; val costingCtx = context.toSigmaContext(IR, isCost = true) @@ -100,7 +109,7 @@ trait Interpreter extends ScorexLogging { estimatedCost } - def calcResult(context: special.sigma.Context, calcF: Rep[IR.Context => Any]): special.sigma.SigmaProp = { + def calcResult(context: special.sigma.Context, calcF: Ref[IR.Context => Any]): special.sigma.SigmaProp = { import IR._ import Context._ import SigmaProp._ diff --git a/src/main/scala/sigmastate/interpreter/InterpreterContext.scala b/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala similarity index 100% rename from src/main/scala/sigmastate/interpreter/InterpreterContext.scala rename to sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala diff --git a/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala similarity index 100% rename from src/main/scala/sigmastate/interpreter/ProverInterpreter.scala rename to sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala diff --git a/src/main/scala/sigmastate/lang/SigmaBinder.scala b/sigmastate/src/main/scala/sigmastate/lang/SigmaBinder.scala similarity index 100% rename from src/main/scala/sigmastate/lang/SigmaBinder.scala rename to sigmastate/src/main/scala/sigmastate/lang/SigmaBinder.scala diff --git a/src/main/scala/sigmastate/lang/SigmaBuilder.scala b/sigmastate/src/main/scala/sigmastate/lang/SigmaBuilder.scala similarity index 97% rename from src/main/scala/sigmastate/lang/SigmaBuilder.scala rename to sigmastate/src/main/scala/sigmastate/lang/SigmaBuilder.scala index 8817828247..ca7186a980 100644 --- a/src/main/scala/sigmastate/lang/SigmaBuilder.scala +++ b/sigmastate/src/main/scala/sigmastate/lang/SigmaBuilder.scala @@ -4,13 +4,9 @@ import java.math.BigInteger import org.ergoplatform.ErgoBox import org.ergoplatform.ErgoBox.RegisterId -import sigmastate.SCollection.SByteArray -import sigmastate.Values.{BigIntValue, BlockItem, BlockValue, BoolValue, ConcreteCollection, Constant, ConstantNode, ConstantPlaceholder, FalseLeaf, FuncValue, GroupElementValue, NoneValue, SValue, SigmaBoolean, SigmaPropValue, SomeValue, StringConstant, TaggedVariable, TaggedVariableNode, TrueLeaf, Tuple, ValUse, Value} -import sigmastate.Values._ +import sigmastate.SCollection.{SByteArray, SIntArray} +import sigmastate.Values.{BlockItem, BlockValue, BoolValue, ConcreteCollection, Constant, ConstantNode, ConstantPlaceholder, FalseLeaf, FuncValue, GroupElementValue, NoneValue, SValue, SigmaBoolean, SigmaPropValue, SomeValue, StringConstant, TaggedVariable, TaggedVariableNode, TrueLeaf, Tuple, ValUse, Value, _} import sigmastate._ -import sigmastate.interpreter.CryptoConstants -import sigmastate.lang.Constraints.{TypeConstraint2, onlyNumeric2, sameType2} -import sigmastate.basics.DLogProtocol.ProveDlog import sigmastate.lang.Constraints.{TypeConstraint2, onlyNumeric2, sameType2} import sigmastate.lang.Terms._ import sigmastate.lang.exceptions.ConstraintFailed @@ -18,17 +14,14 @@ import sigmastate.serialization.OpCodes import sigmastate.utxo._ import scalan.Nullable import sigmastate.SOption.SIntOption -import sigmastate.basics.ProveDHTuple -import sigmastate.eval.{CostingSigmaDslBuilder, Evaluation} -import sigmastate.eval._ -import sigmastate.eval.Extensions._ +import sigmastate.eval.{Evaluation, _} import sigmastate.interpreter.CryptoConstants.EcPointType import special.collection.Coll -import special.sigma.{AvlTree, GroupElement, SigmaProp} import sigmastate.lang.SigmaTyper.STypeSubst import sigmastate.serialization.OpCodes.OpCode -import special.sigma.{GroupElement, SigmaProp} +import special.sigma.{AvlTree, GroupElement, SigmaProp} import spire.syntax.all.cfor + import scala.util.DynamicVariable trait SigmaBuilder { @@ -220,6 +213,9 @@ trait SigmaBuilder { def mkBitShiftLeft[T <: SNumericType](bits: Value[T], shift: Value[T]): Value[T] def mkBitShiftRightZeroed[T <: SNumericType](bits: Value[T], shift: Value[T]): Value[T] + def mkSubstConst[T <: SType](scriptBytes: Value[SByteArray], positions: Value[SIntArray], + newValues: Value[SCollection[T]]): Value[SByteArray] + def mkUnitConstant: Value[SUnit.type] /** Created a new Value instance with an appropriate type derived from the given data `obj`. @@ -646,6 +642,10 @@ class StdSigmaBuilder extends SigmaBuilder { override def mkBitShiftRightZeroed[T <: SNumericType](bits: Value[T], shift: Value[T]): Value[T] = BitOp(bits, shift, OpCodes.BitShiftRightZeroedCode).withSrcCtx(currentSrcCtx.value) + def mkSubstConst[T <: SType](scriptBytes: Value[SByteArray], positions: Value[SIntArray], + newValues: Value[SCollection[T]]): Value[SByteArray] = + SubstConstants(scriptBytes, positions, newValues) + override def mkUnitConstant: Value[SUnit.type] = UnitConstant().withSrcCtx(currentSrcCtx.value) } diff --git a/src/main/scala/sigmastate/lang/SigmaCompiler.scala b/sigmastate/src/main/scala/sigmastate/lang/SigmaCompiler.scala similarity index 100% rename from src/main/scala/sigmastate/lang/SigmaCompiler.scala rename to sigmastate/src/main/scala/sigmastate/lang/SigmaCompiler.scala diff --git a/src/main/scala/sigmastate/lang/SigmaParser.scala b/sigmastate/src/main/scala/sigmastate/lang/SigmaParser.scala similarity index 100% rename from src/main/scala/sigmastate/lang/SigmaParser.scala rename to sigmastate/src/main/scala/sigmastate/lang/SigmaParser.scala diff --git a/src/main/scala/sigmastate/lang/SigmaPredef.scala b/sigmastate/src/main/scala/sigmastate/lang/SigmaPredef.scala similarity index 99% rename from src/main/scala/sigmastate/lang/SigmaPredef.scala rename to sigmastate/src/main/scala/sigmastate/lang/SigmaPredef.scala index 401393b016..e192509b3c 100644 --- a/src/main/scala/sigmastate/lang/SigmaPredef.scala +++ b/sigmastate/src/main/scala/sigmastate/lang/SigmaPredef.scala @@ -315,7 +315,10 @@ object SigmaPredef { Vector("scriptBytes" -> SByteArray, "positions" -> SIntArray, "newValues" -> SCollection(tT)), SByteArray, None ), - PredefFuncInfo( undefined), + PredefFuncInfo( + { case (_, Seq(scriptBytes, positions, newValues)) => + mkSubstConst(scriptBytes.asByteArray, positions.asIntArray, newValues.asInstanceOf[Value[SCollection[SType]]]) + }), OperationInfo(SubstConstants, """Transforms serialized bytes of ErgoTree with segregated constants by replacing constants | at given positions with new values. This operation allow to use serialized scripts as diff --git a/src/main/scala/sigmastate/lang/SigmaPrinter.scala b/sigmastate/src/main/scala/sigmastate/lang/SigmaPrinter.scala similarity index 100% rename from src/main/scala/sigmastate/lang/SigmaPrinter.scala rename to sigmastate/src/main/scala/sigmastate/lang/SigmaPrinter.scala diff --git a/src/main/scala/sigmastate/lang/SigmaSpecializer.scala b/sigmastate/src/main/scala/sigmastate/lang/SigmaSpecializer.scala similarity index 100% rename from src/main/scala/sigmastate/lang/SigmaSpecializer.scala rename to sigmastate/src/main/scala/sigmastate/lang/SigmaSpecializer.scala diff --git a/src/main/scala/sigmastate/lang/SigmaTyper.scala b/sigmastate/src/main/scala/sigmastate/lang/SigmaTyper.scala similarity index 99% rename from src/main/scala/sigmastate/lang/SigmaTyper.scala rename to sigmastate/src/main/scala/sigmastate/lang/SigmaTyper.scala index de62844ec3..0de4fd40f2 100644 --- a/src/main/scala/sigmastate/lang/SigmaTyper.scala +++ b/sigmastate/src/main/scala/sigmastate/lang/SigmaTyper.scala @@ -213,9 +213,12 @@ class SigmaTyper(val builder: SigmaBuilder, predefFuncRegistry: PredefinedFuncRe case _ => typedArgs } val actualTypes = adaptedTypedArgs.map(_.tpe) - if (actualTypes != argTypes) - error(s"Invalid argument type of application $app: expected $argTypes; actual after typing: $actualTypes", app.sourceContext) - mkApply(new_f, adaptedTypedArgs.toIndexedSeq) + unifyTypeLists(argTypes, actualTypes) match { + case Some(_) => + mkApply(new_f, adaptedTypedArgs.toIndexedSeq) + case None => + error(s"Invalid argument type of application $app: expected $argTypes; actual after typing: $actualTypes", app.sourceContext) + } case _: SCollectionType[_] => // If it's a collection then the application has type of that collection's element. args match { diff --git a/src/main/scala/sigmastate/lang/SourceContext.scala b/sigmastate/src/main/scala/sigmastate/lang/SourceContext.scala similarity index 100% rename from src/main/scala/sigmastate/lang/SourceContext.scala rename to sigmastate/src/main/scala/sigmastate/lang/SourceContext.scala diff --git a/src/main/scala/sigmastate/lang/Terms.scala b/sigmastate/src/main/scala/sigmastate/lang/Terms.scala similarity index 98% rename from src/main/scala/sigmastate/lang/Terms.scala rename to sigmastate/src/main/scala/sigmastate/lang/Terms.scala index 49351b41c6..a72ca377cf 100644 --- a/src/main/scala/sigmastate/lang/Terms.scala +++ b/sigmastate/src/main/scala/sigmastate/lang/Terms.scala @@ -2,7 +2,7 @@ package sigmastate.lang import org.bitbucket.inkytonik.kiama.rewriting.Rewriter._ import scalan.Nullable -import sigmastate.SCollection.SByteArray +import sigmastate.SCollection.{SByteArray, SIntArray} import sigmastate.Values._ import sigmastate.utils.Overloading.Overload1 import sigmastate._ @@ -227,6 +227,7 @@ object Terms { def asGroupElement: Value[SGroupElement.type] = v.asInstanceOf[Value[SGroupElement.type]] def asSigmaProp: Value[SSigmaProp.type] = v.asInstanceOf[Value[SSigmaProp.type]] def asByteArray: Value[SByteArray] = v.asInstanceOf[Value[SByteArray]] + def asIntArray: Value[SIntArray] = v.asInstanceOf[Value[SIntArray]] def asCollection[T <: SType]: Value[SCollection[T]] = v.asInstanceOf[Value[SCollection[T]]] def asOption[T <: SType]: Value[SOption[T]] = v.asInstanceOf[Value[SOption[T]]] def asTuple: Value[STuple] = v.asInstanceOf[Value[STuple]] diff --git a/src/main/scala/sigmastate/lang/Types.scala b/sigmastate/src/main/scala/sigmastate/lang/Types.scala similarity index 100% rename from src/main/scala/sigmastate/lang/Types.scala rename to sigmastate/src/main/scala/sigmastate/lang/Types.scala diff --git a/src/main/scala/sigmastate/lang/exceptions/Exceptions.scala b/sigmastate/src/main/scala/sigmastate/lang/exceptions/Exceptions.scala similarity index 100% rename from src/main/scala/sigmastate/lang/exceptions/Exceptions.scala rename to sigmastate/src/main/scala/sigmastate/lang/exceptions/Exceptions.scala diff --git a/src/main/scala/sigmastate/lang/exceptions/SigmaBinderExceptions.scala b/sigmastate/src/main/scala/sigmastate/lang/exceptions/SigmaBinderExceptions.scala similarity index 100% rename from src/main/scala/sigmastate/lang/exceptions/SigmaBinderExceptions.scala rename to sigmastate/src/main/scala/sigmastate/lang/exceptions/SigmaBinderExceptions.scala diff --git a/src/main/scala/sigmastate/lang/exceptions/SigmaBuilderExceptions.scala b/sigmastate/src/main/scala/sigmastate/lang/exceptions/SigmaBuilderExceptions.scala similarity index 100% rename from src/main/scala/sigmastate/lang/exceptions/SigmaBuilderExceptions.scala rename to sigmastate/src/main/scala/sigmastate/lang/exceptions/SigmaBuilderExceptions.scala diff --git a/src/main/scala/sigmastate/lang/exceptions/SigmaInterpreterExceptions.scala b/sigmastate/src/main/scala/sigmastate/lang/exceptions/SigmaInterpreterExceptions.scala similarity index 100% rename from src/main/scala/sigmastate/lang/exceptions/SigmaInterpreterExceptions.scala rename to sigmastate/src/main/scala/sigmastate/lang/exceptions/SigmaInterpreterExceptions.scala diff --git a/src/main/scala/sigmastate/lang/exceptions/SigmaSerializerExceptions.scala b/sigmastate/src/main/scala/sigmastate/lang/exceptions/SigmaSerializerExceptions.scala similarity index 100% rename from src/main/scala/sigmastate/lang/exceptions/SigmaSerializerExceptions.scala rename to sigmastate/src/main/scala/sigmastate/lang/exceptions/SigmaSerializerExceptions.scala diff --git a/src/main/scala/sigmastate/lang/exceptions/SigmaTyperExceptions.scala b/sigmastate/src/main/scala/sigmastate/lang/exceptions/SigmaTyperExceptions.scala similarity index 100% rename from src/main/scala/sigmastate/lang/exceptions/SigmaTyperExceptions.scala rename to sigmastate/src/main/scala/sigmastate/lang/exceptions/SigmaTyperExceptions.scala diff --git a/src/main/scala/sigmastate/lang/syntax/Basic.scala b/sigmastate/src/main/scala/sigmastate/lang/syntax/Basic.scala similarity index 98% rename from src/main/scala/sigmastate/lang/syntax/Basic.scala rename to sigmastate/src/main/scala/sigmastate/lang/syntax/Basic.scala index 9f5d064ef2..0de13a3afa 100644 --- a/src/main/scala/sigmastate/lang/syntax/Basic.scala +++ b/sigmastate/src/main/scala/sigmastate/lang/syntax/Basic.scala @@ -5,7 +5,7 @@ import fastparse.CharPredicates._ import scalan.Nullable import sigmastate.lang.SourceContext import sigmastate.lang.exceptions.SigmaException -import sigma.util.Extensions._ +import scalan.util.Extensions._ object Basic { val digits = "0123456789" diff --git a/src/main/scala/sigmastate/lang/syntax/Core.scala b/sigmastate/src/main/scala/sigmastate/lang/syntax/Core.scala similarity index 100% rename from src/main/scala/sigmastate/lang/syntax/Core.scala rename to sigmastate/src/main/scala/sigmastate/lang/syntax/Core.scala diff --git a/src/main/scala/sigmastate/lang/syntax/Exprs.scala b/sigmastate/src/main/scala/sigmastate/lang/syntax/Exprs.scala similarity index 100% rename from src/main/scala/sigmastate/lang/syntax/Exprs.scala rename to sigmastate/src/main/scala/sigmastate/lang/syntax/Exprs.scala diff --git a/src/main/scala/sigmastate/lang/syntax/Identifiers.scala b/sigmastate/src/main/scala/sigmastate/lang/syntax/Identifiers.scala similarity index 100% rename from src/main/scala/sigmastate/lang/syntax/Identifiers.scala rename to sigmastate/src/main/scala/sigmastate/lang/syntax/Identifiers.scala diff --git a/src/main/scala/sigmastate/lang/syntax/Literals.scala b/sigmastate/src/main/scala/sigmastate/lang/syntax/Literals.scala similarity index 100% rename from src/main/scala/sigmastate/lang/syntax/Literals.scala rename to sigmastate/src/main/scala/sigmastate/lang/syntax/Literals.scala diff --git a/src/main/scala/sigmastate/serialization/ApplySerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/ApplySerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/ApplySerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/ApplySerializer.scala diff --git a/src/main/scala/sigmastate/serialization/BlockValueSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/BlockValueSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/BlockValueSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/BlockValueSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/BoolToSigmaPropSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/BoolToSigmaPropSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/BoolToSigmaPropSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/BoolToSigmaPropSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/ByteBufferSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/ByteBufferSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/ByteBufferSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/ByteBufferSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/CaseObjectSerialization.scala b/sigmastate/src/main/scala/sigmastate/serialization/CaseObjectSerialization.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/CaseObjectSerialization.scala rename to sigmastate/src/main/scala/sigmastate/serialization/CaseObjectSerialization.scala diff --git a/src/main/scala/sigmastate/serialization/ConcreteCollectionBooleanConstantSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/ConcreteCollectionBooleanConstantSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/ConcreteCollectionBooleanConstantSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/ConcreteCollectionBooleanConstantSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/ConcreteCollectionSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/ConcreteCollectionSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/ConcreteCollectionSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/ConcreteCollectionSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/ConstantPlaceholderSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/ConstantPlaceholderSerializer.scala similarity index 88% rename from src/main/scala/sigmastate/serialization/ConstantPlaceholderSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/ConstantPlaceholderSerializer.scala index e9c19ca9e5..3f4765a16c 100644 --- a/src/main/scala/sigmastate/serialization/ConstantPlaceholderSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/ConstantPlaceholderSerializer.scala @@ -14,7 +14,7 @@ case class ConstantPlaceholderSerializer(cons: (Int, SType) => Value[SType]) override def parse(r: SigmaByteReader): Value[SType] = { val id = r.getUInt().toInt - val constant = r.constantStore.get(id) + val constant = r.constantStore.get(id) // TODO HF move this under if branch if (r.resolvePlaceholdersToConstants) constant else diff --git a/src/main/scala/sigmastate/serialization/ConstantSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/ConstantSerializer.scala similarity index 93% rename from src/main/scala/sigmastate/serialization/ConstantSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/ConstantSerializer.scala index d3d82fa58f..74f5451904 100644 --- a/src/main/scala/sigmastate/serialization/ConstantSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/ConstantSerializer.scala @@ -12,8 +12,6 @@ case class ConstantSerializer(builder: SigmaBuilder) extends ByteBufferSerializer[Constant[SType]] with ValueSerializer[Constant[SType]] { override def opDesc = Constant - override def opCost(opId: OperationId): Int = Cost.ConstantNode - override def parse(r: SigmaByteReader): Value[SType] = deserialize(r) override def serialize(c: Constant[SType], w: SigmaByteWriter): Unit = { diff --git a/src/main/scala/sigmastate/serialization/ConstantStore.scala b/sigmastate/src/main/scala/sigmastate/serialization/ConstantStore.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/ConstantStore.scala rename to sigmastate/src/main/scala/sigmastate/serialization/ConstantStore.scala diff --git a/src/main/scala/sigmastate/serialization/CreateAvlTreeSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/CreateAvlTreeSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/CreateAvlTreeSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/CreateAvlTreeSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/DataJsonEncoder.scala b/sigmastate/src/main/scala/sigmastate/serialization/DataJsonEncoder.scala similarity index 94% rename from src/main/scala/sigmastate/serialization/DataJsonEncoder.scala rename to sigmastate/src/main/scala/sigmastate/serialization/DataJsonEncoder.scala index 4f0904fb24..f72e2976cb 100644 --- a/src/main/scala/sigmastate/serialization/DataJsonEncoder.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/DataJsonEncoder.scala @@ -36,6 +36,15 @@ object DataJsonEncoder { ErgoAlgos.encode(bytes).asJson } + def encodeAnyValue(v: AnyValue): Json = { + val encodedType = Evaluation.rtypeToSType(v.tVal) + val encodedData = encodeData[SType](v.value.asInstanceOf[SType#WrappedType], encodedType) + Json.obj( + "type" -> Json.fromString(encodedType.toTermString), + "value" -> encodedData, + ) + } + private def encodeData[T <: SType](v: T#WrappedType, tpe: T): Json = tpe match { case SUnit => Json.Null case SBoolean => v.asInstanceOf[Boolean].asJson @@ -253,4 +262,11 @@ object DataJsonEncoder { val (data, _) = decodeWithTpe(json) data } + + def decodeAnyValue(json: Json): (AnyValue) = { + val tpe = SigmaParser.parseType(json.hcursor.downField("type").focus.get.asString.get) + val value = json.hcursor.downField("value").focus.get + val data = decodeData(value, tpe) + TestValue(data, Evaluation.stypeToRType(tpe).asInstanceOf[RType[Any]]) + } } diff --git a/src/main/scala/sigmastate/serialization/DataSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/DataSerializer.scala similarity index 99% rename from src/main/scala/sigmastate/serialization/DataSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/DataSerializer.scala index d409193fea..cd6ac43bc3 100644 --- a/src/main/scala/sigmastate/serialization/DataSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/DataSerializer.scala @@ -134,6 +134,7 @@ object DataSerializer { case SBoolean => Colls.fromArray(r.getBits(len)).asInstanceOf[Coll[T#WrappedType]] case SByte => + // TODO make covered Colls.fromArray(r.getBytes(len)).asInstanceOf[Coll[T#WrappedType]] case _ => implicit val tItem = (tpeElem match { diff --git a/src/main/scala/sigmastate/serialization/ErgoTreeSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/ErgoTreeSerializer.scala similarity index 99% rename from src/main/scala/sigmastate/serialization/ErgoTreeSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/ErgoTreeSerializer.scala index f49f7dd61c..2adb516431 100644 --- a/src/main/scala/sigmastate/serialization/ErgoTreeSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/ErgoTreeSerializer.scala @@ -8,7 +8,7 @@ import sigmastate.lang.DeserializationSigmaBuilder import sigmastate.lang.Terms.ValueOps import sigmastate.lang.exceptions.{SerializerException, InputSizeLimitExceeded} import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} -import sigma.util.Extensions._ +import scalan.util.Extensions._ import sigmastate.Values.ErgoTree.EmptyConstants import sigmastate.utxo.ComplexityTable import spire.syntax.all.cfor diff --git a/src/main/scala/sigmastate/serialization/FuncValueSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/FuncValueSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/FuncValueSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/FuncValueSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/GetVarSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/GetVarSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/GetVarSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/GetVarSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/GroupElementSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/LogicalNotSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/LogicalNotSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/LogicalNotSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/LogicalNotSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/MethodCallSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/MethodCallSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/MethodCallSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/MethodCallSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/ModQArithOpSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/ModQArithOpSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/ModQArithOpSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/ModQArithOpSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/ModQSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/ModQSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/ModQSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/ModQSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/OneArgumentOperationSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/OneArgumentOperationSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/OneArgumentOperationSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/OneArgumentOperationSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/OpCodes.scala b/sigmastate/src/main/scala/sigmastate/serialization/OpCodes.scala similarity index 99% rename from src/main/scala/sigmastate/serialization/OpCodes.scala rename to sigmastate/src/main/scala/sigmastate/serialization/OpCodes.scala index bb58454901..ef9d5fe068 100644 --- a/src/main/scala/sigmastate/serialization/OpCodes.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/OpCodes.scala @@ -1,6 +1,6 @@ package sigmastate.serialization -import sigma.util.Extensions.ByteOps +import scalan.util.Extensions.ByteOps import sigmastate.serialization.OpCodes.OpCode import supertagged.TaggedType diff --git a/src/main/scala/sigmastate/serialization/OperationSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/OperationSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/OperationSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/OperationSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/OptionGetOrElseSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/OptionGetOrElseSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/OptionGetOrElseSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/OptionGetOrElseSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/PropertyCallSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/PropertyCallSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/PropertyCallSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/PropertyCallSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/ProveDlogSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/ProveDlogSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/ProveDlogSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/ProveDlogSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/SelectFieldSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/SelectFieldSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/SelectFieldSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/SelectFieldSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/SigmaPropBytesSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/SigmaPropBytesSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/SigmaPropBytesSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/SigmaPropBytesSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/SigmaPropIsProvenSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/SigmaPropIsProvenSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/SigmaPropIsProvenSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/SigmaPropIsProvenSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/SigmaSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/SigmaSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/SigmaSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/SigmaSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/SubstConstantsSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/SubstConstantsSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/SubstConstantsSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/SubstConstantsSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/TaggedVariableSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/TaggedVariableSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/TaggedVariableSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/TaggedVariableSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/TupleSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/TupleSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/TupleSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/TupleSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/TwoArgumentsSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/TwoArgumentsSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/TwoArgumentsSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/TwoArgumentsSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/TypeSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/TypeSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/TypeSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/TypeSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/ValDefSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/ValDefSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/ValDefSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/ValDefSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/ValDefTypeStore.scala b/sigmastate/src/main/scala/sigmastate/serialization/ValDefTypeStore.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/ValDefTypeStore.scala rename to sigmastate/src/main/scala/sigmastate/serialization/ValDefTypeStore.scala diff --git a/src/main/scala/sigmastate/serialization/ValUseSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/ValUseSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/ValUseSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/ValUseSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/ValueSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/ValueSerializer.scala similarity index 97% rename from src/main/scala/sigmastate/serialization/ValueSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/ValueSerializer.scala index a0b0ca03b5..26df3df947 100644 --- a/src/main/scala/sigmastate/serialization/ValueSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/ValueSerializer.scala @@ -10,7 +10,7 @@ import sigmastate.lang.Terms.OperationId import sigmastate.serialization.OpCodes._ import sigmastate.serialization.transformers._ import sigmastate.serialization.trees.{QuadrupleSerializer, Relation2Serializer} -import sigma.util.Extensions._ +import scalan.util.Extensions._ import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils._ import sigmastate.utxo.ComplexityTable._ @@ -30,9 +30,6 @@ trait ValueSerializer[V <: Value[SType]] extends SigmaSerializer[Value[SType], V /** Code of the corresponding tree node (Value.opCode) which is used to lookup this serizalizer * during deserialization. It is emitted immediately before the body of this node in serialized byte array. */ @inline final def opCode: OpCode = opDesc.opCode - - def opCost(opId: OperationId): ExpressionCost = - sys.error(s"Operation opCost is not defined for AST node ${this.getClass}") } object ValueSerializer extends SigmaSerializerCompanion[Value[SType]] { @@ -138,9 +135,15 @@ object ValueSerializer extends SigmaSerializerCompanion[Value[SType]] { SigmaTransformerSerializer(SigmaAnd, mkSigmaAnd), SigmaTransformerSerializer(SigmaOr, mkSigmaOr), BoolToSigmaPropSerializer(mkBoolToSigmaProp), + + // TODO hard-fork: this ModQ serializers should be removed only as part of hard-fork + // because their removal may break deserialization of transaction, when for example + // ModQ operation happen to be in one of the outputs (i.e. script is not executed + // during validation, however deserializer is still used) ModQSerializer, ModQArithOpSerializer(ModQArithOp.PlusModQ, mkPlusModQ), ModQArithOpSerializer(ModQArithOp.MinusModQ, mkMinusModQ), + SubstConstantsSerializer, CreateProveDlogSerializer(mkCreateProveDlog), CreateProveDHTupleSerializer(mkCreateProveDHTuple), diff --git a/src/main/scala/sigmastate/serialization/transformers/AppendSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/AppendSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/transformers/AppendSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/transformers/AppendSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/transformers/AtLeastSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/AtLeastSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/transformers/AtLeastSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/transformers/AtLeastSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/transformers/BooleanTransformerSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/BooleanTransformerSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/transformers/BooleanTransformerSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/transformers/BooleanTransformerSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/transformers/ByIndexSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/ByIndexSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/transformers/ByIndexSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/transformers/ByIndexSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/transformers/DeserializeContextSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/DeserializeContextSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/transformers/DeserializeContextSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/transformers/DeserializeContextSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/transformers/DeserializeRegisterSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/DeserializeRegisterSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/transformers/DeserializeRegisterSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/transformers/DeserializeRegisterSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/transformers/ExtractRegisterAsSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/ExtractRegisterAsSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/transformers/ExtractRegisterAsSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/transformers/ExtractRegisterAsSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/transformers/FilterSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/FilterSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/transformers/FilterSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/transformers/FilterSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/transformers/FoldSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/FoldSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/transformers/FoldSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/transformers/FoldSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/transformers/LogicalTransformerSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/LogicalTransformerSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/transformers/LogicalTransformerSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/transformers/LogicalTransformerSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/transformers/MapCollectionSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/MapCollectionSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/transformers/MapCollectionSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/transformers/MapCollectionSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/transformers/NumericCastSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/NumericCastSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/transformers/NumericCastSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/transformers/NumericCastSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/transformers/ProveDHTupleSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/ProveDHTupleSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/transformers/ProveDHTupleSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/transformers/ProveDHTupleSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/transformers/SigmaTransformerSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/SigmaTransformerSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/transformers/SigmaTransformerSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/transformers/SigmaTransformerSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/transformers/SimpleTransformerSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/SimpleTransformerSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/transformers/SimpleTransformerSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/transformers/SimpleTransformerSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/transformers/SliceSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/SliceSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/transformers/SliceSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/transformers/SliceSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/trees/QuadrupleSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/trees/QuadrupleSerializer.scala similarity index 100% rename from src/main/scala/sigmastate/serialization/trees/QuadrupleSerializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/trees/QuadrupleSerializer.scala diff --git a/src/main/scala/sigmastate/serialization/trees/Relation2Serializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/trees/Relation2Serializer.scala similarity index 98% rename from src/main/scala/sigmastate/serialization/trees/Relation2Serializer.scala rename to sigmastate/src/main/scala/sigmastate/serialization/trees/Relation2Serializer.scala index 1270938404..7263190e01 100644 --- a/src/main/scala/sigmastate/serialization/trees/Relation2Serializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/trees/Relation2Serializer.scala @@ -6,7 +6,7 @@ import sigmastate.serialization.OpCodes._ import sigmastate.serialization.ValueSerializer import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import sigmastate.serialization.ValueSerializer._ -import sigma.util.Extensions._ +import scalan.util.Extensions._ case class Relation2Serializer[S1 <: SType, S2 <: SType, R <: Value[SBoolean.type]] (override val opDesc: RelationCompanion, diff --git a/src/main/scala/sigmastate/sigmastate.scala b/sigmastate/src/main/scala/sigmastate/sigmastate.scala similarity index 100% rename from src/main/scala/sigmastate/sigmastate.scala rename to sigmastate/src/main/scala/sigmastate/sigmastate.scala diff --git a/src/main/scala/sigmastate/trees.scala b/sigmastate/src/main/scala/sigmastate/trees.scala similarity index 100% rename from src/main/scala/sigmastate/trees.scala rename to sigmastate/src/main/scala/sigmastate/trees.scala diff --git a/src/main/scala/sigmastate/types.scala b/sigmastate/src/main/scala/sigmastate/types.scala similarity index 89% rename from src/main/scala/sigmastate/types.scala rename to sigmastate/src/main/scala/sigmastate/types.scala index daa52dbca4..0a65eba7bd 100644 --- a/src/main/scala/sigmastate/types.scala +++ b/sigmastate/src/main/scala/sigmastate/types.scala @@ -10,7 +10,7 @@ import scalan.RType.GeneralType import sigmastate.SType.{TypeCode, AnyOps} import sigmastate.interpreter.CryptoConstants import sigmastate.utils.Overloading.Overload1 -import sigma.util.Extensions._ +import scalan.util.Extensions._ import sigmastate.SBigInt.MaxSizeInBytes import sigmastate.Values._ import sigmastate.lang.Terms._ @@ -270,7 +270,6 @@ trait MethodByNameUnapply extends STypeCompanion { /** Base trait for all types which have methods (and properties) */ trait SProduct extends SType { - def ancestors: Seq[SType] /** Returns -1 if `method` is not found. */ def methodIndex(name: String): Int = methods.indexWhere(_.name == name) def hasMethod(name: String): Boolean = methodIndex(name) != -1 @@ -341,8 +340,14 @@ case class ArgInfo(name: String, description: String) /** Meta information which can be attached to SMethod. * @param description human readable description of the method * @param args one item for each argument */ -case class OperationInfo(opDesc: ValueCompanion, description: String, args: Seq[ArgInfo]) { - def isFrontendOnly: Boolean = opDesc == null +case class OperationInfo(opDesc: Option[ValueCompanion], description: String, args: Seq[ArgInfo]) { + def isFrontendOnly: Boolean = opDesc.isEmpty + def opTypeName: String = opDesc.map(_.typeName).getOrElse("(FRONTEND ONLY)") +} + +object OperationInfo { + def apply(opDesc: ValueCompanion, description: String, args: Seq[ArgInfo]): OperationInfo = + OperationInfo(Some(opDesc), description, args) } /** Meta information connecting SMethod with ErgoTree. @@ -380,11 +385,14 @@ case class SMethod( case _ => this } } - def withInfo(opDesc: ValueCompanion, desc: String, args: ArgInfo*) = { + def withInfo(opDesc: ValueCompanion, desc: String, args: ArgInfo*): SMethod = { this.copy(docInfo = Some(OperationInfo(opDesc, desc, ArgInfo("this", "this instance") +: args.toSeq))) } + def withInfo(desc: String, args: ArgInfo*): SMethod = { + this.copy(docInfo = Some(OperationInfo(None, desc, ArgInfo("this", "this instance") +: args.toSeq))) + } def withIRInfo( - irBuilder: PartialFunction[(SigmaBuilder, SValue, SMethod, Seq[SValue], STypeSubst), SValue]) = { + irBuilder: PartialFunction[(SigmaBuilder, SValue, SMethod, Seq[SValue], STypeSubst), SValue]): SMethod = { this.copy(irInfo = MethodIRInfo(Some(irBuilder))) } def argInfo(argName: String): ArgInfo = @@ -459,7 +467,6 @@ object SPrimType { /** Marker trait for all numeric types. */ trait SNumericType extends SProduct { import SNumericType._ - override def ancestors: Seq[SType] = Nil protected override def getMethods(): Seq[SMethod] = { super.getMethods() ++ SNumericType.methods.map { m => m.copy(stype = SigmaTyper.applySubst(m.stype, Map(tNum -> this)).asFunc) @@ -477,48 +484,49 @@ trait SNumericType extends SProduct { /** Number of bytes to store values of this type. */ @inline private def typeIndex: Int = allNumericTypes.indexOf(this) - def castOpDesc(toType: SNumericType): ValueCompanion = { - if ((this max toType) == this) Downcast else Upcast - } - override def toString: Idn = this.getClass.getSimpleName } object SNumericType extends STypeCompanion { final val allNumericTypes = Array(SByte, SShort, SInt, SLong, SBigInt) def typeId: TypeCode = 106: Byte - val ToByte = "toByte" - val ToShort = "toShort" - val ToInt = "toInt" - val ToLong = "toLong" - val ToBigInt = "toBigInt" - val tNum = STypeVar("TNum") - val methods = Vector( - SMethod(this, ToByte, SFunc(tNum, SByte), 1) - .withInfo(PropertyCall, "Converts this numeric value to \\lst{Byte}, throwing exception if overflow."), // see Downcast - SMethod(this, ToShort, SFunc(tNum, SShort), 2) - .withInfo(PropertyCall, "Converts this numeric value to \\lst{Short}, throwing exception if overflow."), // see Downcast - SMethod(this, ToInt, SFunc(tNum, SInt), 3) - .withInfo(PropertyCall, "Converts this numeric value to \\lst{Int}, throwing exception if overflow."), // see Downcast - SMethod(this, ToLong, SFunc(tNum, SLong), 4) - .withInfo(PropertyCall, "Converts this numeric value to \\lst{Long}, throwing exception if overflow."), // see Downcast - SMethod(this, ToBigInt, SFunc(tNum, SBigInt), 5) - .withInfo(PropertyCall, "Converts this numeric value to \\lst{BigInt}"), // see Downcast - SMethod(this, "toBytes", SFunc(tNum, SByteArray), 6) - .withIRInfo(MethodCallIrBuilder) - .withInfo(PropertyCall, - """ Returns a big-endian representation of this numeric value in a collection of bytes. - | For example, the \lst{Int} value \lst{0x12131415} would yield the - | collection of bytes \lst{[0x12, 0x13, 0x14, 0x15]}. - """.stripMargin), - SMethod(this, "toBits", SFunc(tNum, SBooleanArray), 7) - .withIRInfo(MethodCallIrBuilder) - .withInfo(PropertyCall, - """ Returns a big-endian representation of this numeric in a collection of Booleans. - | Each boolean corresponds to one bit. + + val ToByteMethod: SMethod = SMethod(this, "toByte", SFunc(tNum, SByte), 1) + .withInfo(PropertyCall, "Converts this numeric value to \\lst{Byte}, throwing exception if overflow.") + val ToShortMethod: SMethod = SMethod(this, "toShort", SFunc(tNum, SShort), 2) + .withInfo(PropertyCall, "Converts this numeric value to \\lst{Short}, throwing exception if overflow.") + val ToIntMethod: SMethod = SMethod(this, "toInt", SFunc(tNum, SInt), 3) + .withInfo(PropertyCall, "Converts this numeric value to \\lst{Int}, throwing exception if overflow.") + val ToLongMethod: SMethod = SMethod(this, "toLong", SFunc(tNum, SLong), 4) + .withInfo(PropertyCall, "Converts this numeric value to \\lst{Long}, throwing exception if overflow.") + val ToBigIntMethod: SMethod = SMethod(this, "toBigInt", SFunc(tNum, SBigInt), 5) + .withInfo(PropertyCall, "Converts this numeric value to \\lst{BigInt}") + val ToBytesMethod: SMethod = SMethod(this, "toBytes", SFunc(tNum, SByteArray), 6) + .withIRInfo(MethodCallIrBuilder) + .withInfo(PropertyCall, + """ Returns a big-endian representation of this numeric value in a collection of bytes. + | For example, the \lst{Int} value \lst{0x12131415} would yield the + | collection of bytes \lst{[0x12, 0x13, 0x14, 0x15]}. """.stripMargin) + val ToBitsMethod: SMethod = SMethod(this, "toBits", SFunc(tNum, SBooleanArray), 7) + .withIRInfo(MethodCallIrBuilder) + .withInfo(PropertyCall, + """ Returns a big-endian representation of this numeric in a collection of Booleans. + | Each boolean corresponds to one bit. + """.stripMargin) + + override val methods: Seq[SMethod] = Vector( + ToByteMethod, // see Downcast + ToShortMethod, // see Downcast + ToIntMethod, // see Downcast + ToLongMethod, // see Downcast + ToBigIntMethod, // see Downcast + ToBytesMethod, + ToBitsMethod ) - val castMethods: Array[String] = Array(ToByte, ToShort, ToInt, ToLong, ToBigInt) + val castMethods: Array[String] = + Array(ToByteMethod, ToShortMethod, ToIntMethod, ToLongMethod, ToBigIntMethod) + .map(_.name) } trait SLogical extends SType { @@ -528,16 +536,21 @@ trait SLogical extends SType { * @see `SGenericType` */ trait SMonoType extends SType with STypeCompanion { - protected def property(name: String, tpeRes: SType, id: Byte) = + protected def property(name: String, tpeRes: SType, id: Byte): SMethod = SMethod(this, name, SFunc(this, tpeRes), id) - .withIRInfo(MethodCallIrBuilder) + .withIRInfo(MethodCallIrBuilder) + .withInfo(PropertyCall, "") + + protected def property(name: String, tpeRes: SType, id: Byte, valueCompanion: ValueCompanion): SMethod = + SMethod(this, name, SFunc(this, tpeRes), id) + .withIRInfo(MethodCallIrBuilder) + .withInfo(valueCompanion, "") } case object SBoolean extends SPrimType with SEmbeddable with SLogical with SProduct with SMonoType { override type WrappedType = Boolean override val typeCode: TypeCode = 1: Byte override def typeId = typeCode - override def ancestors: Seq[SType] = Nil val ToByte = "toByte" protected override def getMethods() = super.getMethods() /* TODO soft-fork: https://github.com/ScorexFoundation/sigmastate-interpreter/issues/479 @@ -699,7 +712,6 @@ case object SBigInt extends SPrimType with SEmbeddable with SNumericType with SM /** NOTE: this descriptor both type and type companion */ case object SString extends SProduct with SMonoType { override type WrappedType = String - override def ancestors: Seq[SType] = Nil override val typeCode: TypeCode = 102: Byte override def typeId = typeCode override def mkConstant(v: String): Value[SString.type] = StringConstant(v) @@ -713,32 +725,39 @@ case object SGroupElement extends SProduct with SPrimType with SEmbeddable with override val typeCode: TypeCode = 7: Byte override def typeId = typeCode override def coster: Option[CosterFactory] = Some(Coster(_.GroupElementCoster)) + + val GetEncodedMethod: SMethod = SMethod(this, "getEncoded", SFunc(IndexedSeq(this), SByteArray), 2) + .withIRInfo(MethodCallIrBuilder) + .withInfo(PropertyCall, "Get an encoding of the point value.") + val ExponentiateMethod: SMethod = SMethod(this, "exp", SFunc(IndexedSeq(this, SBigInt), this), 3) + .withIRInfo({ case (builder, obj, _, Seq(arg), _) => + builder.mkExponentiate(obj.asGroupElement, arg.asBigInt) + }) + .withInfo(Exponentiate, + "Exponentiate this \\lst{GroupElement} to the given number. Returns this to the power of k", + ArgInfo("k", "The power")) + val MultiplyMethod: SMethod = SMethod(this, "multiply", SFunc(IndexedSeq(this, SGroupElement), this), 4) + .withIRInfo({ case (builder, obj, _, Seq(arg), _) => + builder.mkMultiplyGroup(obj.asGroupElement, arg.asGroupElement) + }) + .withInfo(MultiplyGroup, "Group operation.", ArgInfo("other", "other element of the group")) + val NegateMethod: SMethod = SMethod(this, "negate", SFunc(this, this), 5) + .withIRInfo(MethodCallIrBuilder) + .withInfo(PropertyCall, "Inverse element of the group.") + protected override def getMethods(): Seq[SMethod] = super.getMethods() ++ Seq( /* TODO soft-fork: https://github.com/ScorexFoundation/sigmastate-interpreter/issues/479 SMethod(this, "isIdentity", SFunc(this, SBoolean), 1) .withInfo(PropertyCall, "Checks if this value is identity element of the eliptic curve group."), */ - SMethod(this, "getEncoded", SFunc(IndexedSeq(this), SByteArray), 2) - .withIRInfo(MethodCallIrBuilder) - .withInfo(PropertyCall, "Get an encoding of the point value."), - SMethod(this, "exp", SFunc(IndexedSeq(this, SBigInt), this), 3) - .withIRInfo({ case (builder, obj, _, Seq(arg), _) => - builder.mkExponentiate(obj.asGroupElement, arg.asBigInt) }) - .withInfo(Exponentiate, - "Exponentiate this \\lst{GroupElement} to the given number. Returns this to the power of k", - ArgInfo("k", "The power")), - SMethod(this, "multiply", SFunc(IndexedSeq(this, SGroupElement), this), 4) - .withIRInfo({ case (builder, obj, _, Seq(arg), _) => - builder.mkMultiplyGroup(obj.asGroupElement, arg.asGroupElement) }) - .withInfo(MultiplyGroup, "Group operation.", ArgInfo("other", "other element of the group")), - SMethod(this, "negate", SFunc(this, this), 5) - .withIRInfo(MethodCallIrBuilder) - .withInfo(PropertyCall, "Inverse element of the group.") + GetEncodedMethod, + ExponentiateMethod, + MultiplyMethod, + NegateMethod ) override def mkConstant(v: GroupElement): Value[SGroupElement.type] = GroupElementConstant(v) override def dataSize(v: SType#WrappedType): Long = CryptoConstants.EncodedGroupElementLength.toLong override def isConstantSize = true - def ancestors = Nil } case object SSigmaProp extends SProduct with SPrimType with SEmbeddable with SLogical with SMonoType { @@ -754,14 +773,13 @@ case object SSigmaProp extends SProduct with SPrimType with SEmbeddable with SLo override def dataSize(v: SType#WrappedType): Long = MaxSizeInBytes override def isConstantSize = true - def ancestors = Nil val PropBytes = "propBytes" val IsProven = "isProven" protected override def getMethods() = super.getMethods() ++ Seq( SMethod(this, PropBytes, SFunc(this, SByteArray), 1) .withInfo(SigmaPropBytes, "Serialized bytes of this sigma proposition taken as ErgoTree."), SMethod(this, IsProven, SFunc(this, SBoolean), 2) - .withInfo(null, // available only at frontend of ErgoScript + .withInfo(// available only at frontend of ErgoScript "Verify that sigma proposition is proven.") ) } @@ -792,7 +810,6 @@ case class SOption[ElemType <: SType](elemType: ElemType) extends SProduct with 1L + opt.fold(0L)(x => elemType.dataSize(x)) } override def isConstantSize = elemType.isConstantSize - def ancestors = Nil protected override def getMethods() = super.getMethods() ++ SOption.methods // override lazy val methods: Seq[SMethod] = { // val subst = Map(SOption.tT -> elemType) @@ -907,7 +924,6 @@ object SOption extends STypeCompanion { trait SCollection[T <: SType] extends SProduct with SGenericType { def elemType: T override type WrappedType = Coll[T#WrappedType] - def ancestors = Nil override def isConstantSize = false } @@ -1348,7 +1364,6 @@ case object SBox extends SProduct with SPredefType with SMonoType { Sized.sizeOf(box).dataSize } override def isConstantSize = false - def ancestors = Nil val tT = STypeVar("T") def registers(idOfs: Int): Seq[SMethod] = { @@ -1418,7 +1433,6 @@ case object SAvlTree extends SProduct with SPredefType with SMonoType { override def mkConstant(v: AvlTree): Value[SAvlTree.type] = AvlTreeConstant(v) override def dataSize(v: SType#WrappedType): Long = AvlTreeData.TreeDataSize override def isConstantSize = true - def ancestors = Nil import SOption._ val TCollOptionCollByte = SCollection(SByteArrayOption) @@ -1483,6 +1497,15 @@ case object SAvlTree extends SProduct with SPredefType with SMonoType { .withIRInfo(MethodCallIrBuilder) .withInfo(MethodCall, """ + | /** Checks if an entry with key `key` exists in this tree using proof `proof`. + | * Throws exception if proof is incorrect + | + | * @note CAUTION! Does not support multiple keys check, use [[getMany]] instead. + | * Return `true` if a leaf with the key `key` exists + | * Return `false` if leaf with provided key does not exist. + | * @param key a key of an element of this authenticated dictionary. + | * @param proof + | */ | """.stripMargin) @@ -1491,6 +1514,15 @@ case object SAvlTree extends SProduct with SPredefType with SMonoType { .withIRInfo(MethodCallIrBuilder) .withInfo(MethodCall, """ + | /** Perform a lookup of key `key` in this tree using proof `proof`. + | * Throws exception if proof is incorrect + | * + | * @note CAUTION! Does not support multiple keys check, use [[getMany]] instead. + | * Return Some(bytes) of leaf with key `key` if it exists + | * Return None if leaf with provided key does not exist. + | * @param key a key of an element of this authenticated dictionary. + | * @param proof + | */ | """.stripMargin) @@ -1499,6 +1531,13 @@ case object SAvlTree extends SProduct with SPredefType with SMonoType { .withIRInfo(MethodCallIrBuilder) .withInfo(MethodCall, """ + | /** Perform a lookup of many keys `keys` in this tree using proof `proof`. + | * + | * @note CAUTION! Keys must be ordered the same way they were in lookup before proof was generated. + | * For each key return Some(bytes) of leaf if it exists and None if is doesn't. + | * @param keys keys of elements of this authenticated dictionary. + | * @param proof + | */ | """.stripMargin) @@ -1507,6 +1546,15 @@ case object SAvlTree extends SProduct with SPredefType with SMonoType { .withIRInfo(MethodCallIrBuilder) .withInfo(MethodCall, """ + | /** Perform insertions of key-value entries into this tree using proof `proof`. + | * Throws exception if proof is incorrect + | * + | * @note CAUTION! Pairs must be ordered the same way they were in insert ops before proof was generated. + | * Return Some(newTree) if successful + | * Return None if operations were not performed. + | * @param operations collection of key-value pairs to insert in this authenticated dictionary. + | * @param proof + | */ | """.stripMargin) @@ -1515,6 +1563,15 @@ case object SAvlTree extends SProduct with SPredefType with SMonoType { .withIRInfo(MethodCallIrBuilder) .withInfo(MethodCall, """ + | /** Perform updates of key-value entries into this tree using proof `proof`. + | * Throws exception if proof is incorrect + | * + | * @note CAUTION! Pairs must be ordered the same way they were in update ops before proof was generated. + | * Return Some(newTree) if successful + | * Return None if operations were not performed. + | * @param operations collection of key-value pairs to update in this authenticated dictionary. + | * @param proof + | */ | """.stripMargin) @@ -1523,6 +1580,15 @@ case object SAvlTree extends SProduct with SPredefType with SMonoType { .withIRInfo(MethodCallIrBuilder) .withInfo(MethodCall, """ + | /** Perform removal of entries into this tree using proof `proof`. + | * Throws exception if proof is incorrect + | * Return Some(newTree) if successful + | * Return None if operations were not performed. + | * + | * @note CAUTION! Keys must be ordered the same way they were in remove ops before proof was generated. + | * @param operations collection of keys to remove from this authenticated dictionary. + | * @param proof + | */ | """.stripMargin) @@ -1558,27 +1624,29 @@ case object SContext extends SProduct with SPredefType with SMonoType { override type WrappedType = ErgoLikeContext override val typeCode: TypeCode = 101: Byte override def typeId = typeCode - override def mkConstant(v: ErgoLikeContext): Value[SContext.type] = ContextConstant(v) + override def mkConstant(v: ErgoLikeContext): Value[SContext.type] = + sys.error(s"Cannot create constant of type Context") /** Approximate data size of the given context without ContextExtension. */ override def dataSize(v: SType#WrappedType): Long = { sys.error(s"Should not be used, use SizeContext and Sized typeclass instead") } override def isConstantSize = false - def ancestors = Nil val tT = STypeVar("T") val dataInputsMethod = property("dataInputs", SBoxArray, 1) val headersMethod = property("headers", SHeaderArray, 2) val preHeaderMethod = property("preHeader", SPreHeader, 3) - val inputsMethod = property("INPUTS", SBoxArray, 4) - val outputsMethod = property("OUTPUTS", SBoxArray, 5) - val heightMethod = property("HEIGHT", SInt, 6) - val selfMethod = property("SELF", SBox, 7) + val inputsMethod = property("INPUTS", SBoxArray, 4, Inputs) + val outputsMethod = property("OUTPUTS", SBoxArray, 5, Outputs) + val heightMethod = property("HEIGHT", SInt, 6, Height) + val selfMethod = property("SELF", SBox, 7, Self) val selfBoxIndexMethod = property("selfBoxIndex", SInt, 8) - val lastBlockUtxoRootHashMethod = property("LastBlockUtxoRootHash", SAvlTree, 9) - val minerPubKeyMethod = property("minerPubKey", SByteArray, 10) + val lastBlockUtxoRootHashMethod = property("LastBlockUtxoRootHash", SAvlTree, 9, LastBlockUtxoRootHash) + val minerPubKeyMethod = property("minerPubKey", SByteArray, 10, MinerPubkey) val getVarMethod = SMethod(this, "getVar", SFunc(IndexedSeq(SContext, SByte), SOption(tT), Seq(STypeParam(tT))), 11) + .withInfo(GetVar, "Get context variable with given \\lst{varId} and type.", + ArgInfo("varId", "\\lst{Byte} identifier of context variable")) protected override def getMethods() = super.getMethods() ++ Seq( dataInputsMethod, headersMethod, preHeaderMethod, inputsMethod, outputsMethod, heightMethod, selfMethod, @@ -1612,7 +1680,6 @@ case object SHeader extends SProduct with SPredefType with SMonoType { 3 // votes } override def isConstantSize = true - def ancestors = Nil val idMethod = property("id", SByteArray, 1) val versionMethod = property("version", SByte, 2) @@ -1655,7 +1722,6 @@ case object SPreHeader extends SProduct with SPredefType with SMonoType { 3 // votes } override def isConstantSize = true - def ancestors = Nil val versionMethod = property("version", SByte, 1) val parentIdMethod = property("parentId", SByteArray, 2) @@ -1697,16 +1763,18 @@ case object SGlobal extends SProduct with SPredefType with SMonoType { sys.error(s"Should not be used, use SizeContext and Sized typeclass instead") } override def isConstantSize = true // only fixed amount of global information is allowed - def ancestors = Nil val tT = STypeVar("T") val groupGeneratorMethod = SMethod(this, "groupGenerator", SFunc(this, SGroupElement), 1) - .withIRInfo({ case (builder, obj, method, args, tparamSubst) => GroupGenerator }) - .withInfo(GroupGenerator, "") + .withIRInfo({ case (builder, obj, method, args, tparamSubst) => GroupGenerator }) + .withInfo(GroupGenerator, "") val xorMethod = SMethod(this, "xor", SFunc(IndexedSeq(this, SByteArray, SByteArray), SByteArray), 2) - .withIRInfo({ + .withIRInfo({ case (_, _, _, Seq(l, r), _) => Xor(l.asByteArray, r.asByteArray) - }) + }) + .withInfo(Xor, "Byte-wise XOR of two collections of bytes", + ArgInfo("left", "left operand"), ArgInfo("right", "right operand")) + protected override def getMethods() = super.getMethods() ++ Seq( groupGeneratorMethod, xorMethod diff --git a/src/test/scala/sigmastate/utils/ByteReaderWriterImpSpecification.scala b/sigmastate/src/main/scala/sigmastate/utils/ByteReader.scala similarity index 100% rename from src/test/scala/sigmastate/utils/ByteReaderWriterImpSpecification.scala rename to sigmastate/src/main/scala/sigmastate/utils/ByteReader.scala diff --git a/src/test/scala/sigmastate/utxo/SpamSpecification.scala b/sigmastate/src/main/scala/sigmastate/utils/ByteWriter.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/SpamSpecification.scala rename to sigmastate/src/main/scala/sigmastate/utils/ByteWriter.scala diff --git a/src/main/scala/sigmastate/utils/Helpers.scala b/sigmastate/src/main/scala/sigmastate/utils/Helpers.scala similarity index 100% rename from src/main/scala/sigmastate/utils/Helpers.scala rename to sigmastate/src/main/scala/sigmastate/utils/Helpers.scala diff --git a/src/main/scala/sigmastate/utils/SigmaByteReader.scala b/sigmastate/src/main/scala/sigmastate/utils/SigmaByteReader.scala similarity index 100% rename from src/main/scala/sigmastate/utils/SigmaByteReader.scala rename to sigmastate/src/main/scala/sigmastate/utils/SigmaByteReader.scala diff --git a/src/main/scala/sigmastate/utils/SigmaByteWriter.scala b/sigmastate/src/main/scala/sigmastate/utils/SigmaByteWriter.scala similarity index 100% rename from src/main/scala/sigmastate/utils/SigmaByteWriter.scala rename to sigmastate/src/main/scala/sigmastate/utils/SigmaByteWriter.scala diff --git a/src/main/scala/sigmastate/utils/SparseArrayContainer.scala b/sigmastate/src/main/scala/sigmastate/utils/SparseArrayContainer.scala similarity index 100% rename from src/main/scala/sigmastate/utils/SparseArrayContainer.scala rename to sigmastate/src/main/scala/sigmastate/utils/SparseArrayContainer.scala diff --git a/src/main/scala/sigmastate/utxo/ComplexityTable.scala b/sigmastate/src/main/scala/sigmastate/utxo/ComplexityTable.scala similarity index 100% rename from src/main/scala/sigmastate/utxo/ComplexityTable.scala rename to sigmastate/src/main/scala/sigmastate/utxo/ComplexityTable.scala diff --git a/src/main/scala/sigmastate/utxo/ComplexityTableStat.scala b/sigmastate/src/main/scala/sigmastate/utxo/ComplexityTableStat.scala similarity index 98% rename from src/main/scala/sigmastate/utxo/ComplexityTableStat.scala rename to sigmastate/src/main/scala/sigmastate/utxo/ComplexityTableStat.scala index 6cb2c65cd9..a8502849d3 100644 --- a/src/main/scala/sigmastate/utxo/ComplexityTableStat.scala +++ b/sigmastate/src/main/scala/sigmastate/utxo/ComplexityTableStat.scala @@ -2,7 +2,7 @@ package sigmastate.utxo import sigmastate.serialization.ValueSerializer.getSerializer import sigmastate.serialization.OpCodes.OpCode -import sigma.util.Extensions.ByteOps +import scalan.util.Extensions.ByteOps import sigmastate.SMethod import sigmastate.serialization.OpCodes diff --git a/src/main/scala/sigmastate/utxo/CostTable.scala b/sigmastate/src/main/scala/sigmastate/utxo/CostTable.scala similarity index 99% rename from src/main/scala/sigmastate/utxo/CostTable.scala rename to sigmastate/src/main/scala/sigmastate/utxo/CostTable.scala index 35857c29fc..2d3cd7308f 100644 --- a/src/main/scala/sigmastate/utxo/CostTable.scala +++ b/sigmastate/src/main/scala/sigmastate/utxo/CostTable.scala @@ -6,7 +6,7 @@ import sigmastate.lang.SigmaParser import sigmastate.lang.Terms.OperationId import sigmastate.serialization.OpCodes import sigmastate.serialization.OpCodes.{LastConstantCode, OpCode} -import sigma.util.Extensions.ByteOps +import scalan.util.Extensions.ByteOps import sigmastate.serialization.ValueSerializer.getSerializer import scala.collection.mutable @@ -148,6 +148,7 @@ object CostTable { ("Slice", "(Coll[IV],Int,Int) => Coll[IV]", collToColl), ("Append", "(Coll[IV],Coll[IV]) => Coll[IV]", collToColl), + ("SizeOf", "(Coll[IV]) => Int", collLength), ("ByIndex", "(Coll[IV],Int) => IV", collByIndex), ("SCollection$.exists", "(Coll[IV],(IV) => Boolean) => Boolean", collToColl), diff --git a/src/main/scala/sigmastate/utxo/CostTableStat.scala b/sigmastate/src/main/scala/sigmastate/utxo/CostTableStat.scala similarity index 100% rename from src/main/scala/sigmastate/utxo/CostTableStat.scala rename to sigmastate/src/main/scala/sigmastate/utxo/CostTableStat.scala diff --git a/src/main/scala/sigmastate/utxo/transformers.scala b/sigmastate/src/main/scala/sigmastate/utxo/transformers.scala similarity index 97% rename from src/main/scala/sigmastate/utxo/transformers.scala rename to sigmastate/src/main/scala/sigmastate/utxo/transformers.scala index 731a5a3941..11d0d0bfb1 100644 --- a/src/main/scala/sigmastate/utxo/transformers.scala +++ b/sigmastate/src/main/scala/sigmastate/utxo/transformers.scala @@ -106,13 +106,13 @@ case class Fold[IV <: SType, OV <: SType](input: Value[SCollection[IV]], object Fold extends ValueCompanion { override def opCode: OpCode = OpCodes.FoldCode - def sum[T <: SNumericType](input: Value[SCollection[T]])(implicit tT: T) = + def sum[T <: SNumericType](input: Value[SCollection[T]], varId: Int)(implicit tT: T) = Fold(input, Constant(tT.upcast(0.toByte), tT), - FuncValue(Vector((1, STuple(tT, tT))), + FuncValue(Vector((varId, STuple(tT, tT))), Plus( - SelectField(ValUse(1, STuple(tT, tT)), 1).asNumValue, - SelectField(ValUse(1, STuple(tT, tT)), 2).asNumValue)) + SelectField(ValUse(varId, STuple(tT, tT)), 1).asNumValue, + SelectField(ValUse(varId, STuple(tT, tT)), 2).asNumValue)) ) def concat[T <: SType](input: Value[SCollection[SCollection[T]]])(implicit tT: T): Fold[SCollection[T], T] = { diff --git a/src/test/java/gf2t/GF2_192Test.java b/sigmastate/src/test/java/gf2t/GF2_192Test.java similarity index 100% rename from src/test/java/gf2t/GF2_192Test.java rename to sigmastate/src/test/java/gf2t/GF2_192Test.java diff --git a/src/test/java/gf2t/ReadableTest.java b/sigmastate/src/test/java/gf2t/ReadableTest.java similarity index 100% rename from src/test/java/gf2t/ReadableTest.java rename to sigmastate/src/test/java/gf2t/ReadableTest.java diff --git a/src/test/scala/org/ergoplatform/EmissionSpec.scala b/sigmastate/src/test/scala/org/ergoplatform/EmissionSpec.scala similarity index 100% rename from src/test/scala/org/ergoplatform/EmissionSpec.scala rename to sigmastate/src/test/scala/org/ergoplatform/EmissionSpec.scala diff --git a/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala b/sigmastate/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala similarity index 66% rename from src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala rename to sigmastate/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala index f9afa4dfee..871eb8c97e 100644 --- a/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala +++ b/sigmastate/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala @@ -12,14 +12,20 @@ import sigmastate.serialization.ValueSerializer import sigmastate.serialization.generators.ObjectGenerators import org.ergoplatform.ErgoScriptPredef._ import org.ergoplatform.validation.ValidationSpecification -import sigmastate.Values.ErgoTree +import sigmastate.{AvlTreeData, SType} +import sigmastate.Values.{EvaluatedValue, SigmaPropConstant, ByteArrayConstant, IntConstant, ErgoTree} +import sigmastate.eval.IRContext +import sigmastate.helpers._ +import sigmastate.interpreter.{ContextExtension, Interpreter} +import sigmastate.interpreter.Interpreter.{ScriptNameProp, ScriptEnv} +import sigmastate.lang.Terms.ValueOps class ErgoAddressSpecification extends PropSpec with ObjectGenerators with PropertyChecks with Matchers with TryValues - with ValidationSpecification { + with SigmaTestingCommons { private implicit val ergoAddressEncoder: ErgoAddressEncoder = new ErgoAddressEncoder(TestnetNetworkPrefix) @@ -87,4 +93,32 @@ class ErgoAddressSpecification extends PropSpec } } + def testPay2SHAddress(address: Pay2SHAddress, scriptBytes: Array[Byte])(implicit IR: IRContext) = { + val scriptId = 1.toByte + val boxToSpend = ErgoBox(10, address.script, creationHeight = 5) + val ctx = ErgoLikeContextTesting.dummy(boxToSpend) + .withExtension(ContextExtension(Seq( + scriptId -> ByteArrayConstant(scriptBytes) // provide script bytes in context variable + ).toMap)) + + val env: ScriptEnv = Map() + val prover = new ErgoLikeTestProvingInterpreter() + val pr = prover.prove(env + (ScriptNameProp -> s"prove"), address.script, ctx, fakeMessage).fold(t => throw t, identity) + + val verifier = new ErgoLikeTestInterpreter + verifier.verify(env + (ScriptNameProp -> s"verify_ext"), address.script, ctx, pr.proof, fakeMessage).get._1 shouldBe true + } + + property("spending a box protected by P2SH contract") { + implicit lazy val IR = new TestingIRContext + + val script = "{ 1 < 2 }" + val prop = compile(Map.empty, script).asBoolValue.toSigmaProp + val scriptBytes = ValueSerializer.serialize(prop) + + testPay2SHAddress(Pay2SHAddress(prop), scriptBytes) + + val tree = ErgoTree.fromProposition(prop) + testPay2SHAddress(Pay2SHAddress(tree), scriptBytes) + } } \ No newline at end of file diff --git a/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala b/sigmastate/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala similarity index 100% rename from src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala rename to sigmastate/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala diff --git a/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala b/sigmastate/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala similarity index 100% rename from src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala rename to sigmastate/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala diff --git a/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala b/sigmastate/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala similarity index 94% rename from src/test/scala/org/ergoplatform/JsonSerializationSpec.scala rename to sigmastate/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala index 48f6fec54f..96bb9cd01d 100644 --- a/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala +++ b/sigmastate/src/test/scala/org/ergoplatform/JsonSerializationSpec.scala @@ -2,20 +2,20 @@ package org.ergoplatform import io.circe._ import io.circe.syntax._ -import org.ergoplatform.ErgoBox.{NonMandatoryRegisterId, R4, R5, R6, R7, R8} +import org.ergoplatform.ErgoBox._ import org.ergoplatform.validation.ValidationRules import scorex.crypto.authds.{ADDigest, ADKey} import scorex.crypto.hash.Digest32 import scorex.util.ModifierId import scorex.util.encode.Base16 import sigmastate.{AvlTreeData, SType} -import sigmastate.Values.{ByteArrayConstant, ByteConstant, ErgoTree, EvaluatedValue, IntConstant, LongArrayConstant, SigmaPropConstant} +import sigmastate.Values.{EvaluatedValue, SigmaPropConstant, ByteArrayConstant, IntConstant, ErgoTree, ByteConstant, LongArrayConstant} import sigmastate.basics.DLogProtocol.ProveDlog import sigmastate.helpers.SigmaTestingCommons -import sigmastate.interpreter.{ContextExtension, CryptoConstants, ProverResult} +import sigmastate.interpreter.{ProverResult, ContextExtension, CryptoConstants} import sigmastate.serialization.SerializationSpecification import special.collection.Coll -import special.sigma.{Header, PreHeader} +import special.sigma.{PreHeader, Header} class JsonSerializationSpec extends SigmaTestingCommons with SerializationSpecification with JsonCodecs { diff --git a/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala b/sigmastate/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala similarity index 98% rename from src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala rename to sigmastate/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala index 7041058a58..14aec73804 100644 --- a/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala +++ b/sigmastate/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala @@ -49,7 +49,6 @@ case class TestContractSpec(testSuite: SigmaTestingCommons)(implicit val IR: IRC IR.builder.mkConstant(v.value.asWrappedType, Evaluation.rtypeToSType(v.tA)) } val ctx = inBox.toErgoContext -// val newExtension = ContextExtension(ctx.extension.values ++ bindings) val env = propSpec.scriptSpec.env + (ScriptNameProp -> (propSpec.name + "_prove")) val prop = propSpec.ergoTree val p = bindings.foldLeft(prover) { (p, b) => p.withContextExtender(b._1, b._2) } diff --git a/src/test/scala/org/ergoplatform/validation/RuleStatusSerializerSpec.scala b/sigmastate/src/test/scala/org/ergoplatform/validation/RuleStatusSerializerSpec.scala similarity index 100% rename from src/test/scala/org/ergoplatform/validation/RuleStatusSerializerSpec.scala rename to sigmastate/src/test/scala/org/ergoplatform/validation/RuleStatusSerializerSpec.scala diff --git a/src/test/scala/org/ergoplatform/validation/SigmaValidationSettingsSerializerSpec.scala b/sigmastate/src/test/scala/org/ergoplatform/validation/SigmaValidationSettingsSerializerSpec.scala similarity index 100% rename from src/test/scala/org/ergoplatform/validation/SigmaValidationSettingsSerializerSpec.scala rename to sigmastate/src/test/scala/org/ergoplatform/validation/SigmaValidationSettingsSerializerSpec.scala diff --git a/src/test/scala/org/ergoplatform/validation/ValidationSpecification.scala b/sigmastate/src/test/scala/org/ergoplatform/validation/ValidationSpecification.scala similarity index 100% rename from src/test/scala/org/ergoplatform/validation/ValidationSpecification.scala rename to sigmastate/src/test/scala/org/ergoplatform/validation/ValidationSpecification.scala diff --git a/src/test/scala/sigmastate/CalcSha256Specification.scala b/sigmastate/src/test/scala/sigmastate/CalcSha256Specification.scala similarity index 100% rename from src/test/scala/sigmastate/CalcSha256Specification.scala rename to sigmastate/src/test/scala/sigmastate/CalcSha256Specification.scala diff --git a/src/test/scala/sigmastate/CostingSpecification.scala b/sigmastate/src/test/scala/sigmastate/CostingSpecification.scala similarity index 98% rename from src/test/scala/sigmastate/CostingSpecification.scala rename to sigmastate/src/test/scala/sigmastate/CostingSpecification.scala index 0b2667c28b..0e32779f5c 100644 --- a/src/test/scala/sigmastate/CostingSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/CostingSpecification.scala @@ -311,9 +311,11 @@ class CostingSpecification extends SigmaTestingData { cost(s"{ $coll.exists({ (b: Box) => b.value > 1L }) }") ( lambdaCost + selectField + (accessBox + extractCost + constCost + comparisonCost + lambdaInvoke) * nOutputs + collToColl) + cost(s"{ $coll.append(OUTPUTS).size > 0 }")( selectField + accessBox * tx.outputs.length + - accessBox * tx.outputs.length * 2 + collToColl + LengthGTConstCost) + accessBox * tx.outputs.length * 2 + collToColl + LengthGTConstCost) + cost(s"{ $coll.indices.size > 0 }")( selectField + accessBox * tx.outputs.length + selectField + LengthGTConstCost) cost(s"{ $collBytes.getOrElse(0, 1.toByte) == 0 }")( @@ -326,9 +328,7 @@ class CostingSpecification extends SigmaTestingData { (accessBox + extractCost + GTConstCost + lambdaInvoke) * nOutputs + collToColl) cost(s"{ $coll.slice(0, 1).size > 0 }")( selectField + collToColl + accessBox * tx.outputs.length + LengthGTConstCost) - cost(s"{ $coll.append(OUTPUTS).size > 0 }")( - selectField + accessBox * tx.outputs.length + - accessBox * tx.outputs.length * 2 + collToColl + LengthGTConstCost) + // cost(s"{ $collBytes.patch(1, Coll(3.toByte), 1).size > 0 }")( // AccessHeaderCost + constCost * 3 + concreteCollectionItemCost + collToColl + collToColl + LengthGTConstCost) cost(s"{ $collBytes.updated(0, 1.toByte).size > 0 }")( diff --git a/src/test/scala/sigmastate/FailingToProveSpec.scala b/sigmastate/src/test/scala/sigmastate/FailingToProveSpec.scala similarity index 100% rename from src/test/scala/sigmastate/FailingToProveSpec.scala rename to sigmastate/src/test/scala/sigmastate/FailingToProveSpec.scala diff --git a/src/test/scala/sigmastate/SoftForkabilitySpecification.scala b/sigmastate/src/test/scala/sigmastate/SoftForkabilitySpecification.scala similarity index 93% rename from src/test/scala/sigmastate/SoftForkabilitySpecification.scala rename to sigmastate/src/test/scala/sigmastate/SoftForkabilitySpecification.scala index 7aab722500..df252c6b67 100644 --- a/src/test/scala/sigmastate/SoftForkabilitySpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/SoftForkabilitySpecification.scala @@ -1,18 +1,18 @@ package sigmastate import org.ergoplatform._ -import org.ergoplatform.validation.ValidationRules.{CheckCostFunc, CheckCostFuncOperation, CheckDeserializedScriptIsSigmaProp, CheckTupleType, CheckValidOpCode, trySoftForkable, _} +import org.ergoplatform.validation.ValidationRules.{CheckValidOpCode, trySoftForkable, CheckCostFuncOperation, CheckTupleType, CheckCostFunc, CheckDeserializedScriptIsSigmaProp, _} import org.ergoplatform.validation._ import sigmastate.SPrimType.MaxPrimTypeCode import sigmastate.Values.ErgoTree.EmptyConstants -import sigmastate.Values.{ByteArrayConstant, ErgoTree, IntConstant, NotReadyValueInt, Tuple, UnparsedErgoTree, ValueCompanion} +import sigmastate.Values.{UnparsedErgoTree, NotReadyValueInt, ByteArrayConstant, Tuple, IntConstant, ErgoTree, ValueCompanion} import sigmastate.eval.Colls import sigmastate.helpers.{ErgoLikeContextTesting, ErgoLikeTestInterpreter, ErgoLikeTestProvingInterpreter} import sigmastate.interpreter.Interpreter.{ScriptNameProp, emptyEnv} -import sigmastate.interpreter.{ContextExtension, ProverResult} +import sigmastate.interpreter.{ProverResult, ContextExtension} import sigmastate.lang.Terms._ -import sigmastate.lang.exceptions.{CosterException, SerializerException} -import sigmastate.serialization.OpCodes.{LastConstantCode, OpCode, OpCodeExtra} +import sigmastate.lang.exceptions.{SerializerException, SigmaException, CosterException} +import sigmastate.serialization.OpCodes.{OpCodeExtra, LastConstantCode, OpCode} import sigmastate.serialization._ import sigmastate.utxo.{DeserializeContext, SelectField} import special.sigma.SigmaTestingData @@ -257,10 +257,12 @@ class SoftForkabilitySpecification extends SigmaTestingData { } property("CheckTupleType rule") { - val exp = SelectField(Tuple(IntConstant(1), IntConstant(2), IntConstant(3)), 3) + val tuple = Tuple(IntConstant(1), IntConstant(2), IntConstant(3)) + val exp = SelectField(tuple, 3) val v2vs = vs.updated(CheckTupleType.id, ReplacedRule(0)) checkRule(CheckTupleType, v2vs, { - IR.doCosting(emptyEnv, exp) + // simulate throwing of exception in + CheckTupleType.throwValidationException(new SigmaException(s"Invalid tuple type"), Array[IR.Elem[_]]()) }) } diff --git a/src/test/scala/sigmastate/TestingInterpreterSpecification.scala b/sigmastate/src/test/scala/sigmastate/TestingInterpreterSpecification.scala similarity index 99% rename from src/test/scala/sigmastate/TestingInterpreterSpecification.scala rename to sigmastate/src/test/scala/sigmastate/TestingInterpreterSpecification.scala index 046ebc1de9..28306ba7b9 100644 --- a/src/test/scala/sigmastate/TestingInterpreterSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/TestingInterpreterSpecification.scala @@ -4,7 +4,7 @@ import sigmastate.basics.DLogProtocol.{DLogProverInput, ProveDlog} import scorex.crypto.hash.Blake2b256 import sigmastate.Values._ import sigmastate.interpreter._ -import sigma.util.Extensions._ +import scalan.util.Extensions._ import Interpreter._ import sigmastate.lang.Terms._ import org.ergoplatform._ diff --git a/src/test/scala/sigmastate/crypto/GroupLawsSpecification.scala b/sigmastate/src/test/scala/sigmastate/crypto/GroupLawsSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/crypto/GroupLawsSpecification.scala rename to sigmastate/src/test/scala/sigmastate/crypto/GroupLawsSpecification.scala diff --git a/src/test/scala/sigmastate/crypto/SigningSpecification.scala b/sigmastate/src/test/scala/sigmastate/crypto/SigningSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/crypto/SigningSpecification.scala rename to sigmastate/src/test/scala/sigmastate/crypto/SigningSpecification.scala diff --git a/src/test/scala/sigmastate/eval/BasicOpsTests.scala b/sigmastate/src/test/scala/sigmastate/eval/BasicOpsTests.scala similarity index 67% rename from src/test/scala/sigmastate/eval/BasicOpsTests.scala rename to sigmastate/src/test/scala/sigmastate/eval/BasicOpsTests.scala index 76cd808ca8..718f611f4f 100644 --- a/src/test/scala/sigmastate/eval/BasicOpsTests.scala +++ b/sigmastate/src/test/scala/sigmastate/eval/BasicOpsTests.scala @@ -50,12 +50,6 @@ class BasicOpsTests extends FunSuite with ContractsTestkit with Matchers { SigmaDsl.byteArrayToBigInt(Colls.fromArray(Array.fill[Byte](500)(1))) } - def test(f: Context => Boolean, ctx: Context, expected: Boolean) = { - val contr = NoEnvContract(f) - val res = contr.canOpen(ctx) - res shouldBe expected - } - test("Coll.append") { val c1 = collection[Byte](1, 2) val c2 = collection[Byte](3, 4) @@ -67,28 +61,4 @@ class BasicOpsTests extends FunSuite with ContractsTestkit with Matchers { box.creationInfo._1 shouldBe a [Integer] } - case class Contract1(base64_pk1: String) extends SigmaContract { - override def builder: SigmaDslBuilder = new TestSigmaDslBuilder - override def canOpen(ctx: Context): Boolean = { - val pk: SigmaProp = SigmaDsl.PubKey(base64_pk1) - pk.isValid - } - } - - case class Contract2(base64_pkA: String, base64_pkB: String, base64_pkC: String) extends SigmaContract { - override def builder: SigmaDslBuilder = new TestSigmaDslBuilder - override def canOpen(ctx: Context): Boolean = { - val pkA: SigmaProp = SigmaDsl.PubKey(base64_pkA) - val pkB: SigmaProp = SigmaDsl.PubKey(base64_pkB) - val pkC: SigmaProp = SigmaDsl.PubKey(base64_pkC) - verifyZK(pkA || pkB || pkC) - } - } - - case class FriendContract(friend: Box) extends SigmaContract { - override def builder: SigmaDslBuilder = new TestSigmaDslBuilder - override def canOpen(ctx: Context): Boolean = {ctx.INPUTS.length == 2 && ctx.INPUTS(0).id == friend.id} - } - - } diff --git a/src/test/scala/sigmastate/eval/CompilerItTest.scala b/sigmastate/src/test/scala/sigmastate/eval/CompilerItTest.scala similarity index 95% rename from src/test/scala/sigmastate/eval/CompilerItTest.scala rename to sigmastate/src/test/scala/sigmastate/eval/CompilerItTest.scala index 81237a7c62..ddc7440f59 100644 --- a/src/test/scala/sigmastate/eval/CompilerItTest.scala +++ b/sigmastate/src/test/scala/sigmastate/eval/CompilerItTest.scala @@ -23,7 +23,6 @@ class CompilerItTest extends BaseCtxTests with LangTests with ExampleContracts with ErgoScriptTestkit { import IR._ import builder._ - import WArray._ import WOption._ import CollBuilder._ import SigmaDslBuilder._ @@ -32,8 +31,6 @@ class CompilerItTest extends BaseCtxTests import SigmaProp._ import CostedColl._ import CCostedColl._ - import WBigInteger._ - import WECPoint._ import BigInt._ import GroupElement._ import sigmastate.serialization.OpCodes._ @@ -109,8 +106,8 @@ class CompilerItTest extends BaseCtxTests import SigmaDslBuilder._ val p1Dsl = dslValue.SigmaProp(p1) val p2Dsl = dslValue.SigmaProp(p2) - val p1Sym: Rep[SigmaProp] = liftConst(p1Dsl) - val p2Sym: Rep[SigmaProp] = liftConst(p2Dsl) + val p1Sym: Ref[SigmaProp] = liftConst(p1Dsl) + val p2Sym: Ref[SigmaProp] = liftConst(p2Dsl) Case(env, "andSigmaPropConsts", "p1 && p2", ergoCtx, calc = {_ => dsl.allZK(colBuilder.fromItems(p1Sym, p2Sym)) }, cost = null, @@ -136,7 +133,7 @@ class CompilerItTest extends BaseCtxTests // {_ => // val arr = liftConst(bigIntArr1) // val opType = SFunc(Vector(SBigInt,SBigInt), SBigInt) -// val f = fun { in: Rep[(Int, Long)] => +// val f = fun { in: Ref[(Int, Long)] => // val Pair(c, s) = in // val c1 = c + constCost[WBigInteger] + costOf("+", opType) // val c2 = costOf("+_per_item", opType) * ((s max sizeOf(liftConst(n1))) + 1L).toInt @@ -245,16 +242,16 @@ class CompilerItTest extends BaseCtxTests val env = envCF ++ Seq("projectPubKey" -> projectPK, "backerPubKey" -> backerPK) Case(env, "crowdFunding_Case", crowdFundingScript, ergoCtx, - { ctx: Rep[Context] => + { ctx: Ref[Context] => val backerPubKey = liftConst(dslValue.SigmaProp(backerPK)) val projectPubKey = liftConst(dslValue.SigmaProp(projectPK)) - val c1 = dsl.sigmaProp(ctx.HEIGHT >= toRep(timeout)).asRep[SigmaProp] && backerPubKey - val c2 = dsl.sigmaProp(dsl.allOf(colBuilder.fromItems( + val c1 = asRep[SigmaProp](dsl.sigmaProp(ctx.HEIGHT >= toRep(timeout))) && backerPubKey + val c2 = asRep[SigmaProp](dsl.sigmaProp(dsl.allOf(colBuilder.fromItems( ctx.HEIGHT < toRep(timeout), ctx.OUTPUTS.exists(fun { out => out.value >= toRep(minToRaise) lazy_&& Thunk(out.propositionBytes === projectPubKey.propBytes) })) - )).asRep[SigmaProp] && projectPubKey + ))) && projectPubKey (c1 || c2) }, cost = null, diff --git a/src/test/scala/sigmastate/eval/CostAccumulatorTests.scala b/sigmastate/src/test/scala/sigmastate/eval/CostAccumulatorTests.scala similarity index 70% rename from src/test/scala/sigmastate/eval/CostAccumulatorTests.scala rename to sigmastate/src/test/scala/sigmastate/eval/CostAccumulatorTests.scala index dcf1150d10..49359c7fd0 100644 --- a/src/test/scala/sigmastate/eval/CostAccumulatorTests.scala +++ b/sigmastate/src/test/scala/sigmastate/eval/CostAccumulatorTests.scala @@ -14,7 +14,7 @@ class CostAccumulatorTest extends SigmaTestingCommons { suite => import Liftables._ /** Take graph building lambda, compile it and apply to the given arg */ - def run[ST, T](name: String, fLam: Rep[T] => Rep[Int], x: ST, expectedRes: Int)(implicit lT: Liftable[ST,T]): Unit = { + def run[ST, T](name: String, fLam: Ref[T] => Ref[Int], x: ST, expectedRes: Int)(implicit lT: Liftable[ST,T]): Unit = { val fSym = fun(fLam)(Lazy(lT.eW)) emit(name, fSym) // save graph to file val f = IR.compile(getDataEnv, fSym, None) @@ -23,11 +23,11 @@ class CostAccumulatorTest extends SigmaTestingCommons { suite => } def run2[ST, T, SU, U](name: String, - fLam: (Rep[T], Rep[U]) => Rep[Int], x: (ST, SU), expectedRes: Int) + fLam: (Ref[T], Ref[U]) => Ref[Int], x: (ST, SU), expectedRes: Int) (implicit lT: Liftable[ST, T], lU: Liftable[SU, U]): Unit = { implicit val eT = lT.eW implicit val eU = lU.eW - val fSym = fun((p: Rep[(T,U)]) => fLam(p._1, p._2)) + val fSym = fun((p: Ref[(T,U)]) => fLam(p._1, p._2)) emit(name, fSym) // save graph to file val f = IR.compile(getDataEnv, fSym, None) val (y, _) = f(x) @@ -46,82 +46,82 @@ class CostAccumulatorTest extends SigmaTestingCommons { suite => * S - the value is skipped and not added to the current cost */ property("CostAccumulator single OpCode") { - run("opCost_const", { _: Rep[Int] => + run("opCost_const", { _: Ref[Int] => opCost(v1, Nil, 5/*+,M*/) }, 0/*not used*/, 5) // cost = 5 - run("opCost_arg_const", { _: Rep[Int] => + run("opCost_arg_const", { _: Ref[Int] => opCost(v1, Seq(4/*+4,M*/), 6/*+6*/) // cost = 10 }, 0/*not used*/, 10) - run("opCost_arg_and_const", { _: Rep[Int] => + run("opCost_arg_and_const", { _: Ref[Int] => opCost(v1, Seq(5/*+,M*/), 10/*+*/) // cost = 15 }, 0/*not used*/, 15) - run("opCost_id", { x: Rep[Int] => opCost(v1, Nil, x/*+*/) }, 10, 10) - run("opCost_const_id", { x: Rep[Int] => opCost(v1, Seq(5/*+,M*/), x/*+*/) }, 10, 15) - run2("opCost_const_id2", { (x: Rep[Int], y: Rep[Int]) => opCost(v1, Seq(y), x) }, (10, 5), 15) + run("opCost_id", { x: Ref[Int] => opCost(v1, Nil, x/*+*/) }, 10, 10) + run("opCost_const_id", { x: Ref[Int] => opCost(v1, Seq(5/*+,M*/), x/*+*/) }, 10, 15) + run2("opCost_const_id2", { (x: Ref[Int], y: Ref[Int]) => opCost(v1, Seq(y), x) }, (10, 5), 15) - run("opCost_id_const", { x: Rep[Int] => opCost(v1, Seq(x), 6) }, 10, 16) - run2("opCost_const_id2", { (x: Rep[Int], y: Rep[Int]) => opCost(v1, Seq(x), y) }, (10, 6), 16) + run("opCost_id_const", { x: Ref[Int] => opCost(v1, Seq(x), 6) }, 10, 16) + run2("opCost_const_id2", { (x: Ref[Int], y: Ref[Int]) => opCost(v1, Seq(x), y) }, (10, 6), 16) - an[TestFailedException] should be thrownBy run("opCost_arg_id", { x: Rep[Int] => opCost(v1, Seq(x), x) }, 10, 10) + an[TestFailedException] should be thrownBy run("opCost_arg_id", { x: Ref[Int] => opCost(v1, Seq(x), x) }, 10, 10) - run("opCost_two_args", { x: Rep[Int] => opCost(v1, Seq(x, x), 5) }, 10, 15) - run2("opCost_two_args_2", { (x: Rep[Int], y: Rep[Int]) => opCost(v1, Seq(x, x), y) }, (10, 5), 15) + run("opCost_two_args", { x: Ref[Int] => opCost(v1, Seq(x, x), 5) }, 10, 15) + run2("opCost_two_args_2", { (x: Ref[Int], y: Ref[Int]) => opCost(v1, Seq(x, x), y) }, (10, 5), 15) - an[TestFailedException] should be thrownBy run2("opCost_two_args_3", { (x: Rep[Int], y: Rep[Int]) => opCost(v1, Seq(x, y), y) }, (10, 5), 15) + an[TestFailedException] should be thrownBy run2("opCost_two_args_3", { (x: Ref[Int], y: Ref[Int]) => opCost(v1, Seq(x, y), y) }, (10, 5), 15) - run2("opCost_two_args_4", { (x: Rep[Int], y: Rep[Int]) => opCost(v1, Seq(x, y), x + y) }, (10, 5), 30) + run2("opCost_two_args_4", { (x: Ref[Int], y: Ref[Int]) => opCost(v1, Seq(x, y), x + y) }, (10, 5), 30) } property("CostAccumulator two OpCode") { - run("2xOpCost_1", { _: Rep[Int] => - val c0: Rep[Int] = 5 // const node + run("2xOpCost_1", { _: Ref[Int] => + val c0: Ref[Int] = 5 // const node val c1 = opCost(v1, Nil, c0/*+*/) // cost = 5 val c2 = opCost(v2, Nil, c0/*+*/) // cost = 10 c1 + c2 }, 10, 15) - run("2xOpCost_2", { x: Rep[Int] => + run("2xOpCost_2", { x: Ref[Int] => val c1 = opCost(v1, Nil, x/*+*/) // cost = 10 val c2 = opCost(v2, Nil, x/*+*/) // cost = 20 c1 + c2 }, 10, 30) - run("2xOpCost_3", { x: Rep[Int] => + run("2xOpCost_3", { x: Ref[Int] => val c1 = opCost(v1, Nil, x/*+*/) // cost = 10, c1 marked opCost(v2, Seq(c1), x/*+*/) // cost = 20 }, 10, 20) - run("2xOpCost_4", { x: Rep[Int] => + run("2xOpCost_4", { x: Ref[Int] => val c1 = opCost(v1, Nil, x/*+*/) // cost = 10, c1 marked opCost(v2, Nil, c1) // cost = 10 because c1 is marked }, 10, 10) - run("2xOpCost_5", { x: Rep[Int] => - val c0: Rep[Int] = 5 // const node + run("2xOpCost_5", { x: Ref[Int] => + val c0: Ref[Int] = 5 // const node val c1 = opCost(v1, Seq(c0/*+,M*/), x/*+*/) // cost = 15 opCost(v2, Nil, c1) // cost = 15 because c1 is marked }, 10, 15) - run2("2xOpCost_6", { (x: Rep[Int], y: Rep[Int]) => + run2("2xOpCost_6", { (x: Ref[Int], y: Ref[Int]) => val c1 = opCost(v1, Seq(y/*+,M*/), x/*+*/) // cost = 15 opCost(v2, Nil, c1) // cost = 15 because c1 is marked }, (10, 5), 15) - run2("2xOpCost_7", { (x: Rep[Int], y: Rep[Int]) => + run2("2xOpCost_7", { (x: Ref[Int], y: Ref[Int]) => val c1 = opCost(v1, Seq(y/*+,M*/), x/*+*/) // cost = 15 opCost(v2, Seq(x/*+,M*/), c1/*S*/) // cost = 25 because x is not marked }, (10, 5), 25) } property("CostAccumulator three OpCode") { - run2("3xOpCost_1", { (x: Rep[Int], y: Rep[Int]) => - val c0: Rep[Int] = 5 // const node + run2("3xOpCost_1", { (x: Ref[Int], y: Ref[Int]) => + val c0: Ref[Int] = 5 // const node val o1 = opCost(v1, Seq(x/*+10,M*/), c0/*+5*/) // cost = 15 val o2 = opCost(v2, Seq(c0/*+5,M*/, x/*S*/, o1/*S*/), y/*+5*/) // cost = 25 opCost(v3, Seq(y/*+5,M*/, o2/*S*/), c0/*S*/) // cost = 30 }, (10, 5), 30) // o1 is used in OpCost.args - run2("3xOpCost_2", { (x: Rep[Int], _: Rep[Int]) => - val c0: Rep[Int] = 5 // const node + run2("3xOpCost_2", { (x: Ref[Int], _: Ref[Int]) => + val c0: Ref[Int] = 5 // const node val o1 = opCost(v1, Nil, c0/*+5*/) // cost = 5 val o2 = opCost(v2, Seq(o1/*S*/), x/*+10*/) // cost = 15 val o3 = opCost(v3, Seq(o1/*S*/, o2/*S*/), c0/*+5*/) // cost = 20 @@ -129,8 +129,8 @@ class CostAccumulatorTest extends SigmaTestingCommons { suite => }, (10, 5), 60) // same as above but using y - run2("3xOpCost_3", { (x: Rep[Int], y: Rep[Int]) => - val c0: Rep[Int] = 5 // const node + run2("3xOpCost_3", { (x: Ref[Int], y: Ref[Int]) => + val c0: Ref[Int] = 5 // const node val o1 = opCost(v1, Nil, c0/*+5*/) // cost = 5 val o2 = opCost(v2, Seq(o1/*S*/), x/*+10*/) // cost = 15 val o3 = opCost(v3, Seq(o1/*S*/, o2/*S*/), y/*+5*/) // cost = 20 @@ -138,8 +138,8 @@ class CostAccumulatorTest extends SigmaTestingCommons { suite => }, (10, 5), 60) // o1 is used in outside OpCost - run2("3xOpCost_4", { (x: Rep[Int], y: Rep[Int]) => - val c0: Rep[Int] = 5 // const node + run2("3xOpCost_4", { (x: Ref[Int], y: Ref[Int]) => + val c0: Ref[Int] = 5 // const node val o1 = opCost(v1, Nil, c0/*+5*/) // cost = 5, value = 5 val o2 = opCost(v2, Seq(o1/*S*/), x/*+10*/) // cost = 15 val o3 = opCost(v3, Seq(o1/*S*/, o2/*S*/), y/*+5*/) // cost = 20 @@ -147,8 +147,8 @@ class CostAccumulatorTest extends SigmaTestingCommons { suite => }, (10, 5), 100) // same as above but o1 is used in OpCost.opCost - run2("3xOpCost_5", { (x: Rep[Int], y: Rep[Int]) => - val c0: Rep[Int] = 5 // const node + run2("3xOpCost_5", { (x: Ref[Int], y: Ref[Int]) => + val c0: Ref[Int] = 5 // const node val o1 = opCost(v1, Nil, c0/*+5*/) // cost = 5, value = 5 val o2 = opCost(v2, Seq(o1/*S*/), x/*+10*/) // cost = 15 val o3 = opCost(v3, Seq(o1/*S*/, o2/*S*/), y + o1/*+10*/) // cost = 25 @@ -160,25 +160,25 @@ class CostAccumulatorTest extends SigmaTestingCommons { suite => property("unfolding lambda into thunk") { // the following two tests check cost equivalence under lambda unfolding // with unfolding - run("lambda_1", { y: Rep[Int] => - val c0: Rep[Int] = 5 // const node - val c1: Rep[Int] = 6 // const node - val f1 = fun { x: Rep[Int] => + run("lambda_1", { y: Ref[Int] => + val c0: Ref[Int] = 5 // const node + val c1: Ref[Int] = 6 // const node + val f1 = fun { x: Ref[Int] => opCost(v1, Seq(x/*+5,M*/, y/*+5,M*/), c1/*+6*/) // cost = 16 } // unfold f1 into thunk (this is staging time operation, there is no lambda in the final graph) - val t1: Rep[Int] = ThunkForce(Thunk(f1(c0))) // value = 16 + val t1: Ref[Int] = ThunkForce(Thunk(f1(c0))) // value = 16 opCost(v2, Seq(t1/*+16,M*/, y/*+5*/), c0/*+5*/) // cost = 26 }, 5, 26) // without unfolding f1 - run("lambda_2", { y: Rep[Int] => - val c0: Rep[Int] = 5 // const node - val f1 = fun { x: Rep[Int] => + run("lambda_2", { y: Ref[Int] => + val c0: Ref[Int] = 5 // const node + val f1 = fun { x: Ref[Int] => opCost(v1, Seq(x/*+5,M*/, y/*+5,M*/), c0/*+5*/) // cost = 15 } // reify application without unfolding f1 (the lambda is called at runtime) - val t1: Rep[Int] = Apply(f1, c0, false) // value = 15 + val t1: Ref[Int] = Apply(f1, c0, false) // value = 15 opCost(v2, Seq(t1/*+15,M*/, y/*+5*/), c0/*+5*/) // cost = 25 }, 5, 25) } @@ -186,24 +186,24 @@ class CostAccumulatorTest extends SigmaTestingCommons { suite => property("unfolding collision") { // the following two tests check cost equivalence under lambda unfolding // with unfolding - run("collision_1", { y: Rep[Int] => - val c0: Rep[Int] = 5 // const node - val f1 = fun { x: Rep[Int] => + run("collision_1", { y: Ref[Int] => + val c0: Ref[Int] = 5 // const node + val f1 = fun { x: Ref[Int] => opCost(v1, Seq(x/*+5,M*/, c0/*S*/), y/*+5*/) // cost = 10, c0 is skipped due to collision with x after unfold } // unfold f1 into thunk (this is staging time operation, there is no lambda in the final graph) - val t1: Rep[Int] = ThunkForce(Thunk(f1(c0))) // value = 10 + val t1: Ref[Int] = ThunkForce(Thunk(f1(c0))) // value = 10 opCost(v2, Seq(t1/*+10,M*/, y/*+5*/), c0/*+5*/) // cost = 20 }, 5, 20) // without unfolding f1 - run("collision_2", { y: Rep[Int] => - val c0: Rep[Int] = 5 // const node - val f1 = fun { x: Rep[Int] => + run("collision_2", { y: Ref[Int] => + val c0: Ref[Int] = 5 // const node + val f1 = fun { x: Ref[Int] => opCost(v1, Seq(x/*+5,M*/, c0/*+5,M*/), y/*+5*/) // cost = 15 } // reify application without unfolding f1 (the lambda is called at runtime) - val t1: Rep[Int] = Apply(f1, c0, false) // value = 15 + val t1: Ref[Int] = Apply(f1, c0, false) // value = 15 opCost(v2, Seq(t1/*+15,M*/, y/*+5*/), c0/*+5*/) // cost = 25 }, 5, 25) } diff --git a/src/test/scala/sigmastate/eval/CostingTest.scala b/sigmastate/src/test/scala/sigmastate/eval/CostingTest.scala similarity index 93% rename from src/test/scala/sigmastate/eval/CostingTest.scala rename to sigmastate/src/test/scala/sigmastate/eval/CostingTest.scala index ee8364a766..91904896a2 100644 --- a/src/test/scala/sigmastate/eval/CostingTest.scala +++ b/sigmastate/src/test/scala/sigmastate/eval/CostingTest.scala @@ -26,10 +26,7 @@ class CostingTest extends BaseCtxTests with LangTests with ExampleContracts with new TestContext with IRContext with CompiletimeCosting { } import IR._ - import WArray._ - import WECPoint._ import GroupElement._ - import WBigInteger._ import BigInt._ import Context._; import SigmaContract._ import Cost._; import CollBuilder._; import Coll._; import Box._; import SigmaProp._; @@ -129,7 +126,7 @@ class CostingTest extends BaseCtxTests with LangTests with ExampleContracts with test("context data") { // check("var1", "getVar[BigInt](1)", ctx => ctx.getVar[BigInteger](1.toByte), _ => 1) - def plus[T: Elem](x: Rep[T], y: Rep[T]) = ApplyBinOp(opcodeToEndoBinOp(OpCodes.PlusCode, element[T]), x, y) + def plus[T: Elem](x: Ref[T], y: Ref[T]) = ApplyBinOp(opcodeToEndoBinOp(OpCodes.PlusCode, element[T]), x, y) check("height1", "HEIGHT + 1", ctx => plus(ctx.HEIGHT, 1)) check("height2", "HEIGHT > 1", ctx => ctx.HEIGHT > 1) check("size", "INPUTS.size + OUTPUTS.size", ctx => { plus(ctx.INPUTS.length, ctx.OUTPUTS.length) }) @@ -149,13 +146,13 @@ class CostingTest extends BaseCtxTests with LangTests with ExampleContracts with ignore("lambdas") { check("lam1", "{ (out: Box) => out.value >= 0L }", - ctx => fun { out: Rep[Box] => out.value >= 0L }, null, {_ => 8L}) + ctx => fun { out: Ref[Box] => out.value >= 0L }, null, {_ => 8L}) check("lam2", "{ val f = { (out: Box) => out.value >= 0L }; f }", - ctx => fun { out: Rep[Box] => out.value >= 0L }, null, {_ => 8L}) + ctx => fun { out: Ref[Box] => out.value >= 0L }, null, {_ => 8L}) check("lam3", "{ val f = { (out: Box) => out.value >= 0L }; f(SELF) }", - ctx => { val f = fun { out: Rep[Box] => out.value >= 0L }; Apply(f, ctx.SELF, false) }) + ctx => { val f = fun { out: Ref[Box] => out.value >= 0L }; Apply(f, ctx.SELF, false) }) check("lam4", "{ def f(out: Box) = out.value >= 0L ; f }", - ctx => fun { out: Rep[Box] => out.value >= 0L }, null, {_ => 8L}) + ctx => fun { out: Ref[Box] => out.value >= 0L }, null, {_ => 8L}) } test("if then else") { @@ -170,17 +167,17 @@ class CostingTest extends BaseCtxTests with LangTests with ExampleContracts with val env = envCF ++ Seq("projectPubKey" -> projectPK, "backerPubKey" -> backerPK) checkInEnv(env, "CrowdFunding", crowdFundingScript, - { ctx: Rep[Context] => + { ctx: Ref[Context] => val backerPubKey = liftConst(dslValue.SigmaProp(backerPK)) val projectPubKey = liftConst(dslValue.SigmaProp(projectPK)) val projectBytes = projectPubKey.propBytes - val c1 = dsl.sigmaProp(ctx.HEIGHT >= toRep(timeout)).asRep[SigmaProp] && backerPubKey - val c2 = dsl.sigmaProp(dsl.allOf(colBuilder.fromItems( + val c1 = asRep[SigmaProp](dsl.sigmaProp(ctx.HEIGHT >= toRep(timeout))) && backerPubKey + val c2 = asRep[SigmaProp](dsl.sigmaProp(dsl.allOf(colBuilder.fromItems( ctx.HEIGHT < toRep(timeout), ctx.OUTPUTS.exists(fun { out => out.value >= toRep(minToRaise) lazy_&& Thunk(out.propositionBytes === projectBytes) })) - )).asRep[SigmaProp] && projectPubKey + ))) && projectPubKey (c1 || c2) } ) @@ -200,7 +197,7 @@ class CostingTest extends BaseCtxTests with LangTests with ExampleContracts with } println("Warming up ...") - var res: Rep[Any] = null + var res: Ref[Any] = null for (i <- 1 to 1000) res = eval(i) @@ -229,7 +226,7 @@ class CostingTest extends BaseCtxTests with LangTests with ExampleContracts with } test("measure: costed context data") { - var res: Rep[Any] = null + var res: Ref[Any] = null measure(2) { j => // 10 warm up iterations when j == 0 measure(j*1000 + 10, false) { i => res = check("", s"INPUTS.size + OUTPUTS.size + $i", null diff --git a/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala b/sigmastate/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala similarity index 83% rename from src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala rename to sigmastate/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala index 46c200903f..04ce2f5eb5 100644 --- a/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala +++ b/sigmastate/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala @@ -31,7 +31,6 @@ trait ErgoScriptTestkit extends ContractsTestkit with LangTests import Liftables._ import Context._ import Size._ -// import WBigInteger._ import BigInt._ lazy val compiler = new SigmaCompiler(TestnetNetworkPrefix, IR.builder) @@ -53,8 +52,6 @@ trait ErgoScriptTestkit extends ContractsTestkit with LangTests lazy val boxA1 = newAliceBox(1, 100) lazy val boxA2 = newAliceBox(2, 200) - def contract(canOpen: DContext => Boolean) = new NoEnvContract(canOpen) - lazy val dsl = sigmaDslBuilder lazy val dslValue = sigmaDslBuilderValue lazy val bigSym = liftConst(dslValue.BigInt(big)) @@ -110,9 +107,9 @@ trait ErgoScriptTestkit extends ContractsTestkit with LangTests script: Script, ergoCtx: Option[ErgoLikeContext] = None, testContract: Option[DContext => Any] = None, - expectedCalc: Option[Rep[Context] => Rep[Any]] = None, - expectedCost: Option[Rep[Context] => Rep[Int]] = None, - expectedSize: Option[Rep[Context] => Rep[Long]] = None, + expectedCalc: Option[Ref[Context] => Ref[Any]] = None, + expectedCost: Option[Ref[Context] => Ref[Int]] = None, + expectedSize: Option[Ref[Context] => Ref[Long]] = None, expectedTree: Option[SValue] = None, expectedResult: Result = NoResult, printGraphs: Boolean = true, @@ -133,7 +130,7 @@ trait ErgoScriptTestkit extends ContractsTestkit with LangTests } } - def checkExpectedFunc[A,B](block: => Rep[A => B], expected: Option[Rep[A => B]], messageFmt: String) = { + def checkExpectedFunc[A,B](block: => Ref[A => B], expected: Option[Ref[A => B]], messageFmt: String) = { if (expected.isDefined) { val x = block assert(alphaEqual(x, expected.get), messageFmt) @@ -146,24 +143,19 @@ trait ErgoScriptTestkit extends ContractsTestkit with LangTests case _ => Pair(xs.head, pairify(xs.tail)) } - def doCosting: Rep[(Context => Any, (Size[Context] => Int, Size[Context] => Long))] = { + def doCosting: Ref[(Context => Any, (Size[Context] => Int, Size[Context] => Long))] = { val costed = cost[Any](env, tree) val calcF = costed.sliceCalc val costF = fun { sCtx: RSize[Context] => costed.sliceCost(Pair(0, sCtx)) } val sizeF = fun { sCtx: RSize[Context] => costed.sliceSize(sCtx).dataSize } - val res = Tuple(calcF, costF, sizeF) + val res = Pair(calcF, Pair(costF, sizeF)) if (printGraphs) { - val str = struct( - "calc" -> calcF, - "cost" -> costF, - "size" -> sizeF - ) - val strExp = struct( - expectedCalcF.map("calc" -> _).toSeq ++ - expectedCostF.map("cost" -> _).toSeq ++ - expectedSizeF.map("size" -> _).toSeq - ) - val graphs = Seq(str, strExp) + val str = Pair(calcF, Pair(costF, sizeF)) + val strExp = + expectedCalcF.toSeq ++ + expectedCostF.toSeq ++ + expectedSizeF.toSeq + val graphs = str +: strExp emit(name, graphs:_*) } checkExpectedFunc(calcF, expectedCalcF, "Calc function actual: %s, expected: %s") @@ -178,7 +170,7 @@ trait ErgoScriptTestkit extends ContractsTestkit with LangTests verifyIsProven(calcF) shouldBe Success(()) if (expectedTree.isDefined) { - val compiledProp = IR.buildTree(calcF.asRep[Context => SType#WrappedType]) + val compiledProp = IR.buildTree(asRep[Context => SType#WrappedType](calcF)) checkExpected(compiledProp, expectedTree, "Compiled Tree actual: %s, expected: %s") val ergoTree = compiledProp.treeWithSegregation @@ -200,7 +192,7 @@ trait ErgoScriptTestkit extends ContractsTestkit with LangTests // check size { - val lA = sizeF.elem.eDom.liftable.asLiftable[SSize[SContext], Size[Context]] + val lA = asLiftable[SSize[SContext], Size[Context]](sizeF.elem.eDom.liftable) val sizeFun = IR.compile[SSize[SContext], Long, Size[Context], Long](getDataEnv, sizeF)(lA, liftable[Long, Long]) val estimatedSize = sizeFun(Sized.sizeOf(costCtx)) checkExpected(estimatedSize, expectedResult.size, @@ -209,8 +201,8 @@ trait ErgoScriptTestkit extends ContractsTestkit with LangTests } // check calc - val lA = calcF.elem.eDom.liftable.asLiftable[SContext, Context] - val lB = calcF.elem.eRange.liftable.asLiftable[Any, Any] + val lA = asLiftable[SContext, Context](calcF.elem.eDom.liftable) + val lB = asLiftable[Any, Any](calcF.elem.eRange.liftable) val valueFun = IR.compile(getDataEnv, calcF)(lA, lB) val (res, _) = valueFun(calcCtx) checkExpected(res, expectedResult.calc, @@ -220,9 +212,9 @@ trait ErgoScriptTestkit extends ContractsTestkit with LangTests } def Case(env: ScriptEnv, name: String, script: String, ctx: ErgoLikeContext, - calc: Rep[Context] => Rep[Any], - cost: Rep[Context] => Rep[Int], - size: Rep[Context] => Rep[Long], + calc: Ref[Context] => Ref[Any], + cost: Ref[Context] => Ref[Int], + size: Ref[Context] => Ref[Long], tree: SValue, result: Result) = EsTestCase(name, env, Code(script), Option(ctx), None, @@ -230,9 +222,9 @@ trait ErgoScriptTestkit extends ContractsTestkit with LangTests Option(tree), result) def checkAll(env: ScriptEnv, name: String, script: String, ergoCtx: ErgoLikeContext, - calc: Rep[Context] => Rep[Any], - cost: Rep[Context] => Rep[Int], - size: Rep[Context] => Rep[Long], + calc: Ref[Context] => Ref[Any], + cost: Ref[Context] => Ref[Int], + size: Ref[Context] => Ref[Long], tree: SValue, result: Result): Unit = { @@ -241,11 +233,11 @@ trait ErgoScriptTestkit extends ContractsTestkit with LangTests } def checkInEnv(env: ScriptEnv, name: String, script: String, - expectedCalc: Rep[Context] => Rep[Any], - expectedCost: Rep[Context] => Rep[Int] = null, - expectedSize: Rep[Context] => Rep[Long] = null, + expectedCalc: Ref[Context] => Ref[Any], + expectedCost: Ref[Context] => Ref[Int] = null, + expectedSize: Ref[Context] => Ref[Long] = null, printGraphs: Boolean = true - ): Rep[(Context => Any, (Size[Context] => Int, Size[Context] => Long))] = + ): Ref[(Context => Any, (Size[Context] => Int, Size[Context] => Long))] = { val tc = EsTestCase(name, env, Code(script), None, None, Option(expectedCalc), @@ -256,11 +248,11 @@ trait ErgoScriptTestkit extends ContractsTestkit with LangTests } def check(name: String, script: String, - expectedCalc: Rep[Context] => Rep[Any], - expectedCost: Rep[Context] => Rep[Int] = null, - expectedSize: Rep[Context] => Rep[Long] = null, + expectedCalc: Ref[Context] => Ref[Any], + expectedCost: Ref[Context] => Ref[Int] = null, + expectedSize: Ref[Context] => Ref[Long] = null, printGraphs: Boolean = true - ): Rep[(Context => Any, (Size[Context] => Int, Size[Context] => Long))] = + ): Ref[(Context => Any, (Size[Context] => Int, Size[Context] => Long))] = { checkInEnv(Map(), name, script, expectedCalc, expectedCost, expectedSize, printGraphs) } @@ -275,7 +267,7 @@ trait ErgoScriptTestkit extends ContractsTestkit with LangTests tcase.doReduce() } - def compileAndCost[T](env: ScriptEnv, code: String): Rep[Costed[Context] => Costed[T]] = { + def compileAndCost[T](env: ScriptEnv, code: String): Ref[Costed[Context] => Costed[T]] = { val typed = compiler.typecheck(env, code) cost[T](env, typed) } diff --git a/src/test/scala/sigmastate/eval/ErgoTreeBuildingTest.scala b/sigmastate/src/test/scala/sigmastate/eval/ErgoTreeBuildingTest.scala similarity index 96% rename from src/test/scala/sigmastate/eval/ErgoTreeBuildingTest.scala rename to sigmastate/src/test/scala/sigmastate/eval/ErgoTreeBuildingTest.scala index 421c010c41..65f3845ac5 100644 --- a/src/test/scala/sigmastate/eval/ErgoTreeBuildingTest.scala +++ b/sigmastate/src/test/scala/sigmastate/eval/ErgoTreeBuildingTest.scala @@ -102,9 +102,9 @@ class ErgoTreeBuildingTest extends BaseCtxTests BoolToSigmaProp(AND(Vector( LT(Height,IntConstant(100)), Exists(Outputs, FuncValue(Vector((2,SBox)), - BinAnd( - GE(ExtractAmount(ValUse(2,SBox)),LongConstant(1000)), - EQ(ExtractScriptBytes(ValUse(2,SBox)), SigmaPropBytes(ValUse(1,SSigmaProp))))) + BinAnd( + GE(ExtractAmount(ValUse(2,SBox)),LongConstant(1000)), + EQ(ExtractScriptBytes(ValUse(2,SBox)), SigmaPropBytes(ValUse(1,SSigmaProp))))) )))), ValUse(1,SSigmaProp) )))))) diff --git a/src/test/scala/sigmastate/eval/EvaluationTest.scala b/sigmastate/src/test/scala/sigmastate/eval/EvaluationTest.scala similarity index 100% rename from src/test/scala/sigmastate/eval/EvaluationTest.scala rename to sigmastate/src/test/scala/sigmastate/eval/EvaluationTest.scala diff --git a/src/test/scala/sigmastate/eval/ExampleContracts.scala b/sigmastate/src/test/scala/sigmastate/eval/ExampleContracts.scala similarity index 100% rename from src/test/scala/sigmastate/eval/ExampleContracts.scala rename to sigmastate/src/test/scala/sigmastate/eval/ExampleContracts.scala diff --git a/src/test/scala/sigmastate/eval/MeasureIRContext.scala b/sigmastate/src/test/scala/sigmastate/eval/MeasureIRContext.scala similarity index 100% rename from src/test/scala/sigmastate/eval/MeasureIRContext.scala rename to sigmastate/src/test/scala/sigmastate/eval/MeasureIRContext.scala diff --git a/src/test/scala/sigmastate/eval/SizedTests.scala b/sigmastate/src/test/scala/sigmastate/eval/SizedTests.scala similarity index 100% rename from src/test/scala/sigmastate/eval/SizedTests.scala rename to sigmastate/src/test/scala/sigmastate/eval/SizedTests.scala diff --git a/src/test/scala/sigmastate/helpers/ContextEnrichingProverInterpreter.scala b/sigmastate/src/test/scala/sigmastate/helpers/ContextEnrichingProverInterpreter.scala similarity index 100% rename from src/test/scala/sigmastate/helpers/ContextEnrichingProverInterpreter.scala rename to sigmastate/src/test/scala/sigmastate/helpers/ContextEnrichingProverInterpreter.scala diff --git a/src/test/scala/sigmastate/helpers/ContextEnrichingTestProvingInterpreter.scala b/sigmastate/src/test/scala/sigmastate/helpers/ContextEnrichingTestProvingInterpreter.scala similarity index 100% rename from src/test/scala/sigmastate/helpers/ContextEnrichingTestProvingInterpreter.scala rename to sigmastate/src/test/scala/sigmastate/helpers/ContextEnrichingTestProvingInterpreter.scala diff --git a/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala b/sigmastate/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala similarity index 91% rename from src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala rename to sigmastate/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala index dcdafbf166..257fda7902 100644 --- a/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala +++ b/sigmastate/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala @@ -2,14 +2,14 @@ package sigmastate.helpers import org.ergoplatform.SigmaConstants.ScriptCostLimit import org.ergoplatform.ErgoLikeContext.Height -import org.ergoplatform.{ErgoBox, ErgoBoxReader, ErgoLikeContext, ErgoLikeTransaction, ErgoLikeTransactionTemplate, UnsignedInput} -import org.ergoplatform.validation.{SigmaValidationSettings, ValidationRules} +import org.ergoplatform._ +import org.ergoplatform.validation.{ValidationRules, SigmaValidationSettings} import sigmastate.AvlTreeData import sigmastate.eval._ import sigmastate.interpreter.{ContextExtension, CryptoConstants} -import sigmastate.serialization.{GroupElementSerializer, SigmaSerializer} +import sigmastate.serialization.{SigmaSerializer, GroupElementSerializer} import special.collection.Coll -import special.sigma.{Box, Header, PreHeader} +import special.sigma.{Box, PreHeader, Header} import scala.util.Try diff --git a/src/test/scala/sigmastate/helpers/ErgoLikeTestProvingInterpreter.scala b/sigmastate/src/test/scala/sigmastate/helpers/ErgoLikeTestProvingInterpreter.scala similarity index 100% rename from src/test/scala/sigmastate/helpers/ErgoLikeTestProvingInterpreter.scala rename to sigmastate/src/test/scala/sigmastate/helpers/ErgoLikeTestProvingInterpreter.scala diff --git a/src/test/scala/sigmastate/helpers/ErgoLikeTransactionTesting.scala b/sigmastate/src/test/scala/sigmastate/helpers/ErgoLikeTransactionTesting.scala similarity index 100% rename from src/test/scala/sigmastate/helpers/ErgoLikeTransactionTesting.scala rename to sigmastate/src/test/scala/sigmastate/helpers/ErgoLikeTransactionTesting.scala diff --git a/src/test/scala/sigmastate/helpers/ErgoTransactionValidator.scala b/sigmastate/src/test/scala/sigmastate/helpers/ErgoTransactionValidator.scala similarity index 100% rename from src/test/scala/sigmastate/helpers/ErgoTransactionValidator.scala rename to sigmastate/src/test/scala/sigmastate/helpers/ErgoTransactionValidator.scala diff --git a/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala b/sigmastate/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala similarity index 98% rename from src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala rename to sigmastate/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala index 5d93c51210..9f9e6de88e 100644 --- a/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala +++ b/sigmastate/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala @@ -156,8 +156,8 @@ trait SigmaTestingCommons extends PropSpec val IR.Pair(calcF, _) = IR.doCosting[Any](env, interProp) val tree = IR.buildTree(calcF) checkSerializationRoundTrip(tree) - val lA = calcF.elem.eDom.liftable.asLiftable[SContext, IR.Context] - val lB = calcF.elem.eRange.liftable.asLiftable[Any, Any] + val lA = Liftables.asLiftable[SContext, IR.Context](calcF.elem.eDom.liftable) + val lB = Liftables.asLiftable[Any, Any](calcF.elem.eRange.liftable) val valueFun = IR.compile[SContext, Any, IR.Context, Any](IR.getDataEnv, calcF)(lA, lB) (in: A) => { diff --git a/src/test/scala/sigmastate/lang/LangTests.scala b/sigmastate/src/test/scala/sigmastate/lang/LangTests.scala similarity index 100% rename from src/test/scala/sigmastate/lang/LangTests.scala rename to sigmastate/src/test/scala/sigmastate/lang/LangTests.scala diff --git a/src/test/scala/sigmastate/lang/SigmaBinderTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaBinderTest.scala similarity index 100% rename from src/test/scala/sigmastate/lang/SigmaBinderTest.scala rename to sigmastate/src/test/scala/sigmastate/lang/SigmaBinderTest.scala diff --git a/src/test/scala/sigmastate/lang/SigmaBuilderTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaBuilderTest.scala similarity index 100% rename from src/test/scala/sigmastate/lang/SigmaBuilderTest.scala rename to sigmastate/src/test/scala/sigmastate/lang/SigmaBuilderTest.scala diff --git a/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala similarity index 97% rename from src/test/scala/sigmastate/lang/SigmaCompilerTest.scala rename to sigmastate/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala index b8dda3c5a4..fdcb3bdc7a 100644 --- a/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala +++ b/sigmastate/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala @@ -7,11 +7,11 @@ import sigmastate.Values._ import sigmastate._ import sigmastate.helpers.SigmaTestingCommons import sigmastate.interpreter.Interpreter.ScriptEnv -import sigmastate.lang.Terms.{Lambda, MethodCall, ZKProofBlock, Apply, Ident} +import sigmastate.lang.Terms.{Apply, Ident, Lambda, MethodCall, ZKProofBlock} import sigmastate.lang.exceptions.{CosterException, InvalidArguments, TyperException} import sigmastate.serialization.ValueSerializer import sigmastate.serialization.generators.ObjectGenerators -import sigmastate.utxo.{GetVar, ExtractAmount, ByIndex, SelectField} +import sigmastate.utxo.{ByIndex, ExtractAmount, GetVar, SelectField} import sigmastate.eval._ class SigmaCompilerTest extends SigmaTestingCommons with LangTests with ObjectGenerators { @@ -540,4 +540,13 @@ class SigmaCompilerTest extends SigmaTestingCommons with LangTests with ObjectGe property("xorOf") { comp("xorOf(Coll[Boolean](true, false))") shouldBe XorOf(Seq(TrueLeaf, FalseLeaf)) } + + property("substConst") { + comp("substConstants(getVar[Coll[Byte]](1).get, getVar[Coll[Int]](2).get, getVar[Coll[SigmaProp]](3).get)") shouldBe + SubstConstants( + GetVarByteArray(1).get, + GetVarIntArray(2).get, + GetVar(3.toByte, SCollection(SSigmaProp)).get + ) + } } diff --git a/src/test/scala/sigmastate/lang/SigmaParserTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaParserTest.scala similarity index 100% rename from src/test/scala/sigmastate/lang/SigmaParserTest.scala rename to sigmastate/src/test/scala/sigmastate/lang/SigmaParserTest.scala diff --git a/src/test/scala/sigmastate/lang/SigmaSpecializerTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaSpecializerTest.scala similarity index 100% rename from src/test/scala/sigmastate/lang/SigmaSpecializerTest.scala rename to sigmastate/src/test/scala/sigmastate/lang/SigmaSpecializerTest.scala diff --git a/src/test/scala/sigmastate/lang/SigmaTyperTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaTyperTest.scala similarity index 95% rename from src/test/scala/sigmastate/lang/SigmaTyperTest.scala rename to sigmastate/src/test/scala/sigmastate/lang/SigmaTyperTest.scala index 290fbebad3..d90492dddf 100644 --- a/src/test/scala/sigmastate/lang/SigmaTyperTest.scala +++ b/sigmastate/src/test/scala/sigmastate/lang/SigmaTyperTest.scala @@ -3,18 +3,20 @@ package sigmastate.lang import org.ergoplatform.ErgoAddressEncoder.TestnetNetworkPrefix import org.ergoplatform._ import org.scalatest.prop.PropertyChecks -import org.scalatest.{PropSpec, Matchers} +import org.scalatest.{Matchers, PropSpec} import sigmastate.SCollection._ import sigmastate.Values._ import sigmastate._ -import sigmastate.basics.DLogProtocol.ProveDlog +import sigmastate.basics.DLogProtocol.{DLogProverInput, ProveDlog} +import sigmastate.eval.Colls import sigmastate.interpreter.CryptoConstants import sigmastate.interpreter.Interpreter.ScriptEnv import sigmastate.lang.SigmaPredef._ import sigmastate.lang.Terms.Select import sigmastate.lang.exceptions.TyperException +import sigmastate.serialization.ErgoTreeSerializer import sigmastate.serialization.generators.ObjectGenerators -import sigmastate.utxo.{ExtractCreationInfo, Append} +import sigmastate.utxo.{Append, ExtractCreationInfo} class SigmaTyperTest extends PropSpec with PropertyChecks with Matchers with LangTests with ObjectGenerators { @@ -657,4 +659,27 @@ class SigmaTyperTest extends PropSpec with PropertyChecks with Matchers with Lan property("SGroupElement.exp") { typecheck(env, "g1.exp(1.toBigInt)") shouldBe SGroupElement } + + property("substConst") { + def script(pk: ProveDlog): SigmaPropValue = + AND(EQ(IntConstant(1), IntConstant(1)), SigmaPropConstant(pk).isProven).toSigmaProp + + val pk1 = DLogProverInput.random().publicImage + val pk2 = DLogProverInput.random().publicImage + val script1 = script(pk1) + val script2 = script(pk2) + val inputBytes = ErgoTreeSerializer.DefaultSerializer.serializeErgoTree(script1.treeWithSegregation) + val positions = IntArrayConstant(Array[Int](2)) + val newVals = ConcreteCollection(Vector[SigmaPropValue](SigmaPropConstant(pk2)), SSigmaProp) + + val expectedBytes = ErgoTreeSerializer.DefaultSerializer.serializeErgoTree(script2.treeWithSegregation) + + val customEnv: ScriptEnv = Map( + "scriptBytes" -> Colls.fromArray(inputBytes), + "positions" -> positions, + "newVals" -> newVals, + "expectedBytes" -> Colls.fromArray(expectedBytes), + ) + typecheck(customEnv, "substConstants(scriptBytes, positions, newVals)") shouldBe SByteArray + } } diff --git a/src/test/scala/sigmastate/serialization/AndSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/AndSerializerSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/AndSerializerSpecification.scala rename to sigmastate/src/test/scala/sigmastate/serialization/AndSerializerSpecification.scala diff --git a/src/test/scala/sigmastate/serialization/AvlTreeSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/AvlTreeSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/AvlTreeSpecification.scala rename to sigmastate/src/test/scala/sigmastate/serialization/AvlTreeSpecification.scala diff --git a/src/test/scala/sigmastate/serialization/BlockSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/BlockSerializerSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/BlockSerializerSpecification.scala rename to sigmastate/src/test/scala/sigmastate/serialization/BlockSerializerSpecification.scala diff --git a/src/test/scala/sigmastate/serialization/ConcreteCollectionSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/ConcreteCollectionSerializerSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/ConcreteCollectionSerializerSpecification.scala rename to sigmastate/src/test/scala/sigmastate/serialization/ConcreteCollectionSerializerSpecification.scala diff --git a/src/test/scala/sigmastate/serialization/ConstantSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/ConstantSerializerSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/ConstantSerializerSpecification.scala rename to sigmastate/src/test/scala/sigmastate/serialization/ConstantSerializerSpecification.scala diff --git a/src/test/scala/sigmastate/serialization/ConstantStoreSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/ConstantStoreSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/ConstantStoreSpecification.scala rename to sigmastate/src/test/scala/sigmastate/serialization/ConstantStoreSpecification.scala diff --git a/src/test/scala/sigmastate/serialization/DataJsonEncoderSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/DataJsonEncoderSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/DataJsonEncoderSpecification.scala rename to sigmastate/src/test/scala/sigmastate/serialization/DataJsonEncoderSpecification.scala diff --git a/src/test/scala/sigmastate/serialization/DataSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/DataSerializerSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/DataSerializerSpecification.scala rename to sigmastate/src/test/scala/sigmastate/serialization/DataSerializerSpecification.scala diff --git a/src/test/scala/sigmastate/serialization/DeserializationResilience.scala b/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/DeserializationResilience.scala rename to sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala diff --git a/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala rename to sigmastate/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala diff --git a/src/test/scala/sigmastate/serialization/GroupElementSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/GroupElementSerializerSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/GroupElementSerializerSpecification.scala rename to sigmastate/src/test/scala/sigmastate/serialization/GroupElementSerializerSpecification.scala diff --git a/src/test/scala/sigmastate/serialization/MethodCallSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/MethodCallSerializerSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/MethodCallSerializerSpecification.scala rename to sigmastate/src/test/scala/sigmastate/serialization/MethodCallSerializerSpecification.scala diff --git a/src/test/scala/sigmastate/serialization/ModQSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/ModQSerializerSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/ModQSerializerSpecification.scala rename to sigmastate/src/test/scala/sigmastate/serialization/ModQSerializerSpecification.scala diff --git a/src/test/scala/sigmastate/serialization/OperationSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/OperationSerializerSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/OperationSerializerSpecification.scala rename to sigmastate/src/test/scala/sigmastate/serialization/OperationSerializerSpecification.scala diff --git a/src/test/scala/sigmastate/serialization/OrSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/OrSerializerSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/OrSerializerSpecification.scala rename to sigmastate/src/test/scala/sigmastate/serialization/OrSerializerSpecification.scala diff --git a/src/test/scala/sigmastate/serialization/PDHTSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/PDHTSerializerSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/PDHTSerializerSpecification.scala rename to sigmastate/src/test/scala/sigmastate/serialization/PDHTSerializerSpecification.scala diff --git a/src/test/scala/sigmastate/serialization/ProveDlogSerializerSpec.scala b/sigmastate/src/test/scala/sigmastate/serialization/ProveDlogSerializerSpec.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/ProveDlogSerializerSpec.scala rename to sigmastate/src/test/scala/sigmastate/serialization/ProveDlogSerializerSpec.scala diff --git a/src/test/scala/sigmastate/serialization/RelationsSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/RelationsSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/RelationsSpecification.scala rename to sigmastate/src/test/scala/sigmastate/serialization/RelationsSpecification.scala diff --git a/src/test/scala/sigmastate/serialization/SelectFieldSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/SelectFieldSerializerSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/SelectFieldSerializerSpecification.scala rename to sigmastate/src/test/scala/sigmastate/serialization/SelectFieldSerializerSpecification.scala diff --git a/src/test/scala/sigmastate/serialization/SerializationSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/SerializationSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/SerializationSpecification.scala rename to sigmastate/src/test/scala/sigmastate/serialization/SerializationSpecification.scala diff --git a/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala rename to sigmastate/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala diff --git a/src/test/scala/sigmastate/serialization/SubstConstantsSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/SubstConstantsSerializerSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/SubstConstantsSerializerSpecification.scala rename to sigmastate/src/test/scala/sigmastate/serialization/SubstConstantsSerializerSpecification.scala diff --git a/src/test/scala/sigmastate/serialization/TableSerializationSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/TableSerializationSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/TableSerializationSpecification.scala rename to sigmastate/src/test/scala/sigmastate/serialization/TableSerializationSpecification.scala diff --git a/src/test/scala/sigmastate/serialization/TaggedVariableSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/TaggedVariableSerializerSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/TaggedVariableSerializerSpecification.scala rename to sigmastate/src/test/scala/sigmastate/serialization/TaggedVariableSerializerSpecification.scala diff --git a/src/test/scala/sigmastate/serialization/TransformersSerializationSpec.scala b/sigmastate/src/test/scala/sigmastate/serialization/TransformersSerializationSpec.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/TransformersSerializationSpec.scala rename to sigmastate/src/test/scala/sigmastate/serialization/TransformersSerializationSpec.scala diff --git a/src/test/scala/sigmastate/serialization/TupleSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/TupleSerializerSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/TupleSerializerSpecification.scala rename to sigmastate/src/test/scala/sigmastate/serialization/TupleSerializerSpecification.scala diff --git a/src/test/scala/sigmastate/serialization/TwoArgumentSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/TwoArgumentSerializerSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/TwoArgumentSerializerSpecification.scala rename to sigmastate/src/test/scala/sigmastate/serialization/TwoArgumentSerializerSpecification.scala diff --git a/src/test/scala/sigmastate/serialization/TypeSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/TypeSerializerSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/TypeSerializerSpecification.scala rename to sigmastate/src/test/scala/sigmastate/serialization/TypeSerializerSpecification.scala diff --git a/src/test/scala/sigmastate/serialization/UpcastOnDeserializationSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/UpcastOnDeserializationSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/UpcastOnDeserializationSpecification.scala rename to sigmastate/src/test/scala/sigmastate/serialization/UpcastOnDeserializationSpecification.scala diff --git a/src/test/scala/sigmastate/serialization/generators/ConcreteCollectionGenerators.scala b/sigmastate/src/test/scala/sigmastate/serialization/generators/ConcreteCollectionGenerators.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/generators/ConcreteCollectionGenerators.scala rename to sigmastate/src/test/scala/sigmastate/serialization/generators/ConcreteCollectionGenerators.scala diff --git a/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala b/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala rename to sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala diff --git a/src/test/scala/sigmastate/serialization/generators/OpcodesGen.scala b/sigmastate/src/test/scala/sigmastate/serialization/generators/OpcodesGen.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/generators/OpcodesGen.scala rename to sigmastate/src/test/scala/sigmastate/serialization/generators/OpcodesGen.scala diff --git a/src/test/scala/sigmastate/serialization/generators/RelationGenerators.scala b/sigmastate/src/test/scala/sigmastate/serialization/generators/RelationGenerators.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/generators/RelationGenerators.scala rename to sigmastate/src/test/scala/sigmastate/serialization/generators/RelationGenerators.scala diff --git a/src/test/scala/sigmastate/serialization/generators/TransformerGenerators.scala b/sigmastate/src/test/scala/sigmastate/serialization/generators/TransformerGenerators.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/generators/TransformerGenerators.scala rename to sigmastate/src/test/scala/sigmastate/serialization/generators/TransformerGenerators.scala diff --git a/src/test/scala/sigmastate/serialization/generators/TypeGenerators.scala b/sigmastate/src/test/scala/sigmastate/serialization/generators/TypeGenerators.scala similarity index 100% rename from src/test/scala/sigmastate/serialization/generators/TypeGenerators.scala rename to sigmastate/src/test/scala/sigmastate/serialization/generators/TypeGenerators.scala diff --git a/src/test/scala/special/sigma/SigmaExamplesTests.scala b/sigmastate/src/test/scala/sigmastate/serialization/generators/ValueGenerators.scala similarity index 100% rename from src/test/scala/special/sigma/SigmaExamplesTests.scala rename to sigmastate/src/test/scala/sigmastate/serialization/generators/ValueGenerators.scala diff --git a/sigmastate/src/test/scala/sigmastate/utils/ByteArrayBuilderTests.scala b/sigmastate/src/test/scala/sigmastate/utils/ByteArrayBuilderTests.scala new file mode 100644 index 0000000000..e69de29bb2 diff --git a/sigmastate/src/test/scala/sigmastate/utils/ByteReaderWriterImpSpecification.scala b/sigmastate/src/test/scala/sigmastate/utils/ByteReaderWriterImpSpecification.scala new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/test/scala/sigmastate/utils/GenInfoObjects.scala b/sigmastate/src/test/scala/sigmastate/utils/GenInfoObjects.scala similarity index 100% rename from src/test/scala/sigmastate/utils/GenInfoObjects.scala rename to sigmastate/src/test/scala/sigmastate/utils/GenInfoObjects.scala diff --git a/src/test/scala/sigmastate/utils/GenPredefFuncsApp.scala b/sigmastate/src/test/scala/sigmastate/utils/GenPredefFuncsApp.scala similarity index 100% rename from src/test/scala/sigmastate/utils/GenPredefFuncsApp.scala rename to sigmastate/src/test/scala/sigmastate/utils/GenPredefFuncsApp.scala diff --git a/src/test/scala/sigmastate/utils/GenPredefTypesApp.scala b/sigmastate/src/test/scala/sigmastate/utils/GenPredefTypesApp.scala similarity index 100% rename from src/test/scala/sigmastate/utils/GenPredefTypesApp.scala rename to sigmastate/src/test/scala/sigmastate/utils/GenPredefTypesApp.scala diff --git a/src/test/scala/sigmastate/utils/GenSerializers.scala b/sigmastate/src/test/scala/sigmastate/utils/GenSerializers.scala similarity index 98% rename from src/test/scala/sigmastate/utils/GenSerializers.scala rename to sigmastate/src/test/scala/sigmastate/utils/GenSerializers.scala index c9fc0a5f5e..5d1c8ae0e1 100644 --- a/src/test/scala/sigmastate/utils/GenSerializers.scala +++ b/sigmastate/src/test/scala/sigmastate/utils/GenSerializers.scala @@ -3,7 +3,7 @@ package sigmastate.utils import scalan.util.FileUtil import scalan.util.PrintExtensions._ import sigmastate.serialization.ValueSerializer._ -import sigma.util.Extensions.ByteOps +import scalan.util.Extensions.ByteOps import sigmastate.lang.Terms.{PropertyCall, MethodCall} /** Generate contents of ErgoTree serializer format specification. @@ -140,7 +140,7 @@ object GenSerializers extends SpecGen { .filterNot { case (d,_,_) => d == PropertyCall || d == MethodCall } .opt { case (d, m, f) => m.fold(f.opt { f => - val refName = f.docInfo.opDesc.typeName + val refName = f.docInfo.opTypeName val opName = f.name.replace("%", "\\%") s"See~\\hyperref[sec:appendix:primops:$refName]{\\lst{${opName}}}" })({ m => diff --git a/src/test/scala/sigmastate/utils/HelpersTests.scala b/sigmastate/src/test/scala/sigmastate/utils/HelpersTests.scala similarity index 100% rename from src/test/scala/sigmastate/utils/HelpersTests.scala rename to sigmastate/src/test/scala/sigmastate/utils/HelpersTests.scala diff --git a/src/test/scala/sigmastate/utils/SparseArrayContainerSpecification.scala b/sigmastate/src/test/scala/sigmastate/utils/SparseArrayContainerSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utils/SparseArrayContainerSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utils/SparseArrayContainerSpecification.scala diff --git a/src/test/scala/sigmastate/utils/SpecGen.scala b/sigmastate/src/test/scala/sigmastate/utils/SpecGen.scala similarity index 94% rename from src/test/scala/sigmastate/utils/SpecGen.scala rename to sigmastate/src/test/scala/sigmastate/utils/SpecGen.scala index 32fc81e2d3..0263b04399 100644 --- a/src/test/scala/sigmastate/utils/SpecGen.scala +++ b/sigmastate/src/test/scala/sigmastate/utils/SpecGen.scala @@ -3,7 +3,7 @@ package sigmastate.utils import sigmastate._ import sigmastate.eval.Evaluation._ import sigmastate.eval.{Zero, Sized} -import sigma.util.Extensions.ByteOps +import scalan.util.Extensions.ByteOps import scalan.util.CollectionUtil import scalan.util.PrintExtensions._ import sigmastate.Values.{FalseLeaf, Constant, TrueLeaf, BlockValue, ConstantPlaceholder, Tuple, ValDef, FunDef, ValUse, ValueCompanion, TaggedVariable, ConcreteCollection, ConcreteCollectionBooleanConstant} @@ -59,7 +59,7 @@ trait SpecGen { protected val predefFuncRegistry = new PredefinedFuncRegistry(StdSigmaBuilder) val noFuncs: Set[ValueCompanion] = Set(Constant, MethodCall, PropertyCall) val predefFuncs: Seq[PredefinedFunc] = predefFuncRegistry.funcs.values - .filterNot { f => noFuncs.contains(f.docInfo.opDesc) }.toSeq + .filterNot { f => f.docInfo.opDesc.exists(noFuncs.contains) }.toSeq val specialFuncs: Seq[PredefinedFunc] = predefFuncRegistry.specialFuncs.values.toSeq def collectOpsTable() = { @@ -68,16 +68,16 @@ trait SpecGen { val funcs = predefFuncs ++ specialFuncs val methodsByOpCode = methods - .groupBy(_.docInfo.flatMap(i => Option(i.opDesc).map(_.opCode))) + .groupBy(_.docInfo.flatMap(i => i.opDesc.map(_.opCode))) // .map { case p @ (k, xs) => p.ensuring({ k.isEmpty || xs.length == 1}, p) } val funcsByOpCode = funcs - .groupBy(_.docInfo.opDesc.opCode) + .groupBy(_.docInfo.opDesc.map(_.opCode)) .ensuring(g => g.forall{ case (k, xs) => xs.length <= 1}) val table = ops.map { case (opCode, opDesc) => val methodOpt = methodsByOpCode.get(Some(opCode)).map(_.head) - val funcOpt = funcsByOpCode.get(opCode).map(_.head) + val funcOpt = funcsByOpCode.get(Some(opCode)).map(_.head) (opCode, opDesc, methodOpt, funcOpt) } val rowsWithInfo = @@ -142,7 +142,7 @@ trait SpecGen { val argInfos = m.docInfo.fold( Range(0, types.length).map(i => ArgInfo("arg" + i, "")))(info => info.args.toIndexedSeq) - val serializedAs = m.docInfo.flatMap(i => Option(i.opDesc)).opt { d => + val serializedAs = m.docInfo.flatMap(_.opDesc).opt { d => val opName = d.typeName val opCode = d.opCode.toUByte s""" @@ -168,10 +168,8 @@ trait SpecGen { val types = argTypes.map(_.toTermString) val argInfos = f.docInfo.args val opDesc = f.docInfo.opDesc - val opCode = opDesc.opCode.toUByte - val serializedAs = { - val nodeName = opDesc.typeName + val nodeName = f.docInfo.opTypeName s""" | \\bf{Serialized as} & \\hyperref[sec:serialization:operation:$nodeName]{\\lst{$nodeName}} \\\\ | \\hline @@ -179,8 +177,8 @@ trait SpecGen { } subsectionTempl( opName = toTexName(f.name), - opCode = opCode.toString, - label = s"sec:appendix:primops:${f.docInfo.opDesc.typeName}", + opCode = opDesc.map(_.opCode.toUByte.toString).getOrElse("NA"), + label = s"sec:appendix:primops:${f.docInfo.opTypeName}", desc = f.docInfo.description + f.docInfo.isFrontendOnly.opt(" (FRONTEND ONLY)"), types = types, argInfos = argInfos, @@ -265,7 +263,7 @@ object GenPrimOpsApp extends SpecGen { o => Some(o._1), m => m.docInfo.map(info => if (info.isFrontendOnly) { System.err.println(s"WARNING: Operation is frontend only: $info") None - } else info.opDesc.opCode) + } else info.opDesc.map(_.opCode)) )( (k, o) => Some(o), // left without right (k,i) => None, // right without left @@ -282,7 +280,7 @@ object GenPrimOpsApp extends SpecGen { // join collection of operations with all predef functions by opCode val danglingOps = CollectionUtil.outerJoinSeqs(primOps, predefFuncs)( - o => Some(o._1), f => Some(f.docInfo.opDesc.opCode) + o => Some(o._1), f => Some(f.docInfo.opDesc.map(_.opCode)) )( (k, o) => Some(o), // left without right (k,i) => None, // right without left diff --git a/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/BlockchainSimulationSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/BlockchainSimulationSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/BlockchainSimulationSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/BlockchainSimulationSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/ComplexSigSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/ComplexSigSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/ComplexSigSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/ComplexSigSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/ContextEnrichingSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/ContextEnrichingSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/ContextEnrichingSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/ContextEnrichingSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala similarity index 99% rename from src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala index 1244348741..4dedc606c2 100644 --- a/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala @@ -231,7 +231,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons BoolToSigmaProp( GT( Fold.sum[SLong.type](MapCollection(Outputs, - FuncValue(Vector((1, SBox)), ExtractAmount(ValUse(1, SBox))))), + FuncValue(Vector((1, SBox)), ExtractAmount(ValUse(1, SBox)))), 1), LongConstant(20)) ) ) diff --git a/src/test/scala/sigmastate/utxo/FuncVarSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/FuncVarSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/FuncVarSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/FuncVarSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/SerializationRoundTripSpec.scala b/sigmastate/src/test/scala/sigmastate/utxo/SerializationRoundTripSpec.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/SerializationRoundTripSpec.scala rename to sigmastate/src/test/scala/sigmastate/utxo/SerializationRoundTripSpec.scala diff --git a/src/test/scala/sigmastate/utxo/SigmaCompilerSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/SigmaCompilerSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/SigmaCompilerSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/SigmaCompilerSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/SigmaContract.scala b/sigmastate/src/test/scala/sigmastate/utxo/SigmaContract.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/SigmaContract.scala rename to sigmastate/src/test/scala/sigmastate/utxo/SigmaContract.scala diff --git a/sigmastate/src/test/scala/sigmastate/utxo/SpamSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/SpamSpecification.scala new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/ThresholdSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/UsingContextPropertiesSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/UsingContextPropertiesSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/UsingContextPropertiesSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/UsingContextPropertiesSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/benchmarks/CrowdFundingContract.scala b/sigmastate/src/test/scala/sigmastate/utxo/benchmarks/CrowdFundingContract.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/benchmarks/CrowdFundingContract.scala rename to sigmastate/src/test/scala/sigmastate/utxo/benchmarks/CrowdFundingContract.scala diff --git a/src/test/scala/sigmastate/utxo/benchmarks/CrowdFundingKernelContract.scala b/sigmastate/src/test/scala/sigmastate/utxo/benchmarks/CrowdFundingKernelContract.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/benchmarks/CrowdFundingKernelContract.scala rename to sigmastate/src/test/scala/sigmastate/utxo/benchmarks/CrowdFundingKernelContract.scala diff --git a/src/test/scala/sigmastate/utxo/benchmarks/CrowdFundingScriptContract.scala b/sigmastate/src/test/scala/sigmastate/utxo/benchmarks/CrowdFundingScriptContract.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/benchmarks/CrowdFundingScriptContract.scala rename to sigmastate/src/test/scala/sigmastate/utxo/benchmarks/CrowdFundingScriptContract.scala diff --git a/src/test/scala/sigmastate/utxo/benchmarks/CrowdfundingBenchmark.scala b/sigmastate/src/test/scala/sigmastate/utxo/benchmarks/CrowdfundingBenchmark.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/benchmarks/CrowdfundingBenchmark.scala rename to sigmastate/src/test/scala/sigmastate/utxo/benchmarks/CrowdfundingBenchmark.scala diff --git a/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationTestingCommons.scala b/sigmastate/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationTestingCommons.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationTestingCommons.scala rename to sigmastate/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationTestingCommons.scala diff --git a/src/test/scala/sigmastate/utxo/examples/AssetsAtomicExchange.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/AssetsAtomicExchange.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/AssetsAtomicExchange.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/AssetsAtomicExchange.scala diff --git a/src/test/scala/sigmastate/utxo/examples/AssetsAtomicExchangeErgoTests.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/AssetsAtomicExchangeErgoTests.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/AssetsAtomicExchangeErgoTests.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/AssetsAtomicExchangeErgoTests.scala diff --git a/src/test/scala/sigmastate/utxo/examples/AssetsAtomicExchangeTests.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/AssetsAtomicExchangeTests.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/AssetsAtomicExchangeTests.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/AssetsAtomicExchangeTests.scala diff --git a/src/test/scala/sigmastate/utxo/examples/AssetsPartialFilling.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/AssetsPartialFilling.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/AssetsPartialFilling.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/AssetsPartialFilling.scala diff --git a/src/test/scala/sigmastate/utxo/examples/AtomicSwapExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/AtomicSwapExampleSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/AtomicSwapExampleSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/AtomicSwapExampleSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala similarity index 84% rename from src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala index d684ff908a..cd7a743cda 100644 --- a/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala @@ -64,6 +64,27 @@ class CoinEmissionSpecification extends SigmaTestingCommons with ScorexLogging { }.ensuring(_ >= 0, s"Negative at $h") + /* +block 0 in 0 ms, 2430000000000 coins remain, defs: 0 +block 0 in 41 ms, 2430000000000 coins remain +block 100 in 1292 ms, 2280000000000 coins remain, defs: 61661 +block 200 in 965 ms, 2130000000000 coins remain, defs: 61661 +block 300 in 991 ms, 1980000000000 coins remain, defs: 61661 +block 400 in 842 ms, 1830000000000 coins remain, defs: 61661 +block 500 in 833 ms, 1680000000000 coins remain, defs: 61661 +block 600 in 788 ms, 1530000000000 coins remain, defs: 61661 +block 700 in 903 ms, 1380000000000 coins remain, defs: 61661 +block 800 in 789 ms, 1230000000000 coins remain, defs: 61661 +block 900 in 774 ms, 1080000000000 coins remain, defs: 61661 +block 1000 in 753 ms, 930000000000 coins remain, defs: 61661 +block 1000 in 8889 ms, 930000000000 coins remain +block 1100 in 764 ms, 780000000000 coins remain, defs: 61661 +block 1200 in 886 ms, 630000000000 coins remain, defs: 61661 +block 1300 in 1371 ms, 480000000000 coins remain, defs: 61661 +block 1400 in 1908 ms, 330000000000 coins remain, defs: 61661 +block 1500 in 1626 ms, 180000000000 coins remain, defs: 61661 +block 1600 in 1622 ms, 30000000000 coins remain, defs: 61661 + */ property("emission specification") { val register = reg1 val prover = new ContextEnrichingTestProvingInterpreter() @@ -157,6 +178,7 @@ class CoinEmissionSpecification extends SigmaTestingCommons with ScorexLogging { } var st = System.currentTimeMillis() + var thousandTime = System.currentTimeMillis() def chainGen(state: ValidationState, emissionBox: ErgoBox, @@ -164,10 +186,15 @@ class CoinEmissionSpecification extends SigmaTestingCommons with ScorexLogging { hLimit: Int): Unit = if (height < hLimit) { if (height % 100 == 0) { val t = System.currentTimeMillis() - println(s"block $height in ${t - st} ms, ${emissionBox.value} coins remain") + println(s"block $height in ${t - st} ms, ${emissionBox.value} coins remain, defs: ${IR.defCount}") st = t IR.resetContext() } + if (height % 1000 == 0) { + val t = System.currentTimeMillis() + println(s"block $height in ${t - thousandTime} ms, ${emissionBox.value} coins remain") + thousandTime = t + } val tx = genCoinbaseLikeTransaction(state, emissionBox, height) val block = FullBlock(IndexedSeq(tx), minerPubkey) val newState = state.applyBlock(block).get diff --git a/src/test/scala/sigmastate/utxo/examples/ColdWalletAdvContractExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletAdvContractExampleSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/ColdWalletAdvContractExampleSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletAdvContractExampleSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/examples/ColdWalletContractExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletContractExampleSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/ColdWalletContractExampleSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletContractExampleSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/examples/CoopExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/CoopExampleSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/CoopExampleSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/CoopExampleSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/examples/CrowdFunding.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/CrowdFunding.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/CrowdFunding.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/CrowdFunding.scala diff --git a/src/test/scala/sigmastate/utxo/examples/CrowdFundingTests.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/CrowdFundingTests.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/CrowdFundingTests.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/CrowdFundingTests.scala diff --git a/src/test/scala/sigmastate/utxo/examples/DHTupleExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/DHTupleExampleSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/DHTupleExampleSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/DHTupleExampleSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/examples/DemurrageExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/DemurrageExampleSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/DemurrageExampleSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/DemurrageExampleSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/examples/DummyExamplesSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/DummyExamplesSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/DummyExamplesSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/DummyExamplesSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/examples/ExecuteFromExamplesSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/ExecuteFromExamplesSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/ExecuteFromExamplesSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/ExecuteFromExamplesSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/examples/FsmExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/FsmExampleSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/FsmExampleSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/FsmExampleSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/examples/IcoExample.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/IcoExample.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/IcoExample.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/IcoExample.scala diff --git a/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/examples/OracleDataInputsExamplesSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleDataInputsExamplesSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/OracleDataInputsExamplesSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/OracleDataInputsExamplesSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/examples/OracleTokenExamplesSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleTokenExamplesSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/OracleTokenExamplesSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/OracleTokenExamplesSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/examples/RPSGameExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/RPSGameExampleSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/RPSGameExampleSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/RPSGameExampleSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/examples/RevenueSharingExamplesSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/RevenueSharingExamplesSpecification.scala similarity index 81% rename from src/test/scala/sigmastate/utxo/examples/RevenueSharingExamplesSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/RevenueSharingExamplesSpecification.scala index cbf044fe64..cbe2278793 100644 --- a/src/test/scala/sigmastate/utxo/examples/RevenueSharingExamplesSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/RevenueSharingExamplesSpecification.scala @@ -59,6 +59,24 @@ class RevenueSharingExamplesSpecification extends SigmaTestingCommons { suite => |} """.stripMargin) +// TODO move to a separate test case somewhere +// the following code is minimized version of the above to reproduce the problem +// when fold is pulled into forall during BuildTree. +// In minimized form it can be used to test BuildTree on loop operations. +// """{ +// | val feeBox = OUTPUTS(0) +// | val total = ratios.fold(0, {(l:Int, r:Int) => l + r}) +// | val validOuts = ratios.zip(OUTPUTS).forall({ +// | (e: (Int, Box)) => +// | val ratio = e._1 +// | val box = e._2 +// | val share = total * ratio +// | box.value >= share +// | }) +// | sigmaProp(validOuts) +// |} +// """.stripMargin) + lazy val requireAliceSignature = proposition( "requireAliceSignature", _ => alice.pubKey, @@ -80,7 +98,7 @@ class RevenueSharingExamplesSpecification extends SigmaTestingCommons { suite => } - lazy val spec = TestContractSpec(suite)(new TestingIRContext) + lazy val spec = TestContractSpec(suite)(new TestingIRContext { saveGraphsInFile = true }) lazy val alice = spec.ProvingParty("Alice") lazy val bob = spec.ProvingParty("Bob") diff --git a/src/test/scala/sigmastate/utxo/examples/ReversibleTxExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/ReversibleTxExampleSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/ReversibleTxExampleSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/ReversibleTxExampleSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/examples/Rule110Specification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/Rule110Specification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/Rule110Specification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/Rule110Specification.scala diff --git a/src/test/scala/sigmastate/utxo/examples/TimedPaymentExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/TimedPaymentExampleSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/TimedPaymentExampleSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/TimedPaymentExampleSpecification.scala diff --git a/src/test/scala/sigmastate/utxo/examples/TrustlessLETS.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/TrustlessLETS.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/TrustlessLETS.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/TrustlessLETS.scala diff --git a/src/test/scala/sigmastate/utxo/examples/XorGameExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/XorGameExampleSpecification.scala similarity index 100% rename from src/test/scala/sigmastate/utxo/examples/XorGameExampleSpecification.scala rename to sigmastate/src/test/scala/sigmastate/utxo/examples/XorGameExampleSpecification.scala diff --git a/src/test/scala/special/sigma/ContractsTestkit.scala b/sigmastate/src/test/scala/special/sigma/ContractsTestkit.scala similarity index 92% rename from src/test/scala/special/sigma/ContractsTestkit.scala rename to sigmastate/src/test/scala/special/sigma/ContractsTestkit.scala index 116177380d..8e67330bc9 100644 --- a/src/test/scala/special/sigma/ContractsTestkit.scala +++ b/sigmastate/src/test/scala/special/sigma/ContractsTestkit.scala @@ -79,8 +79,4 @@ trait ContractsTestkit { ctx.copy(vars = contextVars(vars.map { case (k, v) => (k.toByte, v) })) } - case class NoEnvContract(condition: Context => Boolean) extends SigmaContract { - override def builder: SigmaDslBuilder = new TestSigmaDslBuilder - override def canOpen(ctx: Context): Boolean = condition(ctx) - } } diff --git a/sigmastate/src/test/scala/special/sigma/LoopTests.scala b/sigmastate/src/test/scala/special/sigma/LoopTests.scala new file mode 100644 index 0000000000..1495ef4758 --- /dev/null +++ b/sigmastate/src/test/scala/special/sigma/LoopTests.scala @@ -0,0 +1,42 @@ +package special.sigma + +import sigmastate.helpers.SigmaTestingCommons + +class LoopTests extends SigmaTestingCommons { suite => + implicit lazy val IR = new TestingIRContext + import IR._ + + property("Test nested loop") { + import Coll._ + import Context._; import Box._ + // variable to capture internal lambdas + var proj2: Ref[((Coll[Byte], Int)) => Int] = null + var sumFold: Ref[((Int, Int)) => Int] = null + var pred: Ref[(((Coll[Byte], Int), Box)) => Boolean] = null + var total: Ref[Int] = null + + val f = fun { in: Ref[(Context, Coll[(Coll[Byte], Int)])] => + val Pair(ctx, spenders) = in + val feeBox = ctx.OUTPUTS(0) + proj2 = fun { e: Ref[(Coll[Byte], Int)] => e._2 } + val ratios = spenders.map(proj2) + sumFold = fun { in: Ref[(Int, Int)] => in._1 + in._2 } + total = ratios.foldLeft(0, sumFold) + pred = fun { e: Ref[(((Coll[Byte], Int), Box))] => + val ratio = e._1._2 + val box = e._2 + val share = total * ratio + box.value >= share.toLong + } + val validOuts = spenders.zip(ctx.OUTPUTS).forall(pred) + validOuts + } + val Def(l: Lambda[_,_]) = f + assert(l.freeVars.contains(proj2)) + assert(l.freeVars.contains(sumFold)) + val Def(p: Lambda[_,_]) = pred + assert(p.freeVars.contains(total)) + emit("f", f) + } +} + diff --git a/src/test/scala/special/sigma/SigmaDslStaginTests.scala b/sigmastate/src/test/scala/special/sigma/SigmaDslStaginTests.scala similarity index 100% rename from src/test/scala/special/sigma/SigmaDslStaginTests.scala rename to sigmastate/src/test/scala/special/sigma/SigmaDslStaginTests.scala diff --git a/src/test/scala/special/sigma/SigmaDslTest.scala b/sigmastate/src/test/scala/special/sigma/SigmaDslTest.scala similarity index 99% rename from src/test/scala/special/sigma/SigmaDslTest.scala rename to sigmastate/src/test/scala/special/sigma/SigmaDslTest.scala index 2f0b7b0fc3..07e5c0e582 100644 --- a/src/test/scala/special/sigma/SigmaDslTest.scala +++ b/sigmastate/src/test/scala/special/sigma/SigmaDslTest.scala @@ -5,23 +5,20 @@ import java.math.BigInteger import org.ergoplatform.ErgoScriptPredef.TrueProp import org.ergoplatform.dsl.{SigmaContractSyntax, TestContractSpec} import org.ergoplatform._ -import org.scalacheck.Gen.containerOfN -import org.scalacheck.{Arbitrary, Gen} import org.scalatest.prop.PropertyChecks import org.scalatest.{PropSpec, Matchers} import scalan.RType import scorex.crypto.authds.avltree.batch._ import scorex.crypto.authds.{ADKey, ADValue} import scorex.crypto.hash.{Digest32, Blake2b256} +import scalan.util.Extensions._ import sigma.util.Extensions._ -import sigmastate.Values.{BooleanConstant, EvaluatedValue, IntConstant} +import sigmastate.Values.IntConstant import sigmastate._ import sigmastate.Values._ import sigmastate.eval.Extensions._ import sigmastate.eval._ -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, SigmaTestingCommons, ErgoLikeTestInterpreter} -import sigmastate.interpreter.ContextExtension -import sigmastate.interpreter.Interpreter.{ScriptNameProp, ScriptEnv} +import sigmastate.interpreter.Interpreter.ScriptEnv import sigmastate.utxo.ComplexityTableStat import special.collection.{Coll, Builder} diff --git a/sigmastate/src/test/scala/special/sigma/SigmaExamplesTests.scala b/sigmastate/src/test/scala/special/sigma/SigmaExamplesTests.scala new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/test/scala/special/sigma/SigmaTestingData.scala b/sigmastate/src/test/scala/special/sigma/SigmaTestingData.scala similarity index 100% rename from src/test/scala/special/sigma/SigmaTestingData.scala rename to sigmastate/src/test/scala/special/sigma/SigmaTestingData.scala diff --git a/src/test/scala/special/sigma/SigmaTypeGens.scala b/sigmastate/src/test/scala/special/sigma/SigmaTypeGens.scala similarity index 100% rename from src/test/scala/special/sigma/SigmaTypeGens.scala rename to sigmastate/src/test/scala/special/sigma/SigmaTypeGens.scala