From a430a942eaa609d68bf3ccd1de128659b7199c81 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Wed, 8 Jun 2016 15:17:14 -0400 Subject: [PATCH 1/3] Add util to generate large test flix programs for example lattices. --- .../flix/util/perf/RandomLatticeGraph.scala | 178 ++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 main/test/ca/uwaterloo/flix/util/perf/RandomLatticeGraph.scala diff --git a/main/test/ca/uwaterloo/flix/util/perf/RandomLatticeGraph.scala b/main/test/ca/uwaterloo/flix/util/perf/RandomLatticeGraph.scala new file mode 100644 index 00000000000..0d0b3b7de8a --- /dev/null +++ b/main/test/ca/uwaterloo/flix/util/perf/RandomLatticeGraph.scala @@ -0,0 +1,178 @@ +package ca.uwaterloo.flix.util.perf + +import scala.collection.immutable.HashMap +import scala.util.matching.Regex +import scala.util.Random + +object RandomLatticeGraph { + + case class Lattice(name: String, els: Array[String], unOps: Array[String], biOps: Array[String]) + + def main(args: Array[String]): Unit = { + + val lattices = HashMap( + "Belnap" -> Lattice( + "Belnap", + Array("Top", "True", "False", "Bot"), + Array("not"), + Array("lub", "glb", "and", "or", "xor", "implies", "bicondition", "nand") + ), + "Constant" -> Lattice( + "Constant", + Array("Top", "Cst(%n)", "Bot"), + Array("inc", "dec", "negate"), + Array("lub", "glb", "plus", "minus", "times", "divide", "modulo", "and", "or", "xor", "leftShift", "rightShift") + ), + "ConstantParity" -> Lattice( + "ConstParity", + Array("Top", "Odd", "Even", "Cst(%n)", "Bot"), + Array("inc", "Dec"), + Array("lub", "glb", "plus", "minus", "times", "divide", "modulo") + ), + "ConstantSign" -> Lattice( + "ConstSign", + Array("Top", "Neg", "Pos", "Cst(%n)", "Bot"), + Array("inc", "dec"), + Array("lub", "glb", "plus", "minus", "times", "divide", "modulo") + ), + "Interval" -> Lattice( + "Interval", + Array("Top", "Range(%n, %n)"), + Array("norm"), + Array("lub", "glb") + ), + "IntervalAlt" -> Lattice( + "Interval", + Array("Top", "Range(%n, %n)", "Bot"), + Array(), + Array("lub", "glb", "plus", "minus", "times", "divide") + ), + "Mod3" -> Lattice( + "Mod3", + Array("Top", "Zer", "One", "Two", "Bot"), + Array("inc", "dec"), + Array("lub", "glb", "plus", "minus", "times", "divide", "modulo") + ), + "Parity" -> Lattice( + "Parity", + Array("Top", "Odd", "Even", "Bot"), + Array("inc", "dec", "negate"), + Array("lub", "glb", "plus", "minus", "times", "divide", "modulo", "and", "or", "xor", "leftShift", "rightShift") + ), + "ParitySign" -> Lattice( + "ParitySign", + Array("Top", "ENeg", "EPos", "ONeg", "OPos", "Zer", "Bot"), + Array("inc", "dec"), + Array("lub", "glb", "plus", "minus") + ), + "PrefixSuffix" -> Lattice( + "PS", + Array("Top", "Pre(%n)", "Suf(%n)", "PreSuf(%n, %n)", "Bot"), + Array(), + Array("lub", "glb", "concatenate") + ), + "Sign" -> Lattice( + "Sign", + Array("Top", "Neg", "Pos", "Zer", "Bot"), + Array("inc", "dec", "negate"), + Array("lub", "glb", "plus", "minus", "times", "divide", "modulo", "and", "or", "xor", "leftShift", "rightShift") + ), + "StrictSign" -> Lattice( + "Sign", + Array("Top", "Neg", "Pos", "Zer", "Bot"), + Array("inc", "dec", "negate"), + Array("lub", "glb", "plus", "minus", "times", "divide", "modulo", "and", "or", "xor", "leftShift", "rightShift") + ), + "Type" -> Lattice( + "Type", + Array("Err", "Bool", "Int", "Real", "Bot"), + Array(), + Array("lub", "glb", "sum") + ) + ) + + // FIXME: Check for # of args + val which = args(0).toString + val N = args(1).toInt + + val lattice = lattices get which match { + case Some(l) => l + case None => { + println(s"Invalid lattice - $which") + return + } + } + + // Create a list of N values, each assigned a random from our lattice + val values: Array[String] = Seq.fill(N) { + lattice.els(Random.nextInt(lattice.els.length)) + }.toArray + + println(s"namespace Random${which}Graph {") + println() + println(s" lat Value(x: Int, xv: $which/${lattice.name});") + println(s" rel UnOp(y: Int, x: Int, op: Str);") + println(s" rel BiOp(z: Int, x: Int, y: Int, op: Str);") + println() + + // Print out the UnOp rules + for (unOp <- lattice.unOps) { + println(s""" Value(y, $which/$unOp(xv)) :- UnOp(y, x, "$unOp"), Value(x, xv).""") + } + + println() + + // and the BiOp rules + for (biOp <- lattice.biOps) { + println(s""" Value(z, $which/$biOp(xv, yv)) :- BiOp(z, x, y, "$biOp"), Value(x, xv), Value(y, yv).""") + } + + println() + + // Print out the random Values + for ((value, i) <- values.zipWithIndex) { + // Replace any %n in the value with a random Int + val v = "%n".r.replaceAllIn(value, _ => Random.nextInt(100000).toString) + println(s" Value($i, $which/${lattice.name}.$v).") + } + + println() + + if (lattice.unOps.length > 0) { + // Generate and print out random UnOps + for (i <- 0 until 3*N) { + + // Choose some random values + val x = Random.nextInt(values.length) + val y = Random.nextInt(values.length) + + // and a random operation to perform on them + val op = lattice.unOps(Random.nextInt(lattice.unOps.length)) + + println(s""" UnOp($y, $x, "$op").""") + } + } + + if (lattice.biOps.length > 0) { + // Generate and print out random BiOps + for (i <- 0 until 7*N) { + + // Choose some random values + val x = Random.nextInt(values.length) + val y = Random.nextInt(values.length) + val z = Random.nextInt(values.length) + + // and a random operation to perform on them + val op = lattice.biOps(Random.nextInt(lattice.biOps.length)) + + println(s""" BiOp($z, $x, $y, "$op").""") + + } + } + + println() + println("}") + + } + +} From 13776b8c8c19c92f8b29a5a657bede25302c3295 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Wed, 8 Jun 2016 15:54:27 -0400 Subject: [PATCH 2/3] Allow passing a specific seed. --- .../flix/util/perf/RandomLatticeGraph.scala | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/main/test/ca/uwaterloo/flix/util/perf/RandomLatticeGraph.scala b/main/test/ca/uwaterloo/flix/util/perf/RandomLatticeGraph.scala index 0d0b3b7de8a..e5bdd3738e5 100644 --- a/main/test/ca/uwaterloo/flix/util/perf/RandomLatticeGraph.scala +++ b/main/test/ca/uwaterloo/flix/util/perf/RandomLatticeGraph.scala @@ -91,9 +91,22 @@ object RandomLatticeGraph { ) ) - // FIXME: Check for # of args + if (args.length < 2) { + println("Usage: lattice N [seed]") + println() + println(s"\tlattice \t- one of: ${lattices.keys.mkString(", ")}") + println("\t N \t\t- how many random values to generate") + println("\tseed \t\t- value to seed RNG with") + return + } + val which = args(0).toString val N = args(1).toInt + val rng = if (args.length == 3) { + new Random(args(2).toLong) + } else { + new Random() + } val lattice = lattices get which match { case Some(l) => l @@ -105,7 +118,7 @@ object RandomLatticeGraph { // Create a list of N values, each assigned a random from our lattice val values: Array[String] = Seq.fill(N) { - lattice.els(Random.nextInt(lattice.els.length)) + lattice.els(rng.nextInt(lattice.els.length)) }.toArray println(s"namespace Random${which}Graph {") @@ -132,7 +145,7 @@ object RandomLatticeGraph { // Print out the random Values for ((value, i) <- values.zipWithIndex) { // Replace any %n in the value with a random Int - val v = "%n".r.replaceAllIn(value, _ => Random.nextInt(100000).toString) + val v = "%n".r.replaceAllIn(value, _ => rng.nextInt(100000).toString) println(s" Value($i, $which/${lattice.name}.$v).") } @@ -143,11 +156,11 @@ object RandomLatticeGraph { for (i <- 0 until 3*N) { // Choose some random values - val x = Random.nextInt(values.length) - val y = Random.nextInt(values.length) + val x = rng.nextInt(values.length) + val y = rng.nextInt(values.length) // and a random operation to perform on them - val op = lattice.unOps(Random.nextInt(lattice.unOps.length)) + val op = lattice.unOps(rng.nextInt(lattice.unOps.length)) println(s""" UnOp($y, $x, "$op").""") } @@ -158,12 +171,12 @@ object RandomLatticeGraph { for (i <- 0 until 7*N) { // Choose some random values - val x = Random.nextInt(values.length) - val y = Random.nextInt(values.length) - val z = Random.nextInt(values.length) + val x = rng.nextInt(values.length) + val y = rng.nextInt(values.length) + val z = rng.nextInt(values.length) // and a random operation to perform on them - val op = lattice.biOps(Random.nextInt(lattice.biOps.length)) + val op = lattice.biOps(rng.nextInt(lattice.biOps.length)) println(s""" BiOp($z, $x, $y, "$op").""") From 7f2f14b1eab3c828da87f042e6609e4b855dc773 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Wed, 8 Jun 2016 18:24:10 -0400 Subject: [PATCH 3/3] Print out the N and seed value. Also use Map instead of HashMap and add copyright. --- CONTRIBUTORS.md | 1 + .../flix/util/perf/RandomLatticeGraph.scala | 29 ++++++++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 9882984e299..6ed2ab18eb8 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -2,6 +2,7 @@ By adding your name to this document, you agree to release all your contributions to Flix under the [Apache 2.0 License](LICENSE.md). +- [Luqman Aden](https://github.com/luqmana) - [Magnus Madsen](https://github.com/magnus-madsen) ([website](http://plg.uwaterloo.ca/~mmadsen/)) - [Ming-Ho Yee](https://github.com/mhyee) ([website](http://mhyee.com)) diff --git a/main/test/ca/uwaterloo/flix/util/perf/RandomLatticeGraph.scala b/main/test/ca/uwaterloo/flix/util/perf/RandomLatticeGraph.scala index e5bdd3738e5..876594a8d2c 100644 --- a/main/test/ca/uwaterloo/flix/util/perf/RandomLatticeGraph.scala +++ b/main/test/ca/uwaterloo/flix/util/perf/RandomLatticeGraph.scala @@ -1,3 +1,19 @@ +/* + * Copyright 2016 Luqman Aden + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package ca.uwaterloo.flix.util.perf import scala.collection.immutable.HashMap @@ -10,7 +26,7 @@ object RandomLatticeGraph { def main(args: Array[String]): Unit = { - val lattices = HashMap( + val lattices = Map( "Belnap" -> Lattice( "Belnap", Array("Top", "True", "False", "Bot"), @@ -102,11 +118,13 @@ object RandomLatticeGraph { val which = args(0).toString val N = args(1).toInt - val rng = if (args.length == 3) { - new Random(args(2).toLong) + val seed = if (args.length == 3) { + args(2).toLong } else { - new Random() + // We generate one here so that we can print out a seed value even if the user hasn't specified one + Random.nextLong() } + val rng = new Random(seed) val lattice = lattices get which match { case Some(l) => l @@ -116,6 +134,9 @@ object RandomLatticeGraph { } } + println(s"// N: $N") + println(s"// seed: $seed") + // Create a list of N values, each assigned a random from our lattice val values: Array[String] = Seq.fill(N) { lattice.els(rng.nextInt(lattice.els.length))