diff --git a/benchmark/src/main/scala/Benchmark.scala b/benchmark/src/main/scala/Benchmark.scala new file mode 100644 index 000000000..1574e08b0 --- /dev/null +++ b/benchmark/src/main/scala/Benchmark.scala @@ -0,0 +1,193 @@ +package hkmc2 + +import mlscript.utils.*, shorthands.* + +import hkmc2.Config.EffectHandlers +import hkmc2.Config.StackSafety +import hkmc2.Config.LiftDefns + +object Benchmark { + val targetBaseDir = os.pwd/"benchmark"/"target" + val benchmarkBaseDir = os.pwd/"benchmark"/"src" + val runtimeRelPath = os.rel/"precompiled"/"Runtime.mjs" + val noInstrDir = targetBaseDir/"noInstr" + val effectOnlyDir = targetBaseDir/"effectOnly" + val stackSafeDir = targetBaseDir/"stackSafe" + + val preludePath = os.pwd/"hkmc2"/"shared"/"src"/"test"/"mlscript"/"decls"/"Prelude.mls" + val compilerNoInstr = MLsCompiler(preludePath, _(println))(using Config(N, N, S(LiftDefns()))) + val compilerInstr = MLsCompiler(preludePath, _(println))(using Config(N, S(EffectHandlers(false, N)), S(LiftDefns()))) + val compilerStackSafe = MLsCompiler(preludePath, _(println))(using Config(N, S(EffectHandlers(false, S(StackSafety.default))), N)) + val compilerStackSafeLifted = MLsCompiler(preludePath, _(println))(using Config(N, S(EffectHandlers(false, S(StackSafety.default))), S(LiftDefns()))) + + val configsLst = + (noInstrDir, compilerNoInstr, "only lifting") :: + (effectOnlyDir, compilerInstr, "lifting and effect") :: + (stackSafeDir, compilerStackSafeLifted, "lifting, effect, and stack safety") :: Nil + + val configs = configsLst.map((p, c, _) => (p, c)) + + def compileFile(file: os.RelPath, targetDir: os.Path, compiler: MLsCompiler, exportName: Option[Str] = N, outFileOpt: Option[os.RelPath] = N) = + val outFile = outFileOpt.getOrElse(file/os.up/(file.baseName + ".mjs")) + compiler.compileModule(benchmarkBaseDir/file, S(targetDir/outFile), exportName, S(benchmarkBaseDir/runtimeRelPath), true) + + def compileVersions(file: os.RelPath, configs: List[(os.Path, MLsCompiler)]) = + configs.foreach: (targetDir, compiler) => + compileFile(file, targetDir, compiler) + + def precompileModules = + + compileVersions(os.rel/"precompiled"/"Runtime.mls", configs.map((targetDir, _) => (targetDir, compilerNoInstr))) + compileVersions(os.rel/"precompiled"/"Rendering.mls", configs.map((targetDir, _) => (targetDir, compilerNoInstr))) + + configs.foreach: (targetDir, _) => + os.copy.over(benchmarkBaseDir/"precompiled"/"RuntimeJS.mjs", targetDir/"precompiled"/"RuntimeJS.mjs") + + compileVersions(os.rel/"precompiled"/"Predef.mls", configs) + compileVersions(os.rel/"precompiled"/"NofibPrelude.mls", configs) + + configs.foreach: (targetDir, compiler) => + val inFile = if compiler is compilerStackSafeLifted then + os.rel/"precompiled"/"BenchmarkPrelude.instr.mls" + else + os.rel/"precompiled"/"BenchmarkPrelude.noinstr.mls" + compileFile(inFile, targetDir, compiler, S("BenchmarkPrelude"), S(os.rel/"precompiled"/"BenchmarkPrelude.mjs")) + + def main(args: Array[String]) = + + println("Compiling dependencies") + precompileModules + val testDir = os.pwd/"hkmc2"/"shared"/"src"/"test" + // Import nofib + val nofibSources = os.list(os.pwd/"hkmc2"/"shared"/"src"/"test"/"mlscript"/"nofib").filter(_.last != "NofibPrelude.mls").filter(_.last != "input") + nofibSources.foreach: path => + println(s"Importing ${path.last}") + val preludeStr = f"""import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module ${path.baseName.replace("-", "")} with ... +""" + val result = os.read(path).split("\n").flatMap: line => + if line.startsWith(":") || line.startsWith("import ") || line.startsWith("//|") then + N + else if line.startsWith("prog(6).toStr") || line.startsWith("test") || line.startsWith("nofib") || + line.startsWith("map(x => nofib") then + S(f"fun main() = $line") + else if line.startsWith("print(test") || line.startsWith("print(nofib") then + assert(line.endsWith(")")) + S(f"fun main() = ${line.drop(6).dropRight(1)}") + else if line == "print of" then + S("fun main() =") + else if line.startsWith("let ls = testFish") then + S("fun main() = testFish_nofib(1)") + else if line == "ls" && path.baseName == "fish" then + S("") + else if line.startsWith("let ") then + // convert private variables away + S("val " + line.drop(4)) + else + S(line) + .mkString(preludeStr, "\n", "\n") + os.write.over(os.pwd/"benchmark"/"src"/"nofib"/path.last.replace("-", ""), result) + println("Compiling nofib") + val nofibPaths = os.list(benchmarkBaseDir/"nofib") + nofibPaths.foreach: path => + println(s"=> Compiling ${path.last}") + compileVersions(os.rel/"nofib"/path.last, configs) + + val results = nofibPaths.map: path => + println(s"=> Running ${path.last}") + val result = configsLst.map: (targetDir, _, nme) => + println(s"=> => Running ${path.last} with $nme") + val targetImport = s"import Target from \"${targetDir/"nofib"/(path.baseName + ".mjs")}\";\n" + val benchmarkImport = s"import Benchmark from \"${targetDir/"precompiled"/"BenchmarkPrelude.mjs"}\";\n" + val benchmarkJS = targetImport + benchmarkImport + "Benchmark.benchmark(Target.main)" + val result = os.proc("node").call(stdin = benchmarkJS, stderr = os.Inherit) + val resultStr = result.out.bytes.map(_.toChar).mkString + var time: Opt[Double] = N + resultStr.linesIterator.foreach: line => + if line.startsWith("Time: ") then + val t = line.substring(6, line.length - 2).toDouble + println(f"Time: $t%.3f") + time = S(t) + else if line.startsWith("stackSafeCounter: ") then + println(line) + else + println(line) + time + val folded = result.foldRight(S(List.empty): Opt[List[Double]]): (r, acc) => + (r, acc) match + case (S(t), S(lst)) => S(t :: lst) + case _ => N + folded.foreach: lst => + println(f"Effect compared with baseline: ${lst.head / lst(1) * 100}%.3f%%") + println(f"Stack safety compared with effect: ${lst(1) / lst(2) * 100}%.3f%%") + println(f"Stack safety compared with baseline: ${lst.head / lst(2) * 100}%.3f%%") + (path, folded) + + results.foreach: (path, result) => + result match + case S(baseline :: effect :: stackSafe :: Nil) => + println(f"$path: ${(baseline / effect) * 100}%.3f%%, ${(baseline / stackSafe) * 100}%.3f%%") + case _ => + println(s"$path: One of the test failed") + + // val results = nofibFiles.map: path => + // def run(compiler: MLsCompiler): Option[Double] = + // // println(s"Compiling $path") + // compiler.compileModule(path) + // val resultPath = path / os.up / (path.baseName + ".mjs") + // println(s"Running $resultPath") + // val result = os.proc("node", resultPath.toString).call(stderr = os.Inherit) + // val resultStr = result.out.bytes.map(_.toChar).mkString + // var time: Opt[Double] = N + // resultStr.linesIterator.foreach: line => + // if line.startsWith("Time: ") then + // val t = line.substring(6, line.length - 2).toDouble + // println(f"Time: $t%.3f") + // time = S(t) + // else if line.startsWith("stackSafeCounter: ") then + // println(line) + // else + // println(line) + // time + // // if path.last != "cryptarithm1.mls" then + // // useStackSafe + // // println("Stack safety: on") + // // run(compilerStackSafe) + // // else + // // print("Skipping cryptarithm1 as it OOM without lifter") + // useStackSafe + // println("Stack safety: on, Lift: on") + // val t1 = run(compilerStackSafeLifted) + // useNoInstr + // println("Stack safety: off") + // val t2 = run(compilerNoInstr) + // (t1, t2) match + // case (S(t1), S(t2)) => + // val s1 = 1 / t1 + // val s2 = 1 / t2 + // println(f"Speed compared with stack safety off: ${s1 / s2 * 100}%.3f%%") + // path.last -> S(s1 / s2) + // case (S(_), N) => + // path.last -> N + // case _ => + // println("Stack safe version failed") + // path.last -> N + // results.foreach: (path, result) => + // result match + // case S(speed) => + // println(f"$path: ${speed * 100}%.3f%%") + // case N => + // println(s"$path: One of the test failed") + // val speeds = results.collect { case (_, S(speed)) => speed } + // val avg = speeds.sum / speeds.length + // println(f"Average speed ratio: ${avg * 100}%.3f%%") + // val std = math.sqrt(speeds.map(s => (s - avg) * (s - avg)).sum / speeds.length) + // println(f"Standard deviation: ${std * 100}%.3f%%") + // println(f"Min speed ratio: ${speeds.min * 100}%.3f%%") + // println(f"Max speed ratio: ${speeds.max * 100}%.3f%%") +} diff --git a/benchmark/src/nofib/ansi.mls b/benchmark/src/nofib/ansi.mls new file mode 100644 index 000000000..2e045bb89 --- /dev/null +++ b/benchmark/src/nofib/ansi.mls @@ -0,0 +1,98 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module ansi with ... + + +val cls = nofibStringToList("L") +//│ cls = ["L"] + +fun goto(x, y) = "E" :: "[" :: (nofibStringToList(stringOfInt(y)) +: (";" :: nofibStringToList(stringOfInt(x)) +: nofibStringToList("H"))) + +fun at(x_y, s) = if x_y is [x, y] then goto(x, y) +: s + +fun highlight(s) = nofibStringToList("ESC[7m") +: s +: nofibStringToList("ESC[0m") + +fun end(xs) = nofibStringToList("") + +fun readChar(eof, consume, cs) = if cs is + Nil then eof(Nil) + c :: cs then consume(c, cs) + +fun peekChar(eof, consume, cs) = if cs is + Nil then eof(Nil) + c :: cs then consume(c, c :: cs) + +fun pressAnyKey(prog, x) = readChar(prog, (c, x) => prog(x), x) + +fun unreadChar(c, prog, cs) = prog(c :: cs) + +fun writeChar(c, prog, cs) = c :: prog(cs) + +fun writeString(s, prog, cs) = s +: prog(cs) + +fun writes(ss, a, b) = writeString(concat(ss), a, b) + +fun ringBell(prog, cs) = writeChar("B", prog, cs) + +fun clearScreen(a, b) = writeString(cls, a, b) + +fun writeAt(x_y, s, a) = if x_y is [x, y] then p => writeString(goto(x, y) +: s, a, p) + +fun moveTo(x_y, a) = if x_y is [x, y] then p => writeString(goto(x, y), a, p) + +fun returnn(s, consume) = consume(reverse(s)) + +//│ ———————————————————————————————————————————————————————————————————————————————— +fun deletee(n, s, l, consume, d) = if n > 0 then writeString(nofibStringToList("BS_BS"), loop(n - 1, tail(s), l, consume), d) else ringBell(loop(0, nofibStringToList(""), l, consume), d) + +fun loop(n, s, l, consume) = x => readChar of + returnn(s, consume) + (c, d) => if + c == "B" then deletee(n, s, l, consume, d) + c == "D" then deletee(n, s, l, consume, d) + c == "`" then returnn(s, consume)(d) + n < l then writeChar(c, loop(n + 1, c :: s, l, consume), d) + else ringBell(loop(n, s, l, consume), d) + x +//│ ———————————————————————————————————————————————————————————————————————————————— + +fun readAt(x_y, l, consume) = writeAt(x_y, replicate(l, "_"), moveTo(x_y, loop(0, "", l, consume))) + +fun promptReadAt(x_y, l, prompt, consume) = if x_y is [x, y] then + writeAt([x, y], prompt, readAt([x + listLen(prompt), y], l, consume)) + +fun program(input) = writes( + cls :: + at([17, 5], highlight(nofibStringToList("Demonstration program"))) :: + at([48, 5], nofibStringToList("Version 1.0")) :: + at([17, 7], nofibStringToList("This program illustrates a simple approach")) :: + at([17, 8], nofibStringToList("to screen-based interactive programs using")) :: + at([17, 9], nofibStringToList("the Hugs functional programming system.")) :: + at([17, 11], nofibStringToList("Please press any key to continue ...")) :: + Nil, + x => pressAnyKey(promptReadAt( + [17, 15], + 18, + nofibStringToList("Please enter your name: "), + (name) => + let reply = nofibStringToList("Hello ") +: name +: nofibStringToList("!") + writeAt( + [40 - (listLen(reply) / 2), 18], + reply, + moveTo( + [1, 23], + y => writeString(nofibStringToList("I'm waiting..."), x => pressAnyKey(end, x), y) + ) + ) + ), x), + input +) + +fun testAnsi_nofib(n) = foldr(compose, (x) => x, replicate(n, program))(nofibStringToList("testtesttest")) + +fun main() = nofibListToString(testAnsi_nofib(1)) +//│ = "LE[5;17HESC[7mDemonstration programESC[0mE[5;48HVersion 1.0E[7;17HThis program illustrates a simple approachE[8;17Hto screen-based interactive programs usingE[9;17Hthe Hugs functional programming system.E[11;17HPlease press any key to continue ...E[15;17HPlease enter your name: E[15;41H__________________E[15;41HesttesttestE[18;31HHello esttesttest!E[23;1HI'm waiting..." diff --git a/benchmark/src/nofib/atom.mls b/benchmark/src/nofib/atom.mls new file mode 100644 index 000000000..44fced24e --- /dev/null +++ b/benchmark/src/nofib/atom.mls @@ -0,0 +1,53 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module atom with ... + + + +data class State(position: List[Num], velocity: List[Num]) + +fun dotPlus(fs, gs) = if + fs is Nil then gs + gs is Nil then fs + fs is f :: fs and gs is g :: gs then (f + g) :: dotPlus(fs, gs) + +fun dotMult(fs, gs) = if + fs is f :: fs and gs is g :: gs then (f * g) :: dotMult(fs, gs) + else Nil + +fun scalarMut(c, fs) = if fs is + Nil then Nil + f :: fs then (c * f) :: scalarMut(c, fs) + +fun testforce(k, ss) = lazy of () => + if force(ss) is + LzCons(State(pos, vel), atoms) then LzCons(dotMult(scalarMut(-1.0, k), pos), testforce(k, atoms)) + +fun show(s) = + fun lscomp(ls) = if ls is + Nil then Nil + component :: t then Cons(stringConcat(stringOfFloat(component), "\t"), lscomp(t)) + if s is State(pos, vel) then + stringListConcat of lscomp(pos) + +fun propagate(dt, aforce, state) = if state is State(pos, vel) then + State(dotPlus(pos, scalarMut(dt, vel)), dotPlus(vel, scalarMut(dt, aforce))) + +fun runExperiment(law, dt, param, init) = lazy of () => + let stream = runExperiment(law, dt, param, init) + LzCons(init, zipWith_lz_lz((x, y) => propagate(dt, x, y), law(param, stream), stream)) + +fun testAtom_nofib(n) = + fun lscomp(ls) = if ls is + Nil then Nil + state :: t then stringConcat(show(state), "\n") :: lscomp(t) + stringListConcat of lscomp(take_lz(n, runExperiment(testforce, 0.02, 1.0 :: Nil, State(1.0 :: Nil, 0.0 :: Nil)))) + + +// NOTE: original input 1000 +fun main() = testAtom_nofib(20) +//│ = "1\t\n1\t\n0.9996\t\n0.9988\t\n0.9976001600000001\t\n0.9960008\t\n0.994002399936\t\n0.991605599552\t\n0.9888111982080257\t\n0.9856201546242305\t\n0.982033586561152\t\n0.978052770436224\t\n0.9736791408766714\t\n0.9689142902089444\t\n0.9637599678848666\t\n0.9582180798447053\t\n0.95229068781739\t\n0.9459800085581369\t\n0.9392884130237569\t\n0.9322184254859536\t\n" diff --git a/benchmark/src/nofib/awards.mls b/benchmark/src/nofib/awards.mls new file mode 100644 index 000000000..ca0f5aa49 --- /dev/null +++ b/benchmark/src/nofib/awards.mls @@ -0,0 +1,177 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module awards with ... + + + +fun delete_(xs, e) = deleteBy((x, y) => x == y, e, xs) + +fun listDiff(a, ls) = foldl(delete_, a, ls) + +//│ ———————————————————————————————————————————————————————————————————————————————— +fun qsort(le, ls, r) = if ls is + Nil then r + x :: Nil then x :: r + x :: xs then qpart(le, x, xs, Nil, Nil, r) + +fun qpart(le, x, ys, rlt, rge, r) = if ys is + Nil then rqsort(le, rlt, x :: rqsort(le, rge, r)) + y :: ys and + le(x, y) then qpart(le, x, ys, rlt, y :: rge, r) + else qpart(le, x, ys, y :: rlt, rge, r) + +fun rqsort(le, ls, r) = if ls is + Nil then r + x :: Nil then x :: r + x :: xs then rqpart(le, x, xs, Nil, Nil, r) + +fun rqpart(le, x, yss, rle, rgt, r) = if yss is + Nil then qsort(le, rle, x :: qsort(le, rgt, r)) + y :: ys and + le(y, x) then rqpart(le, x, ys, y :: rle, rgt, r) + else rqpart(le, x, ys, rle, y :: rgt, r) +//│ ———————————————————————————————————————————————————————————————————————————————— + +fun sort(l) = qsort((a, b) => ltTup2(a, b, (a, b) => a < b, (a, b) => a > b, (a, b) => ltList(a, b, (a, b) => a < b, (a, b) => a > b)), l, Nil) + +fun perms(m, nns) = if + nns is Nil then Nil + m == 1 then map(x => x :: Nil, nns) + nns is n :: ns then map(x => n :: x, perms(m-1, ns)) +: perms(m, ns) + +fun awards(scores) = + let sumscores = map(p => [sum(p), p], perms(3, scores)) + + fun atleast(threshold) = + filter(case { [sum_, p] then sum_ >= threshold }, sumscores) + + fun award(name_threshold) = if name_threshold is [name, threshold] then + map(ps => [name, ps], sort(atleast(threshold))) + + award(["Gold", 70]) +: award(["Silver", 60]) +: award(["Bronze", 50]) + +fun findawards(scores) = if awards(scores) is + Nil then Nil + head_ :: tail_ and head_ is [award, [sum_, perm]] then + [award, [sum_, perm]] :: findawards(listDiff(scores, perm)) + +fun findallawards(competitors) = + map(case { [name, scores] then [name, findawards(scores)] }, competitors) + +fun competitors(i) = list of + ["Simon", list of 35, 27, 40, i, 34, 21] + ["Hans", list of 23, 19, 45, i, 17, 10, 5, 8, 14] + ["Phil", list of 1, 18, i, 20, 21, 19, 34, 8, 16, 21] + ["Kevin", list of 9, 23, 17, 54, i, 41, 9, 18, 14] + +fun testAwards_nofib(n) = + map(x => print(findallawards(competitors(intMod(x, 100)))), enumFromTo(1, n)) + + +// NOTE: original input 1000 +fun main() = testAwards_nofib(100) +//│ > [["Simon", [["Gold", [70, [35,1,34]]],["Gold", [88, [27,40,21]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Bronze", [52, [23,19,10]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]]]]] +//│ > [["Simon", [["Gold", [71, [35,2,34]]],["Gold", [88, [27,40,21]]]]],["Hans", [["Gold", [70, [23,45,2]]],["Bronze", [50, [19,17,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [70, [54,2,14]]],["Gold", [73, [9,23,41]]]]]] +//│ > [["Simon", [["Gold", [70, [27,40,3]]],["Gold", [90, [35,34,21]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Bronze", [52, [23,19,10]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [71, [54,3,14]]],["Gold", [73, [9,23,41]]]]]] +//│ > [["Simon", [["Gold", [71, [27,40,4]]],["Gold", [90, [35,34,21]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Bronze", [52, [23,19,10]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]]]]] +//│ > [["Simon", [["Gold", [72, [27,40,5]]],["Gold", [90, [35,34,21]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Bronze", [52, [23,19,10]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]]]]] +//│ > [["Simon", [["Gold", [73, [27,40,6]]],["Gold", [90, [35,34,21]]]]],["Hans", [["Gold", [70, [19,45,6]]],["Bronze", [50, [23,17,10]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [70, [23,6,41]]],["Gold", [72, [9,54,9]]]]]] +//│ > [["Simon", [["Gold", [74, [27,40,7]]],["Gold", [90, [35,34,21]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Bronze", [52, [23,19,10]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [70, [9,54,7]]],["Gold", [72, [17,41,14]]],["Bronze", [50, [23,9,18]]]]]] +//│ > [["Simon", [["Gold", [70, [35,27,8]]],["Gold", [95, [40,34,21]]]]],["Hans", [["Gold", [70, [45,8,17]]],["Bronze", [50, [23,19,8]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [71, [9,54,8]]],["Gold", [72, [17,41,14]]],["Bronze", [50, [23,9,18]]]]]] +//│ > [["Simon", [["Gold", [70, [27,9,34]]],["Gold", [96, [35,40,21]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Bronze", [51, [23,19,9]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Bronze", [50, [23,9,18]]]]]] +//│ > [["Simon", [["Gold", [71, [27,10,34]]],["Gold", [96, [35,40,21]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Bronze", [52, [23,19,10]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Bronze", [51, [23,10,18]]]]]] +//│ > [["Simon", [["Gold", [72, [27,11,34]]],["Gold", [96, [35,40,21]]]]],["Hans", [["Gold", [70, [45,11,14]]],["Bronze", [50, [23,17,10]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [70, [11,41,18]]],["Gold", [72, [9,54,9]]],["Bronze", [54, [23,17,14]]]]]] +//│ > [["Simon", [["Gold", [73, [27,12,34]]],["Gold", [96, [35,40,21]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Bronze", [52, [23,19,10]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [70, [17,12,41]]],["Gold", [72, [9,54,9]]],["Bronze", [55, [23,18,14]]]]]] +//│ > [["Simon", [["Gold", [74, [27,13,34]]],["Gold", [96, [35,40,21]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Bronze", [50, [23,13,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [71, [17,13,41]]],["Gold", [72, [9,54,9]]],["Bronze", [55, [23,18,14]]]]]] +//│ > [["Simon", [["Gold", [70, [35,14,21]]],["Gold", [101, [27,40,34]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Bronze", [51, [23,14,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,14,41]]],["Bronze", [55, [23,18,14]]]]]] +//│ > [["Simon", [["Gold", [70, [15,34,21]]],["Gold", [102, [35,27,40]]]]],["Hans", [["Gold", [70, [45,15,10]]],["Bronze", [50, [19,17,14]]]]],["Phil", [["Gold", [70, [15,21,34]]],["Silver", [60, [20,19,21]]]]],["Kevin", [["Gold", [70, [15,41,14]]],["Gold", [72, [9,54,9]]],["Bronze", [58, [23,17,18]]]]]] +//│ > [["Simon", [["Gold", [71, [16,34,21]]],["Gold", [102, [35,27,40]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Bronze", [52, [23,19,10]]]]],["Phil", [["Gold", [70, [16,20,34]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [71, [16,41,14]]],["Gold", [72, [9,54,9]]],["Bronze", [58, [23,17,18]]]]]] +//│ > [["Simon", [["Gold", [72, [17,34,21]]],["Gold", [102, [35,27,40]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Bronze", [50, [19,17,14]]]]],["Phil", [["Gold", [70, [17,19,34]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Bronze", [58, [23,17,18]]]]]] +//│ > [["Simon", [["Gold", [73, [18,34,21]]],["Gold", [102, [35,27,40]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Silver", [60, [23,19,18]]]]],["Phil", [["Gold", [70, [18,18,34]]],["Silver", [60, [20,19,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Bronze", [59, [23,18,18]]]]]] +//│ > [["Simon", [["Gold", [74, [19,34,21]]],["Gold", [102, [35,27,40]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Silver", [61, [23,19,19]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Silver", [60, [23,19,18]]]]]] +//│ > [["Simon", [["Gold", [75, [20,34,21]]],["Gold", [102, [35,27,40]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Silver", [62, [23,19,20]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [70, [9,20,41]]],["Gold", [77, [54,9,14]]],["Bronze", [58, [23,17,18]]]]]] +//│ > [["Simon", [["Gold", [76, [21,34,21]]],["Gold", [102, [35,27,40]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Silver", [63, [23,19,21]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [71, [9,21,41]]],["Gold", [77, [54,9,14]]],["Bronze", [58, [23,17,18]]]]]] +//│ > [["Simon", [["Gold", [70, [27,22,21]]],["Gold", [109, [35,40,34]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Silver", [64, [23,19,22]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,22,41]]],["Gold", [77, [54,9,14]]],["Bronze", [58, [23,17,18]]]]]] +//│ > [["Simon", [["Gold", [71, [27,23,21]]],["Gold", [109, [35,40,34]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Silver", [60, [23,23,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Silver", [60, [18,21,21]]],["Bronze", [50, [23,19,8]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Silver", [64, [23,23,18]]]]]] +//│ > [["Simon", [["Gold", [72, [27,24,21]]],["Gold", [109, [35,40,34]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Silver", [61, [23,24,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Silver", [60, [18,21,21]]],["Bronze", [51, [24,19,8]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Silver", [65, [23,24,18]]]]]] +//│ > [["Simon", [["Gold", [73, [27,25,21]]],["Gold", [109, [35,40,34]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Silver", [62, [23,25,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Silver", [60, [18,21,21]]],["Bronze", [52, [25,19,8]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Silver", [66, [23,25,18]]]]]] +//│ > [["Simon", [["Gold", [74, [27,26,21]]],["Gold", [109, [35,40,34]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Silver", [63, [23,26,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Silver", [60, [18,21,21]]],["Bronze", [53, [26,19,8]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Silver", [67, [23,26,18]]]]]] +//│ > [["Simon", [["Gold", [75, [27,27,21]]],["Gold", [109, [35,40,34]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Silver", [60, [19,27,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Silver", [60, [18,21,21]]],["Bronze", [54, [27,19,8]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Silver", [68, [23,27,18]]]]]] +//│ > [["Simon", [["Gold", [76, [27,28,21]]],["Gold", [109, [35,40,34]]]]],["Hans", [["Gold", [70, [23,19,28]]],["Gold", [70, [45,17,8]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [70, [28,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Silver", [69, [23,28,18]]]]]] +//│ > [["Simon", [["Gold", [77, [27,29,21]]],["Gold", [109, [35,40,34]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [71, [23,19,29]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [71, [29,21,21]]]]],["Kevin", [["Gold", [70, [23,29,18]]],["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]]]]] +//│ > [["Simon", [["Gold", [78, [27,30,21]]],["Gold", [109, [35,40,34]]]]],["Hans", [["Gold", [70, [23,30,17]]],["Gold", [72, [19,45,8]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [70, [30,19,21]]]]],["Kevin", [["Gold", [70, [23,17,30]]],["Gold", [72, [9,54,9]]],["Gold", [73, [41,18,14]]]]]] +//│ > [["Simon", [["Gold", [79, [27,31,21]]],["Gold", [109, [35,40,34]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [73, [23,19,31]]]]],["Phil", [["Gold", [70, [18,31,21]]],["Gold", [70, [20,34,16]]]]],["Kevin", [["Gold", [71, [23,17,31]]],["Gold", [72, [9,54,9]]],["Gold", [73, [41,18,14]]]]]] +//│ > [["Simon", [["Gold", [80, [27,32,21]]],["Gold", [109, [35,40,34]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [74, [23,19,32]]]]],["Phil", [["Gold", [70, [18,32,20]]],["Gold", [71, [21,34,16]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [73, [23,32,18]]]]]] +//│ > [["Simon", [["Gold", [81, [27,33,21]]],["Gold", [109, [35,40,34]]]]],["Hans", [["Gold", [70, [23,33,14]]],["Gold", [70, [45,17,8]]]]],["Phil", [["Gold", [70, [18,33,19]]],["Gold", [70, [20,34,16]]],["Bronze", [50, [21,8,21]]]]],["Kevin", [["Gold", [70, [23,33,14]]],["Gold", [72, [9,54,9]]],["Gold", [76, [17,41,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [109, [35,40,34]]]]],["Hans", [["Gold", [70, [19,34,17]]],["Gold", [73, [23,45,5]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [71, [18,19,34]]],["Bronze", [50, [21,8,21]]]]],["Kevin", [["Gold", [71, [23,34,14]]],["Gold", [72, [9,54,9]]],["Gold", [76, [17,41,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [110, [35,40,35]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [72, [23,35,14]]]]],["Phil", [["Gold", [70, [1,35,34]]],["Silver", [60, [18,21,21]]],["Bronze", [55, [20,19,16]]]]],["Kevin", [["Gold", [70, [17,35,18]]],["Gold", [72, [9,54,9]]],["Gold", [78, [23,41,14]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [111, [35,40,36]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [73, [23,36,14]]]]],["Phil", [["Gold", [70, [18,36,16]]],["Gold", [73, [20,19,34]]],["Bronze", [50, [21,8,21]]]]],["Kevin", [["Gold", [71, [17,36,18]]],["Gold", [72, [9,54,9]]],["Gold", [78, [23,41,14]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [112, [35,40,37]]]]],["Hans", [["Gold", [70, [19,37,14]]],["Gold", [70, [45,17,8]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [74, [18,37,19]]],["Bronze", [50, [21,8,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,37,18]]],["Gold", [78, [23,41,14]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [113, [35,40,38]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [71, [19,38,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [75, [18,38,19]]],["Bronze", [50, [21,8,21]]]]],["Kevin", [["Gold", [70, [9,23,38]]],["Gold", [72, [17,41,14]]],["Gold", [81, [54,9,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [114, [35,40,39]]]]],["Hans", [["Gold", [70, [23,39,8]]],["Gold", [72, [45,17,10]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [76, [18,39,19]]],["Bronze", [50, [21,8,21]]]]],["Kevin", [["Gold", [70, [17,39,14]]],["Gold", [72, [9,54,9]]],["Gold", [82, [23,41,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [115, [35,40,40]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [73, [19,40,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [77, [18,40,19]]],["Bronze", [50, [21,8,21]]]]],["Kevin", [["Gold", [71, [17,40,14]]],["Gold", [72, [9,54,9]]],["Gold", [82, [23,41,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [116, [35,40,41]]]]],["Hans", [["Gold", [70, [19,41,10]]],["Gold", [70, [45,17,8]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [70, [41,8,21]]],["Bronze", [58, [18,19,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [82, [23,41,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [117, [35,40,42]]]]],["Hans", [["Gold", [70, [23,42,5]]],["Gold", [70, [45,17,8]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [71, [42,8,21]]],["Bronze", [58, [18,19,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [83, [23,42,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [118, [35,40,43]]]]],["Hans", [["Gold", [70, [19,43,8]]],["Gold", [72, [45,17,10]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [70, [43,19,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [70, [9,43,18]]],["Gold", [72, [17,41,14]]],["Gold", [86, [23,54,9]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [119, [35,40,44]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [72, [23,44,5]]]]],["Phil", [["Gold", [70, [18,44,8]]],["Gold", [70, [20,34,16]]],["Silver", [61, [21,19,21]]]]],["Kevin", [["Gold", [70, [9,17,44]]],["Gold", [73, [23,41,9]]],["Gold", [86, [54,18,14]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [120, [35,40,45]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [73, [23,45,5]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [71, [18,45,8]]],["Silver", [61, [21,19,21]]]]],["Kevin", [["Gold", [71, [9,17,45]]],["Gold", [73, [23,41,9]]],["Gold", [86, [54,18,14]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [121, [35,40,46]]]]],["Hans", [["Gold", [70, [19,46,5]]],["Gold", [70, [45,17,8]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [72, [18,46,8]]],["Silver", [61, [21,19,21]]]]],["Kevin", [["Gold", [72, [9,17,46]]],["Gold", [73, [23,41,9]]],["Gold", [86, [54,18,14]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [122, [35,40,47]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [71, [19,47,5]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [73, [18,47,8]]],["Silver", [61, [21,19,21]]]]],["Kevin", [["Gold", [70, [9,47,14]]],["Gold", [73, [23,41,9]]],["Gold", [89, [17,54,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [123, [35,40,48]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [72, [19,48,5]]]]],["Phil", [["Gold", [70, [1,48,21]]],["Gold", [70, [20,34,16]]],["Bronze", [58, [18,19,21]]]]],["Kevin", [["Gold", [71, [9,48,14]]],["Gold", [73, [23,41,9]]],["Gold", [89, [17,54,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [124, [35,40,49]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [73, [19,49,5]]]]],["Phil", [["Gold", [70, [1,49,20]]],["Gold", [71, [18,19,34]]],["Bronze", [50, [21,8,21]]]]],["Kevin", [["Gold", [72, [9,49,14]]],["Gold", [73, [23,41,9]]],["Gold", [89, [17,54,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [125, [35,40,50]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [74, [19,50,5]]]]],["Phil", [["Gold", [70, [1,50,19]]],["Gold", [70, [20,34,16]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [91, [23,50,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [126, [35,40,51]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [70, [51,5,14]]],["Bronze", [52, [23,19,10]]]]],["Phil", [["Gold", [70, [1,18,51]]],["Gold", [70, [20,34,16]]],["Silver", [61, [21,19,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [92, [23,51,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [127, [35,40,52]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [71, [52,5,14]]],["Bronze", [52, [23,19,10]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [71, [1,18,52]]],["Silver", [61, [21,19,21]]]]],["Kevin", [["Gold", [70, [9,52,9]]],["Gold", [72, [17,41,14]]],["Gold", [95, [23,54,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [128, [35,40,53]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [72, [53,5,14]]],["Bronze", [52, [23,19,10]]]]],["Phil", [["Gold", [70, [1,53,16]]],["Gold", [71, [18,19,34]]],["Silver", [62, [20,21,21]]]]],["Kevin", [["Gold", [71, [9,53,9]]],["Gold", [72, [17,41,14]]],["Gold", [95, [23,54,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [129, [35,40,54]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [73, [54,5,14]]],["Bronze", [52, [23,19,10]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [73, [1,18,54]]],["Silver", [61, [21,19,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [95, [23,54,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [130, [35,40,55]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [70, [55,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [74, [1,18,55]]],["Silver", [61, [21,19,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [96, [23,55,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [131, [35,40,56]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [71, [56,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [75, [1,18,56]]],["Silver", [61, [21,19,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [97, [23,56,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [132, [35,40,57]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [72, [57,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [76, [1,18,57]]],["Silver", [61, [21,19,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [98, [23,57,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [133, [35,40,58]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [73, [58,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [77, [1,18,58]]],["Silver", [61, [21,19,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [99, [23,58,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [134, [35,40,59]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [74, [59,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [78, [1,18,59]]],["Silver", [61, [21,19,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [100, [23,59,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [135, [35,40,60]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [75, [60,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [79, [1,18,60]]],["Silver", [61, [21,19,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [101, [23,60,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [136, [35,40,61]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [76, [61,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [1,61,8]]],["Gold", [70, [20,34,16]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [102, [23,61,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [137, [35,40,62]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [77, [62,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [71, [1,62,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [103, [23,62,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [138, [35,40,63]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [78, [63,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [72, [1,63,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [104, [23,63,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [139, [35,40,64]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [79, [64,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [73, [1,64,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [105, [23,64,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [140, [35,40,65]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [80, [65,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [74, [1,65,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [106, [23,65,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [141, [35,40,66]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [81, [66,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [75, [1,66,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [107, [23,66,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [142, [35,40,67]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [82, [67,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [76, [1,67,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [108, [23,67,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [143, [35,40,68]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [83, [68,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [77, [1,68,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [109, [23,68,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [144, [35,40,69]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [84, [69,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [78, [1,69,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [110, [23,69,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [145, [35,40,70]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [85, [70,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [79, [1,70,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [111, [23,70,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [146, [35,40,71]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [86, [71,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [80, [1,71,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [112, [23,71,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [147, [35,40,72]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [87, [72,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [81, [1,72,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [113, [23,72,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [148, [35,40,73]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [88, [73,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [82, [1,73,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [114, [23,73,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [149, [35,40,74]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [89, [74,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [83, [1,74,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [115, [23,74,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [150, [35,40,75]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [90, [75,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [84, [1,75,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [116, [23,75,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [151, [35,40,76]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [91, [76,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [85, [1,76,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [117, [23,76,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [152, [35,40,77]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [92, [77,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [86, [1,77,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [118, [23,77,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [153, [35,40,78]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [93, [78,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [87, [1,78,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [119, [23,78,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [154, [35,40,79]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [94, [79,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [88, [1,79,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [120, [23,79,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [155, [35,40,80]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [95, [80,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [89, [1,80,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [121, [23,80,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [156, [35,40,81]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [96, [81,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [90, [1,81,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [122, [23,81,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [157, [35,40,82]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [97, [82,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [91, [1,82,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [123, [23,82,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [158, [35,40,83]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [98, [83,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [92, [1,83,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [124, [23,83,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [159, [35,40,84]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [99, [84,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [93, [1,84,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [125, [23,84,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [160, [35,40,85]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [100, [85,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [94, [1,85,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [126, [23,85,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [161, [35,40,86]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [101, [86,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [95, [1,86,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [127, [23,86,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [162, [35,40,87]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [102, [87,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [96, [1,87,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [128, [23,87,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [163, [35,40,88]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [103, [88,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [97, [1,88,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [129, [23,88,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [164, [35,40,89]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [104, [89,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [98, [1,89,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [130, [23,89,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [165, [35,40,90]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [105, [90,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [99, [1,90,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [131, [23,90,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [166, [35,40,91]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [106, [91,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [100, [1,91,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [132, [23,91,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [167, [35,40,92]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [107, [92,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [101, [1,92,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [133, [23,92,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [168, [35,40,93]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [108, [93,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [102, [1,93,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [134, [23,93,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [169, [35,40,94]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [109, [94,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [103, [1,94,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [135, [23,94,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [170, [35,40,95]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [110, [95,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [104, [1,95,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [136, [23,95,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [171, [35,40,96]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [111, [96,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [105, [1,96,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [137, [23,96,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [172, [35,40,97]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [112, [97,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [106, [1,97,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [138, [23,97,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [173, [35,40,98]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [113, [98,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [107, [1,98,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [139, [23,98,18]]]]]] +//│ > [["Simon", [["Gold", [82, [27,34,21]]],["Gold", [174, [35,40,99]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Gold", [114, [99,10,5]]],["Bronze", [56, [23,19,14]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Gold", [108, [1,99,8]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [72, [9,54,9]]],["Gold", [72, [17,41,14]]],["Gold", [140, [23,99,18]]]]]] +//│ > [["Simon", [["Gold", [74, [40,0,34]]],["Gold", [83, [35,27,21]]]]],["Hans", [["Gold", [70, [45,17,8]]],["Bronze", [52, [23,19,10]]]]],["Phil", [["Gold", [70, [20,34,16]]],["Silver", [60, [18,21,21]]]]],["Kevin", [["Gold", [71, [17,54,0]]],["Gold", [73, [9,23,41]]]]]] +//│ = [(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),(),()] diff --git a/benchmark/src/nofib/banner.mls b/benchmark/src/nofib/banner.mls new file mode 100644 index 000000000..a287abcbb --- /dev/null +++ b/benchmark/src/nofib/banner.mls @@ -0,0 +1,124 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module banner with ... + + + +val blank = + nofibStringToList(" ") :: + nofibStringToList(" ") :: + nofibStringToList(" ") :: + nofibStringToList(" ") :: + nofibStringToList(" ") :: Nil +//│ blank = [[" "," "," "," "," "],[" "," "," "," "," "],[" "," "," "," "," "],[" "," "," "," "," "],[" "," "," "," "," "]] + +val alphas = + (nofibStringToList(" A ") :: nofibStringToList(" A A ") :: nofibStringToList("AAAAA") :: nofibStringToList("A A") :: nofibStringToList("A A") :: Nil) :: + (nofibStringToList("BBBB ") :: nofibStringToList("B B") :: nofibStringToList("BBBB ") :: nofibStringToList("B B") :: nofibStringToList("BBBB ") :: Nil) :: + (nofibStringToList(" CCCC") :: nofibStringToList("C ") :: nofibStringToList("C ") :: nofibStringToList("C ") :: nofibStringToList(" CCCC") :: Nil) :: + (nofibStringToList("DDDD ") :: nofibStringToList("D D") :: nofibStringToList("D D") :: nofibStringToList("D D") :: nofibStringToList("DDDD ") :: Nil) :: + (nofibStringToList("EEEEE") :: nofibStringToList("E ") :: nofibStringToList("EEEEE") :: nofibStringToList("E ") :: nofibStringToList("EEEEE") :: Nil) :: + (nofibStringToList("FFFFF") :: nofibStringToList("F ") :: nofibStringToList("FFFF ") :: nofibStringToList("F ") :: nofibStringToList("F ") :: Nil) :: + (nofibStringToList(" GGGG") :: nofibStringToList("G ") :: nofibStringToList("G GG") :: nofibStringToList("G G") :: nofibStringToList(" GGG ") :: Nil) :: + (nofibStringToList("H H") :: nofibStringToList("H H") :: nofibStringToList("HHHHH") :: nofibStringToList("H H") :: nofibStringToList("H H") :: Nil) :: + (nofibStringToList("IIIII") :: nofibStringToList(" I ") :: nofibStringToList(" I ") :: nofibStringToList(" I ") :: nofibStringToList("IIIII") :: Nil) :: + (nofibStringToList("JJJJJ") :: nofibStringToList(" J ") :: nofibStringToList(" J ") :: nofibStringToList("J J ") :: nofibStringToList(" JJ ") :: Nil) :: + (nofibStringToList("K K") :: nofibStringToList("K K ") :: nofibStringToList("KKK ") :: nofibStringToList("K K ") :: nofibStringToList("K K") :: Nil) :: + (nofibStringToList("L ") :: nofibStringToList("L ") :: nofibStringToList("L ") :: nofibStringToList("L ") :: nofibStringToList("LLLLL") :: Nil) :: + (nofibStringToList("M M") :: nofibStringToList("MM MM") :: nofibStringToList("M M M") :: nofibStringToList("M M") :: nofibStringToList("M M") :: Nil) :: + (nofibStringToList("N N") :: nofibStringToList("NN N") :: nofibStringToList("N N N") :: nofibStringToList("N NN") :: nofibStringToList("N N") :: Nil) :: + (nofibStringToList(" OOO ") :: nofibStringToList("O O") :: nofibStringToList("O O") :: nofibStringToList("O O") :: nofibStringToList(" OOO ") :: Nil) :: + (nofibStringToList("PPPP ") :: nofibStringToList("P P") :: nofibStringToList("PPPP ") :: nofibStringToList("P ") :: nofibStringToList("P ") :: Nil) :: + (nofibStringToList(" QQQ ") :: nofibStringToList("Q Q") :: nofibStringToList("Q Q Q") :: nofibStringToList("Q Q ") :: nofibStringToList(" QQ Q") :: Nil) :: + (nofibStringToList("RRRR ") :: nofibStringToList("R R") :: nofibStringToList("RRRR ") :: nofibStringToList("R R ") :: nofibStringToList("R R") :: Nil) :: + (nofibStringToList(" SSSS") :: nofibStringToList("S ") :: nofibStringToList(" SSS ") :: nofibStringToList(" S") :: nofibStringToList("SSSS ") :: Nil) :: + (nofibStringToList("TTTTT") :: nofibStringToList(" T ") :: nofibStringToList(" T ") :: nofibStringToList(" T ") :: nofibStringToList(" T ") :: Nil) :: + (nofibStringToList("U U") :: nofibStringToList("U U") :: nofibStringToList("U U") :: nofibStringToList("U U") :: nofibStringToList(" UUU ") :: Nil) :: + (nofibStringToList("V V") :: nofibStringToList("V V") :: nofibStringToList("V V") :: nofibStringToList(" V V ") :: nofibStringToList(" V ") :: Nil) :: + (nofibStringToList("W W") :: nofibStringToList("W W") :: nofibStringToList("W W") :: nofibStringToList("W W W") :: nofibStringToList(" W W ") :: Nil) :: + (nofibStringToList("X X") :: nofibStringToList(" X X ") :: nofibStringToList(" X ") :: nofibStringToList(" X X ") :: nofibStringToList("X X") :: Nil) :: + (nofibStringToList("Y Y") :: nofibStringToList(" Y Y ") :: nofibStringToList(" Y ") :: nofibStringToList(" Y ") :: nofibStringToList(" Y ") :: Nil) :: + (nofibStringToList("ZZZZZ") :: nofibStringToList(" Z ") :: nofibStringToList(" Z ") :: nofibStringToList(" Z ") :: nofibStringToList("ZZZZZ") :: Nil) :: Nil +//│ alphas = [[[" "," ","A"," "," "],[" ","A"," ","A"," "],["A","A","A","A","A"],["A"," "," "," ","A"],["A"," "," "," ","A"]],[["B","B","B","B"," "],["B"," "," "," ","B"],["B","B","B","B"," "],["B"," "," "," ","B"],["B","B","B","B"," "]],[[" ","C","C","C","C"],["C"," "," "," "," "],["C"," "," "," "," "],["C"," "," "," "," "],[" ","C","C","C","C"]],[["D","D","D","D"," "],["D"," "," "," ","D"],["D"," "," "," ","D"],["D"," "," "," ","D"],["D","D","D","D"," "]],[["E","E","E","E","E"],["E"," "," "," "," "],["E","E","E","E","E"],["E"," "," "," "," "],["E","E","E","E","E"]],[["F","F","F","F","F"],["F"," "," "," "," "],["F","F","F","F"," "],["F"," "," "," "," "],["F"," "," "," "," "]],[[" ","G","G","G","G"],["G"," "," "," "," "],["G"," "," ","G","G"],["G"," "," "," ","G"],[" ","G","G","G"," "]],[["H"," "," "," ","H"],["H"," "," "," ","H"],["H","H","H","H","H"],["H"," "," "," ","H"],["H"," "," "," ","H"]],[["I","I","I","I","I"],[" "," ","I"," "," "],[" "," ","I"," "," "],[" "," ","I"," "," "],["I","I","I","I","I"]],[["J","J","J","J","J"],[" "," "," ","J"," "],[" "," "," ","J"," "],["J"," "," ","J"," "],[" ","J","J"," "," "]],[["K"," "," "," ","K"],["K"," "," ","K"," "],["K","K","K"," "," "],["K"," "," ","K"," "],["K"," "," "," ","K"]],[["L"," "," "," "," "],["L"," "," "," "," "],["L"," "," "," "," "],["L"," "," "," "," "],["L","L","L","L","L"]],[["M"," "," "," ","M"],["M","M"," ","M","M"],["M"," ","M"," ","M"],["M"," "," "," ","M"],["M"," "," "," ","M"]],[["N"," "," "," ","N"],["N","N"," "," ","N"],["N"," ","N"," ","N"],["N"," "," ","N","N"],["N"," "," "," ","N"]],[[" ","O","O","O"," "],["O"," "," "," ","O"],["O"," "," "," ","O"],["O"," "," "," ","O"],[" ","O","O","O"," "]],[["P","P","P","P"," "],["P"," "," "," ","P"],["P","P","P","P"," "],["P"," "," "," "," "],["P"," "," "," "," "]],[[" ","Q","Q","Q"," "],["Q"," "," "," ","Q"],["Q"," ","Q"," ","Q"],["Q"," "," ","Q"," "],[" ","Q","Q"," ","Q"]],[["R","R","R","R"," "],["R"," "," "," ","R"],["R","R","R","R"," "],["R"," "," ","R"," "],["R"," "," "," ","R"]],[[" ","S","S","S","S"],["S"," "," "," "," "],[" ","S","S","S"," "],[" "," "," "," ","S"],["S","S","S","S"," "]],[["T","T","T","T","T"],[" "," ","T"," "," "],[" "," ","T"," "," "],[" "," ","T"," "," "],[" "," ","T"," "," "]],[["U"," "," "," ","U"],["U"," "," "," ","U"],["U"," "," "," ","U"],["U"," "," "," ","U"],[" ","U","U","U"," "]],[["V"," "," "," ","V"],["V"," "," "," ","V"],["V"," "," "," ","V"],[" ","V"," ","V"," "],[" "," ","V"," "," "]],[["W"," "," "," ","W"],["W"," "," "," ","W"],["W"," "," "," ","W"],["W"," ","W"," ","W"],[" ","W"," ","W"," "]],[["X"," "," "," ","X"],[" ","X"," ","X"," "],[" "," ","X"," "," "],[" ","X"," ","X"," "],["X"," "," "," ","X"]],[["Y"," "," "," ","Y"],[" ","Y"," ","Y"," "],[" "," ","Y"," "," "],[" "," ","Y"," "," "],[" "," ","Y"," "," "]],[["Z","Z","Z","Z","Z"],[" "," "," ","Z"," "],[" "," ","Z"," "," "],[" ","Z"," "," "," "],["Z","Z","Z","Z","Z"]]] + +val slant = + nofibStringToList(" ") :: + nofibStringToList(" ") :: + nofibStringToList(" ") :: + nofibStringToList(" ") :: + nofibStringToList("") :: Nil +//│ slant = [[" "," "," "," "],[" "," "," "],[" "," "],[" "],[]] + +val punct = + [".", nofibStringToList(" ") :: nofibStringToList(" ") :: nofibStringToList(" ") :: nofibStringToList(" .. ") :: nofibStringToList(" .. ") :: Nil] :: + ["?", nofibStringToList(" ??? ") :: nofibStringToList("? ?") :: nofibStringToList(" ? ") :: nofibStringToList(" ? ") :: nofibStringToList(" . ") :: Nil] :: + ["!", nofibStringToList(" ! ") :: nofibStringToList(" ! ") :: nofibStringToList(" ! ") :: nofibStringToList(" ! ") :: nofibStringToList(" . ") :: Nil] :: + ["-", nofibStringToList(" ") :: nofibStringToList(" ") :: nofibStringToList("-----") :: nofibStringToList(" ") :: nofibStringToList(" ") :: Nil] :: + ["+", nofibStringToList(" + ") :: nofibStringToList(" + ") :: nofibStringToList("+++++") :: nofibStringToList(" + ") :: nofibStringToList(" + ") :: Nil] :: + [":", nofibStringToList(" ") :: nofibStringToList(" :: ") :: nofibStringToList(" ") :: nofibStringToList(" :: ") :: nofibStringToList(" ") :: Nil] :: + [";", nofibStringToList(" ") :: nofibStringToList(" ;; ") :: nofibStringToList(" ") :: nofibStringToList(" ;; ") :: nofibStringToList(" ;; ") :: Nil] :: Nil +//│ punct = [[".", [[" "," "," "," "," "],[" "," "," "," "," "],[" "," "," "," "," "],[" "," ",".","."," "],[" "," ",".","."," "]]],["?", [[" ","?","?","?"," "],["?"," "," "," ","?"],[" "," "," ","?"," "],[" "," ","?"," "," "],[" "," ","."," "," "]]],["!", [[" "," ","!"," "," "],[" "," ","!"," "," "],[" "," ","!"," "," "],[" "," ","!"," "," "],[" "," ","."," "," "]]],["-", [[" "," "," "," "," "],[" "," "," "," "," "],["-","-","-","-","-"],[" "," "," "," "," "],[" "," "," "," "," "]]],["+", [[" "," ","+"," "," "],[" "," ","+"," "," "],["+","+","+","+","+"],[" "," ","+"," "," "],[" "," ","+"," "," "]]],[":", [[" "," "," "," "," "],[" "," ",":",":"," "],[" "," "," "," "," "],[" "," ",":",":"," "],[" "," "," "," "," "]]],[";", [[" "," "," "," "," "],[" "," ",";",";"," "],[" "," "," "," "," "],[" "," ",";",";"," "],[" ",";",";"," "," "]]]] + +val digits = + (nofibStringToList(" OOO ") :: nofibStringToList("0 00") :: nofibStringToList("0 0 0") :: nofibStringToList("00 0") :: nofibStringToList(" 000 ") :: Nil) :: + (nofibStringToList(" 1 ") :: nofibStringToList(" 11 ") :: nofibStringToList(" 1 ") :: nofibStringToList(" 1 ") :: nofibStringToList("11111") :: Nil) :: + (nofibStringToList(" 222 ") :: nofibStringToList("2 2") :: nofibStringToList(" 2 ") :: nofibStringToList(" 2 ") :: nofibStringToList("22222") :: Nil) :: + (nofibStringToList("3333 ") :: nofibStringToList(" 3") :: nofibStringToList(" 333 ") :: nofibStringToList(" 3") :: nofibStringToList("3333 ") :: Nil) :: + (nofibStringToList(" 4 ") :: nofibStringToList(" 44 ") :: nofibStringToList(" 4 4 ") :: nofibStringToList("44444") :: nofibStringToList(" 4 ") :: Nil) :: + (nofibStringToList("55555") :: nofibStringToList("5 ") :: nofibStringToList("5555 ") :: nofibStringToList(" 5") :: nofibStringToList("5555 ") :: Nil) :: + (nofibStringToList(" 66") :: nofibStringToList(" 6 ") :: nofibStringToList(" 666 ") :: nofibStringToList("6 6") :: nofibStringToList(" 666 ") :: Nil) :: + (nofibStringToList("77777") :: nofibStringToList(" 7") :: nofibStringToList(" 7 ") :: nofibStringToList(" 7 ") :: nofibStringToList(" 7 ") :: Nil) :: + (nofibStringToList(" 888 ") :: nofibStringToList("8 8") :: nofibStringToList(" 888 ") :: nofibStringToList("8 8") :: nofibStringToList(" 888 ") :: Nil) :: + (nofibStringToList(" 999 ") :: nofibStringToList("9 9") :: nofibStringToList(" 999 ") :: nofibStringToList(" 9 ") :: nofibStringToList("99 ") :: Nil) :: Nil +//│ digits = [[[" ","O","O","O"," "],["0"," "," ","0","0"],["0"," ","0"," ","0"],["0","0"," "," ","0"],[" ","0","0","0"," "]],[[" "," ","1"," "," "],[" ","1","1"," "," "],[" "," ","1"," "," "],[" "," ","1"," "," "],["1","1","1","1","1"]],[[" ","2","2","2"," "],["2"," "," "," ","2"],[" "," "," ","2"," "],[" "," ","2"," "," "],["2","2","2","2","2"]],[["3","3","3","3"," "],[" "," "," "," ","3"],[" ","3","3","3"," "],[" "," "," "," ","3"],["3","3","3","3"," "]],[[" "," "," ","4"," "],[" "," ","4","4"," "],[" ","4"," ","4"," "],["4","4","4","4","4"],[" "," "," ","4"," "]],[["5","5","5","5","5"],["5"," "," "," "," "],["5","5","5","5"," "],[" "," "," "," ","5"],["5","5","5","5"," "]],[[" "," "," ","6","6"],[" "," ","6"," "," "],[" ","6","6","6"," "],["6"," "," "," ","6"],[" ","6","6","6"," "]],[["7","7","7","7","7"],[" "," "," "," ","7"],[" "," "," ","7"," "],[" "," "," ","7"," "],[" "," ","7"," "," "]],[[" ","8","8","8"," "],["8"," "," "," ","8"],[" ","8","8","8"," "],["8"," "," "," ","8"],[" ","8","8","8"," "]],[[" ","9","9","9"," "],["9"," "," "," ","9"],[" ","9","9","9"," "],[" "," ","9"," "," "],["9","9"," "," "," "]]] + +fun unlines(ls) = concat(map(x => x +: ("\n" :: Nil), ls)) + +fun join(ls) = foldr1((xs, ys) => xs +: (" " :: " " :: Nil) +: ys, ls) + +fun isUpper(c) = + let n = int_of_char(c) + (n >= 65) and (n <= 90) + +fun isLower(c) = + let n = int_of_char(c) + (n >= 97) and (n <= 122) + +fun isDigit(c) = + let n = int_of_char(c) + (n >= 48) and (n <= 57) + +fun isSpace(c) = + let n = int_of_char(c) + (n == 32) + +fun picChar(c) = + + fun lscomp(ls) = if ls is + Nil then Nil + h :: t and + h is [c_, letter] and c_ === c then letter :: lscomp(t) + else lscomp(t) + + if + isUpper(c) then atIndex(int_of_char(c) - int_of_char("A"), alphas) + isLower(c) then atIndex(int_of_char(c) - int_of_char("a"), alphas) + isSpace(c) then blank + isDigit(c) then atIndex(int_of_char(c) - int_of_char("0"), digits) + c === "/" then slant + c === "=" then reverse(slant) + else head(lscomp(punct) +: Nil :: Nil :: Nil) + +fun say(s) = "\n" :: (unlines(map(join, transpose(map(picChar, s))))) + +fun testBanner_nofib(n) = + let x = nofibStringToList("Is this not a great banner?") + say(concat(replicate(n, x))) + + +fun main() = nofibListToString(testBanner_nofib(1)) +//│ = "\nIIIII SSSS TTTTT H H IIIII SSSS N N OOO TTTTT A GGGG RRRR EEEEE A TTTTT BBBB A N N N N EEEEE RRRR ??? \n I S T H H I S NN N O O T A A G R R E A A T B B A A NN N NN N E R R ? ?\n I SSS T HHHHH I SSS N N N O O T AAAAA G GG RRRR EEEEE AAAAA T BBBB AAAAA N N N N N N EEEEE RRRR ? \n I S T H H I S N NN O O T A A G G R R E A A T B B A A N NN N NN E R R ? \nIIIII SSSS T H H IIIII SSSS N N OOO T A A GGG R R EEEEE A A T BBBB A A N N N N EEEEE R R . \n" diff --git a/benchmark/src/nofib/boyer.mls b/benchmark/src/nofib/boyer.mls new file mode 100644 index 000000000..9e1dac0e6 --- /dev/null +++ b/benchmark/src/nofib/boyer.mls @@ -0,0 +1,312 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module boyer with ... + + + +abstract class Id: A | B | C | D | X | Y | Z | U | W | ADD1 | AND | APPEND | CONS | CONSP | DIFFERENCE | DIVIDES | EQUAL | EVEN | EXP | F | FALSE | FOUR | GCD | GREATEREQP | GREATERP | IF | IFF | IMPLIES | LENGTH | LESSEQP | LESSP | LISTP | MEMBER | NIL | NILP | NLISTP | NOT | ODD | ONE | OR | PLUS | QUOTIENT | REMAINDER | REVERSE | SUB1 | TIMES | TRUE | TWO | ZERO | ZEROP + +object + A extends Id + B extends Id + C extends Id + D extends Id + X extends Id + Y extends Id + Z extends Id + U extends Id + W extends Id + ADD1 extends Id + AND extends Id + APPEND extends Id + CONS extends Id + CONSP extends Id + DIFFERENCE extends Id + DIVIDES extends Id + EQUAL extends Id + EVEN extends Id + EXP extends Id + F extends Id + FALSE extends Id + FOUR extends Id + GCD extends Id + GREATEREQP extends Id + GREATERP extends Id + IF extends Id + IFF extends Id + IMPLIES extends Id + LENGTH extends Id + LESSEQP extends Id + LESSP extends Id + LISTP extends Id + MEMBER extends Id + NIL extends Id + NILP extends Id + NLISTP extends Id + NOT extends Id + ODD extends Id + ONE extends Id + OR extends Id + PLUS extends Id + QUOTIENT extends Id + REMAINDER extends Id + REVERSE extends Id + SUB1 extends Id + TIMES extends Id + TRUE extends Id + TWO extends Id + ZERO extends Id + ZEROP extends Id + +abstract class Term: Var | Fun | ERROR + +data + class + Var(i: Id) extends Term + Fun(i: Id, t: List[Term], l: [Term, Term]) extends Term +object ERROR extends Term + + +//│ ———————————————————————————————————————————————————————————————————————————————— +fun termLsEq(h1t1, h2t2) = if + h1t1 is h1 :: t1 and h2t2 is h2 :: t2 and + termEq(h1, h2) then termLsEq(t1, t2) + else false + else true + +fun termEq(t1, t2) = if + t1 is Var(i1) and t2 is Var(i2) then i1 === i2 + t1 is Fun(f1, ts1, _) and t2 is Fun(f2, ts2, _) then (f1 === f2) and termLsEq(ts1, ts2) + else false +//│ ———————————————————————————————————————————————————————————————————————————————— + +fun termInList(term, ht) = if ht is + h :: t and + termEq(term, h) then true + else termInList(term, t) + Nil then false + +fun find(vid, ls) = if ls is + Nil then [false, ERROR] + [vid2, val2] :: bs and + vid === vid2 then [true, val2] + else find(vid, bs) + +//│ ———————————————————————————————————————————————————————————————————————————————— +fun one_way_unify1(term1, term2, subst) = if + term2 is Var(vid2) and find(vid2, subst) is [found, v2] and + found then [termEq(term1, v2), subst] + else [true, [vid2, term1] :: subst] + term1 is Fun(f1, as1, _) and term2 is Fun(f2, as2, _) and + f1 === f2 then one_way_unify1_lst(as1, as2, subst) + else [false, Nil] + else [false, Nil] + +fun one_way_unify1_lst(tts1, tts2, subst) = if + tts1 is Nil and tts2 is Nil then [true, subst] + tts1 is t1 :: ts1 and tts2 is t2 :: ts2 and one_way_unify1(t1, t2, subst) is [hd_ok, subst_] and one_way_unify1_lst(ts1, ts2, subst_) is [tl_ok, subst__] then [hd_ok and tl_ok, subst__] + else [false, Nil] +//│ ———————————————————————————————————————————————————————————————————————————————— + +fun one_way_unify(term1, term2) = one_way_unify1(term1, term2, Nil) + +fun apply_subst(subst, t) = if t is + Var(vid) and find(vid, subst) is [found, value] and + found then value + else Var(vid) + Fun(f, args, ls) then Fun(f, map(x => apply_subst(subst, x), args), ls) + +//│ ———————————————————————————————————————————————————————————————————————————————— +fun rewrite_with_lemmas_helper(term, lss) = if lss is + Nil then term + [lhs, rhs] :: ls and one_way_unify(term, lhs) is [unified, subst] and + unified then rewrite(apply_subst(subst, rhs)) + else rewrite_with_lemmas_helper(term, ls) + +fun rewrite_with_lemmas(term, lss) = rewrite_with_lemmas_helper(term, force(lss)) + +fun rewrite(t) = if t is + Var(v) then Var(v) + Fun(f, args, lemmas) then rewrite_with_lemmas(Fun(f, map(rewrite, args), lemmas), lemmas) +//│ ———————————————————————————————————————————————————————————————————————————————— + +fun truep(x, l) = if x is + Fun(TRUE, _, _) then true + else termInList(x, l) + +fun falsep(x, l) = if x is + Fun(FALSE, _, _) then true + else termInList(x, l) + +fun tautologyp(x, true_lst, false_lst) = if + truep(x, true_lst) then true + falsep(x, false_lst) then false + x is + Fun(IF, cond :: t :: e :: Nil, _) and + truep(cond, true_lst) then tautologyp(t, true_lst, false_lst) + falsep(cond, false_lst) then tautologyp(e, true_lst, false_lst) + else tautologyp(t, cond :: true_lst, false_lst) and tautologyp(e, true_lst, cond :: false_lst) + else false + +fun tautp(x) = tautologyp(rewrite(x), Nil, Nil) + +fun test0(xxxx) = + let a = Var(A) + let b = Var(B) + let c = Var(C) + let d = Var(D) + let u = Var(U) + let w = Var(W) + let x = Var(X) + let y = Var(Y) + let z = Var(Z) + let boyerFalse = Fun(FALSE, Nil, lazy of () => Nil) + let nil = Fun(NIL , Nil, lazy of () => Nil) + let boyerTrue = Fun(TRUE , Nil, lazy of () => Nil) + let zero = Fun(ZERO , Nil, lazy of () => Nil) + + fun one() = Fun(ONE, Nil, lazy of () => [one(), add1(zero)] :: Nil) + + fun two() = Fun(TWO, Nil, lazy of () => [two(), add1(one())] :: Nil) + + fun four() = Fun(FOUR, Nil, lazy of () => [four(), add1(add1(two()))] :: Nil) + + fun add1(a) = Fun(ADD1, a :: Nil, lazy of () => Nil) + + fun if_(a, b, c) = Fun(IF, a :: b :: c :: Nil, lazy of () => [if_(if_(x, y, z), u, w), if_(x, if_(y, u, w), if_(z, u, w))] :: Nil) + + fun not_(a) = Fun(NOT, a :: Nil, lazy of () => [not_(x), if_(x, boyerFalse, boyerTrue)] :: Nil) + + fun and_(a, b) = + Fun(AND, a :: b :: Nil, lazy of () => [and_(x, y), if_(x, if_(y, boyerTrue, boyerFalse), boyerFalse)] :: Nil) + + fun append_(a, b) = + Fun(APPEND, a :: b :: Nil, lazy of () => [append_(append_(x, y), z), append_(x, append_(y, z))] :: Nil) + + fun cons(a, b) = + Fun(CONS, a :: b :: Nil, lazy of () => Nil) + + fun consp(a) = + Fun(CONSP, a :: Nil, lazy of () => [consp(cons(x, y)), boyerTrue] :: Nil) + + fun difference(a, b) = + Fun(DIFFERENCE, a :: b :: Nil, lazy of () => [difference(x, x), zero] :: [difference(plus(x, y), x), y] :: [difference(plus(y, x), x), y] :: [difference(plus(x, y), plus(x, z)), difference(y, z)] :: [difference(plus(y, plus(x, z)), x), plus(y, z)] :: [difference(add1(plus(y, z)), z), add1(y)] :: [difference(add1(add1(x)), two()), x] :: Nil) + + fun divides(a, b) = + Fun(DIVIDES, a :: b :: Nil, lazy of () => [divides(x, y), zerop(remainder(y, x))] :: Nil) + + fun equal(a, b) = + Fun( + EQUAL, + a :: b :: Nil, + lazy of () => + [equal(plus(x, y), zero), and_(zerop(x), zerop(y))] :: + [equal(plus(x, y), plus(x, z)), equal(y, z)] :: + [equal(zero, difference(x, y)), not_(lessp(y, x))] :: + [equal(x, difference(x, y)), or_(equal(x, zero), zerop(y))] :: + [equal(times(x, y), zero), or_(zerop(x), zerop(y))] :: + [equal(append_(x, y), append_(x, z)), equal(y, z)] :: + [equal(y, times(x, y)), or_(equal(y, zero), equal(x, one()))] :: + [equal(x, times(x, y)), or_(equal(x, zero), equal(y, one()))] :: + [equal(times(x, y), one()), and_(equal(x, one()), equal(y, one()))] :: + [equal(difference(x, y), difference(z, y)), if_(lessp(x, y), not_(lessp(y, z)), if_(lessp(z, y), not_(lessp(y, x)), equal(x, z)))] :: + [equal(lessp(x, y), z), if_(lessp(x, y), equal(boyerTrue, z), equal(boyerFalse, z))] :: + Nil + ) + + fun even_(a) = + Fun(EVEN, a :: Nil, lazy of () => [even_(x), if_(zerop(x), boyerTrue, odd_(sub1(x)))] :: Nil) + + fun exp_(a, b) = + Fun(EXP, a :: b :: Nil, lazy of () => [exp_(x, plus(y, z)), times(exp_(x, y), exp_(x, z))] :: [exp_(x, times(y, z)), exp_(exp_(x, y), z)] :: Nil) + + fun f(a) = + Fun(F, a :: Nil, lazy of () => Nil) + + fun gcd_(a, b) = + Fun(GCD, a :: b :: Nil, lazy of () => [gcd_(x, y), gcd_(y, x)] :: [gcd_(times(x, z), times(y, z)), times(z, gcd_(x, y))] :: Nil) + + fun greatereqp(a, b) = + Fun(GREATEREQP, a :: b :: Nil, lazy of () => [greatereqp(x, y), not_(lessp(x, y))] :: Nil) + + fun greaterp(a, b) = + Fun(GREATERP, a :: b :: Nil, lazy of () => [greaterp(x, y), lessp(y, x)] :: Nil) + + fun implies(a, b) = + Fun(IMPLIES, a :: b :: Nil, lazy of () => [implies(x, y), if_(x, if_(y, boyerTrue, boyerFalse), boyerTrue)] :: Nil) + + fun iff(a, b) = + Fun(IFF, a :: b :: Nil, lazy of () => [iff(x, y), and_(implies(x, y), implies(y, x))] :: Nil) + + fun length_(a) = + Fun(LENGTH, a :: Nil, lazy of () => [length_(reverse_(x)), length_(x)] :: [length_(cons(x, cons(y, cons(z, cons(u, w))))), plus(four(), length_(w))] :: Nil) + + fun lesseqp(a, b) = + Fun(LESSEQP, a :: b :: Nil, lazy of () => [lesseqp(x, y), not_(lessp(y, x))] :: Nil) + + fun lessp(a, b) = + Fun( + LESSP, + a :: b :: Nil, + lazy of () => + [lessp(remainder(x, y), y), not_(zerop(y))] :: + [lessp(quotient(x, y), x), and_(not_(zerop(x)), lessp(one(), y))] :: + [lessp(plus(x, y), plus(x, z)), lessp(y, z)] :: + [lessp(times(x, z), times(y, z)), and_(not_(zerop(z)), lessp(x, y))] :: + [lessp(y, plus(x, y)), not_(zerop(x))] :: + Nil + ) + + fun nilp(a) = + Fun(NILP, a :: Nil, lazy of () => [nilp(x), equal(x, nil)] :: Nil) + + fun listp(a) = + Fun(LISTP, a :: Nil, lazy of () => [listp(x), or_(nilp(x), consp(x))] :: Nil) + + fun member(a, b) = + Fun(MEMBER, a :: b :: Nil, lazy of () => [member(x, append_(y, z)), or_(member(x, y), member(x, z))] :: [member(x, reverse_(y)), member(x, y)] :: Nil) + + fun nlistp(a) = + Fun(NLISTP, a :: Nil, lazy of () => [nlistp(x), not_(listp(x))] :: Nil) + + fun odd_(a) = + Fun(ODD, a :: Nil, lazy of () => [odd_(x), even_(sub1(x))] :: Nil) + + fun or_(a, b) = + Fun(OR, a :: b :: Nil, lazy of () => [or_(x, y), if_(x, boyerTrue, if_(y, boyerTrue, boyerFalse))] :: Nil) + + fun plus(a, b) = + Fun(PLUS, a :: b :: Nil, lazy of () => [plus(plus(x, y), z), plus(x, plus(y, z))] :: [plus(remainder(x, y), times(y, quotient(x, y))), x] :: [plus(x, add1(y)), add1(plus(x, y))] :: Nil) + + fun quotient(a, b) = + Fun(QUOTIENT, a :: b :: Nil, lazy of () => [quotient(plus(x, plus(x, y)), two()), plus(x, quotient(y, two()))] :: [quotient(times(y, x), y), if_(zerop(y), zero, x)] :: Nil) + + fun remainder(a, b) = + Fun(REMAINDER, a :: b :: Nil, lazy of () => [remainder(x, one()), zero] :: [remainder(x, x), zero] :: [remainder(times(x, y), x), zero] :: [remainder(times(x, y), y), zero] :: Nil) + + fun reverse_(a) = + Fun(REVERSE, a :: Nil, lazy of () => [reverse_(append_(x, y)), append_(reverse_(y), reverse_(x))] :: Nil) + + fun sub1(a) = + Fun(SUB1, a :: Nil, lazy of () => [sub1(add1(x)), x] :: Nil) + + fun times(a, b) = + Fun(TIMES, a :: b :: Nil, lazy of () => [times(x, plus(y, z)), plus(times(x, y), times(x, z))] :: [times(times(x, y), z), times(x, times(y, z))] :: [times(x, difference(y, z)), difference(times(y, x), times(z, x))] :: [times(x, add1(y)), plus(x, times(x, y))] :: Nil) + + fun zerop(a) = + Fun(ZEROP, a :: Nil, lazy of () => [zerop(x), equal(x, zero)] :: Nil) + + let subst0 = [X, f(plus(plus(a, b), plus(c, zero)))] :: [Y, f(times(times(a, b), plus(c, d)))] :: [Z, f(reverse_(append_(append_(a, b), nil)))] :: [U, equal(plus(a, b), difference(x, y))] :: [W, lessp(remainder(a, b), member(a, length_(b)))] :: Nil + + let theorem = implies(and_(implies(xxxx, y), and_(implies(y, z), and_(implies(z, u), implies(u, w)))), implies(x, w)) + + tautp(apply_subst(subst0, theorem)) + +fun testBoyer_nofib(n) = all(test0, replicate(n, Var(X))) + +fun main() = testBoyer_nofib(5) +//│ = true diff --git a/benchmark/src/nofib/boyer2.mls b/benchmark/src/nofib/boyer2.mls new file mode 100644 index 000000000..48fa3f060 --- /dev/null +++ b/benchmark/src/nofib/boyer2.mls @@ -0,0 +1,340 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module boyer2 with ... + + + + +abstract class Lisplist: Nill | Atom | Conss + +object Nill extends Lisplist +data + class + Atom(a: List[Char]) extends Lisplist + Conss(a: [Lisplist, Lisplist]) extends Lisplist + +fun lispListEq(x, y) = if x is + Nill and y is Nill then true + Atom(a) and y is Atom(b) then listEq(a, b) + Conss([a, b]) and y is Conss([c, d]) and (lispListEq(a, c)) then lispListEq(b, d) + else false + +fun lispmember(e_x) = if e_x is + [e, Conss([x, xs])] and + lispListEq(e, x) then true + else lispmember([e, xs]) + [_, _] then false + +fun truep(term_l) = if term_l is + [Nill, _] then false + [Conss([Atom("t" :: Nil), Nill]), _] then true + [term, l] then lispmember([term, l]) + +fun falsep(term_l) = if term_l is + [Nill, _] then false + [Conss([Atom("f" :: Nil), Nill]), _] then true + [term, l] then lispmember([term, l]) + +fun tv(x) = if x is Atom(a) then a + +fun atom(x) = if x is Atom(_) then true else false + +fun car(x) = if x is Conss([a, _]) then a else Nill + +fun cdr(x) = if x is Conss([_, b]) then b else Nill + +fun cadr(x) = car(cdr(x)) + +fun caddr(x) = car(cdr(cdr(x))) + +fun cadddr(x) = car(cdr(cdr(cdr(x)))) + +fun tautologyp(f_truelst_falselst) = if f_truelst_falselst is [f, truelst, falselst] and f is + Nill then false + Atom(x) then truep([Atom(x), truelst]) + Conss([x, y]) and + truep([Conss([x, y]), truelst]) then true + falsep([Conss([x, y]), falselst]) then false + x is + Atom("i" :: "f" :: Nil) and + truep([car(y), truelst]) then + tautologyp([cadr(y), truelst, falselst]) + falsep([car(y), falselst]) then + tautologyp([caddr(y), truelst, falselst]) + else + tautologyp([cadr(y), Conss([car(y), truelst]), falselst]) and tautologyp([caddr(y), truelst, Conss([car(y), falselst])]) + else false + +fun sublist(t) = if t is + Nil then [Nil, Nill] + ("(" :: Nil) :: t and sublist(t) is [r1, l1] and sublist(r1) is [r2, l2] then [r2, Conss([l1, l2])] + (")" :: Nil) :: t then [t, Nill] + h :: t and sublist(t) is [r, l] then [r, Conss([Atom(h), l])] + +fun mkLispList(ls) = if ls is + ("(" :: Nil) :: t and sublist(t) is [r, l] and r is + Nil then l + else Nill + _ then Nill + +fun restOfToken(s) = if s is + Nil then [Nil, Nil] + h :: t and + (h === "(") || (h === ")") || (h === " ") then [Nil, h :: t] + restOfToken(t) is [a, b] then [h :: a, b] + +fun getToken(s) = if s is + Nil then [Nil, Nil] + h :: t and + (h === " ") then getToken(t) + (h === "(") || (h === ")") then [h :: Nil, t] + restOfToken(t) is [a, b] then [h :: a, b] + +fun strToToken(s) = if + s is Nil then Nil + getToken(s) is [a, b] then a :: strToToken(b) + +fun assoc(term_x_y) = if term_x_y is + [term, Conss([x, y])] and x is + Conss([Atom(key), rest]) and + lispListEq(term, Atom(key)) then x + else assoc([term, y]) + _ then Nill + [_, _] then Nill + +type LUTentry = [String, List[Lisplist]] + +abstract class LUT: Empty | Node + +object Empty extends LUT + +data class Node(x: [LUT, LUTentry, LUT]) extends LUT + +fun addtoLUT(k_l_lut) = if k_l_lut is + [k, l, Empty] then Node([Empty, [k, l :: Nil], Empty]) + [k, l, Node([left, [k1, kl], right])] and + listEq(k, k1) then Node([left, [k1, l :: kl], right]) + ltList(k, k1, (x, y) => x < y, (x, y) => x > y) then Node([addtoLUT([k, l, left]), [k1, kl], right]) + else Node([left, [k1, kl], addtoLUT([k, l, right])]) + +fun getLUT(t_lut) = if t_lut is + [t, Empty] then Nil + [t, Node([left, [k, kl], right])] and + listEq(t, k) then kl + ltList(t, k, (x, y) => x < y, (x, y) => x > y) then getLUT([t, left]) + else getLUT([t, right]) + +fun makelemmas(rules) = if rules is + Nil then Nil + h :: t then mkLispList(strToToken(h)) :: makelemmas(t) + +fun addlemma(lspls, term) = if lspls is + Nill then term + Atom(x) then throw new Error("error") + Conss([x, y]) then + let z = car(y) + if listEq(tv(x), nofibStringToList("equal")) and (not(atom(z))) + then addtoLUT([tv(car(z)), Conss([x, y]), term]) + else throw new Error("error") + +fun addlemmalst(lspls, term) = if lspls is + Nil then term + h :: t then addlemmalst(t, addlemma(h, term)) + +//│ ———————————————————————————————————————————————————————————————————————————————— +fun applysubstlst(alist, y) = if y is + Nill then Nill + Atom(x) then throw new Error("error") + Conss([x, y]) then Conss([applysubst(alist, x), applysubstlst(alist, y)]) + +fun applysubst(alist, x) = if x is + Nill then Nill + Atom(x) and assoc([Atom(x), alist]) is + Conss([_, y]) then y + else Atom(x) + Conss([x, y]) then Conss([x, applysubstlst(alist, y)]) +//│ ———————————————————————————————————————————————————————————————————————————————— + +//│ ———————————————————————————————————————————————————————————————————————————————— +fun onewayunify1lst(l1, l2, u) = if + l1 is Nill then [true, u] + onewayunify1(car(l1), car(l2), u) is [b, u1] and + b then onewayunify1lst(cdr(l1), cdr(l2), u1) + else [false, u1] + +fun onewayunify1(t1, t2, u) = if + atom(t2) and assoc([t2, u]) is + Conss([_, y]) then [lispListEq(t1, y), u] + else [true, Conss([Conss([t2, t1]), u])] + atom(t1) then [false, u] + lispListEq(car(t1), car(t2)) then onewayunify1lst(cdr(t1), cdr(t2), u) + else [false, u] +//│ ———————————————————————————————————————————————————————————————————————————————— + +fun onewayunify(t1, t2) = onewayunify1(t1, t2, Nill) + +//│ ———————————————————————————————————————————————————————————————————————————————— +fun rewritewithlemmas(t, l, term) = if l is + Nil then t + lh :: lt and onewayunify(t, cadr(lh)) is [b, u] and + b then rewrite(applysubst(u, caddr(lh)), term) + else rewritewithlemmas(t, lt, term) + +fun rewriteargs(x, term) = if x is + Nill then Nill + Atom(_) then throw new Error("error") + Conss([x, y]) then Conss([rewrite(x, term), rewriteargs(y, term)]) + +fun rewrite(x, term) = if x is + Nill then Nill + Atom(x) then Atom(x) + Conss([l1, l2]) then rewritewithlemmas(Conss([l1, rewriteargs(l2, term)]), getLUT([tv(l1), term]), term) +//│ ———————————————————————————————————————————————————————————————————————————————— + +val statement = mkLispList(strToToken( + nofibStringToList("( implies ( and ( implies x y )( and ( implies y z )( and ( implies z u )( implies u w ) ) ) )( implies x w ) )") +)) +//│ statement = Conss([Atom(["i","m","p","l","i","e","s"]), Conss([Conss([Atom(["a","n","d"]), Conss([Conss([Atom(["i","m","p","l","i","e","s"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["a","n","d"]), Conss([Conss([Atom(["i","m","p","l","i","e","s"]), Conss([Atom(["y"]), Conss([Atom(["z"]), Nill])])]), Conss([Conss([Atom(["a","n","d"]), Conss([Conss([Atom(["i","m","p","l","i","e","s"]), Conss([Atom(["z"]), Conss([Atom(["u"]), Nill])])]), Conss([Conss([Atom(["i","m","p","l","i","e","s"]), Conss([Atom(["u"]), Conss([Atom(["w"]), Nill])])]), Nill])])]), Nill])])]), Nill])])]), Conss([Conss([Atom(["i","m","p","l","i","e","s"]), Conss([Atom(["x"]), Conss([Atom(["w"]), Nill])])]), Nill])])]) + +fun subterm(i) = + let c = stringConcat("c", stringOfInt(i)) + let str = stringConcat( + "( ( x f ( plus ( plus a b )( plus ", + stringConcat( + c, + stringConcat( + " ( zero ) ) ) )( y f ( times ( times a b )( plus ", + stringConcat(c, " d ) ) )( z f ( reverse ( append ( append a b ) ( [] ) ) ) )(u equal ( plus a b ) ( difference x y ) )(w lessp ( remainder a b )( member a ( length b ) ) ) )") + ) + ) + ) + mkLispList(strToToken(nofibStringToList(str))) + +fun report(b) = if b then "The term is a tautology" else "The term is not a tautology" + +val rules = + nofibStringToList("(equal (compile form)(reverse (codegen (optimize form) (Nill) ) ) )") :: + nofibStringToList("(equal (eqp x y)(equal (fix x)(fix y) ) )") :: + nofibStringToList("(equal (greaterp x y)(lessp y x) )") :: + nofibStringToList("(equal (lesseqp x y)(not (lessp y x) ) )") :: + nofibStringToList("(equal (greatereqp x y)(not (lessp y x) ) )") :: + nofibStringToList("(equal (boolean x)(or (equal x (t) )(equal x (f) ) )") :: + nofibStringToList("(equal (iff x y)(and (implies x y)(implies y x) ) )") :: + nofibStringToList("(equal (even1 x)(if (zerop x)(t)(odd (1- x) ) ) )") :: + nofibStringToList("(equal (countps- l pred)(countps-loop l pred (zero) ) )") :: + nofibStringToList("(equal (fact- i)(fact-loop i 1) )") :: + nofibStringToList("(equal (reverse- x)(reverse-loop x (Nill) ) )") :: + nofibStringToList("(equal (divides x y)(zerop (remainder y x) ) )") :: + nofibStringToList("(equal (assume-true var alist)(Conss (Conss var (t) )alist) )") :: + nofibStringToList("(equal (assume-false var alist)(Conss (Conss var (f) )alist) )") :: + nofibStringToList("(equal (tautology-checker x)(tautologyp (normalize x)(Nill) ) )") :: + nofibStringToList("(equal (falsify x)(falsify1 (normalize x)(Nill) ) )") :: + nofibStringToList("(equal (prime x)(and (not (zerop x))(not (equal x (add1 (zero) ) ) )(prime1 x (1- x) ) ) )") :: + nofibStringToList("(equal (and p q)(if p (if q (t) (f) ) (f) ) )") :: + nofibStringToList("(equal (or p q)(if p (t) (if q (t) (f) ) ) )") :: + nofibStringToList("(equal (not p)(if p (f) (t) ) )") :: + nofibStringToList("(equal (implies p q)(if p (if q (t) (f) ) (t) ) )") :: + nofibStringToList("(equal (fix x)(if (numberp x) x (zero) ) )") :: + nofibStringToList("(equal (if (if a b c) d e)(if a (if b d e) (if c d e) ) )") :: + nofibStringToList("(equal (zerop x)(or (equal x (zero) )(not (numberp x) ) ) )") :: + nofibStringToList("(equal (plus (plus x y) z )(plus x (plus y z) ) )") :: + nofibStringToList("(equal (equal (plus a b) (zero ) )(and (zerop a) (zerop b) ) )") :: + nofibStringToList("(equal (difference x x)(zero) )") :: + nofibStringToList("(equal (equal (plus a b) (plus a c) )(equal (fix b) (fix c) ) )") :: + nofibStringToList("(equal (equal (zero) (difference x y) )(not (lessp y x) ) )") :: + nofibStringToList("(equal (equal x (difference x y) )(and (numberp x)(or (equal x (zero) )(zerop y) ) ) )") :: + nofibStringToList("(equal (meaning (plus-tree (append x y) ) a)(plus (meaning (plus-tree x) a)(meaning (plus-tree y) a) ) )") :: + nofibStringToList("(equal (meaning (plus-tree (plus-fringe x) ) a)(fix (meaning x a) ) )") :: + nofibStringToList("(equal (append (append x y) z)(append x (append y z) ) )") :: + nofibStringToList("(equal (reverse (append a b) )(append (reverse b) (reverse a) ) )") :: + nofibStringToList("(equal (times x (plus y z) )(plus (times x y)(times x z) ) )") :: + nofibStringToList("(equal (times (times x y) z)(times x (times y z) ) )") :: + nofibStringToList("(equal (equal (times x y) (zero) )(or (zerop x)(zerop y) ) )") :: + nofibStringToList("(equal (exec (append x y)pds envrn)(exec y (exec x pds envrn)envrn) )") :: + nofibStringToList("(equal (mc-flatten x y)(append (flatten x)y) )") :: + nofibStringToList("(equal (member x (append a b) )(or (member x a)(member x b) ) )") :: + nofibStringToList("(equal (member x (reverse y) )(member x y) )") :: + nofibStringToList("(equal (length (reverse x) )(length x) )") :: + nofibStringToList("(equal (member a (intersect b c) )(and (member a b)(member a c) ) )") :: + nofibStringToList("(equal (nth (zero)i)(zero) )") :: + nofibStringToList("(equal (exp i (plus j k) )(times (exp i j)(exp i k) ) )") :: + nofibStringToList("(equal (exp i (times j k) )(exp (exp i j)k) )") :: + nofibStringToList("(equal (reverse-loop x y)(append (reverse x)y) )") :: + nofibStringToList("(equal (reverse-loop x (Nill) )(reverse x) )") :: + nofibStringToList("(equal (count-list z (sort-lp x y) )(plus (count-list z x)(count-list z y) ) )") :: + nofibStringToList("(equal (equal (append a b)(append a c) )(equal b c) )") :: + nofibStringToList("(equal (plus (remainder x y)(times y (quotient x y) ) )(fix x) )") :: + nofibStringToList("(equal (power-eval (big-plus1 l i base)base)(plus (power-eval l base)i) )") :: + nofibStringToList("(equal (power-eval (big-plus x y i base)base)(plus i (plus (power-eval x base)(power-eval y base) ) ) )") :: + nofibStringToList("(equal (remainder y 1)(zero) )") :: + nofibStringToList("(equal (lessp (remainder x y)y)(not (zerop y) ) )") :: + nofibStringToList("(equal (remainder x x)(zero) )") :: + nofibStringToList("(equal (lessp (quotient i j)i)(and (not (zerop i) )(or (zerop j)(not (equal j 1) ) ) ) )") :: + nofibStringToList("(equal (lessp (remainder x y)x)(and (not (zerop y) )(not (zerop x) )(not (lessp x y) ) ) )") :: + nofibStringToList("(equal (power-eval (power-rep i base)base)(fix i) )") :: + nofibStringToList("(equal (power-eval (big-plus (power-rep i base)(power-rep j base)(zero)base)base)(plus i j) )") :: + nofibStringToList("(equal (gcd x y)(gcd y x) )") :: + nofibStringToList("(equal (nth (append a b)i)(append (nth a i)(nth b (difference i (length a) ) ) ) )") :: + nofibStringToList("(equal (difference (plus x y)x)(fix y) )") :: + nofibStringToList("(equal (difference (plus y x)x)(fix y) )") :: + nofibStringToList("(equal (difference (plus x y)(plus x z) )(difference y z) )") :: + nofibStringToList("(equal (times x (difference c w) )(difference (times c x)(times w x) ) )") :: + nofibStringToList("(equal (remainder (times x z)z)(zero) )") :: + nofibStringToList("(equal (difference (plus b (plus a c) )a)(plus b c) )") :: + nofibStringToList("(equal (difference (add1 (plus y z)z)(add1 y) )") :: + nofibStringToList("(equal (lessp (plus x y)(plus x z ) )(lessp y z) )") :: + nofibStringToList("(equal (lessp (times x z)(times y z) )(and (not (zerop z) )(lessp x y) ) )") :: + nofibStringToList("(equal (lessp y (plus x y) )(not (zerop x) ) )") :: + nofibStringToList("(equal (gcd (times x z)(times y z) )(times z (gcd x y) ) )") :: + nofibStringToList("(equal (value (normalize x)a)(value x a) )") :: + nofibStringToList("(equal (equal (flatten x)(Conss y (Nill) ) )(and (nlistp x)(equal x y) ) )") :: + nofibStringToList("(equal (listp (gopher x) )(listp x) )") :: + nofibStringToList("(equal (samefringe x y)(equal (flatten x)(flatten y) ) )") :: + nofibStringToList("(equal (equal (greatest-factor x y)(zero) )(and (or (zerop y)(equal y 1) )(equal x (zero) ) ) )") :: + nofibStringToList("(equal (equal (greatest-factor x y)1)(equal x 1) )") :: + nofibStringToList("(equal (numberp (greatest-factor x y) )(not (and (or (zerop y)(equal y 1) )(not (numberp x) ) ) ) )") :: + nofibStringToList("(equal (times-list (append x y) )(times (times-list x)(times-list y) ) )") :: + nofibStringToList("(equal (prime-list (append x y) )(and (prime-list x)(prime-list y) ) )") :: + nofibStringToList("(equal (equal z (times w z) )(and (numberp z)(or (equal z (zero) )(equal w 1) ) ) )") :: + nofibStringToList("(equal (greatereqpr x y)(not (lessp x y) ) )") :: + nofibStringToList("(equal (equal x (times x y) )(or (equal x (zero) )(and (numberp x)(equal y 1) ) ) )") :: + nofibStringToList("(equal (remainder (times y x)y)(zero) )") :: + nofibStringToList("(equal (equal (times a b)1)(and (not (equal a (zero) ) )(not (equal b (zero) ) )(numberp a)(numberp b)(equal (1- a)(zero) )(equal (1- b)(zero) ) ) )") :: + nofibStringToList("(equal (lessp (length (delete x l) )(length l) )(member x l) )") :: + nofibStringToList("(equal (sort2 (delete x l) )(delete x (sort2 l) ) )") :: + nofibStringToList("(equal (dsort x)(sort2 x) )") :: + nofibStringToList("(equal (length(Conss x1(Conss x2(Conss x3(Conss x4(Conss x5(Conss x6 x7) ) ) ) ) ) )(plus 6 (length x7) ) )") :: + nofibStringToList("(equal (difference (add1 (add1 x) )2)(fix x) )") :: + nofibStringToList("(equal (quotient (plus x (plus x y) )2)(plus x (quotient y 2) ) )") :: + nofibStringToList("(equal (sigma (zero)i)(quotient (times i (add1 i) )2) )") :: + nofibStringToList("(equal (plus x (add1 y) )(if (numberp y)(add1 (plus x y) )(add1 x) ) )") :: + nofibStringToList("(equal (equal (difference x y)(difference z y) )(if (lessp x y)(not (lessp y z) )(if (lessp z y)(not (lessp y x) )(equal (fix x)(fix z) ) ) ) )") :: + nofibStringToList("(equal (meaning (plus-tree (delete x y) )a)(if (member x y)(difference (meaning (plus-tree y)a)(meaning x a) )(meaning (plus-tree y)a) ) )") :: + nofibStringToList("(equal (times x (add1 y) )(if (numberp y)(plus x (times x y) )(fix x) ) )") :: + nofibStringToList("(equal (nth (Nill)i)(if (zerop i)(Nill)(zero) ) )") :: + nofibStringToList("(equal (last (append a b) )(if (listp b)(last b)(if (listp a)(Conss (car (last a) )b)b) ) )") :: + nofibStringToList("(equal (equal (lessp x y)z)(if (lessp x y)(equal t z)(equal f z) ) )") :: + nofibStringToList("(equal (assignment x (append a b) )(if (assignedp x a)(assignment x a)(assignment x b) ) )") :: + nofibStringToList("(equal (car (gopher x) )(if (listp x)(car (flatten x) )(zero) ) )") :: + nofibStringToList("(equal (flatten (cdr (gopher x) ) )(if (listp x)(cdr (flatten x) )(Conss (zero)(Nill) ) ) )") :: + nofibStringToList("(equal (quotient (times y x)y)(if (zerop y)(zero)(fix x) ) )") :: + nofibStringToList("(equal (get j (set i val mem) )(if (eqp j i)val(get j mem) ) )") :: Nil +//│ rules = [["(","e","q","u","a","l"," ","(","c","o","m","p","i","l","e"," ","f","o","r","m",")","(","r","e","v","e","r","s","e"," ","(","c","o","d","e","g","e","n"," ","(","o","p","t","i","m","i","z","e"," ","f","o","r","m",")"," ","(","N","i","l","l",")"," ",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","e","q","p"," ","x"," ","y",")","(","e","q","u","a","l"," ","(","f","i","x"," ","x",")","(","f","i","x"," ","y",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","g","r","e","a","t","e","r","p"," ","x"," ","y",")","(","l","e","s","s","p"," ","y"," ","x",")"," ",")"],["(","e","q","u","a","l"," ","(","l","e","s","s","e","q","p"," ","x"," ","y",")","(","n","o","t"," ","(","l","e","s","s","p"," ","y"," ","x",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","g","r","e","a","t","e","r","e","q","p"," ","x"," ","y",")","(","n","o","t"," ","(","l","e","s","s","p"," ","y"," ","x",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","b","o","o","l","e","a","n"," ","x",")","(","o","r"," ","(","e","q","u","a","l"," ","x"," ","(","t",")"," ",")","(","e","q","u","a","l"," ","x"," ","(","f",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","i","f","f"," ","x"," ","y",")","(","a","n","d"," ","(","i","m","p","l","i","e","s"," ","x"," ","y",")","(","i","m","p","l","i","e","s"," ","y"," ","x",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","e","v","e","n","1"," ","x",")","(","i","f"," ","(","z","e","r","o","p"," ","x",")","(","t",")","(","o","d","d"," ","(","1","-"," ","x",")"," ",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","c","o","u","n","t","p","s","-"," ","l"," ","p","r","e","d",")","(","c","o","u","n","t","p","s","-","l","o","o","p"," ","l"," ","p","r","e","d"," ","(","z","e","r","o",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","f","a","c","t","-"," ","i",")","(","f","a","c","t","-","l","o","o","p"," ","i"," ","1",")"," ",")"],["(","e","q","u","a","l"," ","(","r","e","v","e","r","s","e","-"," ","x",")","(","r","e","v","e","r","s","e","-","l","o","o","p"," ","x"," ","(","N","i","l","l",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","d","i","v","i","d","e","s"," ","x"," ","y",")","(","z","e","r","o","p"," ","(","r","e","m","a","i","n","d","e","r"," ","y"," ","x",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","a","s","s","u","m","e","-","t","r","u","e"," ","v","a","r"," ","a","l","i","s","t",")","(","C","o","n","s","s"," ","(","C","o","n","s","s"," ","v","a","r"," ","(","t",")"," ",")","a","l","i","s","t",")"," ",")"],["(","e","q","u","a","l"," ","(","a","s","s","u","m","e","-","f","a","l","s","e"," ","v","a","r"," ","a","l","i","s","t",")","(","C","o","n","s","s"," ","(","C","o","n","s","s"," ","v","a","r"," ","(","f",")"," ",")","a","l","i","s","t",")"," ",")"],["(","e","q","u","a","l"," ","(","t","a","u","t","o","l","o","g","y","-","c","h","e","c","k","e","r"," ","x",")","(","t","a","u","t","o","l","o","g","y","p"," ","(","n","o","r","m","a","l","i","z","e"," ","x",")","(","N","i","l","l",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","f","a","l","s","i","f","y"," ","x",")","(","f","a","l","s","i","f","y","1"," ","(","n","o","r","m","a","l","i","z","e"," ","x",")","(","N","i","l","l",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","p","r","i","m","e"," ","x",")","(","a","n","d"," ","(","n","o","t"," ","(","z","e","r","o","p"," ","x",")",")","(","n","o","t"," ","(","e","q","u","a","l"," ","x"," ","(","a","d","d","1"," ","(","z","e","r","o",")"," ",")"," ",")"," ",")","(","p","r","i","m","e","1"," ","x"," ","(","1","-"," ","x",")"," ",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","a","n","d"," ","p"," ","q",")","(","i","f"," ","p"," ","(","i","f"," ","q"," ","(","t",")"," ","(","f",")"," ",")"," ","(","f",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","o","r"," ","p"," ","q",")","(","i","f"," ","p"," ","(","t",")"," ","(","i","f"," ","q"," ","(","t",")"," ","(","f",")"," ",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","n","o","t"," ","p",")","(","i","f"," ","p"," ","(","f",")"," ","(","t",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","i","m","p","l","i","e","s"," ","p"," ","q",")","(","i","f"," ","p"," ","(","i","f"," ","q"," ","(","t",")"," ","(","f",")"," ",")"," ","(","t",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","f","i","x"," ","x",")","(","i","f"," ","(","n","u","m","b","e","r","p"," ","x",")"," ","x"," ","(","z","e","r","o",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","i","f"," ","(","i","f"," ","a"," ","b"," ","c",")"," ","d"," ","e",")","(","i","f"," ","a"," ","(","i","f"," ","b"," ","d"," ","e",")"," ","(","i","f"," ","c"," ","d"," ","e",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","z","e","r","o","p"," ","x",")","(","o","r"," ","(","e","q","u","a","l"," ","x"," ","(","z","e","r","o",")"," ",")","(","n","o","t"," ","(","n","u","m","b","e","r","p"," ","x",")"," ",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","p","l","u","s"," ","(","p","l","u","s"," ","x"," ","y",")"," ","z"," ",")","(","p","l","u","s"," ","x"," ","(","p","l","u","s"," ","y"," ","z",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","e","q","u","a","l"," ","(","p","l","u","s"," ","a"," ","b",")"," ","(","z","e","r","o"," ",")"," ",")","(","a","n","d"," ","(","z","e","r","o","p"," ","a",")"," ","(","z","e","r","o","p"," ","b",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","d","i","f","f","e","r","e","n","c","e"," ","x"," ","x",")","(","z","e","r","o",")"," ",")"],["(","e","q","u","a","l"," ","(","e","q","u","a","l"," ","(","p","l","u","s"," ","a"," ","b",")"," ","(","p","l","u","s"," ","a"," ","c",")"," ",")","(","e","q","u","a","l"," ","(","f","i","x"," ","b",")"," ","(","f","i","x"," ","c",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","e","q","u","a","l"," ","(","z","e","r","o",")"," ","(","d","i","f","f","e","r","e","n","c","e"," ","x"," ","y",")"," ",")","(","n","o","t"," ","(","l","e","s","s","p"," ","y"," ","x",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","e","q","u","a","l"," ","x"," ","(","d","i","f","f","e","r","e","n","c","e"," ","x"," ","y",")"," ",")","(","a","n","d"," ","(","n","u","m","b","e","r","p"," ","x",")","(","o","r"," ","(","e","q","u","a","l"," ","x"," ","(","z","e","r","o",")"," ",")","(","z","e","r","o","p"," ","y",")"," ",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","m","e","a","n","i","n","g"," ","(","p","l","u","s","-","t","r","e","e"," ","(","a","p","p","e","n","d"," ","x"," ","y",")"," ",")"," ","a",")","(","p","l","u","s"," ","(","m","e","a","n","i","n","g"," ","(","p","l","u","s","-","t","r","e","e"," ","x",")"," ","a",")","(","m","e","a","n","i","n","g"," ","(","p","l","u","s","-","t","r","e","e"," ","y",")"," ","a",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","m","e","a","n","i","n","g"," ","(","p","l","u","s","-","t","r","e","e"," ","(","p","l","u","s","-","f","r","i","n","g","e"," ","x",")"," ",")"," ","a",")","(","f","i","x"," ","(","m","e","a","n","i","n","g"," ","x"," ","a",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","a","p","p","e","n","d"," ","(","a","p","p","e","n","d"," ","x"," ","y",")"," ","z",")","(","a","p","p","e","n","d"," ","x"," ","(","a","p","p","e","n","d"," ","y"," ","z",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","r","e","v","e","r","s","e"," ","(","a","p","p","e","n","d"," ","a"," ","b",")"," ",")","(","a","p","p","e","n","d"," ","(","r","e","v","e","r","s","e"," ","b",")"," ","(","r","e","v","e","r","s","e"," ","a",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","t","i","m","e","s"," ","x"," ","(","p","l","u","s"," ","y"," ","z",")"," ",")","(","p","l","u","s"," ","(","t","i","m","e","s"," ","x"," ","y",")","(","t","i","m","e","s"," ","x"," ","z",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","t","i","m","e","s"," ","(","t","i","m","e","s"," ","x"," ","y",")"," ","z",")","(","t","i","m","e","s"," ","x"," ","(","t","i","m","e","s"," ","y"," ","z",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","e","q","u","a","l"," ","(","t","i","m","e","s"," ","x"," ","y",")"," ","(","z","e","r","o",")"," ",")","(","o","r"," ","(","z","e","r","o","p"," ","x",")","(","z","e","r","o","p"," ","y",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","e","x","e","c"," ","(","a","p","p","e","n","d"," ","x"," ","y",")","p","d","s"," ","e","n","v","r","n",")","(","e","x","e","c"," ","y"," ","(","e","x","e","c"," ","x"," ","p","d","s"," ","e","n","v","r","n",")","e","n","v","r","n",")"," ",")"],["(","e","q","u","a","l"," ","(","m","c","-","f","l","a","t","t","e","n"," ","x"," ","y",")","(","a","p","p","e","n","d"," ","(","f","l","a","t","t","e","n"," ","x",")","y",")"," ",")"],["(","e","q","u","a","l"," ","(","m","e","m","b","e","r"," ","x"," ","(","a","p","p","e","n","d"," ","a"," ","b",")"," ",")","(","o","r"," ","(","m","e","m","b","e","r"," ","x"," ","a",")","(","m","e","m","b","e","r"," ","x"," ","b",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","m","e","m","b","e","r"," ","x"," ","(","r","e","v","e","r","s","e"," ","y",")"," ",")","(","m","e","m","b","e","r"," ","x"," ","y",")"," ",")"],["(","e","q","u","a","l"," ","(","l","e","n","g","t","h"," ","(","r","e","v","e","r","s","e"," ","x",")"," ",")","(","l","e","n","g","t","h"," ","x",")"," ",")"],["(","e","q","u","a","l"," ","(","m","e","m","b","e","r"," ","a"," ","(","i","n","t","e","r","s","e","c","t"," ","b"," ","c",")"," ",")","(","a","n","d"," ","(","m","e","m","b","e","r"," ","a"," ","b",")","(","m","e","m","b","e","r"," ","a"," ","c",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","n","t","h"," ","(","z","e","r","o",")","i",")","(","z","e","r","o",")"," ",")"],["(","e","q","u","a","l"," ","(","e","x","p"," ","i"," ","(","p","l","u","s"," ","j"," ","k",")"," ",")","(","t","i","m","e","s"," ","(","e","x","p"," ","i"," ","j",")","(","e","x","p"," ","i"," ","k",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","e","x","p"," ","i"," ","(","t","i","m","e","s"," ","j"," ","k",")"," ",")","(","e","x","p"," ","(","e","x","p"," ","i"," ","j",")","k",")"," ",")"],["(","e","q","u","a","l"," ","(","r","e","v","e","r","s","e","-","l","o","o","p"," ","x"," ","y",")","(","a","p","p","e","n","d"," ","(","r","e","v","e","r","s","e"," ","x",")","y",")"," ",")"],["(","e","q","u","a","l"," ","(","r","e","v","e","r","s","e","-","l","o","o","p"," ","x"," ","(","N","i","l","l",")"," ",")","(","r","e","v","e","r","s","e"," ","x",")"," ",")"],["(","e","q","u","a","l"," ","(","c","o","u","n","t","-","l","i","s","t"," ","z"," ","(","s","o","r","t","-","l","p"," ","x"," ","y",")"," ",")","(","p","l","u","s"," ","(","c","o","u","n","t","-","l","i","s","t"," ","z"," ","x",")","(","c","o","u","n","t","-","l","i","s","t"," ","z"," ","y",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","e","q","u","a","l"," ","(","a","p","p","e","n","d"," ","a"," ","b",")","(","a","p","p","e","n","d"," ","a"," ","c",")"," ",")","(","e","q","u","a","l"," ","b"," ","c",")"," ",")"],["(","e","q","u","a","l"," ","(","p","l","u","s"," ","(","r","e","m","a","i","n","d","e","r"," ","x"," ","y",")","(","t","i","m","e","s"," ","y"," ","(","q","u","o","t","i","e","n","t"," ","x"," ","y",")"," ",")"," ",")","(","f","i","x"," ","x",")"," ",")"],["(","e","q","u","a","l"," ","(","p","o","w","e","r","-","e","v","a","l"," ","(","b","i","g","-","p","l","u","s","1"," ","l"," ","i"," ","b","a","s","e",")","b","a","s","e",")","(","p","l","u","s"," ","(","p","o","w","e","r","-","e","v","a","l"," ","l"," ","b","a","s","e",")","i",")"," ",")"],["(","e","q","u","a","l"," ","(","p","o","w","e","r","-","e","v","a","l"," ","(","b","i","g","-","p","l","u","s"," ","x"," ","y"," ","i"," ","b","a","s","e",")","b","a","s","e",")","(","p","l","u","s"," ","i"," ","(","p","l","u","s"," ","(","p","o","w","e","r","-","e","v","a","l"," ","x"," ","b","a","s","e",")","(","p","o","w","e","r","-","e","v","a","l"," ","y"," ","b","a","s","e",")"," ",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","r","e","m","a","i","n","d","e","r"," ","y"," ","1",")","(","z","e","r","o",")"," ",")"],["(","e","q","u","a","l"," ","(","l","e","s","s","p"," ","(","r","e","m","a","i","n","d","e","r"," ","x"," ","y",")","y",")","(","n","o","t"," ","(","z","e","r","o","p"," ","y",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","r","e","m","a","i","n","d","e","r"," ","x"," ","x",")","(","z","e","r","o",")"," ",")"],["(","e","q","u","a","l"," ","(","l","e","s","s","p"," ","(","q","u","o","t","i","e","n","t"," ","i"," ","j",")","i",")","(","a","n","d"," ","(","n","o","t"," ","(","z","e","r","o","p"," ","i",")"," ",")","(","o","r"," ","(","z","e","r","o","p"," ","j",")","(","n","o","t"," ","(","e","q","u","a","l"," ","j"," ","1",")"," ",")"," ",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","l","e","s","s","p"," ","(","r","e","m","a","i","n","d","e","r"," ","x"," ","y",")","x",")","(","a","n","d"," ","(","n","o","t"," ","(","z","e","r","o","p"," ","y",")"," ",")","(","n","o","t"," ","(","z","e","r","o","p"," ","x",")"," ",")","(","n","o","t"," ","(","l","e","s","s","p"," ","x"," ","y",")"," ",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","p","o","w","e","r","-","e","v","a","l"," ","(","p","o","w","e","r","-","r","e","p"," ","i"," ","b","a","s","e",")","b","a","s","e",")","(","f","i","x"," ","i",")"," ",")"],["(","e","q","u","a","l"," ","(","p","o","w","e","r","-","e","v","a","l"," ","(","b","i","g","-","p","l","u","s"," ","(","p","o","w","e","r","-","r","e","p"," ","i"," ","b","a","s","e",")","(","p","o","w","e","r","-","r","e","p"," ","j"," ","b","a","s","e",")","(","z","e","r","o",")","b","a","s","e",")","b","a","s","e",")","(","p","l","u","s"," ","i"," ","j",")"," ",")"],["(","e","q","u","a","l"," ","(","g","c","d"," ","x"," ","y",")","(","g","c","d"," ","y"," ","x",")"," ",")"],["(","e","q","u","a","l"," ","(","n","t","h"," ","(","a","p","p","e","n","d"," ","a"," ","b",")","i",")","(","a","p","p","e","n","d"," ","(","n","t","h"," ","a"," ","i",")","(","n","t","h"," ","b"," ","(","d","i","f","f","e","r","e","n","c","e"," ","i"," ","(","l","e","n","g","t","h"," ","a",")"," ",")"," ",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","d","i","f","f","e","r","e","n","c","e"," ","(","p","l","u","s"," ","x"," ","y",")","x",")","(","f","i","x"," ","y",")"," ",")"],["(","e","q","u","a","l"," ","(","d","i","f","f","e","r","e","n","c","e"," ","(","p","l","u","s"," ","y"," ","x",")","x",")","(","f","i","x"," ","y",")"," ",")"],["(","e","q","u","a","l"," ","(","d","i","f","f","e","r","e","n","c","e"," ","(","p","l","u","s"," ","x"," ","y",")","(","p","l","u","s"," ","x"," ","z",")"," ",")","(","d","i","f","f","e","r","e","n","c","e"," ","y"," ","z",")"," ",")"],["(","e","q","u","a","l"," ","(","t","i","m","e","s"," ","x"," ","(","d","i","f","f","e","r","e","n","c","e"," ","c"," ","w",")"," ",")","(","d","i","f","f","e","r","e","n","c","e"," ","(","t","i","m","e","s"," ","c"," ","x",")","(","t","i","m","e","s"," ","w"," ","x",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","r","e","m","a","i","n","d","e","r"," ","(","t","i","m","e","s"," ","x"," ","z",")","z",")","(","z","e","r","o",")"," ",")"],["(","e","q","u","a","l"," ","(","d","i","f","f","e","r","e","n","c","e"," ","(","p","l","u","s"," ","b"," ","(","p","l","u","s"," ","a"," ","c",")"," ",")","a",")","(","p","l","u","s"," ","b"," ","c",")"," ",")"],["(","e","q","u","a","l"," ","(","d","i","f","f","e","r","e","n","c","e"," ","(","a","d","d","1"," ","(","p","l","u","s"," ","y"," ","z",")","z",")","(","a","d","d","1"," ","y",")"," ",")"],["(","e","q","u","a","l"," ","(","l","e","s","s","p"," ","(","p","l","u","s"," ","x"," ","y",")","(","p","l","u","s"," ","x"," ","z"," ",")"," ",")","(","l","e","s","s","p"," ","y"," ","z",")"," ",")"],["(","e","q","u","a","l"," ","(","l","e","s","s","p"," ","(","t","i","m","e","s"," ","x"," ","z",")","(","t","i","m","e","s"," ","y"," ","z",")"," ",")","(","a","n","d"," ","(","n","o","t"," ","(","z","e","r","o","p"," ","z",")"," ",")","(","l","e","s","s","p"," ","x"," ","y",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","l","e","s","s","p"," ","y"," ","(","p","l","u","s"," ","x"," ","y",")"," ",")","(","n","o","t"," ","(","z","e","r","o","p"," ","x",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","g","c","d"," ","(","t","i","m","e","s"," ","x"," ","z",")","(","t","i","m","e","s"," ","y"," ","z",")"," ",")","(","t","i","m","e","s"," ","z"," ","(","g","c","d"," ","x"," ","y",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","v","a","l","u","e"," ","(","n","o","r","m","a","l","i","z","e"," ","x",")","a",")","(","v","a","l","u","e"," ","x"," ","a",")"," ",")"],["(","e","q","u","a","l"," ","(","e","q","u","a","l"," ","(","f","l","a","t","t","e","n"," ","x",")","(","C","o","n","s","s"," ","y"," ","(","N","i","l","l",")"," ",")"," ",")","(","a","n","d"," ","(","n","l","i","s","t","p"," ","x",")","(","e","q","u","a","l"," ","x"," ","y",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","l","i","s","t","p"," ","(","g","o","p","h","e","r"," ","x",")"," ",")","(","l","i","s","t","p"," ","x",")"," ",")"],["(","e","q","u","a","l"," ","(","s","a","m","e","f","r","i","n","g","e"," ","x"," ","y",")","(","e","q","u","a","l"," ","(","f","l","a","t","t","e","n"," ","x",")","(","f","l","a","t","t","e","n"," ","y",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","e","q","u","a","l"," ","(","g","r","e","a","t","e","s","t","-","f","a","c","t","o","r"," ","x"," ","y",")","(","z","e","r","o",")"," ",")","(","a","n","d"," ","(","o","r"," ","(","z","e","r","o","p"," ","y",")","(","e","q","u","a","l"," ","y"," ","1",")"," ",")","(","e","q","u","a","l"," ","x"," ","(","z","e","r","o",")"," ",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","e","q","u","a","l"," ","(","g","r","e","a","t","e","s","t","-","f","a","c","t","o","r"," ","x"," ","y",")","1",")","(","e","q","u","a","l"," ","x"," ","1",")"," ",")"],["(","e","q","u","a","l"," ","(","n","u","m","b","e","r","p"," ","(","g","r","e","a","t","e","s","t","-","f","a","c","t","o","r"," ","x"," ","y",")"," ",")","(","n","o","t"," ","(","a","n","d"," ","(","o","r"," ","(","z","e","r","o","p"," ","y",")","(","e","q","u","a","l"," ","y"," ","1",")"," ",")","(","n","o","t"," ","(","n","u","m","b","e","r","p"," ","x",")"," ",")"," ",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","t","i","m","e","s","-","l","i","s","t"," ","(","a","p","p","e","n","d"," ","x"," ","y",")"," ",")","(","t","i","m","e","s"," ","(","t","i","m","e","s","-","l","i","s","t"," ","x",")","(","t","i","m","e","s","-","l","i","s","t"," ","y",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","p","r","i","m","e","-","l","i","s","t"," ","(","a","p","p","e","n","d"," ","x"," ","y",")"," ",")","(","a","n","d"," ","(","p","r","i","m","e","-","l","i","s","t"," ","x",")","(","p","r","i","m","e","-","l","i","s","t"," ","y",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","e","q","u","a","l"," ","z"," ","(","t","i","m","e","s"," ","w"," ","z",")"," ",")","(","a","n","d"," ","(","n","u","m","b","e","r","p"," ","z",")","(","o","r"," ","(","e","q","u","a","l"," ","z"," ","(","z","e","r","o",")"," ",")","(","e","q","u","a","l"," ","w"," ","1",")"," ",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","g","r","e","a","t","e","r","e","q","p","r"," ","x"," ","y",")","(","n","o","t"," ","(","l","e","s","s","p"," ","x"," ","y",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","e","q","u","a","l"," ","x"," ","(","t","i","m","e","s"," ","x"," ","y",")"," ",")","(","o","r"," ","(","e","q","u","a","l"," ","x"," ","(","z","e","r","o",")"," ",")","(","a","n","d"," ","(","n","u","m","b","e","r","p"," ","x",")","(","e","q","u","a","l"," ","y"," ","1",")"," ",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","r","e","m","a","i","n","d","e","r"," ","(","t","i","m","e","s"," ","y"," ","x",")","y",")","(","z","e","r","o",")"," ",")"],["(","e","q","u","a","l"," ","(","e","q","u","a","l"," ","(","t","i","m","e","s"," ","a"," ","b",")","1",")","(","a","n","d"," ","(","n","o","t"," ","(","e","q","u","a","l"," ","a"," ","(","z","e","r","o",")"," ",")"," ",")","(","n","o","t"," ","(","e","q","u","a","l"," ","b"," ","(","z","e","r","o",")"," ",")"," ",")","(","n","u","m","b","e","r","p"," ","a",")","(","n","u","m","b","e","r","p"," ","b",")","(","e","q","u","a","l"," ","(","1","-"," ","a",")","(","z","e","r","o",")"," ",")","(","e","q","u","a","l"," ","(","1","-"," ","b",")","(","z","e","r","o",")"," ",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","l","e","s","s","p"," ","(","l","e","n","g","t","h"," ","(","d","e","l","e","t","e"," ","x"," ","l",")"," ",")","(","l","e","n","g","t","h"," ","l",")"," ",")","(","m","e","m","b","e","r"," ","x"," ","l",")"," ",")"],["(","e","q","u","a","l"," ","(","s","o","r","t","2"," ","(","d","e","l","e","t","e"," ","x"," ","l",")"," ",")","(","d","e","l","e","t","e"," ","x"," ","(","s","o","r","t","2"," ","l",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","d","s","o","r","t"," ","x",")","(","s","o","r","t","2"," ","x",")"," ",")"],["(","e","q","u","a","l"," ","(","l","e","n","g","t","h","(","C","o","n","s","s"," ","x","1","(","C","o","n","s","s"," ","x","2","(","C","o","n","s","s"," ","x","3","(","C","o","n","s","s"," ","x","4","(","C","o","n","s","s"," ","x","5","(","C","o","n","s","s"," ","x","6"," ","x","7",")"," ",")"," ",")"," ",")"," ",")"," ",")"," ",")","(","p","l","u","s"," ","6"," ","(","l","e","n","g","t","h"," ","x","7",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","d","i","f","f","e","r","e","n","c","e"," ","(","a","d","d","1"," ","(","a","d","d","1"," ","x",")"," ",")","2",")","(","f","i","x"," ","x",")"," ",")"],["(","e","q","u","a","l"," ","(","q","u","o","t","i","e","n","t"," ","(","p","l","u","s"," ","x"," ","(","p","l","u","s"," ","x"," ","y",")"," ",")","2",")","(","p","l","u","s"," ","x"," ","(","q","u","o","t","i","e","n","t"," ","y"," ","2",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","s","i","g","m","a"," ","(","z","e","r","o",")","i",")","(","q","u","o","t","i","e","n","t"," ","(","t","i","m","e","s"," ","i"," ","(","a","d","d","1"," ","i",")"," ",")","2",")"," ",")"],["(","e","q","u","a","l"," ","(","p","l","u","s"," ","x"," ","(","a","d","d","1"," ","y",")"," ",")","(","i","f"," ","(","n","u","m","b","e","r","p"," ","y",")","(","a","d","d","1"," ","(","p","l","u","s"," ","x"," ","y",")"," ",")","(","a","d","d","1"," ","x",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","e","q","u","a","l"," ","(","d","i","f","f","e","r","e","n","c","e"," ","x"," ","y",")","(","d","i","f","f","e","r","e","n","c","e"," ","z"," ","y",")"," ",")","(","i","f"," ","(","l","e","s","s","p"," ","x"," ","y",")","(","n","o","t"," ","(","l","e","s","s","p"," ","y"," ","z",")"," ",")","(","i","f"," ","(","l","e","s","s","p"," ","z"," ","y",")","(","n","o","t"," ","(","l","e","s","s","p"," ","y"," ","x",")"," ",")","(","e","q","u","a","l"," ","(","f","i","x"," ","x",")","(","f","i","x"," ","z",")"," ",")"," ",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","m","e","a","n","i","n","g"," ","(","p","l","u","s","-","t","r","e","e"," ","(","d","e","l","e","t","e"," ","x"," ","y",")"," ",")","a",")","(","i","f"," ","(","m","e","m","b","e","r"," ","x"," ","y",")","(","d","i","f","f","e","r","e","n","c","e"," ","(","m","e","a","n","i","n","g"," ","(","p","l","u","s","-","t","r","e","e"," ","y",")","a",")","(","m","e","a","n","i","n","g"," ","x"," ","a",")"," ",")","(","m","e","a","n","i","n","g"," ","(","p","l","u","s","-","t","r","e","e"," ","y",")","a",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","t","i","m","e","s"," ","x"," ","(","a","d","d","1"," ","y",")"," ",")","(","i","f"," ","(","n","u","m","b","e","r","p"," ","y",")","(","p","l","u","s"," ","x"," ","(","t","i","m","e","s"," ","x"," ","y",")"," ",")","(","f","i","x"," ","x",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","n","t","h"," ","(","N","i","l","l",")","i",")","(","i","f"," ","(","z","e","r","o","p"," ","i",")","(","N","i","l","l",")","(","z","e","r","o",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","l","a","s","t"," ","(","a","p","p","e","n","d"," ","a"," ","b",")"," ",")","(","i","f"," ","(","l","i","s","t","p"," ","b",")","(","l","a","s","t"," ","b",")","(","i","f"," ","(","l","i","s","t","p"," ","a",")","(","C","o","n","s","s"," ","(","c","a","r"," ","(","l","a","s","t"," ","a",")"," ",")","b",")","b",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","e","q","u","a","l"," ","(","l","e","s","s","p"," ","x"," ","y",")","z",")","(","i","f"," ","(","l","e","s","s","p"," ","x"," ","y",")","(","e","q","u","a","l"," ","t"," ","z",")","(","e","q","u","a","l"," ","f"," ","z",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","a","s","s","i","g","n","m","e","n","t"," ","x"," ","(","a","p","p","e","n","d"," ","a"," ","b",")"," ",")","(","i","f"," ","(","a","s","s","i","g","n","e","d","p"," ","x"," ","a",")","(","a","s","s","i","g","n","m","e","n","t"," ","x"," ","a",")","(","a","s","s","i","g","n","m","e","n","t"," ","x"," ","b",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","c","a","r"," ","(","g","o","p","h","e","r"," ","x",")"," ",")","(","i","f"," ","(","l","i","s","t","p"," ","x",")","(","c","a","r"," ","(","f","l","a","t","t","e","n"," ","x",")"," ",")","(","z","e","r","o",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","f","l","a","t","t","e","n"," ","(","c","d","r"," ","(","g","o","p","h","e","r"," ","x",")"," ",")"," ",")","(","i","f"," ","(","l","i","s","t","p"," ","x",")","(","c","d","r"," ","(","f","l","a","t","t","e","n"," ","x",")"," ",")","(","C","o","n","s","s"," ","(","z","e","r","o",")","(","N","i","l","l",")"," ",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","q","u","o","t","i","e","n","t"," ","(","t","i","m","e","s"," ","y"," ","x",")","y",")","(","i","f"," ","(","z","e","r","o","p"," ","y",")","(","z","e","r","o",")","(","f","i","x"," ","x",")"," ",")"," ",")"],["(","e","q","u","a","l"," ","(","g","e","t"," ","j"," ","(","s","e","t"," ","i"," ","v","a","l"," ","m","e","m",")"," ",")","(","i","f"," ","(","e","q","p"," ","j"," ","i",")","v","a","l","(","g","e","t"," ","j"," ","m","e","m",")"," ",")"," ",")"]] + +val lemmas = addlemmalst(makelemmas(rules), Empty) +//│ lemmas = Node([Node([Node([Node([Node([Empty, [["a","n","d"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["a","n","d"]), Conss([Atom(["p"]), Conss([Atom(["q"]), Nill])])]), Conss([Conss([Atom(["i","f"]), Conss([Atom(["p"]), Conss([Conss([Atom(["i","f"]), Conss([Atom(["q"]), Conss([Conss([Atom(["t"]), Nill]), Conss([Conss([Atom(["f"]), Nill]), Nill])])])]), Conss([Conss([Atom(["f"]), Nill]), Nill])])])]), Nill])])])]], Node([Empty, [["a","p","p","e","n","d"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["a","p","p","e","n","d"]), Conss([Conss([Atom(["a","p","p","e","n","d"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Atom(["z"]), Nill])])]), Conss([Conss([Atom(["a","p","p","e","n","d"]), Conss([Atom(["x"]), Conss([Conss([Atom(["a","p","p","e","n","d"]), Conss([Atom(["y"]), Conss([Atom(["z"]), Nill])])]), Nill])])]), Nill])])])]], Node([Empty, [["a","s","s","i","g","n","m","e","n","t"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["a","s","s","i","g","n","m","e","n","t"]), Conss([Atom(["x"]), Conss([Conss([Atom(["a","p","p","e","n","d"]), Conss([Atom(["a"]), Conss([Atom(["b"]), Nill])])]), Nill])])]), Conss([Conss([Atom(["i","f"]), Conss([Conss([Atom(["a","s","s","i","g","n","e","d","p"]), Conss([Atom(["x"]), Conss([Atom(["a"]), Nill])])]), Conss([Conss([Atom(["a","s","s","i","g","n","m","e","n","t"]), Conss([Atom(["x"]), Conss([Atom(["a"]), Nill])])]), Conss([Conss([Atom(["a","s","s","i","g","n","m","e","n","t"]), Conss([Atom(["x"]), Conss([Atom(["b"]), Nill])])]), Nill])])])]), Nill])])])]], Empty])])]), [["a","s","s","u","m","e","-","f","a","l","s","e"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["a","s","s","u","m","e","-","f","a","l","s","e"]), Conss([Atom(["v","a","r"]), Conss([Atom(["a","l","i","s","t"]), Nill])])]), Conss([Conss([Atom(["C","o","n","s","s"]), Conss([Conss([Atom(["C","o","n","s","s"]), Conss([Atom(["v","a","r"]), Conss([Conss([Atom(["f"]), Nill]), Nill])])]), Conss([Atom(["a","l","i","s","t"]), Nill])])]), Nill])])])]], Empty]), [["a","s","s","u","m","e","-","t","r","u","e"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["a","s","s","u","m","e","-","t","r","u","e"]), Conss([Atom(["v","a","r"]), Conss([Atom(["a","l","i","s","t"]), Nill])])]), Conss([Conss([Atom(["C","o","n","s","s"]), Conss([Conss([Atom(["C","o","n","s","s"]), Conss([Atom(["v","a","r"]), Conss([Conss([Atom(["t"]), Nill]), Nill])])]), Conss([Atom(["a","l","i","s","t"]), Nill])])]), Nill])])])]], Empty]), [["b","o","o","l","e","a","n"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["b","o","o","l","e","a","n"]), Conss([Atom(["x"]), Nill])]), Conss([Conss([Atom(["o","r"]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Atom(["x"]), Conss([Conss([Atom(["t"]), Nill]), Nill])])]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Atom(["x"]), Conss([Conss([Atom(["f"]), Nill]), Nill])])]), Nill])])]), Nill])])])]], Node([Empty, [["c","a","r"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["c","a","r"]), Conss([Conss([Atom(["g","o","p","h","e","r"]), Conss([Atom(["x"]), Nill])]), Nill])]), Conss([Conss([Atom(["i","f"]), Conss([Conss([Atom(["l","i","s","t","p"]), Conss([Atom(["x"]), Nill])]), Conss([Conss([Atom(["c","a","r"]), Conss([Conss([Atom(["f","l","a","t","t","e","n"]), Conss([Atom(["x"]), Nill])]), Nill])]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Nill])])])]), Nill])])])]], Empty])]), [["c","o","m","p","i","l","e"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["c","o","m","p","i","l","e"]), Conss([Atom(["f","o","r","m"]), Nill])]), Conss([Conss([Atom(["r","e","v","e","r","s","e"]), Conss([Conss([Atom(["c","o","d","e","g","e","n"]), Conss([Conss([Atom(["o","p","t","i","m","i","z","e"]), Conss([Atom(["f","o","r","m"]), Nill])]), Conss([Conss([Atom(["N","i","l","l"]), Nill]), Nill])])]), Nill])]), Nill])])])]], Node([Node([Node([Empty, [["c","o","u","n","t","-","l","i","s","t"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["c","o","u","n","t","-","l","i","s","t"]), Conss([Atom(["z"]), Conss([Conss([Atom(["s","o","r","t","-","l","p"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Nill])])]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Conss([Atom(["c","o","u","n","t","-","l","i","s","t"]), Conss([Atom(["z"]), Conss([Atom(["x"]), Nill])])]), Conss([Conss([Atom(["c","o","u","n","t","-","l","i","s","t"]), Conss([Atom(["z"]), Conss([Atom(["y"]), Nill])])]), Nill])])]), Nill])])])]], Empty]), [["c","o","u","n","t","p","s","-"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["c","o","u","n","t","p","s","-"]), Conss([Atom(["l"]), Conss([Atom(["p","r","e","d"]), Nill])])]), Conss([Conss([Atom(["c","o","u","n","t","p","s","-","l","o","o","p"]), Conss([Atom(["l"]), Conss([Atom(["p","r","e","d"]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Nill])])])]), Nill])])])]], Node([Node([Empty, [["d","i","f","f","e","r","e","n","c","e"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["d","i","f","f","e","r","e","n","c","e"]), Conss([Conss([Atom(["a","d","d","1"]), Conss([Conss([Atom(["a","d","d","1"]), Conss([Atom(["x"]), Nill])]), Nill])]), Conss([Atom(["2"]), Nill])])]), Conss([Conss([Atom(["f","i","x"]), Conss([Atom(["x"]), Nill])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["d","i","f","f","e","r","e","n","c","e"]), Conss([Conss([Atom(["a","d","d","1"]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["y"]), Conss([Atom(["z"]), Nill])])]), Conss([Atom(["z"]), Nill])])]), Conss([Conss([Atom(["a","d","d","1"]), Conss([Atom(["y"]), Nill])]), Nill])])]), Nill])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["d","i","f","f","e","r","e","n","c","e"]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["b"]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["a"]), Conss([Atom(["c"]), Nill])])]), Nill])])]), Conss([Atom(["a"]), Nill])])]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["b"]), Conss([Atom(["c"]), Nill])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["d","i","f","f","e","r","e","n","c","e"]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["x"]), Conss([Atom(["z"]), Nill])])]), Nill])])]), Conss([Conss([Atom(["d","i","f","f","e","r","e","n","c","e"]), Conss([Atom(["y"]), Conss([Atom(["z"]), Nill])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["d","i","f","f","e","r","e","n","c","e"]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["y"]), Conss([Atom(["x"]), Nill])])]), Conss([Atom(["x"]), Nill])])]), Conss([Conss([Atom(["f","i","x"]), Conss([Atom(["y"]), Nill])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["d","i","f","f","e","r","e","n","c","e"]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Atom(["x"]), Nill])])]), Conss([Conss([Atom(["f","i","x"]), Conss([Atom(["y"]), Nill])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["d","i","f","f","e","r","e","n","c","e"]), Conss([Atom(["x"]), Conss([Atom(["x"]), Nill])])]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Nill])])])]], Empty]), [["d","i","v","i","d","e","s"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["d","i","v","i","d","e","s"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["z","e","r","o","p"]), Conss([Conss([Atom(["r","e","m","a","i","n","d","e","r"]), Conss([Atom(["y"]), Conss([Atom(["x"]), Nill])])]), Nill])]), Nill])])])]], Node([Empty, [["d","s","o","r","t"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["d","s","o","r","t"]), Conss([Atom(["x"]), Nill])]), Conss([Conss([Atom(["s","o","r","t","2"]), Conss([Atom(["x"]), Nill])]), Nill])])])]], Empty])])]), [["e","q","p"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["e","q","p"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["f","i","x"]), Conss([Atom(["x"]), Nill])]), Conss([Conss([Atom(["f","i","x"]), Conss([Atom(["y"]), Nill])]), Nill])])]), Nill])])])]], Node([Node([Node([Node([Empty, [["e","q","u","a","l"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["l","e","s","s","p"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Atom(["z"]), Nill])])]), Conss([Conss([Atom(["i","f"]), Conss([Conss([Atom(["l","e","s","s","p"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Atom(["t"]), Conss([Atom(["z"]), Nill])])]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Atom(["f"]), Conss([Atom(["z"]), Nill])])]), Nill])])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["d","i","f","f","e","r","e","n","c","e"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["d","i","f","f","e","r","e","n","c","e"]), Conss([Atom(["z"]), Conss([Atom(["y"]), Nill])])]), Nill])])]), Conss([Conss([Atom(["i","f"]), Conss([Conss([Atom(["l","e","s","s","p"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["n","o","t"]), Conss([Conss([Atom(["l","e","s","s","p"]), Conss([Atom(["y"]), Conss([Atom(["z"]), Nill])])]), Nill])]), Conss([Conss([Atom(["i","f"]), Conss([Conss([Atom(["l","e","s","s","p"]), Conss([Atom(["z"]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["n","o","t"]), Conss([Conss([Atom(["l","e","s","s","p"]), Conss([Atom(["y"]), Conss([Atom(["x"]), Nill])])]), Nill])]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["f","i","x"]), Conss([Atom(["x"]), Nill])]), Conss([Conss([Atom(["f","i","x"]), Conss([Atom(["z"]), Nill])]), Nill])])]), Nill])])])]), Nill])])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Atom(["a"]), Conss([Atom(["b"]), Nill])])]), Conss([Atom(["1"]), Nill])])]), Conss([Conss([Atom(["a","n","d"]), Conss([Conss([Atom(["n","o","t"]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Atom(["a"]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Nill])])]), Nill])]), Conss([Conss([Atom(["n","o","t"]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Atom(["b"]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Nill])])]), Nill])]), Conss([Conss([Atom(["n","u","m","b","e","r","p"]), Conss([Atom(["a"]), Nill])]), Conss([Conss([Atom(["n","u","m","b","e","r","p"]), Conss([Atom(["b"]), Nill])]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["1","-"]), Conss([Atom(["a"]), Nill])]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Nill])])]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["1","-"]), Conss([Atom(["b"]), Nill])]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Nill])])]), Nill])])])])])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Atom(["x"]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Nill])])]), Conss([Conss([Atom(["o","r"]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Atom(["x"]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Nill])])]), Conss([Conss([Atom(["a","n","d"]), Conss([Conss([Atom(["n","u","m","b","e","r","p"]), Conss([Atom(["x"]), Nill])]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Atom(["y"]), Conss([Atom(["1"]), Nill])])]), Nill])])]), Nill])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Atom(["z"]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Atom(["w"]), Conss([Atom(["z"]), Nill])])]), Nill])])]), Conss([Conss([Atom(["a","n","d"]), Conss([Conss([Atom(["n","u","m","b","e","r","p"]), Conss([Atom(["z"]), Nill])]), Conss([Conss([Atom(["o","r"]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Atom(["z"]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Nill])])]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Atom(["w"]), Conss([Atom(["1"]), Nill])])]), Nill])])]), Nill])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["g","r","e","a","t","e","s","t","-","f","a","c","t","o","r"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Atom(["1"]), Nill])])]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Atom(["x"]), Conss([Atom(["1"]), Nill])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["g","r","e","a","t","e","s","t","-","f","a","c","t","o","r"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Nill])])]), Conss([Conss([Atom(["a","n","d"]), Conss([Conss([Atom(["o","r"]), Conss([Conss([Atom(["z","e","r","o","p"]), Conss([Atom(["y"]), Nill])]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Atom(["y"]), Conss([Atom(["1"]), Nill])])]), Nill])])]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Atom(["x"]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Nill])])]), Nill])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["f","l","a","t","t","e","n"]), Conss([Atom(["x"]), Nill])]), Conss([Conss([Atom(["C","o","n","s","s"]), Conss([Atom(["y"]), Conss([Conss([Atom(["N","i","l","l"]), Nill]), Nill])])]), Nill])])]), Conss([Conss([Atom(["a","n","d"]), Conss([Conss([Atom(["n","l","i","s","t","p"]), Conss([Atom(["x"]), Nill])]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Nill])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["a","p","p","e","n","d"]), Conss([Atom(["a"]), Conss([Atom(["b"]), Nill])])]), Conss([Conss([Atom(["a","p","p","e","n","d"]), Conss([Atom(["a"]), Conss([Atom(["c"]), Nill])])]), Nill])])]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Atom(["b"]), Conss([Atom(["c"]), Nill])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Nill])])]), Conss([Conss([Atom(["o","r"]), Conss([Conss([Atom(["z","e","r","o","p"]), Conss([Atom(["x"]), Nill])]), Conss([Conss([Atom(["z","e","r","o","p"]), Conss([Atom(["y"]), Nill])]), Nill])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Atom(["x"]), Conss([Conss([Atom(["d","i","f","f","e","r","e","n","c","e"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Nill])])]), Conss([Conss([Atom(["a","n","d"]), Conss([Conss([Atom(["n","u","m","b","e","r","p"]), Conss([Atom(["x"]), Nill])]), Conss([Conss([Atom(["o","r"]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Atom(["x"]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Nill])])]), Conss([Conss([Atom(["z","e","r","o","p"]), Conss([Atom(["y"]), Nill])]), Nill])])]), Nill])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Conss([Conss([Atom(["d","i","f","f","e","r","e","n","c","e"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Nill])])]), Conss([Conss([Atom(["n","o","t"]), Conss([Conss([Atom(["l","e","s","s","p"]), Conss([Atom(["y"]), Conss([Atom(["x"]), Nill])])]), Nill])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["a"]), Conss([Atom(["b"]), Nill])])]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["a"]), Conss([Atom(["c"]), Nill])])]), Nill])])]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["f","i","x"]), Conss([Atom(["b"]), Nill])]), Conss([Conss([Atom(["f","i","x"]), Conss([Atom(["c"]), Nill])]), Nill])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["a"]), Conss([Atom(["b"]), Nill])])]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Nill])])]), Conss([Conss([Atom(["a","n","d"]), Conss([Conss([Atom(["z","e","r","o","p"]), Conss([Atom(["a"]), Nill])]), Conss([Conss([Atom(["z","e","r","o","p"]), Conss([Atom(["b"]), Nill])]), Nill])])]), Nill])])])]], Empty]), [["e","v","e","n","1"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["e","v","e","n","1"]), Conss([Atom(["x"]), Nill])]), Conss([Conss([Atom(["i","f"]), Conss([Conss([Atom(["z","e","r","o","p"]), Conss([Atom(["x"]), Nill])]), Conss([Conss([Atom(["t"]), Nill]), Conss([Conss([Atom(["o","d","d"]), Conss([Conss([Atom(["1","-"]), Conss([Atom(["x"]), Nill])]), Nill])]), Nill])])])]), Nill])])])]], Node([Node([Empty, [["e","x","e","c"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["e","x","e","c"]), Conss([Conss([Atom(["a","p","p","e","n","d"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Atom(["p","d","s"]), Conss([Atom(["e","n","v","r","n"]), Nill])])])]), Conss([Conss([Atom(["e","x","e","c"]), Conss([Atom(["y"]), Conss([Conss([Atom(["e","x","e","c"]), Conss([Atom(["x"]), Conss([Atom(["p","d","s"]), Conss([Atom(["e","n","v","r","n"]), Nill])])])]), Conss([Atom(["e","n","v","r","n"]), Nill])])])]), Nill])])])]], Node([Empty, [["e","x","p"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["e","x","p"]), Conss([Atom(["i"]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Atom(["j"]), Conss([Atom(["k"]), Nill])])]), Nill])])]), Conss([Conss([Atom(["e","x","p"]), Conss([Conss([Atom(["e","x","p"]), Conss([Atom(["i"]), Conss([Atom(["j"]), Nill])])]), Conss([Atom(["k"]), Nill])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["e","x","p"]), Conss([Atom(["i"]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["j"]), Conss([Atom(["k"]), Nill])])]), Nill])])]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Conss([Atom(["e","x","p"]), Conss([Atom(["i"]), Conss([Atom(["j"]), Nill])])]), Conss([Conss([Atom(["e","x","p"]), Conss([Atom(["i"]), Conss([Atom(["k"]), Nill])])]), Nill])])]), Nill])])])]], Empty])]), [["f","a","c","t","-"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["f","a","c","t","-"]), Conss([Atom(["i"]), Nill])]), Conss([Conss([Atom(["f","a","c","t","-","l","o","o","p"]), Conss([Atom(["i"]), Conss([Atom(["1"]), Nill])])]), Nill])])])]], Node([Empty, [["f","a","l","s","i","f","y"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["f","a","l","s","i","f","y"]), Conss([Atom(["x"]), Nill])]), Conss([Conss([Atom(["f","a","l","s","i","f","y","1"]), Conss([Conss([Atom(["n","o","r","m","a","l","i","z","e"]), Conss([Atom(["x"]), Nill])]), Conss([Conss([Atom(["N","i","l","l"]), Nill]), Nill])])]), Nill])])])]], Node([Empty, [["f","i","x"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["f","i","x"]), Conss([Atom(["x"]), Nill])]), Conss([Conss([Atom(["i","f"]), Conss([Conss([Atom(["n","u","m","b","e","r","p"]), Conss([Atom(["x"]), Nill])]), Conss([Atom(["x"]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Nill])])])]), Nill])])])]], Node([Node([Empty, [["f","l","a","t","t","e","n"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["f","l","a","t","t","e","n"]), Conss([Conss([Atom(["c","d","r"]), Conss([Conss([Atom(["g","o","p","h","e","r"]), Conss([Atom(["x"]), Nill])]), Nill])]), Nill])]), Conss([Conss([Atom(["i","f"]), Conss([Conss([Atom(["l","i","s","t","p"]), Conss([Atom(["x"]), Nill])]), Conss([Conss([Atom(["c","d","r"]), Conss([Conss([Atom(["f","l","a","t","t","e","n"]), Conss([Atom(["x"]), Nill])]), Nill])]), Conss([Conss([Atom(["C","o","n","s","s"]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Conss([Conss([Atom(["N","i","l","l"]), Nill]), Nill])])]), Nill])])])]), Nill])])])]], Empty]), [["g","c","d"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["g","c","d"]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Atom(["x"]), Conss([Atom(["z"]), Nill])])]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Atom(["y"]), Conss([Atom(["z"]), Nill])])]), Nill])])]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Atom(["z"]), Conss([Conss([Atom(["g","c","d"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Nill])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["g","c","d"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["g","c","d"]), Conss([Atom(["y"]), Conss([Atom(["x"]), Nill])])]), Nill])])])]], Node([Empty, [["g","e","t"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["g","e","t"]), Conss([Atom(["j"]), Conss([Conss([Atom(["s","e","t"]), Conss([Atom(["i"]), Conss([Atom(["v","a","l"]), Conss([Atom(["m","e","m"]), Nill])])])]), Nill])])]), Conss([Conss([Atom(["i","f"]), Conss([Conss([Atom(["e","q","p"]), Conss([Atom(["j"]), Conss([Atom(["i"]), Nill])])]), Conss([Atom(["v","a","l"]), Conss([Conss([Atom(["g","e","t"]), Conss([Atom(["j"]), Conss([Atom(["m","e","m"]), Nill])])]), Nill])])])]), Nill])])])]], Empty])])])])])]), [["g","r","e","a","t","e","r","e","q","p"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["g","r","e","a","t","e","r","e","q","p"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["n","o","t"]), Conss([Conss([Atom(["l","e","s","s","p"]), Conss([Atom(["y"]), Conss([Atom(["x"]), Nill])])]), Nill])]), Nill])])])]], Node([Empty, [["g","r","e","a","t","e","r","e","q","p","r"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["g","r","e","a","t","e","r","e","q","p","r"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["n","o","t"]), Conss([Conss([Atom(["l","e","s","s","p"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Nill])]), Nill])])])]], Empty])]), [["g","r","e","a","t","e","r","p"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["g","r","e","a","t","e","r","p"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["l","e","s","s","p"]), Conss([Atom(["y"]), Conss([Atom(["x"]), Nill])])]), Nill])])])]], Node([Node([Node([Empty, [["i","f"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["i","f"]), Conss([Conss([Atom(["i","f"]), Conss([Atom(["a"]), Conss([Atom(["b"]), Conss([Atom(["c"]), Nill])])])]), Conss([Atom(["d"]), Conss([Atom(["e"]), Nill])])])]), Conss([Conss([Atom(["i","f"]), Conss([Atom(["a"]), Conss([Conss([Atom(["i","f"]), Conss([Atom(["b"]), Conss([Atom(["d"]), Conss([Atom(["e"]), Nill])])])]), Conss([Conss([Atom(["i","f"]), Conss([Atom(["c"]), Conss([Atom(["d"]), Conss([Atom(["e"]), Nill])])])]), Nill])])])]), Nill])])])]], Empty]), [["i","f","f"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["i","f","f"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["a","n","d"]), Conss([Conss([Atom(["i","m","p","l","i","e","s"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["i","m","p","l","i","e","s"]), Conss([Atom(["y"]), Conss([Atom(["x"]), Nill])])]), Nill])])]), Nill])])])]], Node([Empty, [["i","m","p","l","i","e","s"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["i","m","p","l","i","e","s"]), Conss([Atom(["p"]), Conss([Atom(["q"]), Nill])])]), Conss([Conss([Atom(["i","f"]), Conss([Atom(["p"]), Conss([Conss([Atom(["i","f"]), Conss([Atom(["q"]), Conss([Conss([Atom(["t"]), Nill]), Conss([Conss([Atom(["f"]), Nill]), Nill])])])]), Conss([Conss([Atom(["t"]), Nill]), Nill])])])]), Nill])])])]], Node([Node([Empty, [["l","a","s","t"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["l","a","s","t"]), Conss([Conss([Atom(["a","p","p","e","n","d"]), Conss([Atom(["a"]), Conss([Atom(["b"]), Nill])])]), Nill])]), Conss([Conss([Atom(["i","f"]), Conss([Conss([Atom(["l","i","s","t","p"]), Conss([Atom(["b"]), Nill])]), Conss([Conss([Atom(["l","a","s","t"]), Conss([Atom(["b"]), Nill])]), Conss([Conss([Atom(["i","f"]), Conss([Conss([Atom(["l","i","s","t","p"]), Conss([Atom(["a"]), Nill])]), Conss([Conss([Atom(["C","o","n","s","s"]), Conss([Conss([Atom(["c","a","r"]), Conss([Conss([Atom(["l","a","s","t"]), Conss([Atom(["a"]), Nill])]), Nill])]), Conss([Atom(["b"]), Nill])])]), Conss([Atom(["b"]), Nill])])])]), Nill])])])]), Nill])])])]], Empty]), [["l","e","n","g","t","h"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["l","e","n","g","t","h"]), Conss([Conss([Atom(["C","o","n","s","s"]), Conss([Atom(["x","1"]), Conss([Conss([Atom(["C","o","n","s","s"]), Conss([Atom(["x","2"]), Conss([Conss([Atom(["C","o","n","s","s"]), Conss([Atom(["x","3"]), Conss([Conss([Atom(["C","o","n","s","s"]), Conss([Atom(["x","4"]), Conss([Conss([Atom(["C","o","n","s","s"]), Conss([Atom(["x","5"]), Conss([Conss([Atom(["C","o","n","s","s"]), Conss([Atom(["x","6"]), Conss([Atom(["x","7"]), Nill])])]), Nill])])]), Nill])])]), Nill])])]), Nill])])]), Nill])])]), Nill])]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["6"]), Conss([Conss([Atom(["l","e","n","g","t","h"]), Conss([Atom(["x","7"]), Nill])]), Nill])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["l","e","n","g","t","h"]), Conss([Conss([Atom(["r","e","v","e","r","s","e"]), Conss([Atom(["x"]), Nill])]), Nill])]), Conss([Conss([Atom(["l","e","n","g","t","h"]), Conss([Atom(["x"]), Nill])]), Nill])])])]], Empty])])]), [["l","e","s","s","e","q","p"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["l","e","s","s","e","q","p"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["n","o","t"]), Conss([Conss([Atom(["l","e","s","s","p"]), Conss([Atom(["y"]), Conss([Atom(["x"]), Nill])])]), Nill])]), Nill])])])]], Node([Node([Node([Node([Node([Node([Node([Empty, [["l","e","s","s","p"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["l","e","s","s","p"]), Conss([Conss([Atom(["l","e","n","g","t","h"]), Conss([Conss([Atom(["d","e","l","e","t","e"]), Conss([Atom(["x"]), Conss([Atom(["l"]), Nill])])]), Nill])]), Conss([Conss([Atom(["l","e","n","g","t","h"]), Conss([Atom(["l"]), Nill])]), Nill])])]), Conss([Conss([Atom(["m","e","m","b","e","r"]), Conss([Atom(["x"]), Conss([Atom(["l"]), Nill])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["l","e","s","s","p"]), Conss([Atom(["y"]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Nill])])]), Conss([Conss([Atom(["n","o","t"]), Conss([Conss([Atom(["z","e","r","o","p"]), Conss([Atom(["x"]), Nill])]), Nill])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["l","e","s","s","p"]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Atom(["x"]), Conss([Atom(["z"]), Nill])])]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Atom(["y"]), Conss([Atom(["z"]), Nill])])]), Nill])])]), Conss([Conss([Atom(["a","n","d"]), Conss([Conss([Atom(["n","o","t"]), Conss([Conss([Atom(["z","e","r","o","p"]), Conss([Atom(["z"]), Nill])]), Nill])]), Conss([Conss([Atom(["l","e","s","s","p"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Nill])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["l","e","s","s","p"]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["x"]), Conss([Atom(["z"]), Nill])])]), Nill])])]), Conss([Conss([Atom(["l","e","s","s","p"]), Conss([Atom(["y"]), Conss([Atom(["z"]), Nill])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["l","e","s","s","p"]), Conss([Conss([Atom(["r","e","m","a","i","n","d","e","r"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Atom(["x"]), Nill])])]), Conss([Conss([Atom(["a","n","d"]), Conss([Conss([Atom(["n","o","t"]), Conss([Conss([Atom(["z","e","r","o","p"]), Conss([Atom(["y"]), Nill])]), Nill])]), Conss([Conss([Atom(["n","o","t"]), Conss([Conss([Atom(["z","e","r","o","p"]), Conss([Atom(["x"]), Nill])]), Nill])]), Conss([Conss([Atom(["n","o","t"]), Conss([Conss([Atom(["l","e","s","s","p"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Nill])]), Nill])])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["l","e","s","s","p"]), Conss([Conss([Atom(["q","u","o","t","i","e","n","t"]), Conss([Atom(["i"]), Conss([Atom(["j"]), Nill])])]), Conss([Atom(["i"]), Nill])])]), Conss([Conss([Atom(["a","n","d"]), Conss([Conss([Atom(["n","o","t"]), Conss([Conss([Atom(["z","e","r","o","p"]), Conss([Atom(["i"]), Nill])]), Nill])]), Conss([Conss([Atom(["o","r"]), Conss([Conss([Atom(["z","e","r","o","p"]), Conss([Atom(["j"]), Nill])]), Conss([Conss([Atom(["n","o","t"]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Atom(["j"]), Conss([Atom(["1"]), Nill])])]), Nill])]), Nill])])]), Nill])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["l","e","s","s","p"]), Conss([Conss([Atom(["r","e","m","a","i","n","d","e","r"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["n","o","t"]), Conss([Conss([Atom(["z","e","r","o","p"]), Conss([Atom(["y"]), Nill])]), Nill])]), Nill])])])]], Node([Empty, [["l","i","s","t","p"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["l","i","s","t","p"]), Conss([Conss([Atom(["g","o","p","h","e","r"]), Conss([Atom(["x"]), Nill])]), Nill])]), Conss([Conss([Atom(["l","i","s","t","p"]), Conss([Atom(["x"]), Nill])]), Nill])])])]], Empty])]), [["m","c","-","f","l","a","t","t","e","n"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["m","c","-","f","l","a","t","t","e","n"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["a","p","p","e","n","d"]), Conss([Conss([Atom(["f","l","a","t","t","e","n"]), Conss([Atom(["x"]), Nill])]), Conss([Atom(["y"]), Nill])])]), Nill])])])]], Empty]), [["m","e","a","n","i","n","g"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["m","e","a","n","i","n","g"]), Conss([Conss([Atom(["p","l","u","s","-","t","r","e","e"]), Conss([Conss([Atom(["d","e","l","e","t","e"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Nill])]), Conss([Atom(["a"]), Nill])])]), Conss([Conss([Atom(["i","f"]), Conss([Conss([Atom(["m","e","m","b","e","r"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["d","i","f","f","e","r","e","n","c","e"]), Conss([Conss([Atom(["m","e","a","n","i","n","g"]), Conss([Conss([Atom(["p","l","u","s","-","t","r","e","e"]), Conss([Atom(["y"]), Nill])]), Conss([Atom(["a"]), Nill])])]), Conss([Conss([Atom(["m","e","a","n","i","n","g"]), Conss([Atom(["x"]), Conss([Atom(["a"]), Nill])])]), Nill])])]), Conss([Conss([Atom(["m","e","a","n","i","n","g"]), Conss([Conss([Atom(["p","l","u","s","-","t","r","e","e"]), Conss([Atom(["y"]), Nill])]), Conss([Atom(["a"]), Nill])])]), Nill])])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["m","e","a","n","i","n","g"]), Conss([Conss([Atom(["p","l","u","s","-","t","r","e","e"]), Conss([Conss([Atom(["p","l","u","s","-","f","r","i","n","g","e"]), Conss([Atom(["x"]), Nill])]), Nill])]), Conss([Atom(["a"]), Nill])])]), Conss([Conss([Atom(["f","i","x"]), Conss([Conss([Atom(["m","e","a","n","i","n","g"]), Conss([Atom(["x"]), Conss([Atom(["a"]), Nill])])]), Nill])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["m","e","a","n","i","n","g"]), Conss([Conss([Atom(["p","l","u","s","-","t","r","e","e"]), Conss([Conss([Atom(["a","p","p","e","n","d"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Nill])]), Conss([Atom(["a"]), Nill])])]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Conss([Atom(["m","e","a","n","i","n","g"]), Conss([Conss([Atom(["p","l","u","s","-","t","r","e","e"]), Conss([Atom(["x"]), Nill])]), Conss([Atom(["a"]), Nill])])]), Conss([Conss([Atom(["m","e","a","n","i","n","g"]), Conss([Conss([Atom(["p","l","u","s","-","t","r","e","e"]), Conss([Atom(["y"]), Nill])]), Conss([Atom(["a"]), Nill])])]), Nill])])]), Nill])])])]], Node([Empty, [["m","e","m","b","e","r"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["m","e","m","b","e","r"]), Conss([Atom(["a"]), Conss([Conss([Atom(["i","n","t","e","r","s","e","c","t"]), Conss([Atom(["b"]), Conss([Atom(["c"]), Nill])])]), Nill])])]), Conss([Conss([Atom(["a","n","d"]), Conss([Conss([Atom(["m","e","m","b","e","r"]), Conss([Atom(["a"]), Conss([Atom(["b"]), Nill])])]), Conss([Conss([Atom(["m","e","m","b","e","r"]), Conss([Atom(["a"]), Conss([Atom(["c"]), Nill])])]), Nill])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["m","e","m","b","e","r"]), Conss([Atom(["x"]), Conss([Conss([Atom(["r","e","v","e","r","s","e"]), Conss([Atom(["y"]), Nill])]), Nill])])]), Conss([Conss([Atom(["m","e","m","b","e","r"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["m","e","m","b","e","r"]), Conss([Atom(["x"]), Conss([Conss([Atom(["a","p","p","e","n","d"]), Conss([Atom(["a"]), Conss([Atom(["b"]), Nill])])]), Nill])])]), Conss([Conss([Atom(["o","r"]), Conss([Conss([Atom(["m","e","m","b","e","r"]), Conss([Atom(["x"]), Conss([Atom(["a"]), Nill])])]), Conss([Conss([Atom(["m","e","m","b","e","r"]), Conss([Atom(["x"]), Conss([Atom(["b"]), Nill])])]), Nill])])]), Nill])])])]], Empty])]), [["n","o","t"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["n","o","t"]), Conss([Atom(["p"]), Nill])]), Conss([Conss([Atom(["i","f"]), Conss([Atom(["p"]), Conss([Conss([Atom(["f"]), Nill]), Conss([Conss([Atom(["t"]), Nill]), Nill])])])]), Nill])])])]], Node([Empty, [["n","t","h"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["n","t","h"]), Conss([Conss([Atom(["N","i","l","l"]), Nill]), Conss([Atom(["i"]), Nill])])]), Conss([Conss([Atom(["i","f"]), Conss([Conss([Atom(["z","e","r","o","p"]), Conss([Atom(["i"]), Nill])]), Conss([Conss([Atom(["N","i","l","l"]), Nill]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Nill])])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["n","t","h"]), Conss([Conss([Atom(["a","p","p","e","n","d"]), Conss([Atom(["a"]), Conss([Atom(["b"]), Nill])])]), Conss([Atom(["i"]), Nill])])]), Conss([Conss([Atom(["a","p","p","e","n","d"]), Conss([Conss([Atom(["n","t","h"]), Conss([Atom(["a"]), Conss([Atom(["i"]), Nill])])]), Conss([Conss([Atom(["n","t","h"]), Conss([Atom(["b"]), Conss([Conss([Atom(["d","i","f","f","e","r","e","n","c","e"]), Conss([Atom(["i"]), Conss([Conss([Atom(["l","e","n","g","t","h"]), Conss([Atom(["a"]), Nill])]), Nill])])]), Nill])])]), Nill])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["n","t","h"]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Conss([Atom(["i"]), Nill])])]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Nill])])])]], Node([Empty, [["n","u","m","b","e","r","p"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["n","u","m","b","e","r","p"]), Conss([Conss([Atom(["g","r","e","a","t","e","s","t","-","f","a","c","t","o","r"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Nill])]), Conss([Conss([Atom(["n","o","t"]), Conss([Conss([Atom(["a","n","d"]), Conss([Conss([Atom(["o","r"]), Conss([Conss([Atom(["z","e","r","o","p"]), Conss([Atom(["y"]), Nill])]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Atom(["y"]), Conss([Atom(["1"]), Nill])])]), Nill])])]), Conss([Conss([Atom(["n","o","t"]), Conss([Conss([Atom(["n","u","m","b","e","r","p"]), Conss([Atom(["x"]), Nill])]), Nill])]), Nill])])]), Nill])]), Nill])])])]], Empty])])]), [["o","r"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["o","r"]), Conss([Atom(["p"]), Conss([Atom(["q"]), Nill])])]), Conss([Conss([Atom(["i","f"]), Conss([Atom(["p"]), Conss([Conss([Atom(["t"]), Nill]), Conss([Conss([Atom(["i","f"]), Conss([Atom(["q"]), Conss([Conss([Atom(["t"]), Nill]), Conss([Conss([Atom(["f"]), Nill]), Nill])])])]), Nill])])])]), Nill])])])]], Node([Empty, [["p","l","u","s"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["x"]), Conss([Conss([Atom(["a","d","d","1"]), Conss([Atom(["y"]), Nill])]), Nill])])]), Conss([Conss([Atom(["i","f"]), Conss([Conss([Atom(["n","u","m","b","e","r","p"]), Conss([Atom(["y"]), Nill])]), Conss([Conss([Atom(["a","d","d","1"]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Nill])]), Conss([Conss([Atom(["a","d","d","1"]), Conss([Atom(["x"]), Nill])]), Nill])])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Conss([Atom(["r","e","m","a","i","n","d","e","r"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Atom(["y"]), Conss([Conss([Atom(["q","u","o","t","i","e","n","t"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Nill])])]), Nill])])]), Conss([Conss([Atom(["f","i","x"]), Conss([Atom(["x"]), Nill])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Atom(["z"]), Nill])])]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["x"]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["y"]), Conss([Atom(["z"]), Nill])])]), Nill])])]), Nill])])])]], Node([Empty, [["p","o","w","e","r","-","e","v","a","l"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["p","o","w","e","r","-","e","v","a","l"]), Conss([Conss([Atom(["b","i","g","-","p","l","u","s"]), Conss([Conss([Atom(["p","o","w","e","r","-","r","e","p"]), Conss([Atom(["i"]), Conss([Atom(["b","a","s","e"]), Nill])])]), Conss([Conss([Atom(["p","o","w","e","r","-","r","e","p"]), Conss([Atom(["j"]), Conss([Atom(["b","a","s","e"]), Nill])])]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Conss([Atom(["b","a","s","e"]), Nill])])])])]), Conss([Atom(["b","a","s","e"]), Nill])])]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["i"]), Conss([Atom(["j"]), Nill])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["p","o","w","e","r","-","e","v","a","l"]), Conss([Conss([Atom(["p","o","w","e","r","-","r","e","p"]), Conss([Atom(["i"]), Conss([Atom(["b","a","s","e"]), Nill])])]), Conss([Atom(["b","a","s","e"]), Nill])])]), Conss([Conss([Atom(["f","i","x"]), Conss([Atom(["i"]), Nill])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["p","o","w","e","r","-","e","v","a","l"]), Conss([Conss([Atom(["b","i","g","-","p","l","u","s"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Conss([Atom(["i"]), Conss([Atom(["b","a","s","e"]), Nill])])])])]), Conss([Atom(["b","a","s","e"]), Nill])])]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["i"]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Conss([Atom(["p","o","w","e","r","-","e","v","a","l"]), Conss([Atom(["x"]), Conss([Atom(["b","a","s","e"]), Nill])])]), Conss([Conss([Atom(["p","o","w","e","r","-","e","v","a","l"]), Conss([Atom(["y"]), Conss([Atom(["b","a","s","e"]), Nill])])]), Nill])])]), Nill])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["p","o","w","e","r","-","e","v","a","l"]), Conss([Conss([Atom(["b","i","g","-","p","l","u","s","1"]), Conss([Atom(["l"]), Conss([Atom(["i"]), Conss([Atom(["b","a","s","e"]), Nill])])])]), Conss([Atom(["b","a","s","e"]), Nill])])]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Conss([Atom(["p","o","w","e","r","-","e","v","a","l"]), Conss([Atom(["l"]), Conss([Atom(["b","a","s","e"]), Nill])])]), Conss([Atom(["i"]), Nill])])]), Nill])])])]], Empty])])]), [["p","r","i","m","e"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["p","r","i","m","e"]), Conss([Atom(["x"]), Nill])]), Conss([Conss([Atom(["a","n","d"]), Conss([Conss([Atom(["n","o","t"]), Conss([Conss([Atom(["z","e","r","o","p"]), Conss([Atom(["x"]), Nill])]), Nill])]), Conss([Conss([Atom(["n","o","t"]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Atom(["x"]), Conss([Conss([Atom(["a","d","d","1"]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Nill])]), Nill])])]), Nill])]), Conss([Conss([Atom(["p","r","i","m","e","1"]), Conss([Atom(["x"]), Conss([Conss([Atom(["1","-"]), Conss([Atom(["x"]), Nill])]), Nill])])]), Nill])])])]), Nill])])])]], Node([Node([Node([Empty, [["p","r","i","m","e","-","l","i","s","t"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["p","r","i","m","e","-","l","i","s","t"]), Conss([Conss([Atom(["a","p","p","e","n","d"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Nill])]), Conss([Conss([Atom(["a","n","d"]), Conss([Conss([Atom(["p","r","i","m","e","-","l","i","s","t"]), Conss([Atom(["x"]), Nill])]), Conss([Conss([Atom(["p","r","i","m","e","-","l","i","s","t"]), Conss([Atom(["y"]), Nill])]), Nill])])]), Nill])])])]], Node([Empty, [["q","u","o","t","i","e","n","t"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["q","u","o","t","i","e","n","t"]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Atom(["y"]), Conss([Atom(["x"]), Nill])])]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["i","f"]), Conss([Conss([Atom(["z","e","r","o","p"]), Conss([Atom(["y"]), Nill])]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Conss([Conss([Atom(["f","i","x"]), Conss([Atom(["x"]), Nill])]), Nill])])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["q","u","o","t","i","e","n","t"]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["x"]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Nill])])]), Conss([Atom(["2"]), Nill])])]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["x"]), Conss([Conss([Atom(["q","u","o","t","i","e","n","t"]), Conss([Atom(["y"]), Conss([Atom(["2"]), Nill])])]), Nill])])]), Nill])])])]], Empty])]), [["r","e","m","a","i","n","d","e","r"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["r","e","m","a","i","n","d","e","r"]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Atom(["y"]), Conss([Atom(["x"]), Nill])])]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["r","e","m","a","i","n","d","e","r"]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Atom(["x"]), Conss([Atom(["z"]), Nill])])]), Conss([Atom(["z"]), Nill])])]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["r","e","m","a","i","n","d","e","r"]), Conss([Atom(["x"]), Conss([Atom(["x"]), Nill])])]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["r","e","m","a","i","n","d","e","r"]), Conss([Atom(["y"]), Conss([Atom(["1"]), Nill])])]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Nill])])])]], Empty]), [["r","e","v","e","r","s","e"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["r","e","v","e","r","s","e"]), Conss([Conss([Atom(["a","p","p","e","n","d"]), Conss([Atom(["a"]), Conss([Atom(["b"]), Nill])])]), Nill])]), Conss([Conss([Atom(["a","p","p","e","n","d"]), Conss([Conss([Atom(["r","e","v","e","r","s","e"]), Conss([Atom(["b"]), Nill])]), Conss([Conss([Atom(["r","e","v","e","r","s","e"]), Conss([Atom(["a"]), Nill])]), Nill])])]), Nill])])])]], Empty])]), [["r","e","v","e","r","s","e","-"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["r","e","v","e","r","s","e","-"]), Conss([Atom(["x"]), Nill])]), Conss([Conss([Atom(["r","e","v","e","r","s","e","-","l","o","o","p"]), Conss([Atom(["x"]), Conss([Conss([Atom(["N","i","l","l"]), Nill]), Nill])])]), Nill])])])]], Node([Node([Empty, [["r","e","v","e","r","s","e","-","l","o","o","p"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["r","e","v","e","r","s","e","-","l","o","o","p"]), Conss([Atom(["x"]), Conss([Conss([Atom(["N","i","l","l"]), Nill]), Nill])])]), Conss([Conss([Atom(["r","e","v","e","r","s","e"]), Conss([Atom(["x"]), Nill])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["r","e","v","e","r","s","e","-","l","o","o","p"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["a","p","p","e","n","d"]), Conss([Conss([Atom(["r","e","v","e","r","s","e"]), Conss([Atom(["x"]), Nill])]), Conss([Atom(["y"]), Nill])])]), Nill])])])]], Node([Empty, [["s","a","m","e","f","r","i","n","g","e"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["s","a","m","e","f","r","i","n","g","e"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["f","l","a","t","t","e","n"]), Conss([Atom(["x"]), Nill])]), Conss([Conss([Atom(["f","l","a","t","t","e","n"]), Conss([Atom(["y"]), Nill])]), Nill])])]), Nill])])])]], Node([Node([Empty, [["s","i","g","m","a"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["s","i","g","m","a"]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Conss([Atom(["i"]), Nill])])]), Conss([Conss([Atom(["q","u","o","t","i","e","n","t"]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Atom(["i"]), Conss([Conss([Atom(["a","d","d","1"]), Conss([Atom(["i"]), Nill])]), Nill])])]), Conss([Atom(["2"]), Nill])])]), Nill])])])]], Empty]), [["s","o","r","t","2"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["s","o","r","t","2"]), Conss([Conss([Atom(["d","e","l","e","t","e"]), Conss([Atom(["x"]), Conss([Atom(["l"]), Nill])])]), Nill])]), Conss([Conss([Atom(["d","e","l","e","t","e"]), Conss([Atom(["x"]), Conss([Conss([Atom(["s","o","r","t","2"]), Conss([Atom(["l"]), Nill])]), Nill])])]), Nill])])])]], Empty])])]), [["t","a","u","t","o","l","o","g","y","-","c","h","e","c","k","e","r"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["t","a","u","t","o","l","o","g","y","-","c","h","e","c","k","e","r"]), Conss([Atom(["x"]), Nill])]), Conss([Conss([Atom(["t","a","u","t","o","l","o","g","y","p"]), Conss([Conss([Atom(["n","o","r","m","a","l","i","z","e"]), Conss([Atom(["x"]), Nill])]), Conss([Conss([Atom(["N","i","l","l"]), Nill]), Nill])])]), Nill])])])]], Node([Node([Empty, [["t","i","m","e","s"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Atom(["x"]), Conss([Conss([Atom(["a","d","d","1"]), Conss([Atom(["y"]), Nill])]), Nill])])]), Conss([Conss([Atom(["i","f"]), Conss([Conss([Atom(["n","u","m","b","e","r","p"]), Conss([Atom(["y"]), Nill])]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["x"]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Nill])])]), Conss([Conss([Atom(["f","i","x"]), Conss([Atom(["x"]), Nill])]), Nill])])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Atom(["x"]), Conss([Conss([Atom(["d","i","f","f","e","r","e","n","c","e"]), Conss([Atom(["c"]), Conss([Atom(["w"]), Nill])])]), Nill])])]), Conss([Conss([Atom(["d","i","f","f","e","r","e","n","c","e"]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Atom(["c"]), Conss([Atom(["x"]), Nill])])]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Atom(["w"]), Conss([Atom(["x"]), Nill])])]), Nill])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Atom(["z"]), Nill])])]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Atom(["x"]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Atom(["y"]), Conss([Atom(["z"]), Nill])])]), Nill])])]), Nill])])]),Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Atom(["x"]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Atom(["y"]), Conss([Atom(["z"]), Nill])])]), Nill])])]), Conss([Conss([Atom(["p","l","u","s"]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Atom(["x"]), Conss([Atom(["z"]), Nill])])]), Nill])])]), Nill])])])]], Node([Node([Empty, [["t","i","m","e","s","-","l","i","s","t"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["t","i","m","e","s","-","l","i","s","t"]), Conss([Conss([Atom(["a","p","p","e","n","d"]), Conss([Atom(["x"]), Conss([Atom(["y"]), Nill])])]), Nill])]), Conss([Conss([Atom(["t","i","m","e","s"]), Conss([Conss([Atom(["t","i","m","e","s","-","l","i","s","t"]), Conss([Atom(["x"]), Nill])]), Conss([Conss([Atom(["t","i","m","e","s","-","l","i","s","t"]), Conss([Atom(["y"]), Nill])]), Nill])])]), Nill])])])]], Empty]), [["v","a","l","u","e"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["v","a","l","u","e"]), Conss([Conss([Atom(["n","o","r","m","a","l","i","z","e"]), Conss([Atom(["x"]), Nill])]), Conss([Atom(["a"]), Nill])])]), Conss([Conss([Atom(["v","a","l","u","e"]), Conss([Atom(["x"]), Conss([Atom(["a"]), Nill])])]), Nill])])])]], Empty])]), [["z","e","r","o","p"], [Conss([Atom(["e","q","u","a","l"]), Conss([Conss([Atom(["z","e","r","o","p"]), Conss([Atom(["x"]), Nill])]), Conss([Conss([Atom(["o","r"]), Conss([Conss([Atom(["e","q","u","a","l"]), Conss([Atom(["x"]), Conss([Conss([Atom(["z","e","r","o"]), Nill]), Nill])])]), Conss([Conss([Atom(["n","o","t"]), Conss([Conss([Atom(["n","u","m","b","e","r","p"]), Conss([Atom(["x"]), Nill])]), Nill])]), Nill])])]), Nill])])])]], Empty])])])])])])]) + +fun tautp(term) = tautologyp([rewrite(term, lemmas), Nill, Nill]) + +fun teststatement(i) = applysubst(subterm(i), statement) + +fun testresult(i) = tautp(teststatement(i)) + +fun testBoyer2_nofib(n) = report(testresult(n)) + +fun main() = testBoyer2_nofib(3) +//│ = "The term is a tautology" diff --git a/benchmark/src/nofib/calendar.mls b/benchmark/src/nofib/calendar.mls new file mode 100644 index 000000000..3da445ba3 --- /dev/null +++ b/benchmark/src/nofib/calendar.mls @@ -0,0 +1,140 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module calendar with ... + + + +fun unlines(ls) = concat(map(x => x +: ("\n" :: Nil), ls)) + +fun height(p) = listLen(p) + +fun width(p) = listLen(head(p)) + +fun stack(ls) = foldr1((a, b) => a +: b, ls) + +fun spread(ls) = foldr1((a, b) => zipWith((a, b) => a +: b, a, b), ls) + +fun emptyPic(hw) = if hw is [h, w] then replicate(h, replicate(w, " ")) + +fun groop(n, xs) = if xs is + Nil then Nil + else take(n, xs) :: groop(n, drop(n, xs)) + +fun block(n, t) = stack(map(spread, groop(n, t))) + +fun blockT(n, t) = stack(map(stack, groop(n, t))) + +fun lframe(mn, p) = if mn is [m,n] then + let h = height(p) + let w = width(p) + zipWith(append, p, emptyPic([h, n - w])) +: emptyPic([m - h, n]) + +fun leap(year) = if + intMod(year, 100) == 0 then intMod(year, 400) == 0 + else intMod(year, 4) == 0 + +fun monthLengths(year) = + let feb = if leap(year) then 29 else 28 + 31 :: feb :: 31 :: 30 :: 31 :: 30 :: 31 :: 31 :: 30 :: 31 :: 30 :: 31 :: Nil + +val monthNames = + nofibStringToList("January") :: + nofibStringToList("February") :: + nofibStringToList("March") :: + nofibStringToList("April") :: + nofibStringToList("May") :: + nofibStringToList("June") :: + nofibStringToList("July") :: + nofibStringToList("August") :: + nofibStringToList("September") :: + nofibStringToList("October") :: + nofibStringToList("November") :: + nofibStringToList("December") :: Nil +//│ monthNames = [["J","a","n","u","a","r","y"],["F","e","b","r","u","a","r","y"],["M","a","r","c","h"],["A","p","r","i","l"],["M","a","y"],["J","u","n","e"],["J","u","l","y"],["A","u","g","u","s","t"],["S","e","p","t","e","m","b","e","r"],["O","c","t","o","b","e","r"],["N","o","v","e","m","b","e","r"],["D","e","c","e","m","b","e","r"]] + +fun jan1st(year) = + let last = year - 1 + intMod(year + intDiv(last, 4) - intDiv(last, 100) + intDiv(last, 400), 7) + +fun firstDays(year) = + take(12, map(x => intMod(x, 7), scanl((a, b) => a + b, jan1st(year), monthLengths(year)))) + +fun space(n) = replicate(n, " ") + +fun ljustify(n, s) = s +: space(n - listLen(s)) + +fun rjustify(n, s) = space(n - listLen(s)) +: s + +fun date(ml, d) = if (d < 1) || (ml < d) then nofibStringToList(" ") :: Nil else rjustify(3, nofibStringToList(stringOfInt(d))) :: Nil + +fun dates(fd, ml) = map(d => date(ml, d), enumFromTo(1 - fd, 42 - fd)) + +fun cjustify(n, s) = + let m = n - listLen(s) + let halfm = intDiv(m, 2) + space(halfm) +: s +: space(m - halfm) + +fun cal(year) = + let side = emptyPic([8, 2]) + let end = emptyPic([1, 25]) + let daynames = nofibStringToList(" Su Mo Tu We Th Fr Sa") :: Nil + fun banner(yr) = cjustify(75, nofibStringToList(stringOfInt(yr))) :: emptyPic([1, 75]) + fun body(yr) = block(3, map(x => pad(pic(x)), months(yr))) + fun pic(mnfdml) = if mnfdml is [mn, fd, ml] then title(mn) +: table(fd, ml) + fun pad(p) = zipWith(append, zipWith(append, side, p), side) +: end + fun title(mn) = cjustify(21, mn) :: Nil + fun table(fd, ml) = daynames +: entries(fd, ml) + fun entries(fd, ml) = block(7, dates(fd, ml)) + fun months(yer) = zip3(monthNames, firstDays(yer), monthLengths(yer)) + + unlines(banner(year) +: body(year)) + +fun testCalendar_nofib(n) = map(x => cal(x), enumFromTo(1993, 1993 + n)) + + +// NOTE: original input: 1000 +fun main() = + nofibListToString of concat of testCalendar_nofib(0) +//│ > 1993 +//│ > +//│ > January February March +//│ > Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa +//│ > 1 2 1 2 3 4 5 6 1 2 3 4 5 6 +//│ > 3 4 5 6 7 8 9 7 8 9 10 11 12 13 7 8 9 10 11 12 13 +//│ > 10 11 12 13 14 15 16 14 15 16 17 18 19 20 14 15 16 17 18 19 20 +//│ > 17 18 19 20 21 22 23 21 22 23 24 25 26 27 21 22 23 24 25 26 27 +//│ > 24 25 26 27 28 29 30 28 28 29 30 31 +//│ > 31 +//│ > +//│ > April May June +//│ > Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa +//│ > 1 2 3 1 1 2 3 4 5 +//│ > 4 5 6 7 8 9 10 2 3 4 5 6 7 8 6 7 8 9 10 11 12 +//│ > 11 12 13 14 15 16 17 9 10 11 12 13 14 15 13 14 15 16 17 18 19 +//│ > 18 19 20 21 22 23 24 16 17 18 19 20 21 22 20 21 22 23 24 25 26 +//│ > 25 26 27 28 29 30 23 24 25 26 27 28 29 27 28 29 30 +//│ > 30 31 +//│ > +//│ > July August September +//│ > Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa +//│ > 1 2 3 1 2 3 4 5 6 7 1 2 3 4 +//│ > 4 5 6 7 8 9 10 8 9 10 11 12 13 14 5 6 7 8 9 10 11 +//│ > 11 12 13 14 15 16 17 15 16 17 18 19 20 21 12 13 14 15 16 17 18 +//│ > 18 19 20 21 22 23 24 22 23 24 25 26 27 28 19 20 21 22 23 24 25 +//│ > 25 26 27 28 29 30 31 29 30 31 26 27 28 29 30 +//│ > +//│ > +//│ > October November December +//│ > Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa +//│ > 1 2 1 2 3 4 5 6 1 2 3 4 +//│ > 3 4 5 6 7 8 9 7 8 9 10 11 12 13 5 6 7 8 9 10 11 +//│ > 10 11 12 13 14 15 16 14 15 16 17 18 19 20 12 13 14 15 16 17 18 +//│ > 17 18 19 20 21 22 23 21 22 23 24 25 26 27 19 20 21 22 23 24 25 +//│ > 24 25 26 27 28 29 30 28 29 30 26 27 28 29 30 31 +//│ > 31 +//│ > +//│ > diff --git a/benchmark/src/nofib/cichelli.mls b/benchmark/src/nofib/cichelli.mls new file mode 100644 index 000000000..b62893ccc --- /dev/null +++ b/benchmark/src/nofib/cichelli.mls @@ -0,0 +1,160 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module cichelli with ... + + + +val keys = + nofibStringToList("case") :: nofibStringToList("class") :: nofibStringToList("data") :: nofibStringToList("default") :: nofibStringToList("deriving") :: nofibStringToList("else") :: + nofibStringToList("hiding") :: nofibStringToList("if") :: nofibStringToList("import") :: nofibStringToList("in") :: nofibStringToList("infix") :: nofibStringToList("infixl") :: nofibStringToList("instance") :: + nofibStringToList("interface") :: nofibStringToList("let") :: nofibStringToList("module") :: nofibStringToList("of") :: nofibStringToList("renaming") :: nofibStringToList("then") :: nofibStringToList("to") :: + nofibStringToList("type") :: nofibStringToList("where") :: Nil +//│ keys = [["c","a","s","e"],["c","l","a","s","s"],["d","a","t","a"],["d","e","f","a","u","l","t"],["d","e","r","i","v","i","n","g"],["e","l","s","e"],["h","i","d","i","n","g"],["i","f"],["i","m","p","o","r","t"],["i","n"],["i","n","f","i","x"],["i","n","f","i","x","l"],["i","n","s","t","a","n","c","e"],["i","n","t","e","r","f","a","c","e"],["l","e","t"],["m","o","d","u","l","e"],["o","f"],["r","e","n","a","m","i","n","g"],["t","h","e","n"],["t","o"],["t","y","p","e"],["w","h","e","r","e"]] + +fun enumFromTo_lz(a, b) = lazy of () => + if a <= b then LzCons(a, enumFromTo_lz(a + 1, b)) else LzNil + +fun last(ls) = + fun go(h, t) = if t is + Nil then h + head :: t then go(head, t) + if ls is + h :: t then go(h, t) + else throw Error("last: empty list") + +data class K(s: String, c1: Char, c2: Char, i: Int) + +data class H(f: Option[Int], s: Option[Int], ls: List[Int]) + +fun ends(k) = if k is K(_, a, z, _) then a :: z :: Nil + +fun assoc(x, yz) = if yz is + [y, z] :: yzs then if x === y then z else assoc(x, yzs) + else throw Error("assoc: not found") + +fun assocm(x, yz) = if yz is + [y, z] :: yzs then if x === y then Some(z) else assocm(x, yzs) + else None + +fun histins(x, yns) = if yns is + [y, n] :: yns then if x === y then [y, n + 1] :: yns else [y, n] :: histins(x, yns) + else [x, 1] :: Nil + +fun histo(ls) = foldr(histins, Nil, ls) + +fun subset(xs, ys) = all(x => inList(x, ys), xs) + +fun union(xs, ys) = + fun lscomp(ls) = if ls is + Nil then Nil + h :: t and + not(inList(h, xs)) then h :: lscomp(t) + else lscomp(t) + append(xs, lscomp(ys)) + +fun attribkeys(ks) = map(k => K(k, head(k), last(k), listLen(k)), ks) + +val numberofkeys = listLen(keys) +//│ numberofkeys = 22 + +fun minm(x, y) = if x is + None then y + Some(x) then min(x, y) + +fun maxm(x, y) = if x is + None then y + Some(x) then max(x, y) + +fun hash(cvs, k) = if k is K(_, a, z, n) then n + assoc(a, cvs) + assoc(z, cvs) + +fun select(p, x, ts_fs) = if ts_fs is [ts, fs] and + p(x) then [x :: ts, fs] + else [ts, x :: fs] + +fun partition_(p, ls) = foldr((x, y) => select(p, x, y), [Nil, Nil], ls) + +fun freqsorted(x) = x + +fun blocked_(ds, ls) = if ls is + Nil then Nil + k :: ks then + let ds_ = union(ds, ends(k)) + if partition_(x => subset(ends(x), ds_), ks) is [det, rest] then + k :: (det +: blocked_(ds_, rest)) + +fun blocked(ls) = blocked_(Nil, ls) + +val freqtab = histo(concat(map(ends, attribkeys(keys)))) +//│ freqtab = [["e", 8],["w", 1],["t", 6],["o", 2],["n", 2],["g", 3],["r", 1],["f", 2],["m", 1],["l", 2],["i", 7],["x", 1],["h", 1],["d", 3],["a", 1],["s", 1],["c", 2]] + +val maxval = listLen(freqtab) +//│ maxval = 17 + +abstract class Status[T]: NotEver | YesIts[T] + +data + class + NotEver(i: Int) extends Status[Nothing] + YesIts[T](i: Int, t: T) extends Status[T] + +fun hinsert(h, hh) = if hh is H(lo, hi, hs) then + let lo_ = minm(lo, h) + let hi_ = maxm(hi, h) + if inList(h, hs) || (1 + hi_ - lo_) > numberofkeys + then None + else Some(H(Some(lo_), Some(hi_), h :: hs)) + +fun first(k, ls) = if force(ls) is + LzNil then NotEver(k) + LzCons(a, l) and a is + YesIts(leaves, y) then YesIts(k + leaves, y) + NotEver(leaves) then first(k + leaves, l) + +fun firstSuccess(f, possibles) = first(0, map_lz(f, possibles)) + +fun findhash_(keyHashSet, charAssocs, ks) = if ks is + Nil then YesIts(1, charAssocs) + K(s, a, z, n) :: ks then + fun tryy(newAssocs) = + let newCharAssocs = newAssocs +: charAssocs + if hinsert(hash(newCharAssocs, K(s, a, z, n)), keyHashSet) is + None then NotEver(1) + Some(newKeyHashSet) then findhash_(newKeyHashSet, newCharAssocs, ks) + if [assocm(a, charAssocs), assocm(z, charAssocs)] is + [None, None] and + a === z then firstSuccess(m => tryy([a, m] :: Nil), enumFromTo_lz(0, maxval)) + else + fun lscomp1(ls1) = lazy of () => + if force(ls1) is + LzNil then LzNil + LzCons(m, ms) then + fun lscomp2(ls2) = + if force(ls2) is + LzNil then lscomp1(ms) + LzCons(n, ns) then lazy of () => LzCons([m, n], lscomp2(ns)) + force(lscomp2(enumFromTo_lz(0, maxval))) + firstSuccess(case { [m, n] then tryy([a, m] :: [z, n] :: Nil) }, lscomp1(enumFromTo_lz(0, maxval))) + [None, Some(zc)] then firstSuccess(m => tryy([a, m] :: Nil), enumFromTo_lz(0, maxval)) + [Some(ac), None] then firstSuccess(n => tryy([z, n] :: Nil), enumFromTo_lz(0, maxval)) + [Some(ac), Some(zc)] then tryy(Nil) + +fun findhash(keys) = findhash_(H(None, None, Nil), Nil, keys) + +fun freq(c) = assoc(c, freqtab) + +fun morefreq(k1, k2) = if + k1 is K(_, a, x, _) and k2 is K(_, b, y, _) then (freq(a) + freq(x)) > (freq(b) + freq(y)) + +fun cichelli(n) = + let attribkeys_ = attribkeys(keys +: take(intMod(n, 2), keys)) + let hashkeys = blocked(freqsorted(attribkeys_)) + findhash(hashkeys) + +fun prog(n) = cichelli(n) + +fun main() = prog(6).toString() +//│ = "YesIts(113994, [[\"w\", 16],[\"r\", 17],[\"o\", 11],[\"m\", 17],[\"l\", 11],[\"x\", 2],[\"n\", 11],[\"i\", 4],[\"f\", 10],[\"h\", 3],[\"g\", 0],[\"t\", 5],[\"d\", 0],[\"a\", 0],[\"s\", 2],[\"c\", 0],[\"e\", 1]])" diff --git a/benchmark/src/nofib/circsim.mls b/benchmark/src/nofib/circsim.mls new file mode 100644 index 000000000..ea52b2d67 --- /dev/null +++ b/benchmark/src/nofib/circsim.mls @@ -0,0 +1,323 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module circsim with ... + + + +abstract class BinTree[T, U]: Cell[T] | Node[T, U] + +data + class + Cell[T](value: T) extends BinTree[T, Nothing] + Node[T, U](value: U, left: BinTree[T, U], right: BinTree[T, U]) extends BinTree[T, U] + +abstract class Componenet: None_ | Inp | Outp | Dff | Inv | And2 | Or2 | Xor + +object + None_ extends Componenet + Inp extends Componenet + Outp extends Componenet + Dff extends Componenet + Inv extends Componenet + And2 extends Componenet + Or2 extends Componenet + Xor extends Componenet + +object Unit + +data class PS[T](pid: Int, compType: Componenet, pathDepth: Int, inports: List[[Int, Int, T]], outports: List[[Int, T, Bool, Int, Bool, Int]]) + +fun pid(p) = p.pid + +fun compType(p) = p.compType + +fun pathDepth(p) = p.pathDepth + +fun inports(p) = p.inports + +fun outports(p) = p.outports + +fun updateOutports(p, noutports) = PS(pid(p), compType(p), pathDepth(p), inports(p), noutports) + +fun updateInports(p, ninports) = PS(pid(p), compType(p), pathDepth(p), ninports, outports(p)) + +abstract class Boolean: F | T + +object + F extends Boolean + T extends Boolean + +fun put(xs) = if + xs is x :: Nil then Cell(x) + splitAt(intDiv(listLen(xs), 2), xs) is [fstHalf, sndHalf] then Node(Unit, put(fstHalf), put(sndHalf)) + +fun get(t) = if t is + Cell(x) then x :: Nil + Node(_, l, r) then get(l) +: get(r) + +fun upsweep(f, t) = if t is + Cell(a) then [a, Cell(a)] + Node(x, l, r) and upsweep(f, l) is [lv, l_] and upsweep(f, r) is [rv, r_] then + [f(lv, rv), Node([lv, rv], l_, r_)] + +fun downsweep(g, d, t) = if t is + Cell(x) then Cell(d) + Node([lv, rv], l, r) and g(lv, rv, d) is [dl, dr] then + Node(Unit, downsweep(g, dl, l), downsweep(g, dr, r)) + +fun sweep_ud(up, down, u, t) = if upsweep(up, t) is [ans, t_] then + [ans, downsweep(down, u, t_)] + +fun scanL(f, u, xs) = + fun down1(l, r, x) = [x, f(x, l)] + if sweep_ud(f, down1, u, put(xs)) is [up_ans, t_] then [up_ans, get(t_)] + +fun scanR(f, u, xs) = + fun down2(l, r, x) = [f(r, x), x] + if sweep_ud(f, down2, u, put(xs)) is [up_ans, t_] then [up_ans, get(t_)] + +fun scanlr(f, g, lu, ru, xs) = + fun up(f, g, lxly, rxry) = if lxly is [lx, ly] and rxry is [rx, ry] then [f(lx, rx), g(ly, ry)] + + fun down3(f, g, lxly, rxry, ab) = if lxly is [lx, ly] and rxry is [rx, ry] and ab is [a, b] then + [[a, g(ry, b)], [f(a, lx), b]] + + let xs_ = map(x => [x, x], xs) + + if sweep_ud((a, b) => up(f, g, a, b), (a, b, c) => down3(f, g, a, b, c), [lu, ru], put(xs_)) is [[l_ans, r_ans], t_] then + let ans = [g(r_ans, ru), f(lu, l_ans)] + [ans, get(t_)] + +fun nearest_power_of_two(x) = until(a => a >= x, a => a * 2, 1) + +val emptyState = PS(-1, None_, -1, Nil, Nil) +//│ emptyState = PS(-1, None_, -1, [], []) + +fun pad_circuit(size_ins_outs_states) = if size_ins_outs_states is [size, ins, outs, states] then + let p2 = nearest_power_of_two(size) + let states_ = append_nl_lz(states, replicate_lz(p2, emptyState)) + [p2, ins, outs, take_lz(p2, states_)] + +fun inv(x) = if x === T then F else T + +fun and2(x, y) = if x === T && y === T then T else F + +fun or2(x, y) = if x === T || y === T then T else F + +fun xor(x, y) = if x === y then T else F + +val emptyPacket = [-1, -1, F, false, 0, false, 0, 1] +//│ emptyPacket = [-1, -1, F, false, 0, false, 0, 1] + +fun send_right(a, b) = if a is [ia, sa, ma, qla, dla, qra, dra, ea] and b is [ib, sb, mb, qlb, dlb, qrb, drb, eb] and + qra and (dra > eb) then [ia, sa, ma, qla, dla, qra, dra - eb, ea + eb] + else [ib, sb, mb, qlb, dlb, qrb, drb, ea + eb] + +fun send_left(a, b) = if a is [ia, sa, ma, qla, dla, qra, dra, ea] and b is [ib, sb, mb, qlb, dlb, qrb, drb, eb] and + qlb && (dlb > ea) then [ib, sb, mb, qlb, dlb - ea, qrb, drb, ea + eb] + else [ia, sa, ma, qla, dla, qra, dra, ea + eb] + +fun send(xs) = scanlr(send_right, send_left, emptyPacket, emptyPacket, xs) + +fun update_outports(state, value) = + fun lscomp(ls) = if ls is + Nil then Nil + h :: t and + h is [p, m, ql, dl, qr, dr] then [p, value, ql, dl, qr, dr] :: lscomp(t) + else lscomp(t) + + updateOutports(state, lscomp(outports(state))) + + +fun critical_path_depth(siot) = if siot is [size, ins, outs, states] then maximum(map(pathDepth, states)) + +fun collect_outputs(tp4) = if tp4 is [size, ins, outs, states] then + fun thrid(tp3) = if tp3 is [_, _, v] then v + + fun get_output(states, label_p) = if label_p is [label, p] then + fun lscomp(ls) = if ls is + Nil then Nil + s :: t and + p == pid(s) then head(inports(s)) :: lscomp(t) + else lscomp(t) + thrid(head(lscomp(states))) + + map(p => get_output(states, p), outs) + + +fun store_inputs(label_inputs, state) = if state is + PS(pid_, Inp, _, _, _) then + fun lscomp(ls) = if ls is + Nil then Nil + h :: t and + h is [[label, input_pid], value] and pid_ == input_pid then update_outports(state, value) :: lscomp(t) + else lscomp(t) + head(lscomp(label_inputs)) + else state + +fun apply_component(comp, signals) = if comp is + Inp then None + Outp and signals is x :: Nil then Some(x) + Dff and signals is x :: Nil then Some(x) + Inv and signals is x :: Nil then Some(inv(x)) + And2 and signals is x :: y :: Nil then Some(and2(x, y)) + Or2 and signals is x :: y :: Nil then Some(or2(x, y)) + Xor and signals is x :: y :: Nil then Some(xor(x, y)) + None_ then None + +fun init_dffs(state) = if compType(state) === Dff then update_outports(state, F) else state + +fun restore_requests(old_states, new_states) = + fun restore(os, ns) = updateOutports(ns, zipWith(restore_outport, outports(os), outports(ns))) + + fun restore_outport(pql, mdq) = if pql is [p, _, ql, dl, qr, dq] and mdq is [_, m, _, _, _, _] then [p, m, ql, dl, qr, dq] + + zipWith(restore, old_states, new_states) + + +fun update_requests(b, state) = + fun lscomp(ls) = if ls is + Nil then Nil + h :: t and + h is [p, m, ql, dl, qr, dr] then [p, m, b, dl, b, dr] :: lscomp(t) + else lscomp(t) + updateOutports(state, lscomp(outports(state))) + +fun check_depth(d, state) = if pathDepth(state) == d then state else update_requests(false, state) + +fun acknowledge(d, states) = + fun check_requests(xs) = orList(map(check_lr_requests, xs)) + + fun check_lr_requests(pql) = if pql is [p,m,ql,dl,qr,dr] then ql || qr + + let states1 = map(s => check_depth(d, s), states) + + not(orList(map(s => check_requests(outports(s)), states1))) + + +fun pad_packets(pss) = + fun pad(xs) = + let max_ps = maximum(map(x => listLen(x), pss)) + take_lz(max_ps, append_nl_lz(xs, replicate_lz(max_ps, emptyPacket))) + + map(x => pad(x), pss) + + +fun make_packet(state) = + fun lscomp(ls) = if ls is + Nil then Nil + h :: t and + h is [p, m, ql, dl, qr, dr] then [pid(state), p, m, ql, dl, qr, dr, 1] :: lscomp(t) + else lscomp(t) + + lscomp(outports(state)) + + +fun compare_and_update(ipm_, pid_port_m) = + if ipm_ is [i, p, m_] and pid_port_m is [pid_, port, m] and + eqTup2([i, p], [pid_, port]) then [pid_, port, m_] + else [pid_, port, m] + +fun up_i(ipm_, ins) = if ipm_ is [i, p, m_, _, _, _, _, _] then map(x => compare_and_update([i, p, m_], x), ins) + +fun update_i(l_r, ins) = if l_r is [l, r] then up_i(l, up_i(r, ins)) + +fun check_left(a, b) = if a is [pid_, port, pm, pql, pdl, pqr, pdr, e] and b is [p, m, ql, dl, qr, dr] and + pqr && (pdr > 0) then [p, m, ql, dl, qr, dr] + else [p, m, ql, dl, false, dr] + +fun check_right(a, b) = if a is [pid_, port, pm, pql, pdl, pqr, pdr, e] and b is [p, m, ql, dl, qr, dr] and + pql && (pdl > 0) then [p, m, ql, dl, qr, dr] + else [p, m, false, dl, qr, dr] + +fun update_o(lp_rp, out_) = if lp_rp is [lp, rp] then check_left(lp, check_right(rp, out_)) + +fun update_io(d, lrps, state) = + fun update_is(state) = updateInports(state, foldr(update_i, inports(state), lrps)) + + fun update_os(state) = if pathDepth(state) == d then updateOutports(state, zipWith(update_o, lrps, outports(state))) else state + + update_os(update_is(state)) + + +fun do_send(d, states) = + let states1 = map(s => check_depth(d, s), states) + let send_results = map(x => snd(send(x)), transpose(pad_packets(map(make_packet, states1)))) + let pss_ = transpose(send_results) + + zipWith((x, y) => update_io(d, x, y), pss_, states) + + +fun do_sends(d, states) = until(s => acknowledge(d, s), x => do_send(d, x), states) + +fun simulate_component(d, state) = + fun lscomp(ls) = if ls is + Nil then Nil + h :: t and + h is [_, _, sig] then sig :: lscomp(t) + else lscomp(t) + + let out_signals = lscomp(inports(state)) + let new_value = apply_component(compType(state), out_signals) + + if + d == pathDepth(state) and not(new_value === None) and new_value is Some(v) then update_outports(state, v) + else state + +fun simulate_components(depth, states) = map(s => simulate_component(depth, s), states) + +fun do_cycle(cpd, tp4, inputs) = + fun sim_then_send(state, d) = do_sends(d, simulate_components(d, state)) + + if tp4 is [size, ins, outs, states] then + let states1 = map(s => store_inputs(zip(ins, inputs), s), states) + let states2 = do_sends(0, states1) + let states3 = foldl(sim_then_send, states2, enumFromTo(1, cpd)) + let states4 = restore_requests(states, states3) + [size, ins, outs, states4] + else throw Error(tp4) + +fun simulate(inputs_list, b) = if b is [size, ins, outs, states] then + tail(scanl((x, y) => do_cycle(critical_path_depth([size, ins, outs, states]), x, y), [size, ins, outs, map(init_dffs, states)], inputs_list)) + +fun reg(sto, n) = + PS(n, Inp, 0, Nil, [0, F, false, 0, true, 4] :: Nil) :: + PS(n + 1, Dff, 1, [n + 5, 0, F] :: Nil, [0, F, false, 0, true, 5] :: Nil) :: + PS(n + 2, Inv, 1, [sto, 0, F] :: Nil, [0, F, false, 0, true, 1] :: Nil) :: + PS(n + 3, And2, 2, [n + 1, 0, F] :: [n + 2, 0, F] :: Nil, [0, F, false, 0, true, 2] :: Nil) :: + PS(n + 4, And2, 1, [sto, 0, F] :: [n, 0, F] :: Nil, [0, F, false, 0, true, 1] :: Nil) :: + PS(n + 5, Or2, 3, [n + 3, 0, F] :: [n + 4, 0, F] :: Nil, [0, F, true, 4, false, 0] :: Nil) :: + PS(n + 6, Outp, 4, [n + 1, 0, F] :: Nil, Nil) :: + Nil + +fun regs(bits) = + fun ilabel(n, pid_) = [stringConcat("x", stringOfInt(n)), pid_] + fun olabel(n, pid_) = [stringConcat("y", stringOfInt(n)), pid_] + let is_ = ["sto", 0] :: zipWith_lz_nl(ilabel, enumFrom(0), map(x => (7 * x) + 1, enumFromTo(0, bits - 1))) + let os = zipWith_lz_nl(olabel, enumFrom(0), map(x => (7 * x) + 7, enumFromTo(0, bits - 1))) + let sto = PS(0, Inp, 0, Nil, [0, F, false, 0, true, (8 * (bits - 1)) + 5] :: Nil) + let states = sto :: concat(map(x => reg(0, x), map(x => (7 * x) + 1, enumFromTo(0, bits - 1)))) + + [1 + (7 * bits), is_, os, states] + + +fun circuit_simulate(inputs_list, circuit) = map(collect_outputs, simulate(inputs_list, circuit)) + +fun run(num_bits, num_cycles) = + let example = pad_circuit(regs(num_bits)) + let inputs = replicate(num_bits + 1, T) + let cycles = replicate(num_cycles, inputs) + + circuit_simulate(cycles, example) + + +fun testCircsim_nofib(n) = run(8, n) + + + +fun main() = testCircsim_nofib(40).toString() +//│ = "[[F,F,F,F,F,F,F,F],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T],[T,T,T,T,T,T,T,T]]" diff --git a/benchmark/src/nofib/clausify.mls b/benchmark/src/nofib/clausify.mls new file mode 100644 index 000000000..2de3ceb29 --- /dev/null +++ b/benchmark/src/nofib/clausify.mls @@ -0,0 +1,151 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module clausify with ... + + +abstract class Formula: Sym | Not | Dis | Con | Imp | Eqv + +data + class + Sym(a: Char) extends Formula + Not(a: Formula) extends Formula + Dis(a: Formula, b: Formula) extends Formula + Con(a: Formula, b: Formula) extends Formula + Imp(a: Formula, b: Formula) extends Formula + Eqv(a: Formula, b: Formula) extends Formula + +abstract class StackFrame: Ast | Lex + +data + class + Ast(f: Formula) extends StackFrame + Lex(s: Char) extends StackFrame + +fun charLt(a, b) = a < b +fun charLeq(a, b) = a <= b +fun charGt(a, b) = a > b +fun charGeq(a, b) = a >= b + +fun insert(x, ys) = if ys is + Nil then x :: Nil + y :: ys and + charLt(x, y) then x :: y :: ys + charGt(x, y) then y :: insert(x, ys) + else y :: ys + +fun clauseHelper(p, x) = if p is + Dis(p, q) then clauseHelper(p, clauseHelper(q, x)) + Sym(s) and x is [c, a] then [insert(s, c), a] + Not(Sym(s)) and x is [c, a] then [c, insert(s, a)] + +fun clause(p) = clauseHelper(p, [Nil, Nil]) + +fun conjunct(p) = if p is Con(_, _) then true else false + +fun disin(p) = if p is + Dis(p, Con(q, r)) then Con(disin(Dis(p, q)), disin(Dis(p, r))) + Dis(Con(p, q), r) then Con(disin(Dis(p, r)), disin(Dis(q, r))) + Dis(p, q) then + let dp = disin(p) + let dq = disin(q) + if conjunct(dp) || conjunct(dq) then disin(Dis(dp, dq)) else Dis(dp, dq) + Con(p, q) then Con(disin(p), disin(q)) + else p + +fun elim(p) = if p is + Sym(s) then Sym(s) + Not(p) then Not(elim(p)) + Dis(p, q) then Dis(elim(p), elim(q)) + Con(p, q) then Con(elim(p), elim(q)) + Imp(p, q) then Dis(Not(elim(p)), elim(q)) + Eqv(f, f_) then Con(elim(Imp(f, f_)), elim(Imp(f_, f))) + +fun interleave(xs, ys) = if xs is + x :: xs then x :: interleave(ys, xs) + Nil then Nil + +fun negin(p) = if p is + Not(Not(p)) then negin(p) + Not(Con(p, q)) then Dis(negin(Not(p)), negin(Not(q))) + Not(Dis(p, q)) then Con(negin(Not(p)), negin(Not(q))) + Dis(p, q) then Dis(negin(p), negin(q)) + Con(p, q) then Con(negin(p), negin(q)) + else p + +fun opri(c) = if c + === "(" then 0 + === "=" then 1 + === ">" then 2 + === "|" then 3 + === "&" then 4 + === "~" then 5 + else throw Error(c) + +fun red(s) = if s is + Ast(p) :: Lex("=") :: Ast(q) :: s then Ast(Eqv(q, p)) :: s + Ast(p) :: Lex(">") :: Ast(q) :: s then Ast(Imp(q, p)) :: s + Ast(p) :: Lex("|") :: Ast(q) :: s then Ast(Dis(q, p)) :: s + Ast(p) :: Lex("&") :: Ast(q) :: s then Ast(Con(q, p)) :: s + Ast(p) :: Lex("~") :: s then Ast(Not(p)) :: s + +fun spri(s) = if s is + Ast(x) :: Lex(c) :: s then opri(c) + else 0 + +fun redstar(s) = while_(s => spri(s) != 0, red, s) + +fun spaces(n) = replicate(n, " ") + +fun parseHelper(t, s) = if t is + Nil then redstar(s) + " " :: t then parseHelper(t, s) + "(" :: t then parseHelper(t, Lex("(") :: s) + ")" :: t and redstar(s) is x :: Lex("(") :: ss then parseHelper(t, x :: ss) + c :: t and + charLeq("a", c) && charLeq(c, "z") then parseHelper(t, Ast(Sym(c)) :: s) + spri(s) > opri(c) then parseHelper(c :: t, red(s)) + else parseHelper(t, Lex(c) :: s) + +fun parse(t) = if parseHelper(t, Nil) is Ast(f) :: Nil then f + +fun splitHelper(p, a) = if p is + Con(p, q) then splitHelper(p, splitHelper(q, a)) + else p :: a + +fun split(p) = splitHelper(p, Nil) + +fun tautclause(c_a) = if c_a is [c, a] then + fun lscomp(ls) = if ls is + Nil then Nil + h :: t and + inList(h, a) then h :: lscomp(t) + else lscomp(t) + listNeq(lscomp(c), Nil) + +fun uniclHelper(p, x) = + let cp = clause(p) + if tautclause(cp) then x else insert(cp, x) + +fun unicl(a) = foldr(uniclHelper, Nil, a) + +fun disp(l_r) = if l_r is [l, r] then + interleave(l, spaces(listLen(l))) +: + nofibStringToList("<=") +: + interleave(spaces(listLen(r)), r) +: + nofibStringToList("\n") + +fun clauses(t) = concat of map of + disp + unicl of split of disin of negin of elim of parse of t + +// NOTE: original input "(a = a = a) = (a = a = a) = (a = a = a)" +fun testClausify_nofib(n) = + let xs = replicate(n, nofibStringToList("a = a = a")) + concat(map(clauses, xs)) + +fun main() = nofibListToString(testClausify_nofib(10)) +//│ = "a <=\na <=\na <=\na <=\na <=\na <=\na <=\na <=\na <=\na <=\n" diff --git a/benchmark/src/nofib/constraints.mls b/benchmark/src/nofib/constraints.mls new file mode 100644 index 000000000..ae555ac88 --- /dev/null +++ b/benchmark/src/nofib/constraints.mls @@ -0,0 +1,248 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module constraints with ... + + + +// -- Figure 1. CSPs in Haskell. +data class Assign(varr: Int, value: Int) + +data class CSP(vars: Int, vals: Int, rel: Int) + +//│ ———————————————————————————————————————————————————————————————————————————————— +fun qsort(le, ls, r) = if ls is + Nil then r + x :: Nil then x :: r + x :: xs then qpart(le, x, xs, Nil, Nil, r) + +fun qpart(le, x, ls, rlt, rge, r) = if ls is + Nil then rqsort(le, rlt, x :: rqsort(le, rge, r)) + y :: ys and + le(x, y) then qpart(le, x, ys, rlt, y :: rge, r) + else qpart(le, x, ys, y :: rlt, rge, r) + +fun rqsort(le, ls, r) = if ls is + Nil then r + x :: Nil then x :: r + x :: xs then rqpart(le, x, xs, Nil, Nil, r) + +fun rqpart(le, x, ls, rle, rgt, r) = if ls is + Nil then rqsort(le, rle, x :: qsort(le, rgt, r)) + y :: ys and + le(y, x) then rqpart(le, x, ys, y :: rle, rgt, r) + else rqpart(le, x, ys, rle, y :: rgt, r) +//│ ———————————————————————————————————————————————————————————————————————————————— + +fun level(a) = if a is Assign(v, _) then v + +fun value(a) = if a is Assign(_, v) then v + +fun maxLevel(ls) = if ls is + Nil then 0 + Assign(v, _) :: t then v + +fun complete(csp, s) = if csp is CSP(v, _, _) then maxLevel(s) == v + +fun safe(as1, as2) = if as1 is Assign(i, m) and as2 is Assign(j, n) then not(m == n) and not(abs(i - j) == abs(m - n)) + +fun queens(n) = CSP(n, n, safe) + +// -- Figure 2. Trees in Haskell. +data class Node[out T](lab: T, children: List[Node[T]]) + +fun label(n) = if n is Node(l, _) then l + +fun mapTree(f, n) = if n is Node(l, c) then Node(f(l), map((x => mapTree(f, x)), c)) + +fun foldTree(f, n) = if n is Node(l, c) then f(l, map((x => foldTree(f, x)), c)) + +fun filterTree(p, t) = + fun f1(a, cs) = Node(a, filter(x => p(label(x)), cs)) + foldTree(f1, t) + +fun prune(p, t) = filterTree(x => not(p(x)), t) + +fun leaves(t) = if t is + Node(leaf, Nil) then leaf :: Nil + Node(_, cs) then concat(map(leaves, cs)) + +fun initTree(f, x) = Node(x, map(y => initTree(f, y), f(x))) + +// -- Figure 3. Simple backtracking solver for CSPs. +fun mkTree(csp) = if csp is CSP(vars, vals, rel) then + fun next(ss) = + if maxLevel(ss) < vars then + fun lscomp1(ls) = if ls is + Nil then Nil + j :: t1 then + (Assign(maxLevel(ss) + 1, j) :: ss) :: lscomp1(t1) + lscomp1(enumFromTo(1, vals)) + else + Nil + + initTree(next, Nil) + + +fun earliestInconsistency(csp, aas) = if csp is CSP(vars, vals, rel) and aas is + Nil then None + a :: as_ and filter(x => not(rel(a, x)), reverse(as_)) is + Nil then None + b :: _ then Some([level(a), level(b)]) + +fun labelInconsistencies(csp, t) = + fun f2(s) = [s, earliestInconsistency(csp, s)] + + mapTree(f2, t) + + +fun btsolver0(csp) = + filter of + x => complete(csp, x) + leaves of + mapTree of + fst + prune of + x => not(snd(x) === None) + labelInconsistencies(csp, mkTree(csp)) + +// -- Figure 6. Conflict-directed solving of CSPs. +abstract class ConflictSet: Known | Unknown +data class Known(vs: List[Int]) extends ConflictSet +object Unknown extends ConflictSet + +fun knownConflict(c) = if c is + Known(a :: as_) then true + else false + +fun knownSolution(c) = if c is + Known(Nil) then true + else false + +fun checkComplete(csp, s) = if complete(csp, s) then Known(Nil) else Unknown + +fun search(labeler, csp) = + map of + fst + filter of + x => knownSolution(snd(x)) + leaves of prune of + x => knownConflict(snd(x)) + labeler(csp, mkTree(csp)) + +fun bt(csp, t) = + fun f3(s) = [s, (if earliestInconsistency(csp, s) is Some([a, b]) then Known(a :: b :: Nil) else checkComplete(csp, s))] + + mapTree(f3, t) + +// -- Figure 8. Backmarking. + +fun emptyTable(csp) = if csp is CSP(vars, vals, rel) then + fun lscomp1(ls) = if ls is + Nil then Nil + n :: t1 then + fun lscomp2(ls) = if ls is + Nil then Nil + m :: t2 then + Unknown :: lscomp2(t2) + lscomp2(enumFromTo(1, vals)) :: lscomp1(t1) + + Nil :: lscomp1(enumFromTo(1, vars)) + + +fun fillTable(s, csp, tbl) = if s is + Nil then tbl + Assign(var_, val_) :: as_ and csp is CSP(vars, vals, rel) then + fun f4(cs, varval) = if varval is [varr, vall] and + cs === Unknown and not(rel(Assign(var_, val_), Assign(varr, vall))) then Known(var_ :: varr :: Nil) + else cs + + fun lscomp1(ls) = if ls is + Nil then Nil + varrr :: t1 then + fun lscomp2(ls) = if ls is + Nil then Nil + valll :: t2 then [varrr, valll] :: lscomp2(t2) + lscomp2(enumFromTo(1, vals)) :: lscomp1(t1) + + zipWith((x, y) => zipWith(f4, x, y), tbl, lscomp1(enumFromTo(var_ + 1, vars))) + + +fun lookupCache(csp, t) = + fun f5(csp, tp) = if tp is + [Nil, tbl] then [[Nil, Unknown], tbl] + [a :: as_, tbl] then + let tableEntry = atIndex(value(a) - 1, head(tbl)) + let cs = if tableEntry === Unknown then checkComplete(csp, a :: as_) else tableEntry + [[a :: as_, cs], tbl] + + mapTree(x => f5(csp, x), t) + + +fun cacheChecks(csp, tbl, n) = if n is Node(s, cs) then + Node([s, tbl], map(x => cacheChecks(csp, fillTable(s, csp, tail(tbl)), x), cs)) + +fun bm(csp, t) = mapTree(fst, lookupCache(csp, cacheChecks(csp, emptyTable(csp), t))) + +// -- Figure 10. Conflict-directed backjumping. +fun combine(ls, acc) = if ls is + Nil then acc + [s, Known(cs)] :: css and + notElem(maxLevel(s), cs) then cs + else combine(css, union(cs, acc)) + +fun bj_(csp, t) = + fun f7(tp2, chs) = if tp2 is + [a, Known(cs)] then Node([a, Known(cs)], chs) + [a, Unknown] and + let cs_ = Known(combine(map(label, chs), Nil)) + knownConflict(cs_) then Node([a, cs_], Nil) + else Node([a, cs_], chs) + + foldTree(f7, t) + + +fun bj(csp, t) = + fun f6(tp2, chs) = if tp2 is + [a, Known(cs)] then Node([a, Known(cs)], chs) + [a, Unknown] then Node([a, Known(combine(map(label, chs), Nil))], chs) + + foldTree(f6, t) + + +fun bjbt(csp, t) = bj(csp, bt(csp, t)) + +fun bjbt_(csp, t) = bj_(csp, bt(csp, t)) + +// -- Figure 11. Forward checking. +fun collect(ls) = if ls is + Nil then Nil + Known(cs) :: css then union(cs, collect(css)) + +fun domainWipeout(csp, t) = if csp is CSP(vars, vals, rel) then + fun f8(tp2) = if tp2 is [[as_, cs], tbl] then + let wipedDomains = + fun lscomp1(ls) = if ls is + Nil then Nil + vs :: t1 and + all(knownConflict, vs) then vs :: lscomp1(t1) + else lscomp1(t1) + lscomp1(tbl) + let cs_ = if null_(wipedDomains) then cs else Known(collect(head(wipedDomains))) + [as_, cs_] + + mapTree(f8, t) + + +fun fc(csp, t) = domainWipeout(csp, lookupCache(csp, cacheChecks(csp, emptyTable(csp), t))) + +fun try_(n, algorithm) = listLen(search(algorithm, queens(n))) + +fun testConstraints_nofib(n) = map(x => try_(n, x), bt :: bm :: bjbt :: bjbt_ :: fc :: Nil) + + +fun main() = testConstraints_nofib(6).toString() +//│ = "[4,4,4,4,4]" diff --git a/benchmark/src/nofib/cryptarithm1.mls b/benchmark/src/nofib/cryptarithm1.mls new file mode 100644 index 000000000..d5d184a7a --- /dev/null +++ b/benchmark/src/nofib/cryptarithm1.mls @@ -0,0 +1,44 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module cryptarithm1 with ... + + + +fun expand(a, b, c, d, e, f) = f + (e*10) + (d*100) + (c*1000) + (b*10000) + (a*100000) + +fun condition(thirywelvn) = if thirywelvn is + t :: h :: i :: r :: y :: w :: e :: l :: v :: n :: Nil then + (expand(t, h, i, r, t, y) + 5 * expand(t, w, e, l, v, e)) == expand(n, i, n, e, t, y) + +fun addj(j, ls) = if ls is + Nil then (j :: Nil) :: Nil + k :: ks then + fun lscomp(p1) = if p1 is + Nil then Nil + h1 :: t1 then (k :: h1) :: lscomp(t1) + + (j :: (k :: ks)) :: lscomp(addj(j, ks)) + +fun permutations(ls) = if ls is + Nil then Nil :: Nil + j :: js then + fun lscomp1(p1) = if p1 is + Nil then Nil + pjs :: t1 then + fun lscomp2(p2) = if p2 is + Nil then lscomp1(t1) + r :: t2 then r :: lscomp2(t2) + lscomp2(addj(j, pjs)) + + lscomp1(permutations(js)) + +fun testCryptarithm_nofib(n) = + map((i => let p0 = take(10, enumFromTo(0, 9 + i)) in filter(condition, permutations(p0))), enumFromTo(1, n)) + + +fun main() = testCryptarithm_nofib(1) +//│ ═══[RUNTIME ERROR] RangeError: Maximum call stack size exceeded diff --git a/benchmark/src/nofib/cryptarithm2.mls b/benchmark/src/nofib/cryptarithm2.mls new file mode 100644 index 000000000..d4add9c4c --- /dev/null +++ b/benchmark/src/nofib/cryptarithm2.mls @@ -0,0 +1,115 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module cryptarithm2 with ... + + +object Unit + +fun unlines(ls) = concat of map(x => x +: ("\n" :: Nil), ls) + +fun lookup(k, t) = if t is + Nil then None + [x, v] :: t then if k === x then Some(v) else lookup(k, t) + +fun delete_(xs, e) = deleteBy((x, y) => x === y, e, xs) + +fun listDiff(a, ls) = foldl(delete_, a, ls) + +data class StateT[S, M, A](run) + +fun runStateT(m, s) = if m is StateT(run) then run(s) + +fun bind(m, f) = + StateT of + s => concat of map(case { [a, ss] then runStateT(f(a), ss) }, runStateT(m, s)) + +fun return_(a) = StateT(s => [a, s] :: Nil) + +fun mapM(f, ls) = foldr((a, r) => bind(f(a), x => bind(r, xs => return_(x :: xs))), return_(Nil), ls) + +fun lift(ls) = StateT(s => concat(map(x => [x, s] :: Nil, ls))) + +fun execStateT(m, s) = concat(map(case { [a, s] then s :: Nil }, runStateT(m, s))) + +fun guard(b) = if b then StateT(s => [Unit, s] :: Nil) else StateT(s => Nil) + +fun put(s) = StateT(x => [Unit, s] :: Nil) + +val get = StateT(s => [s, s] :: Nil) +//│ get = StateT([function]) + +data class Digits(i: List[Int], c: List[[Char, Int]]) + +fun digits(d) = if d is Digits(a, b) then a + +fun digitEnv(d) = if d is Digits(a, b) then b + +fun permute(c) = + bind of + get + st => + bind of + let xs = digits(st) in lift(map(x => [x, listDiff(xs, x :: Nil)], xs)) + iis => + if iis is [i, iss] then + bind of + put(Digits(iss, [c, i] :: digitEnv(st))) + _p => return_(i) + +fun select(c) = + bind of + get + st => + if lookup(c, digitEnv(st)) is + Some(r) then return_(r) + None then permute(c) + +fun rest(ls) = if ls is + Nil then Nil + x :: xs then xs + +fun solve(tops, bots, carry) = if bots is + bot :: botss then + bind of + if tops is + Nil then return_(carry) + top :: _ then bind(mapM(select, top), topNS => return_(sum(topNS) + carry)) + topN => bind of + select(bot) + botN => bind of + guard(intMod(topN, 10) === botN) + _s => solve(rest(tops), botss, intDiv(topN, 10)) + Nil and tops is Nil and carry === 0 then return_(Unit) + else StateT(_p => Nil) + +fun puzzle(top, bot) = + let solution = solve(transpose(map(reverse, top)), reverse(bot), 0) + let answer = if execStateT(solution, Digits(enumFromTo(0, 9), Nil)) is a :: _ then a + let env = digitEnv(answer) + let look = c => fromSome(lookup(c, env)) + let expand = ls => foldl((a, b) => a * 10 + look(b), 0, ls) + let topVal = sum(map(xs => expand(xs), top)) + let botVal = expand(bot) + if + listLen(nubBy((x,y) => x === y, concat(top) +: bot)) > 10 then throw Error("error") + topVal != botVal then throw Error("error") + else unlines of map of + case { [c, i] then c :: nofibStringToList(" => ") +: nofibStringToList(stringOfInt(i)) } + env + +fun testCryptarithm2_nofib(n) = + let args = + nofibStringToList("THIRTY") :: + nofibStringToList("TWELVE") :: + nofibStringToList("TWELVE") :: + nofibStringToList("TWELVE") :: + nofibStringToList("TWELVE") :: + append(nofibStringToList("TWELVE"), (if n > 999999 then nofibStringToList("1") else Nil)) :: Nil + puzzle(args, nofibStringToList("NINETY")) + +fun main() = testCryptarithm2_nofib(1).toString() +//│ = "[\"W\",\" \",\"=\",\">\",\" \",\"3\",\"\\n\",\"H\",\" \",\"=\",\">\",\" \",\"9\",\"\\n\",\"N\",\" \",\"=\",\">\",\" \",\"8\",\"\\n\",\"I\",\" \",\"=\",\">\",\" \",\"4\",\"\\n\",\"L\",\" \",\"=\",\">\",\" \",\"7\",\"\\n\",\"R\",\" \",\"=\",\">\",\" \",\"2\",\"\\n\",\"V\",\" \",\"=\",\">\",\" \",\"6\",\"\\n\",\"T\",\" \",\"=\",\">\",\" \",\"1\",\"\\n\",\"E\",\" \",\"=\",\">\",\" \",\"0\",\"\\n\",\"Y\",\" \",\"=\",\">\",\" \",\"5\",\"\\n\"]" diff --git a/benchmark/src/nofib/cse.mls b/benchmark/src/nofib/cse.mls new file mode 100644 index 000000000..847004543 --- /dev/null +++ b/benchmark/src/nofib/cse.mls @@ -0,0 +1,148 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module cse with ... + + + +fun retURN(a) = s => [s, a] + +fun bind(m, f) = s => if m(s) is [s_, a] then f(a)(s_) + +fun join(m) = s => if m(s) is [s_, ma] then ma(s_) + +fun mmap(f, m) = s => if m(s) is [s_, a] then [s_, f(a)] + +fun mmapl(f, aas) = if aas is + Nil then retURN(Nil) + a :: as_ then + bind of + f(a) + b => bind of + mmapl(f, as_) + bs => retURN(b :: bs) + +fun mmapr(f, xs) = if xs is + Nil then retURN(Nil) + x :: xs then + bind of + mmapr(f, xs) + ys => bind of + f(x) + y => retURN(y :: ys) + +fun mfoldl(f, a, xs) = if xs is + Nil then retURN(a) + x :: xs then + bind(f(a, x), fax => mfoldl(f, fax, xs)) + +fun mfoldr(f, a, xs) = if xs is + Nil then retURN(a) + x :: xs then + bind(mfoldr(f, a, xs), y => f(x, y)) + +fun mif(c, t, f) = bind(c, cond => if cond then t else f) + +fun startingWith(m, v) = if m(v) is [final, answer] then answer + +fun fetch(s) = [s, s] + +fun fetchWith(f) = s => [s, f(s)] + +fun update(f) = s => [f(s), s] + +fun set_(s_) = s => [s_, s] + +val incr = update(x => x + 1) +//│ incr = [function] + +data class Node[T](a: T, b: List[Node[T]]) + +fun labelTree(t) = + fun label(t) = if t is Node(x, xs) then + bind of + incr + n => bind of + mmapl(label, xs) + ts => retURN(Node([n, x], ts)) + startingWith(label(t), 0) + +fun ltGraph(t) = + fun labelOf(t) = if t is Node([n, x], xs) then n + if t is Node([n, x], xs) then + [n, x, map(labelOf, xs)] :: concat(map(ltGraph, xs)) + +fun visited(n) = bind of + fetch + us => if inList(n, us) then retURN(true) else bind(set_(n :: us), _p => retURN(false)) + +fun newlyDefined(x, fx, f, y) = if x === y then fx else f(y) + +fun findCommon(ls) = + fun sim(n_s_cs, r_lg) = if n_s_cs is [n, s, cs] and r_lg is [r, lg] then + let rcs = map(r, cs) + fun lscomp(ls) = if ls is + Nil then Nil + [m, s_, cs_] :: t and + s === s_ and listEq(cs_, rcs) then m :: lscomp(t) + else lscomp(t) + let ms = lscomp(lg) + if null_(ms) + then [r, [n, s, rcs] :: lg] + else [x => newlyDefined(n, head(ms), r, x), lg] + if foldr(sim, [x => x, Nil], ls) is [a, b] then b else throw Error(ls.toString()) + +fun cse(t) = findCommon(ltGraph(labelTree(t))) + +fun plus_(x, y) = Node("+", x :: y :: Nil) + +fun mult_(x, y) = Node("*", x :: y :: Nil) + +fun prod(xs) = Node("X", xs) + +val zerO = Node("0", Nil) +//│ zerO = Node("0", []) + +val a = Node("a", Nil) +//│ a = Node("a", []) + +val b = Node("b", Nil) +//│ b = Node("b", []) + +val c = Node("c", Nil) +//│ c = Node("c", []) + +val d = Node("d", Nil) +//│ d = Node("d", []) + +val example0 = a +//│ example0 = Node("a", []) + +val example1 = plus_(a, a) +//│ example1 = Node("+", [Node("a", []),Node("a", [])]) + +val example2 = plus_(mult_(a, b), mult_(a, b)) +//│ example2 = Node("+", [Node("*", [Node("a", []),Node("b", [])]),Node("*", [Node("a", []),Node("b", [])])]) + +val example3 = plus_(mult_(plus_(a, b), c), plus_(a, b)) +//│ example3 = Node("+", [Node("*", [Node("+", [Node("a", []),Node("b", [])]),Node("c", [])]),Node("+", [Node("a", []),Node("b", [])])]) + +val example4 = prod(scanl(plus_, zerO, a :: b :: c :: d :: Nil)) +//│ example4 = Node("X", [Node("0", []),Node("+", [Node("0", []),Node("a", [])]),Node("+", [Node("+", [Node("0", []),Node("a", [])]),Node("b", [])]),Node("+", [Node("+", [Node("+", [Node("0", []),Node("a", [])]),Node("b", [])]),Node("c", [])]),Node("+", [Node("+", [Node("+", [Node("+", [Node("0", []),Node("a", [])]),Node("b", [])]),Node("c", [])]),Node("d", [])])]) + +val example5 = prod(scanr(plus_, zerO, a :: b :: c :: d :: Nil)) +//│ example5 = Node("X", [Node("+", [Node("a", []),Node("+", [Node("b", []),Node("+", [Node("c", []),Node("+", [Node("d", []),Node("0", [])])])])]),Node("+", [Node("b", []),Node("+", [Node("c", []),Node("+", [Node("d", []),Node("0", [])])])]),Node("+", [Node("c", []),Node("+", [Node("d", []),Node("0", [])])]),Node("+", [Node("d", []),Node("0", [])]),Node("0", [])]) + +fun testCse_nofib(n) = map( + i => map( + cse, + take(intMod(i, 6), example0 :: example1 :: example2 :: example3 :: example4 :: example5 :: Nil) + ), + enumFromTo(1, n) +) + +fun main() = testCse_nofib(6).toString() +//│ = "[[[[0, \"a\", []]]],[[[0, \"a\", []]],[[0, \"+\", [2,2]],[2, \"a\", []]]],[[[0, \"a\", []]],[[0, \"+\", [2,2]],[2, \"a\", []]],[[0, \"+\", [4,4]],[4, \"*\", [5,6]],[5, \"a\", []],[6, \"b\", []]]],[[[0, \"a\", []]],[[0, \"+\", [2,2]],[2, \"a\", []]],[[0, \"+\", [4,4]],[4, \"*\", [5,6]],[5, \"a\", []],[6, \"b\", []]],[[0, \"+\", [1,6]],[1, \"*\", [6,5]],[5, \"c\", []],[6, \"+\", [7,8]],[7, \"a\", []],[8, \"b\", []]]],[[[0, \"a\", []]],[[0, \"+\", [2,2]],[2, \"a\", []]],[[0, \"+\", [4,4]],[4, \"*\", [5,6]],[5, \"a\", []],[6, \"b\", []]],[[0, \"+\", [1,6]],[1, \"*\", [6,5]],[5, \"c\", []],[6, \"+\", [7,8]],[7, \"a\", []],[8, \"b\", []]],[[0, \"X\", [21,20,19,18,17]],[17, \"+\", [18,25]],[18, \"+\", [19,24]],[19, \"+\", [20,23]],[20, \"+\", [21,22]],[21, \"0\", []],[22, \"a\", []],[23, \"b\", []],[24, \"c\", []],[25, \"d\", []]]],[]]" diff --git a/benchmark/src/nofib/eliza.mls b/benchmark/src/nofib/eliza.mls new file mode 100644 index 000000000..825729d1e --- /dev/null +++ b/benchmark/src/nofib/eliza.mls @@ -0,0 +1,352 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module eliza with ... + + + +fun toUpper(c) = c.toUpperCase() + +fun lz_map(f, ls) = lazy of () => + if ls is + Nil then LzNil + h :: t then LzCons(f(h), lz_map(f, t)) + +fun append_lz(xs, ys) = if xs is + Nil then force(ys) + h :: t then lazy of () => LzCons(h, append_lz(t, ys)) + +fun cycle(xs) = append_lz(xs, lazy of () => cycle(xs)) + +fun isSpace(c) = c === " " + +fun words(s) = if dropWhile(isSpace, s) is + Nil then Nil + h :: t and + break_(isSpace, h :: t) is [w, s_] then w :: words(s_) + +fun unwords(ws) = + fun go(ws) = if ws is + Nil then Nil + w :: ws then " " :: w +: go(ws) + if ws is + Nil then Nil + w :: ws then w +: go(ws) + +fun null_lz(ls) = if force(ls) is + LzNil then true + LzCons(h, t) then false + +fun trim(ls) = + fun cons(x, xs) = if inList(x, nofibStringToList(" .!?,")) and null_(xs) then Nil else x :: xs + foldr(cons, Nil, dropWhile(x => inList(x, nofibStringToList(" .!?,")), ls)) + +fun repeated(kt_rp) = if kt_rp is [kt, r :: rp] then [r, [kt, rp]] + +fun newKeyTab(kt_, kt_rp) = if kt_rp is [kt, rp] then [kt_, rp] + +fun keyTabOf(kt_rp) = if kt_rp is [kt, rp] then kt + +fun makeResponse(cs, us) = if cs is + "?" :: cs_ then cs_ +: nofibStringToList(" ") +: us +: nofibStringToList("?") + "." :: cs_ then cs_ +: nofibStringToList(" ") +: us +: nofibStringToList(".") + else cs + +val repeatMsgs = + nofibStringToList("Why did you repeat yourself?") :: + nofibStringToList("Do you expect a different answer by repeating yourself?") :: + nofibStringToList("Come, come, elucidate your thoughts.") :: + nofibStringToList("Please don't repeat yourself!") :: + Nil +//│ repeatMsgs = [["W","h","y"," ","d","i","d"," ","y","o","u"," ","r","e","p","e","a","t"," ","y","o","u","r","s","e","l","f","?"],["D","o"," ","y","o","u"," ","e","x","p","e","c","t"," ","a"," ","d","i","f","f","e","r","e","n","t"," ","a","n","s","w","e","r"," ","b","y"," ","r","e","p","e","a","t","i","n","g"," ","y","o","u","r","s","e","l","f","?"],["C","o","m","e",","," ","c","o","m","e",","," ","e","l","u","c","i","d","a","t","e"," ","y","o","u","r"," ","t","h","o","u","g","h","t","s","."],["P","l","e","a","s","e"," ","d","o","n","'","t"," ","r","e","p","e","a","t"," ","y","o","u","r","s","e","l","f","!"]] + +val respMsgs = + let canYou = nofibStringToList("?Don_t you believe that I can") :: + nofibStringToList("?Perhaps you would like to be able to") :: + nofibStringToList("?You want me to be able to") :: + Nil + let canI = nofibStringToList("?Perhaps you don_t want to") :: + nofibStringToList("?Do you want to be able to") :: + Nil + let youAre = nofibStringToList("?What makes you think I am") :: + nofibStringToList("?Does it please you to believe I am") :: + nofibStringToList("?Perhaps you would like to be") :: + nofibStringToList("?Do you sometimes wish you were") :: + Nil + let iDont = nofibStringToList("?Don_t you really") :: + nofibStringToList("?Why don_t you") :: + nofibStringToList("?Do you wish to be able to") :: + nofibStringToList("Does that trouble you?") :: + Nil + let iFeel = nofibStringToList("Tell me more about such feelings.") :: + nofibStringToList("?Do you often feel") :: + nofibStringToList("?Do you enjoy feeling") :: + Nil + let whyDont = nofibStringToList("?Do you really believe I don't") :: + nofibStringToList(".Perhaps in good time I will") :: + nofibStringToList("?Do you want me to") :: + Nil + let whyCant = nofibStringToList("?Do you think you should be able to") :: + nofibStringToList("?Why can't you") :: + Nil + let areYou = nofibStringToList("?Why are you interested in whether or not I am") :: + nofibStringToList("?Would you prefer if I were not") :: + nofibStringToList("?Perhaps in your fantasies I am") :: + Nil + let iCant = nofibStringToList("?How do you know you can't") :: + nofibStringToList("Have you tried?") :: + nofibStringToList("?Perhaps you can now") :: + Nil + let iAm = nofibStringToList("?Did you come to me because you are") :: + nofibStringToList("?How long have you been") :: + nofibStringToList("?Do you believe it is normal to be") :: + nofibStringToList("?Do you enjoy being") :: + Nil + let you = nofibStringToList("We were discussing you --not me.") :: + nofibStringToList("?Oh,") :: + nofibStringToList("You're not really talking about me, are you?") :: + Nil + let yes = nofibStringToList("You seem quite positive.") :: + nofibStringToList("Are you Sure?") :: + nofibStringToList("I see.") :: + nofibStringToList("I understand.") :: + Nil + let no = nofibStringToList("Are you saying no just to be negative?") :: + nofibStringToList("You are being a bit negative.") :: + nofibStringToList("Why not?") :: + nofibStringToList("Are you sure?") :: + nofibStringToList("Why no?") :: + Nil + let computer = nofibStringToList("Do computers worry you?") :: + nofibStringToList("Are you talking about me in particular?") :: + nofibStringToList("Are you frightened by machines?") :: + nofibStringToList("Why do you mention computers?") :: + nofibStringToList("What do you think machines have to do with your problems?") :: + nofibStringToList("Don't you think computers can help people?") :: + nofibStringToList("What is it about machines that worries you?") :: + Nil + let iWant = nofibStringToList("?Why do you want") :: + nofibStringToList("?What would it mean to you if you got") :: + nofibStringToList("?Suppose you got") :: + nofibStringToList("?What if you never got") :: + nofibStringToList(".I sometimes also want") :: + Nil + let question = nofibStringToList("Why do you ask?") :: + nofibStringToList("Does that question interest you?") :: + nofibStringToList("What answer would please you the most?") :: + nofibStringToList("What do you think?") :: + nofibStringToList("Are such questions on your mind often?") :: + nofibStringToList("What is it that you really want to know?") :: + nofibStringToList("Have you asked anyone else?") :: + nofibStringToList("Have you asked such questions before?") :: + nofibStringToList("What else comes to mind when you ask that?") :: + Nil + let name = nofibStringToList("Names don't interest me.") :: + nofibStringToList("I don't care about names --please go on.") :: + Nil + let because = nofibStringToList("Is that the real reason?") :: + nofibStringToList("Don't any other reasons come to mind?") :: + nofibStringToList("Does that reason explain anything else?") :: + nofibStringToList("What other reasons might there be?") :: + Nil + let sorry = nofibStringToList("Please don't apologise!") :: + nofibStringToList("Apologies are not necessary.") :: + nofibStringToList("What feelings do you have when you apologise?") :: + nofibStringToList("Don't be so defensive!") :: + Nil + let dream = nofibStringToList("What does that dream suggest to you?") :: + nofibStringToList("Do you dream often?") :: + nofibStringToList("What persons appear in your dreams?") :: + nofibStringToList("Are you disturbed by your dreams?") :: + Nil + let hello = nofibStringToList("How do you...please state your problem.") :: + Nil + let maybe = nofibStringToList("You don't seem quite certain.") :: + nofibStringToList("Why the uncertain tone?") :: + nofibStringToList("Can't you be more positive?") :: + nofibStringToList("You aren't sure?") :: + nofibStringToList("Don't you know?") :: + Nil + let your = nofibStringToList("?Why are you concerned about my") :: + nofibStringToList("?What about your own") :: + Nil + let always = nofibStringToList("Can you think of a specific example?") :: + nofibStringToList("When?") :: + nofibStringToList("What are you thinking of?") :: + nofibStringToList("Really, always?") :: + Nil + let think = nofibStringToList("Do you really think so?") :: + nofibStringToList("?But you are not sure you") :: + nofibStringToList("?Do you doubt you") :: + Nil + let alike = nofibStringToList("In what way?") :: + nofibStringToList("What resemblence do you see?") :: + nofibStringToList("What does the similarity suggest to you?") :: + nofibStringToList("What other connections do you see?") :: + nofibStringToList("Cound there really be some connection?") :: + nofibStringToList("How?") :: + Nil + let friend = nofibStringToList("Why do you bring up the topic of friends?") :: + nofibStringToList("Do your friends worry you?") :: + nofibStringToList("Do your friends pick on you?") :: + nofibStringToList("Are you sure you have any friends?") :: + nofibStringToList("Do you impose on your friends?") :: + nofibStringToList("Perhaps your love for friends worries you.") :: + Nil + let nokeyMsgs = nofibStringToList("I'm not sure I understand you fully.") :: + nofibStringToList("What does that suggest to you?") :: + nofibStringToList("I see.") :: + nofibStringToList("Can you elaborate on that?") :: + nofibStringToList("Say, do you have any psychological problems?") :: + Nil + [nofibStringToList("CAN YOU"), canYou] :: + [nofibStringToList("CAN I"), canI] :: + [nofibStringToList("YOU ARE"), youAre] :: + [nofibStringToList("YOU'RE"), youAre] :: + [nofibStringToList("I DON'T"), iDont] :: + [nofibStringToList("I FEEL"), iFeel] :: + [nofibStringToList("WHY DON'T YOU"), whyDont] :: + [nofibStringToList("WHY CAN'T I"), whyCant] :: + [nofibStringToList("ARE YOU"), areYou] :: + [nofibStringToList("I CAN'T"), iCant] :: + [nofibStringToList("I AM"), iAm] :: + [nofibStringToList("I'M"), iAm] :: + [nofibStringToList("YOU"), you] :: + [nofibStringToList("YES"), yes] :: + [nofibStringToList("NO"), no] :: + [nofibStringToList("COMPUTER"), computer] :: + [nofibStringToList("COMPUTERS"), computer] :: + [nofibStringToList("I WANT"), iWant] :: + [nofibStringToList("WHAT"), question] :: + [nofibStringToList("HOW"), question] :: + [nofibStringToList("WHO"), question] :: + [nofibStringToList("WHERE"), question] :: + [nofibStringToList("WHEN"), question] :: + [nofibStringToList("NAME"), name] :: + [nofibStringToList("WHY"), question] :: + [nofibStringToList("CAUSE"), because] :: + [nofibStringToList("BECAUSE"), because] :: + [nofibStringToList("DREAM"), dream] :: + [nofibStringToList("SORRY"), sorry] :: + [nofibStringToList("HI"), hello] :: + [nofibStringToList("DREAMS"), dream] :: + [nofibStringToList("MAYBE"), maybe] :: + [nofibStringToList("HELLO"), hello] :: + [nofibStringToList("ALWAYS"), always] :: + [nofibStringToList("YOUR"), your] :: + [nofibStringToList("ALIKE"), alike] :: + [nofibStringToList("THINK"), think] :: + [nofibStringToList("FRIENDS"), friend] :: + [nofibStringToList("FRIEND"), friend] :: + [Nil, nokeyMsgs] :: + Nil +//│ respMsgs = [[["C","A","N"," ","Y","O","U"], [["?","D","o","n","_","t"," ","y","o","u"," ","b","e","l","i","e","v","e"," ","t","h","a","t"," ","I"," ","c","a","n"],["?","P","e","r","h","a","p","s"," ","y","o","u"," ","w","o","u","l","d"," ","l","i","k","e"," ","t","o"," ","b","e"," ","a","b","l","e"," ","t","o"],["?","Y","o","u"," ","w","a","n","t"," ","m","e"," ","t","o"," ","b","e"," ","a","b","l","e"," ","t","o"]]],[["C","A","N"," ","I"], [["?","P","e","r","h","a","p","s"," ","y","o","u"," ","d","o","n","_","t"," ","w","a","n","t"," ","t","o"],["?","D","o"," ","y","o","u"," ","w","a","n","t"," ","t","o"," ","b","e"," ","a","b","l","e"," ","t","o"]]],[["Y","O","U"," ","A","R","E"], [["?","W","h","a","t"," ","m","a","k","e","s"," ","y","o","u"," ","t","h","i","n","k"," ","I"," ","a","m"],["?","D","o","e","s"," ","i","t"," ","p","l","e","a","s","e"," ","y","o","u"," ","t","o"," ","b","e","l","i","e","v","e"," ","I"," ","a","m"],["?","P","e","r","h","a","p","s"," ","y","o","u"," ","w","o","u","l","d"," ","l","i","k","e"," ","t","o"," ","b","e"],["?","D","o"," ","y","o","u"," ","s","o","m","e","t","i","m","e","s"," ","w","i","s","h"," ","y","o","u"," ","w","e","r","e"]]],[["Y","O","U","'","R","E"], [["?","W","h","a","t"," ","m","a","k","e","s"," ","y","o","u"," ","t","h","i","n","k"," ","I"," ","a","m"],["?","D","o","e","s"," ","i","t"," ","p","l","e","a","s","e"," ","y","o","u"," ","t","o"," ","b","e","l","i","e","v","e"," ","I"," ","a","m"],["?","P","e","r","h","a","p","s"," ","y","o","u"," ","w","o","u","l","d"," ","l","i","k","e"," ","t","o"," ","b","e"],["?","D","o"," ","y","o","u"," ","s","o","m","e","t","i","m","e","s"," ","w","i","s","h"," ","y","o","u"," ","w","e","r","e"]]],[["I"," ","D","O","N","'","T"], [["?","D","o","n","_","t"," ","y","o","u"," ","r","e","a","l","l","y"],["?","W","h","y"," ","d","o","n","_","t"," ","y","o","u"],["?","D","o"," ","y","o","u"," ","w","i","s","h"," ","t","o"," ","b","e"," ","a","b","l","e"," ","t","o"],["D","o","e","s"," ","t","h","a","t"," ","t","r","o","u","b","l","e"," ","y","o","u","?"]]],[["I"," ","F","E","E","L"], [["T","e","l","l"," ","m","e"," ","m","o","r","e"," ","a","b","o","u","t"," ","s","u","c","h"," ","f","e","e","l","i","n","g","s","."],["?","D","o"," ","y","o","u"," ","o","f","t","e","n"," ","f","e","e","l"],["?","D","o"," ","y","o","u"," ","e","n","j","o","y"," ","f","e","e","l","i","n","g"]]],[["W","H","Y"," ","D","O","N","'","T"," ","Y","O","U"], [["?","D","o"," ","y","o","u"," ","r","e","a","l","l","y"," ","b","e","l","i","e","v","e"," ","I"," ","d","o","n","'","t"],[".","P","e","r","h","a","p","s"," ","i","n"," ","g","o","o","d"," ","t","i","m","e"," ","I"," ","w","i","l","l"],["?","D","o"," ","y","o","u"," ","w","a","n","t"," ","m","e"," ","t","o"]]],[["W","H","Y"," ","C","A","N","'","T"," ","I"], [["?","D","o"," ","y","o","u"," ","t","h","i","n","k"," ","y","o","u"," ","s","h","o","u","l","d"," ","b","e"," ","a","b","l","e"," ","t","o"],["?","W","h","y"," ","c","a","n","'","t"," ","y","o","u"]]],[["A","R","E"," ","Y","O","U"], [["?","W","h","y"," ","a","r","e"," ","y","o","u"," ","i","n","t","e","r","e","s","t","e","d"," ","i","n"," ","w","h","e","t","h","e","r"," ","o","r"," ","n","o","t"," ","I"," ","a","m"],["?","W","o","u","l","d"," ","y","o","u"," ","p","r","e","f","e","r"," ","i","f"," ","I"," ","w","e","r","e"," ","n","o","t"],["?","P","e","r","h","a","p","s"," ","i","n"," ","y","o","u","r"," ","f","a","n","t","a","s","i","e","s"," ","I"," ","a","m"]]],[["I"," ","C","A","N","'","T"], [["?","H","o","w"," ","d","o"," ","y","o","u"," ","k","n","o","w"," ","y","o","u"," ","c","a","n","'","t"],["H","a","v","e"," ","y","o","u"," ","t","r","i","e","d","?"],["?","P","e","r","h","a","p","s"," ","y","o","u"," ","c","a","n"," ","n","o","w"]]],[["I"," ","A","M"], [["?","D","i","d"," ","y","o","u"," ","c","o","m","e"," ","t","o"," ","m","e"," ","b","e","c","a","u","s","e"," ","y","o","u"," ","a","r","e"],["?","H","o","w"," ","l","o","n","g"," ","h","a","v","e"," ","y","o","u"," ","b","e","e","n"],["?","D","o"," ","y","o","u"," ","b","e","l","i","e","v","e"," ","i","t"," ","i","s"," ","n","o","r","m","a","l"," ","t","o"," ","b","e"],["?","D","o"," ","y","o","u"," ","e","n","j","o","y"," ","b","e","i","n","g"]]],[["I","'","M"], [["?","D","i","d"," ","y","o","u"," ","c","o","m","e"," ","t","o"," ","m","e"," ","b","e","c","a","u","s","e"," ","y","o","u"," ","a","r","e"],["?","H","o","w"," ","l","o","n","g"," ","h","a","v","e"," ","y","o","u"," ","b","e","e","n"],["?","D","o"," ","y","o","u"," ","b","e","l","i","e","v","e"," ","i","t"," ","i","s"," ","n","o","r","m","a","l"," ","t","o"," ","b","e"],["?","D","o"," ","y","o","u"," ","e","n","j","o","y"," ","b","e","i","n","g"]]],[["Y","O","U"], [["W","e"," ","w","e","r","e"," ","d","i","s","c","u","s","s","i","n","g"," ","y","o","u"," ","-","-","n","o","t"," ","m","e","."],["?","O","h",","],["Y","o","u","'","r","e"," ","n","o","t"," ","r","e","a","l","l","y"," ","t","a","l","k","i","n","g"," ","a","b","o","u","t"," ","m","e",","," ","a","r","e"," ","y","o","u","?"]]],[["Y","E","S"], [["Y","o","u"," ","s","e","e","m"," ","q","u","i","t","e"," ","p","o","s","i","t","i","v","e","."],["A","r","e"," ","y","o","u"," ","S","u","r","e","?"],["I"," ","s","e","e","."],["I"," ","u","n","d","e","r","s","t","a","n","d","."]]],[["N","O"], [["A","r","e"," ","y","o","u"," ","s","a","y","i","n","g"," ","n","o"," ","j","u","s","t"," ","t","o"," ","b","e"," ","n","e","g","a","t","i","v","e","?"],["Y","o","u"," ","a","r","e"," ","b","e","i","n","g"," ","a"," ","b","i","t"," ","n","e","g","a","t","i","v","e","."],["W","h","y"," ","n","o","t","?"],["A","r","e"," ","y","o","u"," ","s","u","r","e","?"],["W","h","y"," ","n","o","?"]]],[["C","O","M","P","U","T","E","R"], [["D","o"," ","c","o","m","p","u","t","e","r","s"," ","w","o","r","r","y"," ","y","o","u","?"],["A","r","e"," ","y","o","u"," ","t","a","l","k","i","n","g"," ","a","b","o","u","t"," ","m","e"," ","i","n"," ","p","a","r","t","i","c","u","l","a","r","?"],["A","r","e"," ","y","o","u"," ","f","r","i","g","h","t","e","n","e","d"," ","b","y"," ","m","a","c","h","i","n","e","s","?"],["W","h","y"," ","d","o"," ","y","o","u"," ","m","e","n","t","i","o","n"," ","c","o","m","p","u","t","e","r","s","?"],["W","h","a","t"," ","d","o"," ","y","o","u"," ","t","h","i","n","k"," ","m","a","c","h","i","n","e","s"," ","h","a","v","e"," ","t","o"," ","d","o"," ","w","i","t","h"," ","y","o","u","r"," ","p","r","o","b","l","e","m","s","?"],["D","o","n","'","t"," ","y","o","u"," ","t","h","i","n","k"," ","c","o","m","p","u","t","e","r","s"," ","c","a","n"," ","h","e","l","p"," ","p","e","o","p","l","e","?"],["W","h","a","t"," ","i","s"," ","i","t"," ","a","b","o","u","t"," ","m","a","c","h","i","n","e","s"," ","t","h","a","t"," ","w","o","r","r","i","e","s"," ","y","o","u","?"]]],[["C","O","M","P","U","T","E","R","S"], [["D","o"," ","c","o","m","p","u","t","e","r","s"," ","w","o","r","r","y"," ","y","o","u","?"],["A","r","e"," ","y","o","u"," ","t","a","l","k","i","n","g"," ","a","b","o","u","t"," ","m","e"," ","i","n"," ","p","a","r","t","i","c","u","l","a","r","?"],["A","r","e"," ","y","o","u"," ","f","r","i","g","h","t","e","n","e","d"," ","b","y"," ","m","a","c","h","i","n","e","s","?"],["W","h","y"," ","d","o"," ","y","o","u"," ","m","e","n","t","i","o","n"," ","c","o","m","p","u","t","e","r","s","?"],["W","h","a","t"," ","d","o"," ","y","o","u"," ","t","h","i","n","k"," ","m","a","c","h","i","n","e","s"," ","h","a","v","e"," ","t","o"," ","d","o"," ","w","i","t","h"," ","y","o","u","r"," ","p","r","o","b","l","e","m","s","?"],["D","o","n","'","t"," ","y","o","u"," ","t","h","i","n","k"," ","c","o","m","p","u","t","e","r","s"," ","c","a","n"," ","h","e","l","p"," ","p","e","o","p","l","e","?"],["W","h","a","t"," ","i","s"," ","i","t"," ","a","b","o","u","t"," ","m","a","c","h","i","n","e","s"," ","t","h","a","t"," ","w","o","r","r","i","e","s"," ","y","o","u","?"]]],[["I"," ","W","A","N","T"], [["?","W","h","y"," ","d","o"," ","y","o","u"," ","w","a","n","t"],["?","W","h","a","t"," ","w","o","u","l","d"," ","i","t"," ","m","e","a","n"," ","t","o"," ","y","o","u"," ","i","f"," ","y","o","u"," ","g","o","t"],["?","S","u","p","p","o","s","e"," ","y","o","u"," ","g","o","t"],["?","W","h","a","t"," ","i","f"," ","y","o","u"," ","n","e","v","e","r"," ","g","o","t"],[".","I"," ","s","o","m","e","t","i","m","e","s"," ","a","l","s","o"," ","w","a","n","t"]]],[["W","H","A","T"], [["W","h","y"," ","d","o"," ","y","o","u"," ","a","s","k","?"],["D","o","e","s"," ","t","h","a","t"," ","q","u","e","s","t","i","o","n"," ","i","n","t","e","r","e","s","t"," ","y","o","u","?"],["W","h","a","t"," ","a","n","s","w","e","r"," ","w","o","u","l","d"," ","p","l","e","a","s","e"," ","y","o","u"," ","t","h","e"," ","m","o","s","t","?"],["W","h","a","t"," ","d","o"," ","y","o","u"," ","t","h","i","n","k","?"],["A","r","e"," ","s","u","c","h"," ","q","u","e","s","t","i","o","n","s"," ","o","n"," ","y","o","u","r"," ","m","i","n","d"," ","o","f","t","e","n","?"],["W","h","a","t"," ","i","s"," ","i","t"," ","t","h","a","t"," ","y","o","u"," ","r","e","a","l","l","y"," ","w","a","n","t"," ","t","o"," ","k","n","o","w","?"],["H","a","v","e"," ","y","o","u"," ","a","s","k","e","d"," ","a","n","y","o","n","e"," ","e","l","s","e","?"],["H","a","v","e"," ","y","o","u"," ","a","s","k","e","d"," ","s","u","c","h"," ","q","u","e","s","t","i","o","n","s"," ","b","e","f","o","r","e","?"],["W","h","a","t"," ","e","l","s","e"," ","c","o","m","e","s"," ","t","o"," ","m","i","n","d"," ","w","h","e","n"," ","y","o","u"," ","a","s","k"," ","t","h","a","t","?"]]],[["H","O","W"], [["W","h","y"," ","d","o"," ","y","o","u"," ","a","s","k","?"],["D","o","e","s"," ","t","h","a","t"," ","q","u","e","s","t","i","o","n"," ","i","n","t","e","r","e","s","t"," ","y","o","u","?"],["W","h","a","t"," ","a","n","s","w","e","r"," ","w","o","u","l","d"," ","p","l","e","a","s","e"," ","y","o","u"," ","t","h","e"," ","m","o","s","t","?"],["W","h","a","t"," ","d","o"," ","y","o","u"," ","t","h","i","n","k","?"],["A","r","e"," ","s","u","c","h"," ","q","u","e","s","t","i","o","n","s"," ","o","n"," ","y","o","u","r"," ","m","i","n","d"," ","o","f","t","e","n","?"],["W","h","a","t"," ","i","s"," ","i","t"," ","t","h","a","t"," ","y","o","u"," ","r","e","a","l","l","y"," ","w","a","n","t"," ","t","o"," ","k","n","o","w","?"],["H","a","v","e"," ","y","o","u"," ","a","s","k","e","d"," ","a","n","y","o","n","e"," ","e","l","s","e","?"],["H","a","v","e"," ","y","o","u"," ","a","s","k","e","d"," ","s","u","c","h"," ","q","u","e","s","t","i","o","n","s"," ","b","e","f","o","r","e","?"],["W","h","a","t"," ","e","l","s","e"," ","c","o","m","e","s"," ","t","o"," ","m","i","n","d"," ","w","h","e","n"," ","y","o","u"," ","a","s","k"," ","t","h","a","t","?"]]],[["W","H","O"], [["W","h","y"," ","d","o"," ","y","o","u"," ","a","s","k","?"],["D","o","e","s"," ","t","h","a","t"," ","q","u","e","s","t","i","o","n"," ","i","n","t","e","r","e","s","t"," ","y","o","u","?"],["W","h","a","t"," ","a","n","s","w","e","r"," ","w","o","u","l","d"," ","p","l","e","a","s","e"," ","y","o","u"," ","t","h","e"," ","m","o","s","t","?"],["W","h","a","t"," ","d","o"," ","y","o","u"," ","t","h","i","n","k","?"],["A","r","e"," ","s","u","c","h"," ","q","u","e","s","t","i","o","n","s"," ","o","n"," ","y","o","u","r"," ","m","i","n","d"," ","o","f","t","e","n","?"],["W","h","a","t"," ","i","s"," ","i","t"," ","t","h","a","t"," ","y","o","u"," ","r","e","a","l","l","y"," ","w","a","n","t"," ","t","o"," ","k","n","o","w","?"],["H","a","v","e"," ","y","o","u"," ","a","s","k","e","d"," ","a","n","y","o","n","e"," ","e","l","s","e","?"],["H","a","v","e"," ","y","o","u"," ","a","s","k","e","d"," ","s","u","c","h"," ","q","u","e","s","t","i","o","n","s"," ","b","e","f","o","r","e","?"],["W","h","a","t"," ","e","l","s","e"," ","c","o","m","e","s"," ","t","o"," ","m","i","n","d"," ","w","h","e","n"," ","y","o","u"," ","a","s","k"," ","t","h","a","t","?"]]],[["W","H","E","R","E"], [["W","h","y"," ","d","o"," ","y","o","u"," ","a","s","k","?"],["D","o","e","s"," ","t","h","a","t"," ","q","u","e","s","t","i","o","n"," ","i","n","t","e","r","e","s","t"," ","y","o","u","?"],["W","h","a","t"," ","a","n","s","w","e","r"," ","w","o","u","l","d"," ","p","l","e","a","s","e"," ","y","o","u"," ","t","h","e"," ","m","o","s","t","?"],["W","h","a","t"," ","d","o"," ","y","o","u"," ","t","h","i","n","k","?"],["A","r","e"," ","s","u","c","h"," ","q","u","e","s","t","i","o","n","s"," ","o","n"," ","y","o","u","r"," ","m","i","n","d"," ","o","f","t","e","n","?"],["W","h","a","t"," ","i","s"," ","i","t"," ","t","h","a","t"," ","y","o","u"," ","r","e","a","l","l","y"," ","w","a","n","t"," ","t","o"," ","k","n","o","w","?"],["H","a","v","e"," ","y","o","u"," ","a","s","k","e","d"," ","a","n","y","o","n","e"," ","e","l","s","e","?"],["H","a","v","e"," ","y","o","u"," ","a","s","k","e","d"," ","s","u","c","h"," ","q","u","e","s","t","i","o","n","s"," ","b","e","f","o","r","e","?"],["W","h","a","t"," ","e","l","s","e"," ","c","o","m","e","s"," ","t","o"," ","m","i","n","d"," ","w","h","e","n"," ","y","o","u"," ","a","s","k"," ","t","h","a","t","?"]]],[["W","H","E","N"], [["W","h","y"," ","d","o"," ","y","o","u"," ","a","s","k","?"],["D","o","e","s"," ","t","h","a","t"," ","q","u","e","s","t","i","o","n"," ","i","n","t","e","r","e","s","t"," ","y","o","u","?"],["W","h","a","t"," ","a","n","s","w","e","r"," ","w","o","u","l","d"," ","p","l","e","a","s","e"," ","y","o","u"," ","t","h","e"," ","m","o","s","t","?"],["W","h","a","t"," ","d","o"," ","y","o","u"," ","t","h","i","n","k","?"],["A","r","e"," ","s","u","c","h"," ","q","u","e","s","t","i","o","n","s"," ","o","n"," ","y","o","u","r"," ","m","i","n","d"," ","o","f","t","e","n","?"],["W","h","a","t"," ","i","s"," ","i","t"," ","t","h","a","t"," ","y","o","u"," ","r","e","a","l","l","y"," ","w","a","n","t"," ","t","o"," ","k","n","o","w","?"],["H","a","v","e"," ","y","o","u"," ","a","s","k","e","d"," ","a","n","y","o","n","e"," ","e","l","s","e","?"],["H","a","v","e"," ","y","o","u"," ","a","s","k","e","d"," ","s","u","c","h"," ","q","u","e","s","t","i","o","n","s"," ","b","e","f","o","r","e","?"],["W","h","a","t"," ","e","l","s","e"," ","c","o","m","e","s"," ","t","o"," ","m","i","n","d"," ","w","h","e","n"," ","y","o","u"," ","a","s","k"," ","t","h","a","t","?"]]],[["N","A","M","E"], [["N","a","m","e","s"," ","d","o","n","'","t"," ","i","n","t","e","r","e","s","t"," ","m","e","."],["I"," ","d","o","n","'","t"," ","c","a","r","e"," ","a","b","o","u","t"," ","n","a","m","e","s"," ","-","-","p","l","e","a","s","e"," ","g","o"," ","o","n","."]]],[["W","H","Y"], [["W","h","y"," ","d","o"," ","y","o","u"," ","a","s","k","?"],["D","o","e","s"," ","t","h","a","t"," ","q","u","e","s","t","i","o","n"," ","i","n","t","e","r","e","s","t"," ","y","o","u","?"],["W","h","a","t"," ","a","n","s","w","e","r"," ","w","o","u","l","d"," ","p","l","e","a","s","e"," ","y","o","u"," ","t","h","e"," ","m","o","s","t","?"],["W","h","a","t"," ","d","o"," ","y","o","u"," ","t","h","i","n","k","?"],["A","r","e"," ","s","u","c","h"," ","q","u","e","s","t","i","o","n","s"," ","o","n"," ","y","o","u","r"," ","m","i","n","d"," ","o","f","t","e","n","?"],["W","h","a","t"," ","i","s"," ","i","t"," ","t","h","a","t"," ","y","o","u"," ","r","e","a","l","l","y"," ","w","a","n","t"," ","t","o"," ","k","n","o","w","?"],["H","a","v","e"," ","y","o","u"," ","a","s","k","e","d"," ","a","n","y","o","n","e"," ","e","l","s","e","?"],["H","a","v","e"," ","y","o","u"," ","a","s","k","e","d"," ","s","u","c","h"," ","q","u","e","s","t","i","o","n","s"," ","b","e","f","o","r","e","?"],["W","h","a","t"," ","e","l","s","e"," ","c","o","m","e","s"," ","t","o"," ","m","i","n","d"," ","w","h","e","n"," ","y","o","u"," ","a","s","k"," ","t","h","a","t","?"]]],[["C","A","U","S","E"], [["I","s"," ","t","h","a","t"," ","t","h","e"," ","r","e","a","l"," ","r","e","a","s","o","n","?"],["D","o","n","'","t"," ","a","n","y"," ","o","t","h","e","r"," ","r","e","a","s","o","n","s"," ","c","o","m","e"," ","t","o"," ","m","i","n","d","?"],["D","o","e","s"," ","t","h","a","t"," ","r","e","a","s","o","n"," ","e","x","p","l","a","i","n"," ","a","n","y","t","h","i","n","g"," ","e","l","s","e","?"],["W","h","a","t"," ","o","t","h","e","r"," ","r","e","a","s","o","n","s"," ","m","i","g","h","t"," ","t","h","e","r","e"," ","b","e","?"]]],[["B","E","C","A","U","S","E"], [["I","s"," ","t","h","a","t"," ","t","h","e"," ","r","e","a","l"," ","r","e","a","s","o","n","?"],["D","o","n","'","t"," ","a","n","y"," ","o","t","h","e","r"," ","r","e","a","s","o","n","s"," ","c","o","m","e"," ","t","o"," ","m","i","n","d","?"],["D","o","e","s"," ","t","h","a","t"," ","r","e","a","s","o","n"," ","e","x","p","l","a","i","n"," ","a","n","y","t","h","i","n","g"," ","e","l","s","e","?"],["W","h","a","t"," ","o","t","h","e","r"," ","r","e","a","s","o","n","s"," ","m","i","g","h","t"," ","t","h","e","r","e"," ","b","e","?"]]],[["D","R","E","A","M"], [["W","h","a","t"," ","d","o","e","s"," ","t","h","a","t"," ","d","r","e","a","m"," ","s","u","g","g","e","s","t"," ","t","o"," ","y","o","u","?"],["D","o"," ","y","o","u"," ","d","r","e","a","m"," ","o","f","t","e","n","?"],["W","h","a","t"," ","p","e","r","s","o","n","s"," ","a","p","p","e","a","r"," ","i","n"," ","y","o","u","r"," ","d","r","e","a","m","s","?"],["A","r","e"," ","y","o","u"," ","d","i","s","t","u","r","b","e","d"," ","b","y"," ","y","o","u","r"," ","d","r","e","a","m","s","?"]]],[["S","O","R","R","Y"], [["P","l","e","a","s","e"," ","d","o","n","'","t"," ","a","p","o","l","o","g","i","s","e","!"],["A","p","o","l","o","g","i","e","s"," ","a","r","e"," ","n","o","t"," ","n","e","c","e","s","s","a","r","y","."],["W","h","a","t"," ","f","e","e","l","i","n","g","s"," ","d","o"," ","y","o","u"," ","h","a","v","e"," ","w","h","e","n"," ","y","o","u"," ","a","p","o","l","o","g","i","s","e","?"],["D","o","n","'","t"," ","b","e"," ","s","o"," ","d","e","f","e","n","s","i","v","e","!"]]],[["H","I"], [["H","o","w"," ","d","o"," ","y","o","u",".",".",".","p","l","e","a","s","e"," ","s","t","a","t","e"," ","y","o","u","r"," ","p","r","o","b","l","e","m","."]]],[["D","R","E","A","M","S"], [["W","h","a","t"," ","d","o","e","s"," ","t","h","a","t"," ","d","r","e","a","m"," ","s","u","g","g","e","s","t"," ","t","o"," ","y","o","u","?"],["D","o"," ","y","o","u"," ","d","r","e","a","m"," ","o","f","t","e","n","?"],["W","h","a","t"," ","p","e","r","s","o","n","s"," ","a","p","p","e","a","r"," ","i","n"," ","y","o","u","r"," ","d","r","e","a","m","s","?"],["A","r","e"," ","y","o","u"," ","d","i","s","t","u","r","b","e","d"," ","b","y"," ","y","o","u","r"," ","d","r","e","a","m","s","?"]]],[["M","A","Y","B","E"], [["Y","o","u"," ","d","o","n","'","t"," ","s","e","e","m"," ","q","u","i","t","e"," ","c","e","r","t","a","i","n","."],["W","h","y"," ","t","h","e"," ","u","n","c","e","r","t","a","i","n"," ","t","o","n","e","?"],["C","a","n","'","t"," ","y","o","u"," ","b","e"," ","m","o","r","e"," ","p","o","s","i","t","i","v","e","?"],["Y","o","u"," ","a","r","e","n","'","t"," ","s","u","r","e","?"],["D","o","n","'","t"," ","y","o","u"," ","k","n","o","w","?"]]],[["H","E","L","L","O"], [["H","o","w"," ","d","o"," ","y","o","u",".",".",".","p","l","e","a","s","e"," ","s","t","a","t","e"," ","y","o","u","r"," ","p","r","o","b","l","e","m","."]]],[["A","L","W","A","Y","S"], [["C","a","n"," ","y","o","u"," ","t","h","i","n","k"," ","o","f"," ","a"," ","s","p","e","c","i","f","i","c"," ","e","x","a","m","p","l","e","?"],["W","h","e","n","?"],["W","h","a","t"," ","a","r","e"," ","y","o","u"," ","t","h","i","n","k","i","n","g"," ","o","f","?"],["R","e","a","l","l","y",","," ","a","l","w","a","y","s","?"]]],[["Y","O","U","R"], [["?","W","h","y"," ","a","r","e"," ","y","o","u"," ","c","o","n","c","e","r","n","e","d"," ","a","b","o","u","t"," ","m","y"],["?","W","h","a","t"," ","a","b","o","u","t"," ","y","o","u","r"," ","o","w","n"]]],[["A","L","I","K","E"], [["I","n"," ","w","h","a","t"," ","w","a","y","?"],["W","h","a","t"," ","r","e","s","e","m","b","l","e","n","c","e"," ","d","o"," ","y","o","u"," ","s","e","e","?"],["W","h","a","t"," ","d","o","e","s"," ","t","h","e"," ","s","i","m","i","l","a","r","i","t","y"," ","s","u","g","g","e","s","t"," ","t","o"," ","y","o","u","?"],["W","h","a","t"," ","o","t","h","e","r"," ","c","o","n","n","e","c","t","i","o","n","s"," ","d","o"," ","y","o","u"," ","s","e","e","?"],["C","o","u","n","d"," ","t","h","e","r","e"," ","r","e","a","l","l","y"," ","b","e"," ","s","o","m","e"," ","c","o","n","n","e","c","t","i","o","n","?"],["H","o","w","?"]]],[["T","H","I","N","K"], [["D","o"," ","y","o","u"," ","r","e","a","l","l","y"," ","t","h","i","n","k"," ","s","o","?"],["?","B","u","t"," ","y","o","u"," ","a","r","e"," ","n","o","t"," ","s","u","r","e"," ","y","o","u"],["?","D","o"," ","y","o","u"," ","d","o","u","b","t"," ","y","o","u"]]],[["F","R","I","E","N","D","S"], [["W","h","y"," ","d","o"," ","y","o","u"," ","b","r","i","n","g"," ","u","p"," ","t","h","e"," ","t","o","p","i","c"," ","o","f"," ","f","r","i","e","n","d","s","?"],["D","o"," ","y","o","u","r"," ","f","r","i","e","n","d","s"," ","w","o","r","r","y"," ","y","o","u","?"],["D","o"," ","y","o","u","r"," ","f","r","i","e","n","d","s"," ","p","i","c","k"," ","o","n"," ","y","o","u","?"],["A","r","e"," ","y","o","u"," ","s","u","r","e"," ","y","o","u"," ","h","a","v","e"," ","a","n","y"," ","f","r","i","e","n","d","s","?"],["D","o"," ","y","o","u"," ","i","m","p","o","s","e"," ","o","n"," ","y","o","u","r"," ","f","r","i","e","n","d","s","?"],["P","e","r","h","a","p","s"," ","y","o","u","r"," ","l","o","v","e"," ","f","o","r"," ","f","r","i","e","n","d","s"," ","w","o","r","r","i","e","s"," ","y","o","u","."]]],[["F","R","I","E","N","D"], [["W","h","y"," ","d","o"," ","y","o","u"," ","b","r","i","n","g"," ","u","p"," ","t","h","e"," ","t","o","p","i","c"," ","o","f"," ","f","r","i","e","n","d","s","?"],["D","o"," ","y","o","u","r"," ","f","r","i","e","n","d","s"," ","w","o","r","r","y"," ","y","o","u","?"],["D","o"," ","y","o","u","r"," ","f","r","i","e","n","d","s"," ","p","i","c","k"," ","o","n"," ","y","o","u","?"],["A","r","e"," ","y","o","u"," ","s","u","r","e"," ","y","o","u"," ","h","a","v","e"," ","a","n","y"," ","f","r","i","e","n","d","s","?"],["D","o"," ","y","o","u"," ","i","m","p","o","s","e"," ","o","n"," ","y","o","u","r"," ","f","r","i","e","n","d","s","?"],["P","e","r","h","a","p","s"," ","y","o","u","r"," ","l","o","v","e"," ","f","o","r"," ","f","r","i","e","n","d","s"," ","w","o","r","r","i","e","s"," ","y","o","u","."]]],[[], [["I","'","m"," ","n","o","t"," ","s","u","r","e"," ","I"," ","u","n","d","e","r","s","t","a","n","d"," ","y","o","u"," ","f","u","l","l","y","."],["W","h","a","t"," ","d","o","e","s"," ","t","h","a","t"," ","s","u","g","g","e","s","t"," ","t","o"," ","y","o","u","?"],["I"," ","s","e","e","."],["C","a","n"," ","y","o","u"," ","e","l","a","b","o","r","a","t","e"," ","o","n"," ","t","h","a","t","?"],["S","a","y",","," ","d","o"," ","y","o","u"," ","h","a","v","e"," ","a","n","y"," ","p","s","y","c","h","o","l","o","g","i","c","a","l"," ","p","r","o","b","l","e","m","s","?"]]]] + +val initial = + fun lscomp(ls) = if ls is + Nil then Nil + [k, rs] :: t then [words(k), cycle(rs)] :: lscomp(t) + [lscomp(respMsgs), cycle(repeatMsgs)] +//│ initial = [[[[["C","A","N"],["Y","O","U"]], Lazy([function])],[[["C","A","N"],["I"]], Lazy([function])],[[["Y","O","U"],["A","R","E"]], Lazy([function])],[[["Y","O","U","'","R","E"]], Lazy([function])],[[["I"],["D","O","N","'","T"]], Lazy([function])],[[["I"],["F","E","E","L"]], Lazy([function])],[[["W","H","Y"],["D","O","N","'","T"],["Y","O","U"]], Lazy([function])],[[["W","H","Y"],["C","A","N","'","T"],["I"]], Lazy([function])],[[["A","R","E"],["Y","O","U"]], Lazy([function])],[[["I"],["C","A","N","'","T"]], Lazy([function])],[[["I"],["A","M"]], Lazy([function])],[[["I","'","M"]], Lazy([function])],[[["Y","O","U"]], Lazy([function])],[[["Y","E","S"]], Lazy([function])],[[["N","O"]], Lazy([function])],[[["C","O","M","P","U","T","E","R"]], Lazy([function])],[[["C","O","M","P","U","T","E","R","S"]], Lazy([function])],[[["I"],["W","A","N","T"]], Lazy([function])],[[["W","H","A","T"]], Lazy([function])],[[["H","O","W"]], Lazy([function])],[[["W","H","O"]], Lazy([function])],[[["W","H","E","R","E"]], Lazy([function])],[[["W","H","E","N"]], Lazy([function])],[[["N","A","M","E"]], Lazy([function])],[[["W","H","Y"]], Lazy([function])],[[["C","A","U","S","E"]], Lazy([function])],[[["B","E","C","A","U","S","E"]], Lazy([function])],[[["D","R","E","A","M"]], Lazy([function])],[[["S","O","R","R","Y"]], Lazy([function])],[[["H","I"]], Lazy([function])],[[["D","R","E","A","M","S"]], Lazy([function])],[[["M","A","Y","B","E"]], Lazy([function])],[[["H","E","L","L","O"]], Lazy([function])],[[["A","L","W","A","Y","S"]], Lazy([function])],[[["Y","O","U","R"]], Lazy([function])],[[["A","L","I","K","E"]], Lazy([function])],[[["T","H","I","N","K"]], Lazy([function])],[[["F","R","I","E","N","D","S"]], Lazy([function])],[[["F","R","I","E","N","D"]], Lazy([function])],[[], Lazy([function])]], Lazy([function])] + +fun prefix(xxs, yys) = if xxs is + Nil then true + x :: xs and + force(yys) is + LzNil then false + LzCons(y, ys) then listEq(x, y) && prefix(xs, ys) + +fun tails(xs) = lazy of () => + if xs is + Nil then LzNil + xss then LzCons(xss, tails(tail(xss))) + +fun ucase(ls) = map(toUpper, ls) + +val conjugates = + let oneways = [nofibStringToList("me"), nofibStringToList("you")] :: Nil + let bothways = [nofibStringToList("are"), nofibStringToList("am")] :: + [nofibStringToList("we're"), nofibStringToList("was")] :: + [nofibStringToList("you"), nofibStringToList("I")] :: + [nofibStringToList("your"), nofibStringToList("my")] :: + [nofibStringToList("I've"), nofibStringToList("you've")] :: + [nofibStringToList("I'm"), nofibStringToList("you're")] :: + Nil + fun prepare(ls) = map(case { [w, r] then [ucase(w), r] }, ls) + fun lscomp(ls) = if ls is + Nil then Nil + [x, y] :: t then ([x, y] :: [y, x] :: Nil) :: lscomp(t) + prepare(oneways +: concat(lscomp(bothways))) +//│ conjugates = [[["M","E"], ["y","o","u"]],[["A","R","E"], ["a","m"]],[["A","M"], ["a","r","e"]],[["W","E","'","R","E"], ["w","a","s"]],[["W","A","S"], ["w","e","'","r","e"]],[["Y","O","U"], ["I"]],[["I"], ["y","o","u"]],[["Y","O","U","R"], ["m","y"]],[["M","Y"], ["y","o","u","r"]],[["I","'","V","E"], ["y","o","u","'","v","e"]],[["Y","O","U","'","V","E"], ["I","'","v","e"]],[["I","'","M"], ["y","o","u","'","r","e"]],[["Y","O","U","'","R","E"], ["I","'","m"]]] + +fun conjug(d, w) = + fun maybe(d, xs) = if null_(xs) then d else xs + fun conj(w) = + fun lscomp(ls) = if ls is + Nil then Nil + [w_, m] :: t and + listEq(ucase(w), w_) then m :: lscomp(t) + else lscomp(t) + head(lscomp(conjugates) +: w :: Nil) + fun trailingI(ls) = + fun cons(x, xs) = + if listEq(x, nofibStringToList("I")) && null_(xs) + then nofibStringToList("me") :: Nil + else x :: xs + foldr(cons, Nil, ls) + unwords(trailingI(map(conj, maybe(d, w)))) + +fun replies(key, l) = + map_lz of + x => conjug(l, drop(listLen(key), x)) + filter_lz of + ls => prefix(key, lz_map(ucase, ls)) + tails(l) + +fun answer(st, l) = + fun cons(e, r_es) = if r_es is [r, es] then [r, e :: es] + fun ans(e_es, l) = if e_es is + [key, a_as] :: es and force(a_as) is LzCons(a, as_) then + let rs = replies(key, l) + if null_lz(rs) + then cons([key, a_as], ans(es, l)) + else [makeResponse(a, head_lz(rs)), [key, as_] :: es] + if ans(keyTabOf(st), l) is [response, kt] then [response, newKeyTab(kt, st)] + +fun session(rs, prev, ls) = if ls is + Nil then Nil + l :: ls and + (if listEqBy(listEq, prev, l) then repeated(rs) else answer(rs, l)) is [response, rs_] then + response +: nofibStringToList("\n\n") +: session(rs_, l, ls) + +fun testEliza_nofib(n) = + let input = + nofibStringToList("Are we alone?") :: + nofibStringToList("That the Roswell event was actually an alien encounter. Do you agreed?") :: + nofibStringToList("But why not talk about you, its more fun.") :: + nofibStringToList("I dont ask, you do") :: + nofibStringToList("do ray me") :: + nofibStringToList("Nop, thats because your a computer") :: + nofibStringToList("you dont") :: + nofibStringToList("Oh, a paranoid computer, ehh?") :: + nofibStringToList("Tell me about *your* mother") :: + nofibStringToList("No, what what was she like?") :: + nofibStringToList("I'm asking questions, not you") :: + nofibStringToList("no") :: + nofibStringToList("yes") :: + nofibStringToList("but I'm not") :: + Nil + map of + i => session of + initial + Nil + filter of + x => not(null_(x)) + map(x => words(trim(x)), take(intMod(i, 20), input)) + enumFromTo(1, n) + +fun main() = map(x => nofibListToString(x), testEliza_nofib(20)).toString() +//│ = "[\"I'm not sure I understand you fully.\\n\\n\",\"I'm not sure I understand you fully.\\n\\nWe were discussing you --not me.\\n\\n\",\"I'm not sure I understand you fully.\\n\\nWe were discussing you --not me.\\n\\nWhy do you ask?\\n\\n\",\"I'm not sure I understand you fully.\\n\\nWe were discussing you --not me.\\n\\nWhy do you ask?\\n\\nOh, do?\\n\\n\",\"I'm not sure I understand you fully.\\n\\nWe were discussing you --not me.\\n\\nWhy do you ask?\\n\\nOh, do?\\n\\nWhat does that suggest to you?\\n\\n\",\"I'm not sure I understand you fully.\\n\\nWe were discussing you --not me.\\n\\nWhy do you ask?\\n\\nOh, do?\\n\\nWhat does that suggest to you?\\n\\nDo computers worry you?\\n\\n\",\"I'm not sure I understand you fully.\\n\\nWe were discussing you --not me.\\n\\nWhy do you ask?\\n\\nOh, do?\\n\\nWhat does that suggest to you?\\n\\nDo computers worry you?\\n\\nYou're not really talking about me, are you?\\n\\n\",\"I'm not sure I understand you fully.\\n\\nWe were discussing you --not me.\\n\\nWhy do you ask?\\n\\nOh, do?\\n\\nWhat does that suggest to you?\\n\\nDo computers worry you?\\n\\nYou're not really talking about me, are you?\\n\\nI see.\\n\\n\",\"I'm not sure I understand you fully.\\n\\nWe were discussing you --not me.\\n\\nWhy do you ask?\\n\\nOh, do?\\n\\nWhat does that suggest to you?\\n\\nDo computers worry you?\\n\\nYou're not really talking about me, are you?\\n\\nI see.\\n\\nCan you elaborate on that?\\n\\n\",\"I'm not sure I understand you fully.\\n\\nWe were discussing you --not me.\\n\\nWhy do you ask?\\n\\nOh, do?\\n\\nWhat does that suggest to you?\\n\\nDo computers worry you?\\n\\nYou're not really talking about me, are you?\\n\\nI see.\\n\\nCan you elaborate on that?\\n\\nWhy do you ask?\\n\\n\",\"I'm not sure I understand you fully.\\n\\nWe were discussing you --not me.\\n\\nWhy do you ask?\\n\\nOh, do?\\n\\nWhat does that suggest to you?\\n\\nDo computers worry you?\\n\\nYou're not really talking about me, are you?\\n\\nI see.\\n\\nCan you elaborate on that?\\n\\nWhy do you ask?\\n\\nDid you come to me because you are asking questions, not me?\\n\\n\",\"I'm not sure I understand you fully.\\n\\nWe were discussing you --not me.\\n\\nWhy do you ask?\\n\\nOh, do?\\n\\nWhat does that suggest to you?\\n\\nDo computers worry you?\\n\\nYou're not really talking about me, are you?\\n\\nI see.\\n\\nCan you elaborate on that?\\n\\nWhy do you ask?\\n\\nDid you come to me because you are asking questions, not me?\\n\\nAre you saying no just to be negative?\\n\\n\",\"I'm not sure I understand you fully.\\n\\nWe were discussing you --not me.\\n\\nWhy do you ask?\\n\\nOh, do?\\n\\nWhat does that suggest to you?\\n\\nDo computers worry you?\\n\\nYou're not really talking about me, are you?\\n\\nI see.\\n\\nCan you elaborate on that?\\n\\nWhy do you ask?\\n\\nDid you come to me because you are asking questions, not me?\\n\\nAre you saying no just to be negative?\\n\\nYou seem quite positive.\\n\\n\",\"I'm not sure I understand you fully.\\n\\nWe were discussing you --not me.\\n\\nWhy do you ask?\\n\\nOh, do?\\n\\nWhat does that suggest to you?\\n\\nDo computers worry you?\\n\\nYou're not really talking about me, are you?\\n\\nI see.\\n\\nCan you elaborate on that?\\n\\nWhy do you ask?\\n\\nDid you come to me because you are asking questions, not me?\\n\\nAre you saying no just to be negative?\\n\\nYou seem quite positive.\\n\\nHow long have you been not?\\n\\n\",\"I'm not sure I understand you fully.\\n\\nWe were discussing you --not me.\\n\\nWhy do you ask?\\n\\nOh, do?\\n\\nWhat does that suggest to you?\\n\\nDo computers worry you?\\n\\nYou're not really talking about me, are you?\\n\\nI see.\\n\\nCan you elaborate on that?\\n\\nWhy do you ask?\\n\\nDid you come to me because you are asking questions, not me?\\n\\nAre you saying no just to be negative?\\n\\nYou seem quite positive.\\n\\nHow long have you been not?\\n\\n\",\"I'm not sure I understand you fully.\\n\\nWe were discussing you --not me.\\n\\nWhy do you ask?\\n\\nOh, do?\\n\\nWhat does that suggest to you?\\n\\nDo computers worry you?\\n\\nYou're not really talking about me, are you?\\n\\nI see.\\n\\nCan you elaborate on that?\\n\\nWhy do you ask?\\n\\nDid you come to me because you are asking questions, not me?\\n\\nAre you saying no just to be negative?\\n\\nYou seem quite positive.\\n\\nHow long have you been not?\\n\\n\",\"I'm not sure I understand you fully.\\n\\nWe were discussing you --not me.\\n\\nWhy do you ask?\\n\\nOh, do?\\n\\nWhat does that suggest to you?\\n\\nDo computers worry you?\\n\\nYou're not really talking about me, are you?\\n\\nI see.\\n\\nCan you elaborate on that?\\n\\nWhy do you ask?\\n\\nDid you come to me because you are asking questions, not me?\\n\\nAre you saying no just to be negative?\\n\\nYou seem quite positive.\\n\\nHow long have you been not?\\n\\n\",\"I'm not sure I understand you fully.\\n\\nWe were discussing you --not me.\\n\\nWhy do you ask?\\n\\nOh, do?\\n\\nWhat does that suggest to you?\\n\\nDo computers worry you?\\n\\nYou're not really talking about me, are you?\\n\\nI see.\\n\\nCan you elaborate on that?\\n\\nWhy do you ask?\\n\\nDid you come to me because you are asking questions, not me?\\n\\nAre you saying no just to be negative?\\n\\nYou seem quite positive.\\n\\nHow long have you been not?\\n\\n\",\"I'm not sure I understand you fully.\\n\\nWe were discussing you --not me.\\n\\nWhy do you ask?\\n\\nOh, do?\\n\\nWhat does that suggest to you?\\n\\nDo computers worry you?\\n\\nYou're not really talking about me, are you?\\n\\nI see.\\n\\nCan you elaborate on that?\\n\\nWhy do you ask?\\n\\nDid you come to me because you are asking questions, not me?\\n\\nAre you saying no just to be negative?\\n\\nYou seem quite positive.\\n\\nHow long have you been not?\\n\\n\",\"\"]" diff --git a/benchmark/src/nofib/fish.mls b/benchmark/src/nofib/fish.mls new file mode 100644 index 000000000..288dba7bd --- /dev/null +++ b/benchmark/src/nofib/fish.mls @@ -0,0 +1,167 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module fish with ... + + +fun vec_add(v1, v2) = if v1 is [x1, y1] and v2 is [x2, y2] then [x1 + x2, y1 + y2] + +fun vec_sub(v1, v2) = if v1 is [x1, y1] and v2 is [x2, y2] then [x1 - x2, y1 - y2] + +fun scale_vec2(v, a, b) = if v is [x, y] then [intDiv(x * a, b), intDiv(y * a, b)] + +val p_tile = + [0, 3, 3, 4] :: [3, 4, 0, 8] :: [0, 8, 0, 3] :: [6, 0, 4, 4] :: [4, 5, 4, 10] :: + [4, 10, 7, 6] :: [7, 6, 4, 5] :: [11, 0, 10, 4] :: [10, 4, 9, 6] :: [9, 6, 8, 8] :: [8, 8, 4, 13] :: + [4, 13, 0, 16] :: [0, 16, 6, 15] :: [6, 15, 8, 16] :: [8, 16, 12, 12] :: [12, 12, 16, 12] :: + [10, 16, 12, 14] :: [12, 14, 16, 13] :: [12, 16, 13, 15] :: [13, 15, 16, 14] :: [14, 16, 16, 15] :: + [8, 12, 16, 10] :: [8, 8, 12, 9] :: [12, 9, 16, 8] :: [9, 6, 12, 7] :: [12, 7, 16, 6] :: + [10, 4, 13, 5] :: [13, 5, 16, 4] :: [11, 0, 14, 2] :: [14, 2, 16, 2] :: Nil +//│ p_tile = [[0, 3, 3, 4],[3, 4, 0, 8],[0, 8, 0, 3],[6, 0, 4, 4],[4, 5, 4, 10],[4, 10, 7, 6],[7, 6, 4, 5],[11, 0, 10, 4],[10, 4, 9, 6],[9, 6, 8, 8],[8, 8, 4, 13],[4, 13, 0, 16],[0, 16, 6, 15],[6, 15, 8, 16],[8, 16, 12, 12],[12, 12, 16, 12],[10, 16, 12, 14],[12, 14, 16, 13],[12, 16, 13, 15],[13, 15, 16, 14],[14, 16, 16, 15],[8, 12, 16, 10],[8, 8, 12, 9],[12, 9, 16, 8],[9, 6, 12, 7],[12, 7, 16, 6],[10, 4, 13, 5],[13, 5, 16, 4],[11, 0, 14, 2],[14, 2, 16, 2]] + +val q_tile = + [0, 8, 4, 7] :: [4, 7, 6, 7] :: [6, 7, 8, 8] :: [8, 8, 12, 10] :: [12, 10, 16, 16] :: + [0, 12, 3, 13] :: [3, 13, 5, 14] :: [5, 14, 7, 15] :: [7, 15, 8, 16] :: [2, 16, 3, 13] :: + [4, 16, 5, 14] :: [6, 16, 7, 15] :: [0, 10, 7, 11] :: [9, 13, 8, 15] :: [8, 15, 11, 15] :: + [11, 15, 9, 13] :: [10, 10, 8, 12] :: [8, 12, 12, 12] :: [12, 12, 10, 10] :: [2, 0, 4, 5] :: + [4, 5, 4, 7] :: [4, 0, 6, 5] :: [6, 5, 6, 7] :: [6, 0, 8, 5] :: [8, 5, 8, 8] :: + [10, 0, 14, 11] :: [12, 0, 13, 4] :: [13, 4, 16, 8] :: [16, 8, 15, 10] :: [15, 10, 16, 16] :: + [13, 0, 16, 6] :: [14, 0, 16, 4] :: [15, 0, 16, 2] :: [0, 0, 8, 0] :: [12, 0, 16, 0] :: + [0, 0, 0, 8] :: [0, 12, 0, 16] :: Nil +//│ q_tile = [[0, 8, 4, 7],[4, 7, 6, 7],[6, 7, 8, 8],[8, 8, 12, 10],[12, 10, 16, 16],[0, 12, 3, 13],[3, 13, 5, 14],[5, 14, 7, 15],[7, 15, 8, 16],[2, 16, 3, 13],[4, 16, 5, 14],[6, 16, 7, 15],[0, 10, 7, 11],[9, 13, 8, 15],[8, 15, 11, 15],[11, 15, 9, 13],[10, 10, 8, 12],[8, 12, 12, 12],[12, 12, 10, 10],[2, 0, 4, 5],[4, 5, 4, 7],[4, 0, 6, 5],[6, 5, 6, 7],[6, 0, 8, 5],[8, 5, 8, 8],[10, 0, 14, 11],[12, 0, 13, 4],[13, 4, 16, 8],[16, 8, 15, 10],[15, 10, 16, 16],[13, 0, 16, 6],[14, 0, 16, 4],[15, 0, 16, 2],[0, 0, 8, 0],[12, 0, 16, 0],[0, 0, 0, 8],[0, 12, 0, 16]] + +val r_tile = + [0, 0, 8, 8] :: [12, 12, 16, 16] :: [0, 4, 5, 10] :: [0, 8, 2, 12] :: [0, 12, 1, 14] :: + [16, 6, 11, 10] :: [11, 10, 6, 16] :: [16, 4, 14, 6] :: [14, 6, 8, 8] :: [8, 8, 5, 10] :: + [5, 10, 2, 12] :: [2, 12, 0, 16] :: [16, 8, 12, 12] :: [12, 12, 11, 16] :: [1, 1, 4, 0] :: + [2, 2, 8, 0] :: [3, 3, 8, 2] :: [8, 2, 12, 0] :: [5, 5, 12, 3] :: [12, 3, 16, 0] :: + [11, 16, 12, 12] :: [12, 12, 16, 8] :: [13, 13, 16, 10] :: [14, 14, 16, 12] :: [15, 15, 16, 14] :: Nil +//│ r_tile = [[0, 0, 8, 8],[12, 12, 16, 16],[0, 4, 5, 10],[0, 8, 2, 12],[0, 12, 1, 14],[16, 6, 11, 10],[11, 10, 6, 16],[16, 4, 14, 6],[14, 6, 8, 8],[8, 8, 5, 10],[5, 10, 2, 12],[2, 12, 0, 16],[16, 8, 12, 12],[12, 12, 11, 16],[1, 1, 4, 0],[2, 2, 8, 0],[3, 3, 8, 2],[8, 2, 12, 0],[5, 5, 12, 3],[12, 3, 16, 0],[11, 16, 12, 12],[12, 12, 16, 8],[13, 13, 16, 10],[14, 14, 16, 12],[15, 15, 16, 14]] + +val s_tile = + [0, 0, 4, 2] :: [4, 2, 8, 2] :: [8, 2, 16, 0] :: [0, 4, 2, 1] :: [0, 6, 7, 4] :: + [0, 8, 8, 6] :: [0, 10, 7, 8] :: [0, 12, 7, 10] :: [0, 14, 7, 13] :: [13, 13, 16, 14] :: + [14, 11, 16, 12] :: [15, 9, 16, 10] :: [16, 0, 10, 4] :: [10, 4, 8, 6] :: [8, 6, 7, 8] :: + [7, 8, 7, 13] :: [7, 13, 8, 16] :: [12, 16, 13, 13] :: [13, 13, 14, 11] :: [14, 11, 15, 9] :: + [15, 9, 16, 8] :: [10, 16, 11, 10] :: [12, 4, 10, 6] :: [10, 6, 12, 7] :: [12, 7, 12, 4] :: + [15, 5, 13, 7] :: [13, 7, 15, 8] :: [15, 8, 15, 5] :: Nil +//│ s_tile = [[0, 0, 4, 2],[4, 2, 8, 2],[8, 2, 16, 0],[0, 4, 2, 1],[0, 6, 7, 4],[0, 8, 8, 6],[0, 10, 7, 8],[0, 12, 7, 10],[0, 14, 7, 13],[13, 13, 16, 14],[14, 11, 16, 12],[15, 9, 16, 10],[16, 0, 10, 4],[10, 4, 8, 6],[8, 6, 7, 8],[7, 8, 7, 13],[7, 13, 8, 16],[12, 16, 13, 13],[13, 13, 14, 11],[14, 11, 15, 9],[15, 9, 16, 8],[10, 16, 11, 10],[12, 4, 10, 6],[10, 6, 12, 7],[12, 7, 12, 4],[15, 5, 13, 7],[13, 7, 15, 8],[15, 8, 15, 5]] + +fun nil(a, b, c) = Nil + +fun tup2(a_b, c_d) = if a_b is [a, b] and c_d is [c, d] then [a, b, c, d] + +fun grid(m, n, segments, a, b, c) = + fun lscomp(ls) = if ls is + Nil then Nil + [x0, y0, x1, y1] :: t then + tup2( + vec_add(vec_add(a, scale_vec2(b, x0, m)), scale_vec2(c, y0, n)), + vec_add(vec_add(a, scale_vec2(b, x1, m)), scale_vec2(c, y1, n)) + ) :: + lscomp(t) + lscomp(segments) + +fun rot(p, a, b, c) = p(vec_add(a, b), c, vec_sub([0, 0], b)) + +fun beside(m, n, p, q, a, b, c) = + p(a, scale_vec2(b, m, m + n), c) +: + q(vec_add(a, scale_vec2(b, m, m + n)), scale_vec2(b, n, n + m), c) + +fun above(m, n, p, q, a, b, c) = + p(vec_add(a, scale_vec2(c, n, m + n)), b, scale_vec2(c, m, n + m)) +: + q(a, b, scale_vec2(c, n, m + n)) + +fun tile_to_grid(arg, arg2, arg3, arg4) = grid(16, 16, arg, arg2, arg3, arg4) + +fun p(arg, q6, q7) = tile_to_grid(p_tile, arg, q6, q7) + +fun q(arg, q6, q7) = tile_to_grid(q_tile, arg, q6, q7) + +fun r(arg, q6, q7) = tile_to_grid(r_tile, arg, q6, q7) + +fun s(arg, q6, q7) = tile_to_grid(s_tile, arg, q6, q7) + +fun quartet(a, b, c, d, arg, a6, a7) = + above of + 1 + 1 + (p5, p6, p7) => beside(1, 1, a, b, p5, p6, p7) + (p5, p6, p7) => beside(1, 1, c, d, p5, p6, p7) + arg + a6 + a7 + +fun t(arg, q6, q7) = quartet(p, q, r, s, arg, q6, q7) + +fun cycle_(p1, arg, p3, p4) = + quartet of + p1 + (a, b, c) => rot of + (a, b, c) => rot of + (a, b, c) => rot(p1, a, b, c) + a + b + c + a + b + c + (a, b, c) => rot(p1, a, b, c) + (a, b, c) => rot of + (a, b, c) => rot(p1, a, b, c) + a + b + c + arg + p3 + p4 + +fun u(arg, p2, p3) = cycle_((a, b, c) => rot(q, a, b, c), arg, p2, p3) + +fun side1(arg, q6, q7) = quartet(nil, nil, (a, b, c) => rot(t, a, b, c), t, arg, q6, q7) + +fun side2(arg, q6, q7) = quartet(side1, side1, (a, b, c) => rot(t, a, b, c), t, arg, q6, q7) + +fun corner1(arg, q6, q7) = quartet(nil, nil, nil, u, arg, q6, q7) + +fun corner2(arg, q6, q7) = quartet(corner1, side1, (a, b, c) => rot(side1, a, b, c), u, arg, q6, q7) + +fun pseudocorner(arg, q6, q7) = quartet(corner2, side2, (a, b, c) => rot(side2, a, b, c), (a, b, c) => rot(t, a, b, c), arg, q6, q7) + +fun pseudolimit(arg, p2, p3) = cycle_(pseudocorner, arg, p2, p3) + +fun showFourTupleofInt(a_b_c_d) = if a_b_c_d is [a, b, c, d] then + nofibStringToList("(") +: + nofibStringToList(stringOfInt(a)) +: + nofibStringToList(",") +: + nofibStringToList(stringOfInt(b)) +: + nofibStringToList(",") +: + nofibStringToList(stringOfInt(c)) +: + nofibStringToList(",") +: + nofibStringToList(stringOfInt(d)) + +fun fmt(ls) = if ls is + Nil then nofibStringToList("[]") + x :: xs then + fun showl(ls, s) = if ls is + Nil then "]" :: s + x :: xs then + nofibStringToList(",|") +: + showFourTupleofInt(x) +: + showl(xs, s) + nofibStringToList("[|") +: + showFourTupleofInt(x) +: + showl(xs, "") + +fun testFish_nofib(n) = + map of + i => let n = min(0, i) in (pseudolimit([0, 0], [640 + n, 0], [0, 640 + n])), + enumFromTo(0, n) + +fun main() = testFish_nofib(1) + + +//│ ═══[RUNTIME ERROR] RangeError: Maximum call stack size exceeded diff --git a/benchmark/src/nofib/gcd.mls b/benchmark/src/nofib/gcd.mls new file mode 100644 index 000000000..e07ef2d58 --- /dev/null +++ b/benchmark/src/nofib/gcd.mls @@ -0,0 +1,53 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module gcd with ... + + + +fun g(u1u2u3, v1v2v3) = if u1u2u3 is [u1, u2, u3] and v1v2v3 is [v1, v2, v3] then + if + v3 == 0 then [u3, u1, u2] + else if + quotRem(u3, v3) is [q, r] then + g([v1, v2, v3], [u1 - (q * v1), u2 - (q * v2), r]) + +fun gcdE(x, y) = if + x == 0 then [y, 0, 1] + else g([1, 0, x], [0, 1, y]) + +fun max_(ls) = if ls is + x :: Nil then x + x :: y :: xs then if x < y then max_(y :: xs) else max_(x :: xs) + +fun test(d) = + let ns = enumFromTo(5000, 5000 + d) + + let ms = enumFromTo(10000, 10000 + d) + + fun lscomp1(p1) = if p1 is + Nil then Nil + h1 :: t1 then + fun lscomp2(p2) = if p2 is + Nil then lscomp1(t1) + h2 :: t2 then [h1, h2] :: lscomp2(t2) + lscomp2(ms) + + let tripls = + map(case { [x, y] then [x, y, gcdE(x, y)] }, lscomp1(ns)) + + let rs = map(case { [d1, d2, [gg, u, v]] then abs(gg + u + v) }, tripls) + + max_(rs) + + +fun testGcd_nofib(x) = test(x) + + + +// NOTE: original input 400 +fun main() = testGcd_nofib(40) +//│ = 5021 diff --git a/benchmark/src/nofib/integer.mls b/benchmark/src/nofib/integer.mls new file mode 100644 index 000000000..4d62ab738 --- /dev/null +++ b/benchmark/src/nofib/integer.mls @@ -0,0 +1,65 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module integer with ... + + + +fun integerbench(op, astart, astep, alim, bstart, bstep, blim) = + fun lscomp1(ls) = if ls is + Nil then Nil + a :: t1 then + fun lscomp2(ls) = if ls is + Nil then lscomp1(t1) + b :: t2 then op(a, b) :: lscomp2(t2) + lscomp2(enumFromThenTo(bstart, bstart + bstep, blim)) + + lscomp1(enumFromThenTo(astart, astart + astep, alim)) + +fun intbench(op, astart, astep, alim, bstart, bstep, blim) = + fun lscomp1(ls) = if ls is + Nil then Nil + a :: t1 then + fun lscomp2(ls) = if ls is + Nil then lscomp1(t1) + b :: t2 then op(a, b) :: lscomp2(t2) + lscomp2(enumFromThenTo(bstart, bstart + bstep, blim)) + + lscomp1(enumFromThenTo(astart, astart + astep, alim)) + +fun runbench(jop, iop, opstr, astart, astep, alim, bstart, bstep, blim) = + intbench(iop, astart, astep, alim, astart, astep, alim); + integerbench(jop, astart, astep, alim, astart, astep, alim) + +fun runalltests(astart, astep, alim, bstart, bstep, blim) = + fun z_add(a, b) = a + b + fun z_sub(a, b) = a - b + fun z_mul(a, b) = a * b + fun z_div(a, b) = intDiv(a, b) + fun z_mod(a, b) = intMod(a, b) + fun z_equal(a, b) = a == b + fun z_lt(a, b) = a < b + fun z_leq(a, b) = a <= b + fun z_gt(a, b) = a > b + fun z_geq(a, b) = a >= b + + runbench((a, b) => z_add(a, b), (a, b) => a + b, "(+)", astart, astep, alim, astart, astep, alim); + runbench((a, b) => z_sub(a, b), (a, b) => a - b, "(-)", astart, astep, alim, astart, astep, alim); + runbench((a, b) => z_mul(a, b), (a, b) => a * b, "(*)", astart, astep, alim, astart, astep, alim); + runbench((a, b) => z_div(a, b), (a, b) => intDiv(a, b), "div", astart, astep, alim, astart, astep, alim); + runbench((a, b) => z_mod(a, b), (a, b) => intMod(a, b), "mod", astart, astep, alim, astart, astep, alim); + runbench((a, b) => z_equal(a, b), (a, b) => a == b, "(==)", astart, astep, alim, astart, astep, alim); + runbench((a, b) => z_lt(a, b), (a, b) => a < b, "(<)", astart, astep, alim, astart, astep, alim); + runbench((a, b) => z_leq(a, b), (a, b) => a <= b, "(<=)", astart, astep, alim, astart, astep, alim); + runbench((a, b) => z_gt(a, b), (a, b) => a > b, "(>)", astart, astep, alim, astart, astep, alim); + runbench((a, b) => z_geq(a, b), (a, b) => a >= b, "(>=)", astart, astep, alim, astart, astep, alim) + +fun testInteger_nofib(n) = runalltests(-2100000000, n, 2100000000, -2100000000, n, -2100000000) + + +// NOTE: original input -2100000000 14000001 2100000000 +fun main() = testInteger_nofib(700000001).toString() +//│ = "[true,false,false,false,false,false,true,true,false,false,false,false,true,true,true,false,false,false,true,true,true,true,false,false,true,true,true,true,true,false,true,true,true,true,true,true]" diff --git a/benchmark/src/nofib/knights.mls b/benchmark/src/nofib/knights.mls new file mode 100644 index 000000000..84505d69c --- /dev/null +++ b/benchmark/src/nofib/knights.mls @@ -0,0 +1,292 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module knights with ... + + +fun myIsDigit(c) = + c.codePointAt(0) >= 48 && c.codePointAt(0) <= 57 + +fun intintComp(a_b, c_d) = if a_b is [a, b] and c_d is [c, d] then (a < c) || ((a === c) && (b < d)) + +fun intChessSetComp(a_b, c_d) = if a_b is [a, b] and c_d is [c, d] then a < c + +fun myInit(a_t) = if a_t is + a :: Nil then Nil + a :: t then a :: myInit(t) + +fun myLast(a_t) = + fun go(h, t) = if t is + Nil then h + head :: t then go(head, t) + if a_t is a :: t then go(a, t) + +fun quickSortIntInt(xs) = if xs is + Nil then Nil + x :: xs then + fun lscomp1(ls) = if ls is + Nil then Nil + h :: t and + intintComp(h, x) then h :: lscomp1(t) + else lscomp1(t) + fun lscomp2(ls) = if ls is + Nil then Nil + h :: t and + not(intintComp(h, x)) then h :: lscomp2(t) + else lscomp2(t) + quickSortIntInt(lscomp1(xs)) +: (x :: quickSortIntInt(lscomp2(xs))) + +fun quickSortIntChessSet(xs) = if force(xs) is + LzNil then lazy of () => LzNil + LzCons(x, xs) then + fun lscomp1(ls) = if force(ls) is + LzNil then lazy of () => LzNil + LzCons(h, t) and + intChessSetComp(h, x) then lazy of () => LzCons(h, lscomp1(t)) + else lscomp1(t) + fun lscomp2(ls) = if force(ls) is + LzNil then lazy of () => LzNil + LzCons(h, t) and + not(intChessSetComp(h, x)) then lazy of () => LzCons(h, lscomp2(t)) + else lscomp2(t) + append_lz_lz(quickSortIntChessSet(lscomp1(xs)), lazy of () => LzCons(x, quickSortIntChessSet(lscomp2(xs)))) + +fun sizeQueue(xs) = listLen(xs) + +fun emptyQueue(x) = listEq(x, Nil) + +fun removeBack(xs) = if xs is + x :: Nil then Nil + x :: xs then x :: removeBack(xs) + +fun removeFront(xs) = if xs is + h :: t then t + +fun inquireBack(xs) = if xs is + x :: Nil then x + x :: xs then inquireBack(xs) + +fun inquireFront(h_t) = head(h_t) + +fun addAllBack(list, q) = q +: list + +fun addAllFront(list, q) = list +: q + +fun addBack(x, q) = q +: (x :: Nil) + +fun addFront(x, q) = x :: q + +val createQueue = Nil +//│ createQueue = [] + +data class Board(a: Int, b: Int, c: Lazy[[Int, Int]], d: List[[Int, Int]]) + +fun createBoard(x, t) = Board(x, 1, (lazy of (() => t)), t :: Nil) + +fun sizeBoard(b) = if b is Board(a, _, _, _) then a + +fun noPieces(b) = if b is Board(_, n, _, _) then n + +fun addPiece(t, b) = if b is Board(s, n, f, ts) then Board(s, n + 1, f, t :: ts) + +fun deleteFirst(b) = if b is Board(s, n, f, ts) then + let ts_ = myInit(ts) + Board(s, n - 1, (lazy of () => myLast(ts_)), ts_) + +fun positionPiece(x, b) = if b is Board(_, n, _, ts) then atIndex(n - x, ts) + +fun lastPiece(b) = if b is Board(_, _, _, t :: ts) then t + +fun firstPiece(b) = if b is Board(_, _, f, _) then force(f) + +fun pieceAtTile(x, b) = if b is Board(_, _, _, ts) then + fun find(x, xs) = if xs is + Nil then throw Error("Tile not used") + y :: xs then if eqTup2(x, y) then 1 + listLen(xs) else find(x, xs) + find(x, ts) + +fun tup2InList(y, xs) = if xs is + Nil then false + x :: xs and + eqTup2(y, x) then true + else tup2InList(y, xs) + +fun isSquareFree(x, b) = if b is Board(_, _, _, ts) then not(tup2InList(x, ts)) + +fun assignMoveNo(t, size, z) = if t is + Nil then Nil + [x, y] :: t then [(y - 1) * size + x, z] :: assignMoveNo(t, size, z - 1) + +fun spaces(s, y) = + fun logTen(x) = if x === 0 then 0 else 1 + logTen(intDiv(x, 10)) + replicate((logTen(s) - logTen(y)) + 1, " ") + +fun printBoard(s, n, xs) = if xs is + Nil and + n > s * s then Nil + intMod(n, s) != 0 then "*" :: (spaces(s * s, 1) +: printBoard(s, n + 1, Nil)) + intMod(n, s) === 0 then nofibStringToList("*\n") +: printBoard(s, n + 1, Nil) + else throw Error("printBoard empty list error") + [i, j] :: xs and + i === n and intMod(n, s) === 0 then nofibStringToList(stringOfInt(j)) +: nofibStringToList("\n") +: printBoard(s, n + 1, xs) + i === n and intMod(n, s) != 0 then nofibStringToList(stringOfInt(j)) +: spaces(s * s, j) +: printBoard(s, n + 1, xs) + intMod(n, s) != 0 then "*" :: (spaces(s * s, 1) +: printBoard(s, n + 1, [i, j] :: xs)) + intMod(n, s) === 0 then nofibStringToList("*\n") +: printBoard(s, n + 1, [i, j] :: xs) + else throw Error("printBoard non-empty list error") + +abstract class Direction: UL | UR | DL | DR | LU | LD | RU | RD + +object + UL extends Direction + UR extends Direction + DL extends Direction + DR extends Direction + LU extends Direction + LD extends Direction + RU extends Direction + RD extends Direction + +fun move(d, x_y) = if x_y is [x, y] and d is + UL then [x - 1, y - 2] + UR then [x + 1, y - 2] + DL then [x - 1, y + 2] + DR then [x + 1, y + 2] + LU then [x - 2, y - 1] + LD then [x - 2, y + 1] + RU then [x + 2, y - 1] + RD then [x + 2, y + 1] + +fun startTour(st, size) = + if intMod(size, 2) === 0 then createBoard(size, st) + else throw Error("Tour doesnt exist for odd size board") + +fun moveKnight(board, dir) = addPiece(move(dir, lastPiece(board)), board) + +fun canMoveTo(x_y, board) = if x_y is [x, y] then + let sze = sizeBoard(board) + let res = (x >= 1) and (x <= sze) and (y >= 1) and (y <= sze) and (isSquareFree(x_y, board)) + res + +fun canMove(board, dir) = canMoveTo(move(dir, lastPiece(board)), board) + +fun canJumpFirst(board) = canMoveTo(firstPiece(board), deleteFirst(board)) + +fun tourFinished(board) = + let sze = sizeBoard(board) + (noPieces(board) === (sze * sze)) && canJumpFirst(board) + +fun possibleMoves(board) = + fun lscomp(ls) = if ls is + Nil then Nil + x :: t and + canMove(board, x) then x :: lscomp(t) + else lscomp(t) + let res = lscomp(UL :: UR :: DL :: DR :: LU :: LD :: RU :: RD :: Nil) + res + +fun deadEnd(board) = listLen(possibleMoves(board)) === 0 + +fun allDescend(board) = map(b => moveKnight(board, b), possibleMoves(board)) + +fun descAndNo(board) = + fun lscomp(ls) = if ls is + Nil then lazy of () => LzNil + x :: t then lazy of () => LzCons([listLen(possibleMoves(deleteFirst(x))), x], lscomp(t)) + lscomp(allDescend(board)) + +fun singleDescend(board) = + fun lscomp(ls) = if force(ls) is + LzNil then Nil + LzCons([y, x], t) and + y === 1 then x :: lscomp(t) + else lscomp(t) + lscomp(descAndNo(board)) + +fun descendents(board) = + if canJumpFirst(board) && deadEnd(addPiece(firstPiece(board), board)) then lazy of () => LzNil + else + let singles = singleDescend(board) + let scrut = listLen(singles) + let res = if scrut === + 0 then map_lz(snd, quickSortIntChessSet(descAndNo(board))) + 1 then if singles is h :: Nil then lazy of () => LzCons(h, lazy of () => LzNil) else throw Error("unreachable") + else lazy of () => LzNil + res + + +fun showChessSet(b) = if b is Board(sze, n, f, ts) then + let sortedTrail = quickSortIntInt(assignMoveNo(ts, sze, n)) + printBoard(sze, 1, sortedTrail) + +fun root(sze) = + fun lscomp1(ls) = if ls is + Nil then lazy of () => LzNil + h1 :: t1 then + fun lscomp2(ls) = if ls is + Nil then lscomp1(t1) + h2 :: t2 then lazy of () => LzCons([h1, h2], lscomp2(t2)) + lscomp2(enumFromTo(1, sze)) + append_lz_lz( + zip_lz_lz( + repeat(1 - (sze * sze)), + zipWith_lz_lz(startTour, lscomp1(enumFromTo(1, sze)), replicate_lz(sze * sze, sze)) + ), + lazy of () => LzNil + ) + +fun grow(x_y) = if x_y is [x, y] then zip_lz_lz(repeat(x + 1), descendents(y)) + +fun isFinished(x_y) = if x_y is [x, y] then tourFinished(y) + +fun emptyQueue_lz(x) = force(x) is LzNil + +fun removeFront_lz(xs) = if force(xs) is LzCons(h, t) then t + +fun inquireFront_lz(h_t) = if force(h_t) is LzCons(h, t) then h + +fun addAllFront_lz(list, q) = append_lz_lz(list, q) + +fun depthSearch(q, growFn, finFn) = + if + emptyQueue_lz(q) then lazy of () => LzNil + finFn(inquireFront_lz(q)) then lazy of () => LzCons(inquireFront_lz(q), depthSearch(removeFront_lz(q), growFn, finFn)) + else depthSearch(addAllFront_lz(growFn(inquireFront_lz(q)), removeFront_lz(q)), growFn, finFn) + +fun printTour(ss) = + fun strToInt(y, xs) = if xs is + Nil then y + x :: xs then strToInt((10 * y) + (x.codePointAt(0) - 48), xs) + fun pp(xs) = if xs is + Nil then Nil + [x, y] :: xs then + nofibStringToList("\nKnights tour with ") +: + nofibStringToList(stringOfInt(x)) +: + nofibStringToList(" backtracking moves\n") +: + showChessSet(y) +: + pp(xs) + if map(x => strToInt(0, x), ss) is + size :: number :: Nil then pp(take_lz(number, depthSearch(root(size), grow, isFinished))) + else throw Error("printTour error") + +fun testKnights_nofib(ss) = + let usageString = "\nUsage: knights \n" + fun all_digits(s) = foldr((a, b) => (myIsDigit(a)) && b, true, s) + fun argsOk(ss) = (listLen(ss) === 2) && (foldr((a, b) => (all_digits(a)) && b, true, ss)) + if argsOk(ss) then (printTour(ss)) else throw Error(usageString) + + +fun main() = nofibListToString(testKnights_nofib(nofibStringToList("8") :: nofibStringToList("1") :: Nil)) +//│ > +//│ > Knights tour with 0 backtracking moves +//│ > 1 34 3 18 41 32 13 16 +//│ > 4 19 64 33 14 17 44 31 +//│ > 35 2 37 40 63 42 15 12 +//│ > 20 5 56 47 38 45 30 43 +//│ > 55 36 39 62 57 48 11 26 +//│ > 6 21 52 49 46 27 60 29 +//│ > 51 54 23 8 61 58 25 10 +//│ > 22 7 50 53 24 9 28 59 +//│ > diff --git a/benchmark/src/nofib/lambda.mls b/benchmark/src/nofib/lambda.mls new file mode 100644 index 000000000..29dd13836 --- /dev/null +++ b/benchmark/src/nofib/lambda.mls @@ -0,0 +1,199 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module lambda with ... + + + +fun lookup(k, t) = if t is + Nil then None + [x, v] :: t then if listEq(k, x) then Some(v) else lookup(k, t) + +data class MyState[S, A](r: S -> [S, A]) + +fun myRunState(m, s) = if m is MyState(f) then f(s) + +fun myBind(m, f) = MyState(s => if myRunState(m, s) is [s_, a] then myRunState(f(a), s_)) + +fun myReturn(a) = MyState(s => [s, a]) + +val myGet = MyState(s => [s, s]) +//│ myGet = MyState([function]) + +fun myEvalState(m, s) = if myRunState(m, s) is [s_, a] then a + + +abstract class Term: Var | Con | Incr | Add | Lam | App | IfZero | Thunk + +object Incr extends Term + +data + class + Var(s: String) extends Term + Con(i: Int) extends Term + Add(a: Term, b: Term) extends Term + Lam(s: String, t: Term) extends Term + App(a: Term, b: Term) extends Term + IfZero(a: Term, b: Term, c: Term) extends Term + Thunk(t: Term, e: List[[String, Term]]) extends Term + +object Unit + +//│ ———————————————————————————————————————————————————————————————————————————————— +fun eqEnv(a, b) = if a is + Nil and b is Nil then true + [s1, t1] :: b and b is [s2, t2] :: d and + listEq(s1, s2) and eqTerm(t1, t2) then eqEnv(b, d) + else false + else false + +fun eqTerm(a, b) = if a is + Var(a) and b is Var(b) then listEq(a, b) + Con(a) and b is Con(b) then a === b + Incr and b is Incr then true + Add(a, b) and b is Add(c, d) then eqTerm(a, c) && eqTerm(b, d) + Lam(a, b) and b is Lam(c, d) then listEq(a, c) && eqTerm(b, d) + App(a, b) and b is App(c, d) then eqTerm(a, c) && eqTerm(b, d) + IfZero(a, b, c) and b is IfZero(d, e, f) then eqTerm(a, d) && eqTerm(b, e) && eqTerm(c, f) + Thunk(a, b) and b is Thunk(c, d) then eqTerm(a, c) && eqEnv(b, d) + else false +//│ ———————————————————————————————————————————————————————————————————————————————— + +fun myMaybe(d, f, x) = if x is Some(x) then f(x) + +val incr = myReturn(Unit) +//│ incr = MyState([function]) + +fun lookupVar(v) = + fun lookup2(env) = myMaybe(dummy => throw Error("undefined"), x => x, lookup(v, env)) + myBind(myGet, env => myReturn(lookup2(env))) + +fun withEnv(tmp, m) = myReturn(myEvalState(m, tmp)) + +fun pushVar(v, t, m) = myBind(myGet, env => withEnv([v, t] :: env, m)) + +//│ ———————————————————————————————————————————————————————————————————————————————— +fun traverseTerm(t) = eval(t) + +fun traverseCon(t) = + myBind( + traverseTerm(t), + _t => if _t is Con(c) then myReturn(c) else throw Error("Not a Con") + ) + +fun apply(t, a) = if t is Thunk(Lam(x, b), e) then + myBind( + myGet, + orig => withEnv(e, pushVar(x, Thunk(a, orig), traverseTerm(b))) + ) + +fun eval(ter) = if ter is + Var(x) then + myBind of + myGet + e => myBind(lookupVar(x), t => traverseTerm(t)) + Add(u, v) then + myBind of + traverseCon(u) + u_ => myBind(traverseCon(v), v_ => myReturn(Con(u_ + v_))) + Thunk(t, e) then withEnv(e, traverseTerm(t)) + Lam(x, b) then myBind(myGet, env => myReturn(Thunk(Lam(x, b), env))) + App(u, v) then myBind(traverseTerm(u), u_ => apply(u_, v)) + IfZero(c, a, b) then + myBind of + traverseTerm(c) + vall => if eqTerm(vall, Con(0)) then traverseTerm(a) else traverseTerm(b) + Con(i) then myReturn(Con(i)) + Incr then myBind(incr, _dummy => myReturn(Con(0))) +//│ ———————————————————————————————————————————————————————————————————————————————— + +//│ ———————————————————————————————————————————————————————————————————————————————— +fun simpleEval(env, ter) = if ter is + Var(v) then simpleEval(env, myMaybe(dummy => throw Error("undefined var"), x => x, lookup(v, env))) + Con(e) then Con(e) + Incr then Con(0) + Add(u, v) then + let u_ = simpleEvalCon(env, u) + let v_ = simpleEvalCon(env, v) + Con(u_ + v_) + Lam(x, b) then Thunk(Lam(x, b), env) + App(u, v) then + let u_ = simpleEval(env, u) + simpleApply(env, u_, v) + IfZero(c, a, b) then + let val_ = simpleEval(env, c) + if eqTerm(val_, Con(0)) then simpleEval(env, a) else simpleEval(env, b) + Thunk(t, e) then simpleEval(e, t) + else throw Error(ter) + +fun simpleApply(env, t, a) = if t is + Thunk(Lam(x, b), e) then simpleEval([x, Thunk(a, env)] :: e, b) + else throw Error("bad application") + +fun simpleEvalCon(env, e) = + let e_ = simpleEval(env, e) + if e_ is Con(c) then c else throw Error("Not a Con") +//│ ———————————————————————————————————————————————————————————————————————————————— + +fun bracket(ot, ths, t) = if ths <= ot then "(" :: (t +: nofibStringToList(")")) else t + +//│ ———————————————————————————————————————————————————————————————————————————————— +fun ppn(n, ter) = if ter is + Var(v) then v + Con(i) then nofibStringToList(stringOfInt(i)) + Incr then nofibStringToList("INCR") + Lam(v, t) then bracket(n, 0, "@" :: (v +: nofibStringToList(". ") +: ppn(0-1, t))) + Add(a, b) then bracket(n, 1, ppn(1, a) +: nofibStringToList(" + ") +: ppn(1, b)) + App(a, b) then bracket(n, 2, ppn(2, a) +: nofibStringToList(" ") +: ppn(2, b)) + IfZero(c, a, b) then bracket(n, 0, nofibStringToList("IF ") +: ppn(0, c) +: nofibStringToList(" THEN ") +: ppn(0, a) +: nofibStringToList(" ELSE ") +: ppn(0, b)) + Thunk(t, e) then bracket(n, 0, ppn(3, t) +: nofibStringToList("::") +: ppenv(e)) + +fun pp(t) = ppn(0, t) + +fun ppenv(env) = + nofibStringToList("[") +: + flatMap( + case { [v, t] then v +: nofibStringToList("=") +: pp(t) +: nofibStringToList(", ") } + env + ) +: + nofibStringToList("]") +//│ ———————————————————————————————————————————————————————————————————————————————— + +val lfxx = Lam(nofibStringToList("x"), App(Var(nofibStringToList("F")), App(Var(nofibStringToList("x")), Var(nofibStringToList("x"))))) +//│ lfxx = Lam(["x"], App(Var(["F"]), App(Var(["x"]), Var(["x"])))) + +val fix = Lam(nofibStringToList("F"), App(lfxx, lfxx)) +//│ fix = Lam(["F"], App(Lam(["x"], App(Var(["F"]), App(Var(["x"]), Var(["x"])))), Lam(["x"], App(Var(["F"]), App(Var(["x"]), Var(["x"])))))) + +val nMinus1 = Add(Var(nofibStringToList("n")), Con(-1)) +//│ nMinus1 = Add(Var(["n"]), Con(-1)) + +val partialSum0 = Lam(nofibStringToList("sum"), Lam(nofibStringToList("n"), IfZero(Var(nofibStringToList("n")), Con(0), Add(Var(nofibStringToList("n")), App(Var(nofibStringToList("sum")), nMinus1))))) +//│ partialSum0 = Lam(["s","u","m"], Lam(["n"], IfZero(Var(["n"]), Con(0), Add(Var(["n"]), App(Var(["s","u","m"]), Add(Var(["n"]), Con(-1))))))) + +val sum0 = App(fix, partialSum0) +//│ sum0 = App(Lam(["F"], App(Lam(["x"], App(Var(["F"]), App(Var(["x"]), Var(["x"])))), Lam(["x"], App(Var(["F"]), App(Var(["x"]), Var(["x"])))))), Lam(["s","u","m"], Lam(["n"], IfZero(Var(["n"]), Con(0), Add(Var(["n"]), App(Var(["s","u","m"]), Add(Var(["n"]), Con(-1)))))))) + +fun showTerm(t) = if t is Con(a) then nofibStringToList("Con ") +: nofibStringToList(stringOfInt(a)) + +fun ev(t) = + let envt2 = myRunState(traverseTerm(t), Nil) + if envt2 is [env, t2] then pp(t2) +: nofibStringToList(" ") +: ppenv(env) + +fun mainSimple(args) = + if null_(args) + then throw Error("Args: number-to-sum-up-to") + else showTerm(simpleEval(Nil, App(sum0, Con(head(args))))) + +fun mainMonad(args) = + if null_(args) + then throw Error("Args: number-to-sum-up-to") + else ev(App(sum0, Con(head(args)))) + +fun testLambda_nofib(n) = [mainSimple(n :: Nil), mainMonad(n :: Nil)] + +fun main() = testLambda_nofib(80).toString() +//│ = "[\"C\",\"o\",\"n\",\" \",\"3\",\"2\",\"4\",\"0\"],[\"3\",\"2\",\"4\",\"0\",\" \",\" \",\"[\",\"]\"]" diff --git a/benchmark/src/nofib/lastpiece.mls b/benchmark/src/nofib/lastpiece.mls new file mode 100644 index 000000000..c635f4068 --- /dev/null +++ b/benchmark/src/nofib/lastpiece.mls @@ -0,0 +1,607 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module lastpiece with ... + + + +fun isSome(x) = x is Some + +fun mapMaybe(f, ls) = if ls is + Nil then Nil + h :: t and f(h) is + None then mapMaybe(f, t) + Some(a) then a :: mapMaybe(f, t) + +object + GT + LT + EQ + +fun compareIntInt(ab, cd) = if ab is [a, b] and cd is [c, d] and + a > c then GT + a < c then LT + b > d then GT + b < d then LT + else EQ + +abstract class Map[K, A]: Tip | Bin[K, A] + +object Tip extends Map[Anything, Nothing] + +data class Bin[K, A](i: Int, k: K, v: A, l: Map[K, A], r: Map[K, A]) extends Map[K, A] + +fun mapLookup(k, m) = if m is + Tip then None + Bin(_, kx, x, l, r) and compareIntInt(k, kx) is + LT then mapLookup(k, l) + GT then mapLookup(k, r) + EQ then Some(x) + +fun size(p) = if p is + Tip then 0 + Bin(sz, _, _, _, _) then sz + +fun bin(k, x, l, r) = Bin(size(l) + size(r) + 1, k, x, l, r) + +fun singleL(k1, x1, t1, r) = if r is + Bin(_, k2, x2, t2, t3) then bin(k2, x2, bin(k1, x1, t1, t2), t3) + else throw Error("singleL Tip") + +fun singleR(k1, x1, l, t3) = if l is + Bin(_, k2, x2, t1, t2) then bin(k2, x2, t1, bin(k1, x1, t2, t3)) + else throw Error("singleR Tip") + +fun doubleL(k1, x1, t1, r) = if r is + Bin(_, k2, x2, Bin(_, k3, x3, t2, t3), t4) then bin(k3, x3, bin(k1, x1, t1, t2), bin(k2, x2, t3, t4)) + else throw Error("doubleL Tip") + +fun doubleR(k1, x1, l, t4) = if l is + Bin(_, k2, x2, t1, Bin(_, k3, x3, t2, t3)) then bin(k3, x3, bin(k2, x2, t1, t2), bin(k1, x1, t3, t4)) + else throw Error("doubleR Tip") + +fun rotateL(k, x, l, r) = if r is + Bin(_, _, _, ly, ry) and + size(ly) < 2 * size(ry) then singleL(k, x, l, r) + else doubleL(k, x, l, r) + else throw Error("rotateL Tip") + +fun rotateR(k, x, l, r) = if l is + Bin(_, _, _, ly, ry) and + size(ry) < 2 * size(ly) then singleR(k, x, l, r) + else doubleR(k, x, l, r) + else throw Error("rotateR Tip") + +fun balance(k, x, l, r) = + let sizeL = size(l) + let sizeR = size(r) + let sizeX = sizeL + sizeR + 1 + if + (sizeL + sizeR) <= 1 then Bin(sizeX, k, x, l, r) + sizeR >= (4 * sizeL) then rotateL(k, x, l, r) + sizeL >= (4 * sizeR) then rotateR(k, x, l, r) + else Bin(sizeX, k, x, l, r) + +fun insert(kx, x, m) = if m is + Tip then Bin(1, kx, x, Tip, Tip) + Bin(sz, ky, y, l, r) and compareIntInt(kx, ky) is + LT then balance(ky, y, insert(kx, x, l), r) + GT then balance(ky, y, l, insert(kx, x, r)) + EQ then Bin(sz, kx, x, l, r) + +fun indent(n) = if n <= 0 then Nil else " " :: indent(n - 1) + +data class P(i: Char, a: List[List[[Int, Int]]], b: List[List[[Int, Int]]]) + +abstract class S: Male | Female + +object + Male extends S + Female extends S + +fun flip(s) = if s is + Male then Female + Female then Male + +abstract class Solution: Soln | Choose | Fail + +type Board = Map[[Int, Int], Char] + +data + class + Soln(b: Board) extends Solution + Choose(s: List[Solution]) extends Solution + Fail(b: Board, s: [Int, Int]) extends Solution + +fun addIntInt(row_col, orow_ocol) = if row_col is [row, col] and orow_ocol is [orow, ocol] then + [row + orow, col + ocol] + +fun next(row_col) = if row_col is [row, col] then [row, col + 1] + +val maxRow = 8 +//│ maxRow = 8 + +val maxCol = 8 +//│ maxCol = 8 + +val emptyBoard = Tip +//│ emptyBoard = Tip + +fun check(bd, sq) = mapLookup(sq, bd) + +fun extend(bd, sq, id) = insert(sq, id, bd) + +fun extend_maybe(bd, sq, id) = if sq is [row, col] and + (row > maxRow) || (col < 1) || (col > maxCol) then None + check(bd, sq) is + Some(_) then None + None then Some(extend(bd, sq, id)) + +fun pickOne(xs) = + fun go(f, xs) = if xs is + Nil then Nil + x :: xs then [x, f(xs)] :: go(p => x :: f(p), xs) + go(x => x, xs) + +fun fit(bd, sq, id, os) = if os is + Nil then Some(extend(bd, sq, id)) + o :: os and extend_maybe(bd, addIntInt(sq, o), id) is + Some(bd1) then fit(bd1, sq, id, os) + None then None + +//│ ———————————————————————————————————————————————————————————————————————————————— +fun tryy(sq, se, bd, id_is_ps) = if id_is_ps is [id, os, ps] and fit(bd, sq, id, os) is + Some(bd1) then Some(search(next(sq), flip(se), bd1, ps)) + None then None + +fun search(row_col, sey, bd, ps) = if row_col is [row, col] and + ps is Nil then Soln(bd) + col === (maxCol + 1) then search([row + 1, 1], flip(sey), bd, ps) + check(bd, row_col) is Some(_) then search(next(row_col), flip(sey), bd, ps) + else + fun lscomp1(ls) = if ls is + Nil then Nil + [P(id, ms, fs), ps] :: ls then + fun lscomp2(ls2) = if ls2 is + Nil then lscomp1(ls) + os :: ls then [id, os, ps] :: lscomp2(ls) + lscomp2(if sey is Male then ms else fs) + let choices = lscomp1(pickOne(ps)) + if mapMaybe(x => tryy(row_col, sey, bd, x), choices) is + Nil then Fail(bd, row_col) + ss then Choose(ss) +//│ ———————————————————————————————————————————————————————————————————————————————— + +val nPiece = P( + "n", + ([0,1] :: [1,1] :: [2,1] :: [2,2] :: Nil) :: + ([1,0] :: [1,-1] :: [1,-2] :: [2,-2] :: Nil) :: Nil, + Nil +) +//│ nPiece = P("n", [[[0, 1],[1, 1],[2, 1],[2, 2]],[[1, 0],[1, -1],[1, -2],[2, -2]]], []) + +val mPiece = P( + "m", + ([0,1] :: [1,0] :: [2,0] :: [3,0] :: Nil) :: Nil, + ([0,1] :: [0,2] :: [0,3] :: [1,3] :: Nil) :: + ([1,0] :: [2,0] :: [3,0] :: [3,-1] :: Nil) :: Nil +) +//│ mPiece = P("m", [[[0, 1],[1, 0],[2, 0],[3, 0]]], [[[0, 1],[0, 2],[0, 3],[1, 3]],[[1, 0],[2, 0],[3, 0],[3, -1]]]) + +val lPiece = P( + "l", + ([0,1] :: [0,2] :: [0,3] :: [1,2] :: Nil) :: + ([1,0] :: [2,0] :: [3,0] :: [2,-1] :: Nil) :: Nil, + ([1,-1] :: [1,0] :: [1,1] :: [1,2] :: Nil) :: + ([1,0] :: [2,0] :: [3,0] :: [1,1] :: Nil) :: Nil +) +//│ lPiece = P("l", [[[0, 1],[0, 2],[0, 3],[1, 2]],[[1, 0],[2, 0],[3, 0],[2, -1]]], [[[1, -1],[1, 0],[1, 1],[1, 2]],[[1, 0],[2, 0],[3, 0],[1, 1]]]) + +val kPiece = P( + "k", + ([0,1] :: [1,0] :: [2,0] :: [2,-1] :: Nil) :: Nil, + ([1,0] :: [1,1] :: [1,2] :: [2,2] :: Nil) :: Nil +) +//│ kPiece = P("k", [[[0, 1],[1, 0],[2, 0],[2, -1]]], [[[1, 0],[1, 1],[1, 2],[2, 2]]]) + +val jPiece = P( + "j", + ([0,1] :: [0,2] :: [0,3] :: [1,1] :: Nil) :: + ([1,0] :: [2,0] :: [3,0] :: [1,-1] :: Nil) :: + ([1,-2] :: [1,-1] :: [1,0] :: [1,1] :: Nil) :: Nil, + ([1,0] :: [2,0] :: [3,0] :: [2,2] :: Nil) :: Nil +) +//│ jPiece = P("j", [[[0, 1],[0, 2],[0, 3],[1, 1]],[[1, 0],[2, 0],[3, 0],[1, -1]],[[1, -2],[1, -1],[1, 0],[1, 1]]], [[[1, 0],[2, 0],[3, 0],[2, 2]]]) + +val iPiece = P( + "i", + ([1,0] :: [2,0] :: [2,1] :: [3,1] :: Nil) :: + ([0,1] :: [0,2] :: [1,0] :: [1,-1] :: Nil) :: + ([1,0] :: [1,1] :: [2,1] :: [3,1] :: Nil) :: Nil, + ([0,1] :: [1,0] :: [1,-1] :: [1,-2] :: Nil) :: Nil +) +//│ iPiece = P("i", [[[1, 0],[2, 0],[2, 1],[3, 1]],[[0, 1],[0, 2],[1, 0],[1, -1]],[[1, 0],[1, 1],[2, 1],[3, 1]]], [[[0, 1],[1, 0],[1, -1],[1, -2]]]) + +val hPiece = P( + "h", + ([0,1] :: [1,1] :: [1,2] :: [2,2] :: Nil) :: + ([1,0] :: [1,-1] :: [2,-1] :: [2,-2] :: Nil) :: + ([1,0] :: [1,1] :: [2,1] :: [2,2] :: Nil) :: Nil, + ([0,1] :: [1,0] :: [1,-1] :: [2,-1] :: Nil) :: Nil +) +//│ hPiece = P("h", [[[0, 1],[1, 1],[1, 2],[2, 2]],[[1, 0],[1, -1],[2, -1],[2, -2]],[[1, 0],[1, 1],[2, 1],[2, 2]]], [[[0, 1],[1, 0],[1, -1],[2, -1]]]) + +val gPiece = P( + "g", + Nil, + ([0,1] :: [1,1] :: [1,2] :: [1,3] :: Nil) :: + ([1,0] :: [1,-1] :: [2,-1] :: [3,-1] :: Nil) :: + ([0,1] :: [0,2] :: [1,2] :: [1,3] :: Nil) :: + ([1,0] :: [2,0] :: [2,-1] :: [3,-1] :: Nil) :: Nil +) +//│ gPiece = P("g", [], [[[0, 1],[1, 1],[1, 2],[1, 3]],[[1, 0],[1, -1],[2, -1],[3, -1]],[[0, 1],[0, 2],[1, 2],[1, 3]],[[1, 0],[2, 0],[2, -1],[3, -1]]]) + +val fPiece = P( + "f", + ([0,1] :: [1,1] :: [2,1] :: [3,1] :: Nil) :: + ([1,0] :: [1,-1] :: [1,-2] :: [1,-3] :: Nil) :: + ([1,0] :: [2,0] :: [3,0] :: [3,1] :: Nil) :: Nil, + ([0,1] :: [0,2] :: [0,3] :: [1,0] :: Nil) :: Nil +) +//│ fPiece = P("f", [[[0, 1],[1, 1],[2, 1],[3, 1]],[[1, 0],[1, -1],[1, -2],[1, -3]],[[1, 0],[2, 0],[3, 0],[3, 1]]], [[[0, 1],[0, 2],[0, 3],[1, 0]]]) + +val ePiece = P( + "e", + ([0,1] :: [1,1] :: [1,2] :: Nil) :: + ([1,0] :: [1,-1] :: [2,-1] :: Nil) :: Nil, + ([0,1] :: [1,1] :: [1,2] :: Nil) :: + ([1,0] :: [1,-1] :: [2,-1] :: Nil) :: Nil +) +//│ ePiece = P("e", [[[0, 1],[1, 1],[1, 2]],[[1, 0],[1, -1],[2, -1]]], [[[0, 1],[1, 1],[1, 2]],[[1, 0],[1, -1],[2, -1]]]) + +val dPiece = P( + "d", + ([0,1] :: [1,1] :: [2,1] :: Nil) :: + ([1,0] :: [1,-1] :: [1,-2] :: Nil) :: Nil, + ([1,0] :: [2,0] :: [2,1] :: Nil) :: Nil +) +//│ dPiece = P("d", [[[0, 1],[1, 1],[2, 1]],[[1, 0],[1, -1],[1, -2]]], [[[1, 0],[2, 0],[2, 1]]]) + +val cPiece = P( + "c", + Nil, + ([0,1] :: [0,2] :: [1,1] :: Nil) :: + ([1,0] :: [1,-1] :: [2,0] :: Nil) :: + ([1,-1] :: [1,0] :: [1,1] :: Nil) :: + ([1,0] :: [1,1] :: [2,0] :: Nil) :: Nil +) +//│ cPiece = P("c", [], [[[0, 1],[0, 2],[1, 1]],[[1, 0],[1, -1],[2, 0]],[[1, -1],[1, 0],[1, 1]],[[1, 0],[1, 1],[2, 0]]]) + +val bPiece = P( + "b", + ([0,1] :: [0,2] :: [1,2] :: Nil) :: + ([1,0] :: [2,0] :: [2,-1] :: Nil) :: + ([0,1] :: [1,0] :: [2,0] :: Nil) :: Nil, + ([1,0] :: [1,1] :: [1,2] :: Nil) :: Nil +) +//│ bPiece = P("b", [[[0, 1],[0, 2],[1, 2]],[[1, 0],[2, 0],[2, -1]],[[0, 1],[1, 0],[2, 0]]], [[[1, 0],[1, 1],[1, 2]]]) + +val initialPieces = bPiece :: cPiece :: dPiece :: ePiece :: fPiece :: + gPiece :: hPiece :: iPiece :: jPiece :: kPiece :: lPiece :: + mPiece :: nPiece :: Nil +//│ initialPieces = [P("b", [[[0, 1],[0, 2],[1, 2]],[[1, 0],[2, 0],[2, -1]],[[0, 1],[1, 0],[2, 0]]], [[[1, 0],[1, 1],[1, 2]]]),P("c", [], [[[0, 1],[0, 2],[1, 1]],[[1, 0],[1, -1],[2, 0]],[[1, -1],[1, 0],[1, 1]],[[1, 0],[1, 1],[2, 0]]]),P("d", [[[0, 1],[1, 1],[2, 1]],[[1, 0],[1, -1],[1, -2]]], [[[1, 0],[2, 0],[2, 1]]]),P("e", [[[0, 1],[1, 1],[1, 2]],[[1, 0],[1, -1],[2, -1]]], [[[0, 1],[1, 1],[1, 2]],[[1, 0],[1, -1],[2, -1]]]),P("f", [[[0, 1],[1, 1],[2, 1],[3, 1]],[[1, 0],[1, -1],[1, -2],[1, -3]],[[1, 0],[2, 0],[3, 0],[3, 1]]], [[[0, 1],[0, 2],[0, 3],[1, 0]]]),P("g", [], [[[0, 1],[1, 1],[1, 2],[1, 3]],[[1, 0],[1, -1],[2, -1],[3, -1]],[[0, 1],[0, 2],[1, 2],[1, 3]],[[1, 0],[2, 0],[2, -1],[3, -1]]]),P("h", [[[0, 1],[1, 1],[1, 2],[2, 2]],[[1, 0],[1, -1],[2, -1],[2, -2]],[[1, 0],[1, 1],[2, 1],[2, 2]]], [[[0, 1],[1, 0],[1, -1],[2, -1]]]),P("i", [[[1, 0],[2, 0],[2, 1],[3, 1]],[[0, 1],[0, 2],[1, 0],[1, -1]],[[1, 0],[1, 1],[2, 1],[3, 1]]], [[[0, 1],[1, 0],[1, -1],[1, -2]]]),P("j", [[[0, 1],[0, 2],[0, 3],[1, 1]],[[1, 0],[2, 0],[3, 0],[1, -1]],[[1, -2],[1, -1],[1, 0],[1, 1]]], [[[1, 0],[2, 0],[3, 0],[2, 2]]]),P("k", [[[0, 1],[1, 0],[2, 0],[2, -1]]], [[[1, 0],[1, 1],[1, 2],[2, 2]]]),P("l", [[[0, 1],[0, 2],[0, 3],[1, 2]],[[1, 0],[2, 0],[3, 0],[2, -1]]], [[[1, -1],[1, 0],[1, 1],[1, 2]],[[1, 0],[2, 0],[3, 0],[1, 1]]]),P("m", [[[0, 1],[1, 0],[2, 0],[3, 0]]], [[[0, 1],[0, 2],[0, 3],[1, 3]],[[1, 0],[2, 0],[3, 0],[3, -1]]]),P("n", [[[0, 1],[1, 1],[2, 1],[2, 2]],[[1, 0],[1, -1],[1, -2],[2, -2]]], [])] + +abstract class Mode: PageMode | ZigZagMode | LeftMode | OneLineMode + +object + PageMode extends Mode + ZigZagMode extends Mode + LeftMode extends Mode + OneLineMode extends Mode + +abstract class TextDetails: Chr | Str | PStr + +data + class + Chr(c: Char) extends TextDetails + Str(s: String) extends TextDetails + PStr(s: String) extends TextDetails + +abstract class AnnotDetails: AnnotStart | NoAnnot | AnnotEnd + +object + AnnotStart extends AnnotDetails + AnnotEnd extends AnnotDetails + +data class NoAnnot(t: TextDetails, i: Int) extends AnnotDetails + +abstract class IsEmptyy: IsEmpty | NotEmpty + +object + IsEmpty extends IsEmptyy + NotEmpty extends IsEmptyy + +abstract class Doc: Empty | NilAbove | TextBeside | Nest | Union | NoDoc | Beside | Above + +object + Empty extends Doc + NoDoc extends Doc + +data + class + NilAbove(d: Doc) extends Doc + TextBeside(a: AnnotDetails, d: Doc) extends Doc + Nest(i: Int, d: Doc) extends Doc + Union(d1: Doc, d2: Doc) extends Doc + Beside(d1: Doc, b: Bool, d2: Doc) extends Doc + Above(d1: Doc, b: Bool, d2: Doc) extends Doc + +val spaceText = NoAnnot(Chr(" "), 1) +//│ spaceText = NoAnnot(Chr(" "), 1) + +val nlText = NoAnnot(Chr("\n"), 1) +//│ nlText = NoAnnot(Chr("\n"), 1) + +fun annotSize(p) = if p is + NoAnnot(_, l) then l + _ then 0 + +//│ ———————————————————————————————————————————————————————————————————————————————— +fun display(s) = if s is + Soln(bd) then vcat(text(nofibStringToList("Success!")) :: nest(2, displayBoard(bd)) :: Nil) + Choose(ss) then vcat(map(display, ss)) + Fail(bd, [row, col]) then Empty + +fun displayBoard(bd) = + fun sq(n, col) = if check(bd, [n, col]) is + Some(id) then char(id) + None then char(".") + fun row(n) = hcat(map(col => sq(n, col), enumFromTo(1, maxCol))) + above_(vcat(map(row, enumFromTo(1, maxCol))), false, text(Nil)) + +fun eliminateEmpty(cons, p, g, q) = if p is + Empty then q + else [ + NotEmpty, + if q is + [NotEmpty, q1] then cons(p, g, q1) + [IsEmpty, _] then p + ] + +fun reduceVert(doc) = if doc is + Above(p, g, q) then eliminateEmpty((a, b, c) => Above(a, b, c), snd(reduceVert(p)), g, reduceVert(q)) + else [NotEmpty, doc] + +fun vcat(ls) = snd(reduceVert(foldr((p, q) => Above(p, false, q), Empty, ls))) + +fun text(s) = + let sl = listLen(s) + TextBeside(NoAnnot(Str(s), sl), Empty) + +fun char(c) = TextBeside(NoAnnot(Chr(c), 1), Empty) + +fun reduceHoriz(doc) = if doc is + Beside(p, g, q) then eliminateEmpty((a, b, c) => Beside(a, b, c), snd(reduceHoriz(p)), g, reduceHoriz(q)) + else [NotEmpty, doc] + +fun hcat(ls) = snd of reduceHoriz of foldr of + (p, q) => Beside(p, false, q) + Empty + ls + +fun above_(p, g, q) = if + q is Empty then p + g is Empty then q + else Above(p, g, q) + +fun nest(k, p) = mkNest(k, reduceDoc(p)) + +fun mkNest(k, p) = if + p is Nest(k1, p1) then mkNest(k + k1, p1) + p is NoDoc then NoDoc + p is Empty then Empty + k === 0 then p + else Nest(k, p) + +fun reduceDoc(p) = if p is + Beside(p1, g, q) then beside(p1, g, reduceDoc(q)) + Above(p1, g, q) then above(p1, g, reduceDoc(q)) + else p + + +fun beside(p, g, q) = if p is + NoDoc then NoDoc + Union(p1, p2) then Union(beside(p1, g, q), beside(p2, g, q)) + Empty then q + Nest(k, p1) then Nest(k, beside(p1, g, q)) + Beside(p1, g1, q1) and + g1 === g then beside(p1, g1, beside(q1, g, q)) + else beside(reduceDoc(Beside(p1, g1, q1)), g, q) + Above(_, _, _) then beside(reduceDoc(p), g, q) + NilAbove(p1) then NilAbove(beside(p1, g, q)) + TextBeside(t, p1) then + let rest = if p1 is Empty then nilBeside(g, q) else beside(p1, g, q) + TextBeside(t, rest) + +fun above(p, g, q) = if p is + Above(p1, g1, q1) then above(p1, g1, above(q1, g, q)) + Beside(_, _, _) then aboveNest(reduceDoc(p), g, 0, reduceDoc(q)) + else aboveNest(p, g, 0, reduceDoc(q)) + +fun nilBeside(g, p) = if + p is Empty then Empty + p is Nest(_, p1) then nilBeside(g, p1) + g then TextBeside(spaceText, p) + else p + +fun aboveNest(p, g, k, q) = if p is + NoDoc then NoDoc + Union(p1, p2) then Union(aboveNest(p1, g, k, q), aboveNest(p2, g, k, q)) + Empty then mkNest(k, q) + Nest(k1, p1) then Nest(k1, aboveNest(p1, g, k - k1, q)) + NilAbove(p1) then NilAbove(aboveNest(p1, g, k, q)) + TextBeside(s, p1) then + let k1 = k - annotSize(s) + let rest = if p1 is Empty then nilAboveNest(g, k1, q) else aboveNest(p1, g, k1, q) + TextBeside(s, rest) + Above(_, _, _) then throw Error("aboveNest Above") + Beside(_, _, _) then throw Error("aboveNest Beside") + +fun nilAboveNest(g, k, q) = if + q is Empty then Empty + q is Nest(k1, q1) then nilAboveNest(g, k + k1, q1) + not(g) and (k > 0) then TextBeside(NoAnnot(Str(indent(k)), k), q) + else NilAbove(mkNest(k, q)) + +fun printDoc(d) = + fun put(k, next) = if k is + Chr(c) then c :: next + Str(s) then s +: next + PStr(s) then s +: next + let done = "\n" :: Nil + fullRender(ZigZagMode, 200, 1.5, put, done, d) + +fun fullRender(m, l, r, txt, a, b) = + fun annTxt(p, x) = if p is + NoAnnot(s, _) then txt(s, x) + _ then x + fullRenderAnn(m, l, r, annTxt, a, b) + +fun ceiling(x) = globalThis.Math.ceil(x) + +fun fullRenderAnn(m, lineLen, ribbons, txt, rest, doc) = if m is + OneLineMode then easyDisplay(spaceText, (a, b) => b, txt, rest, reduceDoc(doc)) + LeftMode then easyDisplay(nlText, first, txt, rest, reduceDoc(doc)) + else + let ribbonLen = ceiling(lineLen / ribbons) + let bestLineLen = if m is ZigZagMode then 2147483647 else lineLen + let doc1 = best(bestLineLen, ribbonLen, reduceDoc(doc)) + displayDoc(m, lineLen, ribbonLen, txt, rest, doc1) + +fun easyDisplay(nlSpaceText, choose, txt, end, x) = + fun lay(x) = if x is + NoDoc then throw Error("easyDisplay: NoDoc") + Union(p, q) then lay(choose(p, q)) + Nest(_, p) then lay(p) + Empty then end + NilAbove(p) then txt(nlSpaceText, lay(p)) + TextBeside(s, p) then txt(s, lay(p)) + Above(_, _, _) then throw Error("easyDisplay Above") + Beside(_, _, _) then throw Error("easyDisplay Beside") + lay(x) + +fun displayDoc(m, pageWidth, ribbonWidth, txt, end, doc) = + let gapWidth = pageWidth - ribbonWidth + let shift = intDiv(gapWidth, 2) + fun lay(k, docc) = + fun lay2(k, param) = if param is + NilAbove(p) then txt(nlText, lay(k, p)) + TextBeside(s, p) then txt(s, lay2(k + annotSize(s), p)) + Nest(_, p) then lay2(k, p) + Empty then end + fun lay1(k, s, p) = + let r = k + annotSize(s) + txt(NoAnnot(Str(indent(k)), k), txt(s, lay2(r, p))) + if docc is + Nest(k1, p) then lay(k + k1, p) + Empty then end + NilAbove(p) then txt(nlText, lay(k, p)) + TextBeside(s, p) and m is + ZigZagMode and k + >= gapWidth then txt(nlText, txt(NoAnnot(Str(replicate(shift, "/")), shift), txt(nlText, lay1(k - shift, s, p)))) + < 0 then txt(nlText, txt(NoAnnot(Str(replicate(shift, "|")), shift), txt(nlText, lay1(k + shift, s, p)))) + else lay1(k, s, p) + else lay1(k, s, p) + lay(0, doc) + +fun best(w0, r, doc) = + fun get(r, w, docc) = if docc is + Empty then Empty + NoDoc then NoDoc + NilAbove(p) then NilAbove(get(r, w, p)) + TextBeside(s, p) then TextBeside(s, get1(r, w, annotSize(s), p)) + Nest(k, p) then Nest(k, get(r, w - k, p)) + Union(p, q) then nicest(w, r, get(r, w, p), get(r, w, q)) + Above(_, _, _) then throw Error("best get Above") + Beside(_, _, _) then throw Error("best get Beside") + fun get1(r, w, sl, p) = if p is + Empty then Empty + NoDoc then NoDoc + NilAbove(p) then NilAbove(get(r, w - sl, p)) + TextBeside(s, p) then TextBeside(s, get1(r, w, sl + annotSize(s), p)) + Nest(_, p) then get1(r, w, sl, p) + Union(p, q) then nicest1(w, r, sl, get1(r, w, sl, p), get1(r, w, sl, q)) + Above(_, _, _) then throw Error("best get1 Above") + Beside(_, _, _) then throw Error("best get1 Beside") + get(r, w0, doc) + +fun nonEmptySet(doc) = if doc is + NoDoc then false + Union(_, _) then true + Empty then true + NilAbove(_) then true + TextBeside(_, p) then nonEmptySet(p) + Nest(_, p) then nonEmptySet(p) + Above(_, _, _) then throw Error("nonEmptySet Above") + Beside(_, _, _) then throw Error("nonEmptySet Beside") + +fun fits(n, param) = if + n < 0 then false + param is + NoDoc then false + Empty then true + NilAbove(_) then true + TextBeside(s, p) then fits(n - annotSize(s), p) + Above(_, _, _) then throw Error("fits Above") + Beside(_, _, _) then throw Error("fits Beside") + Union(_, _) then throw Error("fits Union") + Nest(_, _) then throw Error("fits Nest") + +fun first(p, q) = if nonEmptySet(p) then p else q + +fun nicest1(w, r, sl, p, q) = if fits(min(w, r) - sl, p) then p else q + +fun nicest(w, r, p, q) = nicest1(w, r, 0, p, q) +//│ ———————————————————————————————————————————————————————————————————————————————— + + +fun testLastPiece_nofib() = + let initialBoard = fromSome(fit(emptyBoard, [1, 1], "a", [1, 0] :: [1, 1] :: Nil)) + let solutions = search([1,2], Female, initialBoard, initialPieces) + printDoc(display(solutions)) + +fun main() = nofibListToString(testLastPiece_nofib()) +//│ > Success! +//│ > accchhff +//│ > aacnghhf +//│ > innnglhf +//│ > inmggllf +//│ > iimgelkk +//│ > dimeelkb +//│ > dmmejkkb +//│ > ddjjjjbb +//│ > +//│ > Success! +//│ > acccjjjj +//│ > aacffjgb +//│ > hhddfggb +//│ > lhhdfgbb +//│ > llhdfgnm +//│ > lkkennnm +//│ > lkeeniim +//│ > kkeiiimm +//│ > +//│ > Success! +//│ > ammmmccc +//│ > aaiimnch +//│ > iiinnnhh +//│ > gggnlhhj +//│ > fkgglljj +//│ > fkkklbdj +//│ > feeklbdj +//│ > ffeebbdd +//│ > +//│ > diff --git a/benchmark/src/nofib/lcss.mls b/benchmark/src/nofib/lcss.mls new file mode 100644 index 000000000..731770729 --- /dev/null +++ b/benchmark/src/nofib/lcss.mls @@ -0,0 +1,57 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module lcss with ... + + + +fun algb2(x, k0j1, k1j1, yss) = if yss is + Nil then Nil + [y, k0j] :: ys then + let kjcurr = if x == y then k0j1 + 1 else max(k1j1, k0j) + [y, kjcurr] :: algb2(x, k0j, kjcurr, ys) + +fun algb1(xss, yss) = if xss is + Nil then map(snd, yss) + x :: xs then algb1(xs, algb2(x, 0, 0, yss)) + +fun algb(xs, ys) = + fun listcomp_fun(listcomp_fun_para) = if listcomp_fun_para is + listcomp_fun_ls_h :: listcomp_fun_ls_t then [listcomp_fun_ls_h, 0] :: listcomp_fun(listcomp_fun_ls_t) + Nil then Nil + + 0 :: algb1(xs, listcomp_fun(ys)) + + +fun findk(k, km, m, ls) = if ls is + Nil then km + [x,y] :: xys then if (x + y) >= m then findk(k+1, k, x+y, xys) else findk(k+1, km, m, xys) + +fun algc(m, n, xs, ys) = if + ys is Nil then x => x + xs is + x :: Nil and + inList(x, ys) then t => x :: t + else x => x + else + let m2 = intDiv(m, 2) + let xs1 = take(m2, xs) + let xs2 = drop(m2, xs) + let l1 = algb(xs1, ys) + let l2 = reverse(algb(reverse(xs2), reverse(ys))) + let k = findk(0, 0, -1, zip(l1, l2)) + compose(algc(m2, k, xs1, take(k, ys)), (algc(m-m2, n-k, xs2, drop(k, ys)))) + +fun lcss(xs, ys) = algc(listLen(xs), listLen(ys), xs, ys)(Nil) + +fun lcssMain(a, b ,c, d, e, f) = lcss(enumFromThenTo(a,b,c), enumFromThenTo(d,e,f)) + +fun testLCSS_nofib(d) = lcssMain(1,2,60,30,31,90) + + + +fun main() = testLCSS_nofib(0).toString() +//│ = "[30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60]" diff --git a/benchmark/src/nofib/life.mls b/benchmark/src/nofib/life.mls new file mode 100644 index 000000000..cc1b9037f --- /dev/null +++ b/benchmark/src/nofib/life.mls @@ -0,0 +1,110 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module life with ... + + +fun last(a_t) = + fun go(h, t) = if t is + Nil then h + head :: t then go(head, t) + if a_t is a :: t then go(a, t) + +fun copy_lz(n, x) = lazy of () => + if n === 0 then LzNil else LzCons(x, copy_lz(n - 1, x)) + +fun append_lz_lz(xs, ys) = lazy of () => + if force(xs) is + LzNil then force(ys) + LzCons(h, t) then LzCons(h, append_lz_lz(t, ys)) + +fun init(ls) = if ls is + a :: Nil then Nil + a :: t then a :: init(t) + else throw Error(ls) + +fun zipWith3(f, xs, ys, zs) = if + xs is hx :: tx and ys is hy :: ty and zs is hz :: tz then f(hx, hy, hz) :: zipWith3(f, tx, ty, tz) + else Nil + +fun zip3(xs, ys, zs) = if + xs is hx :: tx and ys is hy :: ty and zs is hz :: tz then [hx, hy, hz] :: zip3(tx, ty, tz) + else Nil + +fun lzfy(ls) = lazy of () => + if ls is + a :: t then LzCons(a, lzfy(t)) + else LzNil + +val start = + (lazy of () => LzNil) :: + (lazy of () => LzNil) :: + (lazy of () => LzNil) :: + (lazy of () => LzNil) :: + (lazy of () => LzNil) :: + (lazy of () => LzNil) :: + (lazy of () => LzNil) :: + (lazy of () => LzNil) :: + (lazy of () => LzNil) :: + (lazy of () => LzNil) :: + (lazy of () => LzNil) :: + (lazy of () => LzNil) :: + (lazy of () => LzNil) :: + (lazy of () => LzNil) :: + lzfy(0 :: 0 :: 0 :: 1 :: 1 :: 1 :: 1 :: 1 :: 0 :: 1 :: 1 :: 1 :: 1 :: 1 :: 0 :: 1 :: 1 :: 1 :: 1 :: 1 :: 0 :: 1 :: 1 :: 1 :: 1 :: 1 :: 0 :: Nil) :: Nil +//│ start = [Lazy([function]),Lazy([function]),Lazy([function]),Lazy([function]),Lazy([function]),Lazy([function]),Lazy([function]),Lazy([function]),Lazy([function]),Lazy([function]),Lazy([function]),Lazy([function]),Lazy([function]),Lazy([function]),Lazy([function])] + +fun elt(a_b_c, d_e_f, g_h_i) = if a_b_c is [a, b, c] and d_e_f is [d, e, f] and g_h_i is [g, h, i] then + let tot = a + b + c + d + f + g + h + i + if + tot < 2 || tot > 3 then 0 + tot === 3 then 1 + else e + +fun shiftr(x, xs) = x :: init(xs) + +fun shiftl(x, xs) = init(xs) +: (x :: Nil) + +fun shift(x, xs) = zip3(shiftr(x, xs), xs, shiftl(x, xs)) + +fun row(last_this_next) = if last_this_next is [last, this_, next] then + zipWith3(elt, shift(0, last), shift(0, this_), shift(0, next)) + +fun gen(n, board) = map(row, shift(replicate(n, 0), board)) + +fun star(x) = if x === + 0 then nofibStringToList(" ") + 1 then nofibStringToList(" o") + +fun glue(s, xs, ys) = xs +: s +: ys + +fun limit(ls) = if force(ls) is + LzCons(x, ys) and force(ys) is LzCons(y, xs) and + listEqBy(listEq, x, y) then x :: Nil + else x :: limit(lazy of () => LzCons(y, xs)) + +fun disp(gen_xss) = if gen_xss is [genn, xss] then lazy of () => + genn +: + nofibStringToList("nn") +: + foldr((a, b) => glue("n" :: Nil, a, b), Nil, map(x => concat(map(star, x)), xss)) + +fun generations(sz) = + map of + disp + zip_lz_nl of + map_lz(i => nofibStringToList(stringOfInt(i)), enumFrom(0)), + limit of iterate of + b => gen(sz, b) + take_lz of + sz + map_lz of + l => take_lz(sz, append_lz_lz(l, copy_lz(sz, 0))), + append_nl_lz(start, copy_lz(sz, copy_lz(sz, 0))) + +fun testLife_nofib(n) = listLen(force(last(generations(n)))) + +fun main() = testLife_nofib(15) +//│ = 468 diff --git a/benchmark/src/nofib/mandel.mls b/benchmark/src/nofib/mandel.mls new file mode 100644 index 000000000..d257eaf7c --- /dev/null +++ b/benchmark/src/nofib/mandel.mls @@ -0,0 +1,78 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module mandel with ... + + + +data class Pixmap(a: Int, b: Int, c: Int, d:List[[Int, Int, Int]]) + +fun createPixmap(width, height, max, colours) = Pixmap(width, height, max, colours) + +data class Complex(r: Num, i: Num) + +fun comp_magnitude(c) = if c is Complex(a, b) then sqrt(a * a + b * b) + +fun comp_times(x, y) = if + x is Complex(a, b) and y is Complex(c, d) then Complex((a * c) - (b * d), (a * d) + (b * c)) + +fun comp_plus(x, y) = if + x is Complex(a, b) and y is Complex(c, d) then Complex(a + c, b + d) + +fun mandel(c) = + fun infiniteMandel() = lazy of () => + LzCons(c, map_lz((z => comp_plus(comp_times(z, z), c)), infiniteMandel())) + infiniteMandel() + +fun diverge(cmplx, radius) = + comp_magnitude(cmplx) > radius + +fun whenDiverge(limit, radius, c) = + fun walkIt(ls) = if force(ls) is + LzNil then 0 + LzCons(x, xs) and + diverge(x, radius) then 0 + else 1 + walkIt(xs) + + walkIt(take_lz_lz(limit, mandel(c))) + +fun parallelMandel(mat, limit, radius) = map(c => whenDiverge(limit, radius, c), mat) + +fun mandelset(x, y, x_, y_, screenX, screenY, lIMIT) = + fun prettyRGB(s) = + let t = lIMIT - s + [s, t, t] + + fun windowToViewport(s, t) = + Complex(x + ((s * (x_ - x)) / screenX), y + ((t * (y_ - y)) / screenY)) + + fun lscomp1(ls1) = if ls1 is + Nil then Nil + t :: t1 then + fun lscomp2(ls2) = if ls2 is + Nil then lscomp1(t1) + s :: t2 then windowToViewport(s, t) :: lscomp2(t2) + lscomp2(enumFromTo(1, screenX)) + + let result = parallelMandel(lscomp1(enumFromTo(1, screenY)), lIMIT, max(x_ - x, y_ - y) / 2) + + createPixmap(screenX, screenY, lIMIT, map(prettyRGB, result)) + + +fun testMandel_nofib(dummy) = + let minx = -2.0 + let miny = -2.0 + let maxx = 2.0 + let maxy = 2.0 + let screenX = 25 + let screenY = 25 + let limit = 75 + mandelset(minx, miny, maxx, maxy, screenX, screenY, limit) + + + +fun main() = testMandel_nofib(0).toString() +//│ = "Pixmap(25, 25, 75, [[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[1, 74, 74],[1, 74, 74],[1, 74, 74],[2, 73, 73],[2, 73, 73],[2, 73, 73],[2, 73, 73],[2, 73, 73],[2, 73, 73],[2, 73, 73],[2, 73, 73],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[1, 74, 74],[1, 74, 74],[2, 73, 73],[2, 73, 73],[2, 73, 73],[2, 73, 73],[2, 73, 73],[3, 72, 72],[3, 72, 72],[5, 70, 70],[5, 70, 70],[3, 72, 72],[2, 73, 73],[2, 73, 73],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[0, 75, 75],[0, 75, 75],[0, 75, 75],[1, 74, 74],[2, 73, 73],[2, 73, 73],[2, 73, 73],[2, 73, 73],[2, 73, 73],[3, 72, 72],[3, 72, 72],[4, 71, 71],[14, 61, 61],[55, 20, 20],[4, 71, 71],[3, 72, 72],[2, 73, 73],[2, 73, 73],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[0, 75, 75],[0, 75, 75],[1, 74, 74],[2, 73, 73],[2, 73, 73],[2, 73, 73],[2, 73, 73],[2, 73, 73],[3, 72, 72],[3, 72, 72],[6, 69, 69],[6, 69, 69],[59, 16, 16],[75, 0, 0],[7, 68, 68],[5, 70, 70],[4, 71, 71],[2, 73, 73],[2, 73, 73],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[0, 75, 75],[2, 73, 73],[2, 73, 73],[2, 73, 73],[2, 73, 73],[3, 72, 72],[4, 71, 71],[4, 71, 71],[5, 70, 70],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[39, 36, 36],[23, 52, 52],[3, 72, 72],[2, 73, 73],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[0, 75, 75],[2, 73, 73],[2, 73, 73],[3, 72, 72],[4, 71, 71],[6, 69, 69],[6, 69, 69],[6, 69, 69],[9, 66, 66],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[8, 67, 67],[3, 72, 72],[2, 73, 73],[2, 73, 73],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[0, 75, 75],[3, 72, 72],[3, 72, 72],[4, 71, 71],[6, 69, 69],[19, 56, 56],[75, 0, 0],[24, 51, 51],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[24, 51, 51],[3, 72, 72],[2, 73, 73],[2, 73, 73],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[0, 75, 75],[3, 72, 72],[5, 70, 70],[6, 69, 69],[18, 57, 57],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[6, 69, 69],[3, 72, 72],[2, 73, 73],[2, 73, 73],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[0, 75, 75],[3, 72, 72],[5, 70, 70],[6, 69, 69],[18, 57, 57],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[6, 69, 69],[3, 72, 72],[2, 73, 73],[2, 73, 73],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[0, 75, 75],[3, 72, 72],[3, 72, 72],[4, 71, 71],[6, 69, 69],[19, 56, 56],[75, 0, 0],[24, 51, 51],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[24, 51, 51],[3, 72, 72],[2, 73, 73],[2, 73, 73],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[0, 75, 75],[2, 73, 73],[2, 73, 73],[3, 72, 72],[4, 71, 71],[6, 69, 69],[6, 69, 69],[6, 69, 69],[9, 66, 66],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[8, 67, 67],[3, 72, 72],[2, 73, 73],[2, 73, 73],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[0, 75, 75],[2, 73, 73],[2, 73, 73],[2, 73, 73],[2, 73, 73],[3, 72, 72],[4, 71, 71],[4, 71, 71],[5, 70, 70],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[75, 0, 0],[39, 36, 36],[23, 52, 52],[3, 72, 72],[2, 73, 73],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[0, 75, 75],[1, 74, 74],[2, 73, 73],[2, 73, 73],[2, 73, 73],[2, 73, 73],[2, 73, 73],[3, 72, 72],[3, 72, 72],[6, 69, 69],[6, 69, 69],[59, 16, 16],[75, 0, 0],[7, 68, 68],[5, 70, 70],[4, 71, 71],[2, 73, 73],[2, 73, 73],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[0, 75, 75],[0, 75, 75],[1, 74, 74],[2, 73, 73],[2, 73, 73],[2, 73, 73],[2, 73, 73],[2, 73, 73],[3, 72, 72],[3, 72, 72],[4, 71, 71],[14, 61, 61],[55, 20, 20],[4, 71, 71],[3, 72, 72],[2, 73, 73],[2, 73, 73],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[0, 75, 75],[0, 75, 75],[0, 75, 75],[1, 74, 74],[1, 74, 74],[2, 73, 73],[2, 73, 73],[2, 73, 73],[2, 73, 73],[2, 73, 73],[3, 72, 72],[3, 72, 72],[5, 70, 70],[5, 70, 70],[3, 72, 72],[2, 73, 73],[2, 73, 73],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[1, 74, 74],[1, 74, 74],[1, 74, 74],[2, 73, 73],[2, 73, 73],[2, 73, 73],[2, 73, 73],[2, 73, 73],[2, 73, 73],[2, 73, 73],[2, 73, 73],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[1, 74, 74],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75],[0, 75, 75]])" diff --git a/benchmark/src/nofib/mandel2.mls b/benchmark/src/nofib/mandel2.mls new file mode 100644 index 000000000..862291ab3 --- /dev/null +++ b/benchmark/src/nofib/mandel2.mls @@ -0,0 +1,128 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module mandel2 with ... + + + +abstract class MandTree: NS | EW | Leaf + +data + class + NS(l: MandTree, r: MandTree) extends MandTree + EW(l: MandTree, r: MandTree) extends MandTree + Leaf(colour: Int) extends MandTree + +val size = 200 +val pmn = -2.25 +val pmx = 0.75 +val qmn = -1.5 +val qmx = 1.5 +val m = 20 +val num_cols = 26 +val delta_p = (pmx - pmn) / (size - 1) +val delta_q = (qmx - qmn) / (size - 1) +val up = [ 0,-1] +val down = [ 0, 1] +val left = [-1, 0] +val right = [ 1, 0] +//│ delta_p = 0.01507537688442211 +//│ delta_q = 0.01507537688442211 +//│ down = [0, 1] +//│ left = [-1, 0] +//│ m = 20 +//│ num_cols = 26 +//│ pmn = -2.25 +//│ pmx = 0.75 +//│ qmn = -1.5 +//│ qmx = 1.5 +//│ right = [1, 0] +//│ size = 200 +//│ up = [0, -1] + +fun equalp(p1, p2) = if p1 is [x1, x2] and p2 is [y1, y2] then (x1 == y1) and (x2 == y2) + +fun np(x) = pmn + (x * delta_p) + +fun nq(y) = qmn + (y * delta_q) + +fun radius(x, y) = (x * x) + (y * y) + +fun new_x(x, y, p) = (x * x) - (y * y) + p + +fun new_y(x, y, q) = (2.0 * x * y) + q + +fun finite(t) = if t is + Leaf(c) then c == c + NS(t1, t2) then finite(t1) and finite(t2) + EW(t1, t2) then finite(t1) and finite(t2) + +fun check_radius(p, q, k, x, y) = + let xn = new_x(x, y, p) + let yn = new_y(x, y, q) + let r = radius(xn, yn) + let kp = k + 1 + if + kp == num_cols then 0 + r > m then kp + else check_radius(p, q, kp, xn, yn) + +fun point_colour(xy) = if xy is [x, y] then check_radius(np(x), nq(y), 0, 0.0, 0.0) + +fun check_perim(x1y1, x2y2) = + let col1 = point_colour(x1y1) + if x1y1 is [x1, y1] and x2y2 is [x2, y2] then + + fun check_line(xcyc, xdyd) = + if xcyc is [xc, yc] and xdyd is [xd, yd] and + let finished = if + equalp(xdyd, right) then xc >= x2 + equalp(xdyd, down) then yc <= y2 + equalp(xdyd, left) then xc <= x1 + else yc >= y1 + finished then true + not(point_colour(xcyc) == col1) then false + else check_line([xc + xd, yc + yd], [xd, yd]) + + if + equalp(x1y1, x2y2) then col1 + let col2 = point_colour([x2, y1]) + let col3 = point_colour(x2y2) + let col4 = point_colour([x1, y2]) + let corners_diff = if (col1 == col2) and (col1 == col3) and (col1 == col4) then false else true + corners_diff then -1 + check_line([x1+1,y1], right) and check_line([x2,y1+1], down) and check_line([x2-1,y2], left) and check_line([x1,y2-1], up) then col1 + else -1 + + +fun build_tree(x1y1, x2y2) = + if x1y1 is [x1, y1] and x2y2 is [x2, y2] then + let rec_col = check_perim(x1y1, x2y2) + if + not(rec_col == -1) then Leaf(rec_col) + let split = if (x2-x1) >= (y2-y1) then "NS" else "EW" + let split_x = intDiv((x2+x1), 2) + let split_y = intDiv((y2+y1), 2) + let nsp1 = x1y1 + let nsp2 = [split_x, y2] + let nsp3 = [split_x+1, y1] + let nsp4 = x2y2 + let ewp1 = x1y1 + let ewp2 = [x2, split_y] + let ewp3 = [x1, split_y+1] + let ewp4 = x2y2 + split == "NS" then NS(build_tree(nsp1, nsp2), build_tree(nsp3, nsp4)) + else EW(build_tree(ewp1, ewp2), build_tree(ewp3, ewp4)) + +fun testMandel2_nofib(n) = + finite(build_tree([0,0], [size, intDiv(size, 2)])) + + + +fun main() = testMandel2_nofib(0) +//│ = true + + diff --git a/benchmark/src/nofib/mate.mls b/benchmark/src/nofib/mate.mls new file mode 100644 index 000000000..470ccf5e7 --- /dev/null +++ b/benchmark/src/nofib/mate.mls @@ -0,0 +1,576 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module mate with ... + + + +//│ ———————————————————————————————————————————————————————————————————————————————— +fun rqpart(le, x, ys, rle, rgt, r) = if ys is + Nil then qsort(le, rle, x :: qsort(le, rgt, r)) + y :: ys and + le(y, x) then rqpart(le, x, ys, y :: rle, rgt, r) + else rqpart(le, x, ys, rle, y :: rgt, r) + +fun rqsort(le, xs, r) = if xs is + Nil then r + x :: Nil then x :: r + x :: xs then rqpart(le, x, xs, Nil, Nil, r) + +fun qpart(le, x, ys, rlt, rge, r) = if ys is + Nil then rqsort(le, rlt, x :: rqsort(le, rge, r)) + y :: ys and + le(x, y) then qpart(le, x, ys, rlt, y :: rge, r) + else qpart(le, x, ys, y :: rlt, rge, r) + +fun qsort(le, xs, r) = if xs is + Nil then r + x :: Nil then x :: r + x :: xs then qpart(le, x, xs, Nil, Nil, r) +//│ ———————————————————————————————————————————————————————————————————————————————— + +fun sort(l) = qsort of + (a, b) => if a is [aa, _] and b is [bb, _] then listLen(aa) <= listLen(bb) + l + Nil + +abstract class Kind: King | Queen | Rook | Bishop | Knight | Pawn + +object + King extends Kind + Queen extends Kind + Rook extends Kind + Bishop extends Kind + Knight extends Kind + Pawn extends Kind + +abstract class Colour: Black | White + +object + Black extends Colour + White extends Colour + +type Piece = [Colour,Kind] + +type Square = [Int,Int] + +data class Board(a: List[[Kind, Square]], b: List[[Kind, Square]]) + +data class Move(a: Square, b: Option[Piece], c: Option[Piece]) + +data class MoveInFull(a: Piece, b: Square, c: Move) + +data class Solution(a: MoveInFull, b: List[[List[MoveInFull],Solution]]) + +fun maybe(d, f, x) = if x is + None then d + Some(x) then f(x) + +fun isUpper(c) = let x = c.charCodeAt(0) in (x >= 65 and x <= 90) + +fun isLower(c) = let x = c.charCodeAt(0) in (x >= 97 and x <= 122) + +fun toLower(c) = if isUpper(c) then String.fromCharCode(c.charCodeAt(0) + 32) else c + +fun words(s) = if dropWhile(x => x === " ", s) is + Nil then Nil + s_ and + break_(x => x === " ", s_) is [w, s__] then w :: words(s__) + +fun unlines(ls) = concat(map(l => append(l, "\n" :: Nil), ls)) + +fun lines(s) = if break_(x => x === "\n", s) is [l, s_] then + Cons of + l + if s_ is + Nil then Nil + Cons(_, s__) then lines(s__) + +fun any(p, ls) = if ls is + Nil then false + x :: xs then p(x) || any(p, xs) + +fun showColour(c) = nofibStringToList(if c is Black then "Black" else "White") + +fun pieceAt(bd, sq) = if bd is Board(wkss, bkss) then + fun pieceAtWith(c, n, ls) = if ls is + Nil then n + [k, s] :: xs and + eqTup2(s, sq) then Some([c, k]) + else pieceAtWith(c, n, xs) + pieceAtWith(White, pieceAtWith(Black, None, bkss), wkss) + +fun kindToChar(k) = if k is + King then "K" + Queen then "Q" + Rook then "R" + Bishop then "B" + Knight then "N" + Pawn then "P" + +fun pieceToChar(p) = if p is + [Black, k] then kindToChar(k) + [White, k] then toLower(kindToChar(k)) + +fun showBoard(bd) = + fun showRank(r) = + fun consFile(f, s) = if pieceAt(bd, [f, r]) is + None then nofibStringToList(" -") +: s + Some(p) then " " :: pieceToChar(p) :: s + foldr(consFile, Nil, enumFromTo(1, 8)) + unlines(map(showRank, reverse(enumFromTo(1, 8)))) + +fun showPiece(p) = if p is [c, k] then kindToChar(k) :: Nil + +fun showSquare(c, x_y) = if x_y is [x, y] then + atIndex( + x - 1, + nofibStringToList("QR") :: + nofibStringToList("QN") :: + nofibStringToList("QB") :: + nofibStringToList("Q") :: + nofibStringToList("K") :: + nofibStringToList("KB") :: + nofibStringToList("KN") :: + nofibStringToList("KR") :: Nil + ) +: + nofibStringToList(stringOfInt(if c is Black then 9 - y else y)) + +fun emptyAtAll(bd, e) = if bd is Board(wkss, bkss) then + fun emptyAtAllAnd(b, ls) = if ls is + Nil then b + [_, s] :: xs then (not(e(s)) and emptyAtAllAnd(b, xs)) + emptyAtAllAnd(emptyAtAllAnd(true, bkss), wkss) + +fun rPa(sq, kss) = if kss is + Nil then throw Error("rPa") + [k, s] :: kss then if eqTup2(s, sq) then kss else [k, s] :: rPa(sq, kss) + +fun rmPieceAt(c, sq, bd) = if bd is Board(wkss, bkss) and c is + White then Board(rPa(sq, wkss), bkss) + Black then Board(wkss, rPa(sq, bkss)) + +fun putPieceAt(sq, c_k, bd) = + if c_k is [c, k] and bd is Board(wkss, bkss) and c is + White then Board([k, sq] :: wkss, bkss) + Black then Board(wkss, [k, sq] :: bkss) + +fun kSq(kss) = if kss is + [King, s] :: _ then s + _ :: kss then kSq(kss) + Nil then throw Error("kSq") + +fun kingSquare(c, bd) = if bd is Board(wkss, bkss) and c is + White then kSq(wkss) + Black then kSq(bkss) + +fun opponent(c) = if c is White then Black else White + +fun colourOf(c_k) = if c_k is [c, _] then c + +fun kindOf(c_k) = if c_k is [_, k] then k + +fun onboard(p_q) = if p_q is [p, q] then + (p >= 1 and p <= 8) and (q >= 1 and q <= 8) + +fun forcesColoured(c, bd) = if bd is Board(wkss, bkss) and c is + White then wkss + Black then bkss + +val emptyBoard = Board(Nil, Nil) +//│ emptyBoard = Board([], []) + +fun showMove(withPiece, m) = if m is MoveInFull([c, k], sq, Move(sq_, mcp, mpp)) then + let capt = mcp is Some(_) + let prom = mpp is Some(_) + (if withPiece + then + showPiece([c, k]) +: + if ((k === King) || (k is Pawn and not(capt || prom))) then Nil else "/" :: showSquare(c, sq) + else Nil + ) +: + maybe("-" :: Nil, cp => "x" :: append(showPiece(cp), "/" :: Nil), mcp) +: + showSquare(c, sq_) +: + maybe(Nil, pp => "(" :: append(showPiece(pp), ")" :: Nil), mpp) + +fun showMoveInFull(a) = showMove(true, a) + +fun showMovesAfter(p_, mifs) = if mifs is + Nil then Nil + MoveInFull(p, sq, d_) :: mifs and p_ is MoveInFull(p_, sq_, _) then + nofibStringToList(", ") +: + showMove(not(eqTup2(p, p_)) || not(eqTup2(sq, sq_)), MoveInFull(p, sq, d_)) +: + showMovesAfter(MoveInFull(p, sq, d_), mifs) + +fun showMoves(mifs) = if mifs is + Nil then throw Error("showMoves") + mif :: mifs then + showMoveInFull(mif) +: + showMovesAfter(mif, mifs) + +fun sift(c, bd, ms, sqs) = if sqs is + Nil then ms + sq :: sqs and + onboard(sq) and pieceAt(bd, sq) is + None then sift(c, bd, Move(sq, None, None) :: ms, sqs) + Some(p_) and + colourOf(p_) === c then sift(c, bd, ms, sqs) + else sift(c, bd, Move(sq, Some(p_), None) :: ms, sqs) + else sift(c, bd, ms, sqs) + +fun moveLine(bd, c, sq, inc, cont) = + fun ml(sq, ms) = + let sq_ = inc(sq) + if onboard(sq_) and pieceAt(bd, sq_) is + None then ml(sq_, Move(sq_, None, None) :: ms) + Some(p_) and + not(colourOf(p_) === c) then cont(Move(sq_, Some(p_), None) :: ms) + else cont(ms) + else cont(ms) + ms => ml(sq, ms) + +fun bishopmoves(c, sq, bd) = + (moveLine of + bd + c + sq + case { [x, y] then [x - 1, y + 1] } + moveLine of + bd + c + sq + case { [x, y] then [x + 1, y + 1] } + moveLine of + bd + c + sq + case { [x, y] then [x - 1, y - 1] } + moveLine of + bd + c + sq + case { [x, y] then [x + 1, y - 1] } + x => x + ) of Nil + +fun rookmoves(c, sq, bd) = + (moveLine of + bd + c + sq + case { [x, y] then [x - 1, y] } + moveLine of + bd + c + sq + case { [x, y] then [x + 1, y] } + moveLine of + bd + c + sq + case { [x, y] then [x, y - 1] } + moveLine of + bd + c + sq + case { [x, y] then [x, y + 1] } + x => x + ) of Nil + +fun kingmoves(c, pq, bd) = if pq is [p, q] then + sift of + c + bd + Nil + [p - 1, q + 1] :: + [p, q + 1] :: + [p + 1, q + 1] :: + [p - 1, q] :: + [p + 1, q] :: + [p - 1, q - 1] :: + [p, q - 1] :: + [p + 1, q - 1] :: Nil + +fun knightmoves(c, pq, bd) = if pq is [p, q] then + sift of + c + bd + Nil + [p - 1, q + 2] :: + [p + 1, q + 2] :: + [p - 2, q + 1] :: + [p + 2, q + 1] :: + [p - 2, q - 1] :: + [p + 2, q - 1] :: + [p - 1, q - 2] :: + [p + 1, q - 2] :: Nil + +fun pawnmoves(c, pq, bd) = if pq is [p, q] then + let fwd = if c is White then 1 else -1 + fun promote(xy, mcp) = if xy is [x, y] and + ((c is Black) and y === 1) || ((c is White) and y === 8) then + map( + param => Move([x, y], mcp, Some(param)), + [c, Queen] :: + [c, Rook] :: + [c, Bishop] :: + [c, Knight] :: Nil + ) + else Move([x, y], mcp, None) :: Nil + let movs = + let on1 = [p, q + fwd] + let on2 = [p, q + 2 * fwd] + if pieceAt(bd, on1) is None then + promote(on1, None) +: + (if (q === 2 and c is White) || (q === 7 and c is Black) and pieceAt(bd, on2) is None then + Move(on2, None, None) :: Nil + else Nil) + else Nil + fun lscomp1(ls) = if ls is + Nil then Nil + sq :: sqs then + fun lscomp2(ls) = if ls is + Nil then lscomp1(sqs) + h :: ls and + h is Some(p_) and not(colourOf(p_) === c) then promote(sq, Some(p_)) :: lscomp2(ls) + else lscomp2(ls) + lscomp2(pieceAt(bd, sq) :: Nil) + let caps = concat(lscomp1([p + 1, q + fwd] :: [p - 1, q + fwd] :: Nil)) + movs +: caps + +fun queenmoves(c, sq, bd) = bishopmoves(c, sq, bd) +: rookmoves(c, sq, bd) + +fun kingincheck(c, bd) = + fun givesCheck(kxy) = if kxy is [k, [x, y]] then + fun kthreat(param) = if kingSquare(c, bd) is [xk, yk] and param is + King then (abs(x - xk) <= 1) and (abs(y - yk) <= 1) + Queen then kthreat(Rook) || kthreat(Bishop) + Rook then + ((x === xk) && emptyAtAll(bd, case { [xe, ye] then (xe === xk) && ((min(y, yk) < ye) && (ye < max(y, yk))) } )) || + ((y === yk) && emptyAtAll(bd, case { [xe, ye] then (ye === yk) && ((min(x, xk) < xe) && (xe < max(x, xk))) } )) + Bishop then + (((x + y) === (xk + yk)) && emptyAtAll(bd, case { [xe, ye] then ((xe + ye) === (xk + yk)) && ((min(x, xk) < xe) && (xe < max(x, xk))) } )) || + (((x - y) === (xk - yk)) && emptyAtAll(bd, case { [xe, ye] then ((xe - ye) === (xk - yk)) && ((min(x, xk) < xe) && (xe < max(x, xk))) } )) + Knight then + (((abs(x - xk)) === 2) && ((abs(y - yk)) === 1)) || (((abs(x - xk)) === 1) && ((abs(y - yk)) === 2)) + Pawn then + ((abs(x - xk) === 1) && (if c is Black then yk === (y + 1) else yk === (y - 1))) + kthreat(k) + any(givesCheck, forcesColoured(opponent(c), bd)) + +fun tryMove(c, ksq, m, bd) = if + ksq is [k, sq] and m is Move(sq_, mcp, mpp) then + let p = [c, k] + let bd1 = rmPieceAt(c, sq, bd) + let p_ = maybe(p, x => x, mpp) + let bd2 = maybe( + putPieceAt(sq_, p_, bd1), + dummy => putPieceAt(sq_, p_, rmPieceAt(opponent(c), sq_, bd1)), + mcp + ) + if not(kingincheck(c, bd2)) then Some([MoveInFull(p, sq, Move(sq_, mcp, mpp)), bd2]) else None + else + throw Error(m) + +fun rawmoves(c, ksq, bd) = if ksq is [k, sq] then + let m = if k is + King then kingmoves + Queen then queenmoves + Rook then rookmoves + Bishop then bishopmoves + Knight then knightmoves + Pawn then pawnmoves + let res = m(c, sq, bd) + res + +fun moveDetailsFor(c, bd) = foldr of + (ksq, ms) => foldr of + (rm, ms_) => maybe(x => x, h => (t => h :: t), tryMove(c, ksq, rm, bd))(ms_) + ms + rawmoves(c, ksq, bd) + Nil + forcesColoured(c, bd) + +fun comment(s) = (s is Nil) || listEq(take(2, s), nofibStringToList("--")) + +fun last(ls) = if ls is + x :: Nil then x + h :: t then last(t) + +fun intOfString(s) = globalThis.parseInt(nofibListToString(s)) + +fun parseGoal(ls) = if ls is + gltxt :: Nil then + let ws = words(gltxt) + let c = if listEq(head(ws), nofibStringToList("Black")) then Black else White + let n = intOfString(last(ws)) + [c, n] + else throw Error("parseGoal") + +fun parseSquare(r, f, c) = if c === "-" then Nil else + let clr = if isUpper(c) then Black else White + let kin = if toLower(c) === + "k" then King + "q" then Queen + "r" then Rook + "b" then Bishop + "n" then Knight + "p" then Pawn + [[clr, kin], [f, r]] :: Nil + +fun parseRank(r, x) = concat of zipWith of + (a, b) => parseSquare(r, a, b) + enumFromTo(1, 8) + filter(pp => not(pp === " "), x) + + +fun parseBoard(ls) = + fun addPiece(p_sq, x) = if p_sq is [p, sq] then putPieceAt(sq, p, x) + foldr of + addPiece + emptyBoard + concat(zipWith(parseRank, reverse(enumFromTo(1, 8)), ls)) + +fun parseProblem(s) = + let bdtxt_gltxt = splitAt(8, filter(x => not(comment(x)), s)) + if bdtxt_gltxt is [bdtxt, gltxt] then + let bd = parseBoard(bdtxt) + let gl = parseGoal(gltxt) + [bd, gl] + +fun readProblem(s) = parseProblem(lines(s)) + +fun foldr_lz(f, a, x) = if x is + h :: t then f(h, lazy of () => foldr_lz(f, a, t)) + Nil then a + +//│ ———————————————————————————————————————————————————————————————————————————————— +fun replies(bd, c, n) = + let mds = moveDetailsFor(c, bd) + fun solnAnd(mifb, rest) = if mifb is [mif, b] then + let sm = solution(b, opponent(c), n - 1) + if sm is + None then None + Some(s) and + force(rest) is + None then None + Some(ms) then Some([mif, s] :: ms) + if n + === 0 and + null_(mds) then Some(Nil) + else None + > 0 then foldr_lz(solnAnd, Some(Nil), mds) + else throw Error("n < 0") + +fun solution(bd, c, n) = + fun solnOr(mifb, other) = if mifb is + [mif, b] then + let rsm = replies(b, opponent(c), n - 1) + if rsm is + None then force(other) + Some(Nil) and + kingincheck(opponent(c), b) then + Some(Solution(mif, Nil)) + else force(other) + Some(rs) then Some(Solution(mif, rs)) + if n > 0 then + let mds = moveDetailsFor(c, bd) + foldr_lz(solnOr, None, mds) + else throw Error("n <= 0") +//│ ———————————————————————————————————————————————————————————————————————————————— + +data class Soln(a: MoveInFull, b: List[[List[MoveInFull],Soln]]) + +fun tab(n) = if n <= 0 then Nil else " " :: tab(n - 1) + +//│ ———————————————————————————————————————————————————————————————————————————————— +fun showReplies(rs, n) = if rs is + Nil then Nil + [mifs, s] :: rs then + tab(n) +: + nofibStringToList("if ") +: + if null_(rs) && (listLen(mifs) > 1) then nofibStringToList("others") else showMoves(mifs) +: + nofibStringToList("; ") +: + showSoln(s, n + 1) +: + showReplies(rs, n) + +fun showSoln(s, n) = if s is Soln(mif, rs) then + nofibStringToList(stringOfInt(n)) +: + nofibStringToList(". ") +: + showMoveInFull(mif) +: + if rs is + Nil then nofibStringToList("++\n") + [mifs, s_] :: Nil then + nofibStringToList(", ") +: + (if listLen(mifs) > 1 then nofibStringToList("...") else showMoves(mifs)) +: + nofibStringToList("; ") +: + showSoln(s_, n + 1) + else + nofibStringToList(",\n") +: showReplies(sort(rs), n) +//│ ———————————————————————————————————————————————————————————————————————————————— + + +//│ ———————————————————————————————————————————————————————————————————————————————— +fun compact(s) = if s is Solution(mif, rs) then Soln(mif, foldr(insertCompact, Nil, rs)) + +fun insertCompact(mif_s, ls) = if mif_s is [mif, s] then + fun insert(x, ls) = if ls is + Nil then x :: Nil + y :: ys then if x > y then y :: insert(x, ys) else x :: y :: ys + let cs = compact(s) + fun ic(ls) = if ls is + Nil then [mif :: Nil, cs] :: Nil + [mifs, cs_] :: etc then + let a = showSoln(cs, 1) + let b = showSoln(cs_, 1) + if + ltList(a, b, (x, y) => x < y, (x, y) => x > y) then [mif :: Nil, cs] :: [mifs, cs_] :: etc + listEq(a, b) then [insert(mif, mifs), cs] :: etc + not(ltList(a, b, (x, y) => x < y, (x, y) => x > y)) then [mifs, cs_] :: ic(etc) + else throw Error("compare error") + ic(ls) +//│ ———————————————————————————————————————————————————————————————————————————————— + +fun showResult(s) = if s is + None then nofibStringToList("No solution!") + Some(s) then showSoln(compact(s), 1) + +fun solve(bd, c, n) = showResult(solution(bd, c, (2 * n) - 1)) + +fun testMate_nofib(dummy) = + let input = nofibStringToList of + fs.readFileSync("hkmc2/shared/src/test/mlscript/nofib/input/heathcote3.prob").toString() + let bdcn = readProblem(input) + if bdcn is [bd, [c, n]] then + showBoard(bd) +: + nofibStringToList("\n") +: + showColour(c) +: + nofibStringToList(" to move and mate in ") +: + nofibStringToList(stringOfInt(n)) +: + nofibStringToList("\n") +: + nofibStringToList("\n") +: + solve(bd, c, n) + +fun main() = nofibListToString(testMate_nofib(0)) +//│ > - - - - - - - - +//│ > - - - - - - - - +//│ > - - - - - - - - +//│ > - - - - P - - - +//│ > - - - - p - k b +//│ > - P n - K - - - +//│ > - P - - - - - - +//│ > - q - - - - - - +//│ > +//│ > White to move and mate in 3 +//│ > +//│ > 1. N/QB3-QR2, +//│ > if K-Q5; 2. B/KR4-KB2, K-QB5; 3. Q/QN1-KB1++ +//│ > if K-Q7; 2. K-KB3, P/QN6xN/QR7; 3. B/KR4-K1++ +//│ > if K-K7; 2. N/QR2-QN4, +//│ > if K-Q7; 3. Q/QN1-K1++ +//│ > if K-K6; 3. Q/QN1-Q3++ +//│ > if P/QN6xN/QR7; 2. Q/QN1-QB2, ...; 3. B/KR4-KB2++ +//│ > diff --git a/benchmark/src/nofib/minimax.mls b/benchmark/src/nofib/minimax.mls new file mode 100644 index 000000000..f484c851c --- /dev/null +++ b/benchmark/src/nofib/minimax.mls @@ -0,0 +1,311 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module minimax with ... + + +fun andd(ls) = if ls is + Nil then true + b :: bs then b && andd(bs) + +abstract class Piece: X | O | Empty + +object + X extends Piece + O extends Piece + Empty extends Piece + +fun eqPiece(p1, p2) = if p1 is + X and p2 is X then true + O and p2 is O then true + Empty and p2 is Empty then true + else false + +abstract class Evaluation: XWin | OWin | Score + +object + XWin extends Evaluation + OWin extends Evaluation + +data class Score(i: Int) extends Evaluation + +fun evaluationEq(x, y) = if x is + XWin and y is XWin then true + OWin and y is OWin then true + Score(i) and y is Score(j) and i === j then true + else false + +data class Branch[A](a: A, cs: List[Branch[A]]) + +fun showEvaluation(e) = if e is + XWin then nofibStringToList("XWin") + OWin then nofibStringToList("OWin") + Score(i) then nofibStringToList("Score ") +: nofibStringToList(stringOfInt(i)) + +val win1 = + (1 :: 1 :: 1 :: Nil) :: + (0 :: 0 :: 0 :: Nil) :: + (0 :: 0 :: 0 :: Nil) :: Nil +//│ win1 = [[1,1,1],[0,0,0],[0,0,0]] + +val win2 = + (0 :: 0 :: 0 :: Nil) :: + (1 :: 1 :: 1 :: Nil) :: + (0 :: 0 :: 0 :: Nil) :: Nil +//│ win2 = [[0,0,0],[1,1,1],[0,0,0]] + +val win3 = + (0 :: 0 :: 0 :: Nil) :: + (0 :: 0 :: 0 :: Nil) :: + (1 :: 1 :: 1 :: Nil) :: Nil +//│ win3 = [[0,0,0],[0,0,0],[1,1,1]] + +val win4 = + (1 :: 0 :: 0 :: Nil) :: + (1 :: 0 :: 0 :: Nil) :: + (1 :: 0 :: 0 :: Nil) :: Nil +//│ win4 = [[1,0,0],[1,0,0],[1,0,0]] + +val win5 = + (0 :: 1 :: 0 :: Nil) :: + (0 :: 1 :: 0 :: Nil) :: + (0 :: 1 :: 0 :: Nil) :: Nil +//│ win5 = [[0,1,0],[0,1,0],[0,1,0]] + +val win6 = + (0 :: 0 :: 1 :: Nil) :: + (0 :: 0 :: 1 :: Nil) :: + (0 :: 0 :: 1 :: Nil) :: Nil +//│ win6 = [[0,0,1],[0,0,1],[0,0,1]] + +val win7 = + (1 :: 0 :: 0 :: Nil) :: + (0 :: 1 :: 0 :: Nil) :: + (0 :: 0 :: 1 :: Nil) :: Nil +//│ win7 = [[1,0,0],[0,1,0],[0,0,1]] + +val win8 = + (0 :: 0 :: 1 :: Nil) :: + (0 :: 1 :: 0 :: Nil) :: + (1 :: 0 :: 0 :: Nil) :: Nil +//│ win8 = [[0,0,1],[0,1,0],[1,0,0]] + +val wins = win1 :: win2 :: win3 :: win4 :: win5 :: win6 :: win7 :: win8 :: Nil +//│ wins = [[[1,1,1],[0,0,0],[0,0,0]],[[0,0,0],[1,1,1],[0,0,0]],[[0,0,0],[0,0,0],[1,1,1]],[[1,0,0],[1,0,0],[1,0,0]],[[0,1,0],[0,1,0],[0,1,0]],[[0,0,1],[0,0,1],[0,0,1]],[[1,0,0],[0,1,0],[0,0,1]],[[0,0,1],[0,1,0],[1,0,0]]] + +fun showPiece(p) = if p is + X then nofibStringToList("X") + O then nofibStringToList("O") + Empty then nofibStringToList(" ") + +fun showRow(ps) = if ps is + p1 :: p2 :: p3 :: Nil then + showPiece(p1) +: nofibStringToList("|") +: showPiece(p2) +: nofibStringToList("|") +: showPiece(p3) + +fun showBoard(rs) = if rs is + r1 :: r2 :: r3 :: Nil then + showRow(r1) +: + nofibStringToList("\n------\n") +: + showRow(r2) +: + nofibStringToList("\n------\n") +: + showRow(r3) +: + nofibStringToList("\n\n") + +fun insert(p, ps, i) = if ps is Cons(p1, Cons(p2, Cons(p3, Nil))) and i === + 1 then p :: p2 :: p3 :: Nil + 2 then p1 :: p :: p3 :: Nil + 3 then p1 :: p2 :: p :: Nil + +fun empty_(x, r) = if + x === 1 and r is Empty :: _ :: _ :: Nil then true + x === 2 and r is _ :: Empty :: _ :: Nil then true + x === 3 and r is _ :: _ :: Empty :: Nil then true + else false + +fun empty(pos, board) = if board is r1 :: r2 :: r3 :: Nil and pos is + [1, x] then empty_(x, r1) + [2, x] then empty_(x, r2) + [3, x] then empty_(x, r3) + +fun placePiece(p, board, pos) = if + not(empty(pos, board)) then Nil + board is r1 :: r2 :: r3 :: Nil and pos is + [1, x] then (insert(p, r1, x) :: r2 :: r3 :: Nil) :: Nil + [2, x] then (r1 :: insert(p, r2, x) :: r3 :: Nil) :: Nil + [3, x] then (r1 :: r2 :: insert(p, r3, x) :: Nil) :: Nil + +fun fullBoard(b) = andd of map of + x => not(eqPiece(x, Empty)) + concat(b) + +fun newPositions(piece, board) = + fun lscomp1(ls) = if ls is + Nil then Nil + x :: xs then + fun lscomp2(ls) = if ls is + Nil then lscomp1(xs) + y :: ys then [x, y] :: lscomp2(ys) + lscomp2(1 :: 2 :: 3 :: Nil) + concat of map of + pos => placePiece(piece, board, pos) + lscomp1(1 :: 2 :: 3 :: Nil) + +val initialBoard = replicate(3, replicate(3, Empty)) +//│ initialBoard = [[Empty,Empty,Empty],[Empty,Empty,Empty],[Empty,Empty,Empty]] + +fun eval(x) = if x === + 3 then XWin + -3 then OWin + else Score(x) + +fun interpret(x, l) = if l is + Nil then Score(x) + Score(y) :: ls then interpret(x + y, ls) + XWin :: _ then XWin + OWin :: _ then OWin + +fun scorePiece(p, score) = if p is + X then score + Empty then 0 + O then -score + +fun map2(f, xs, ys) = if xs is + Nil then Nil + x :: xs and + ys is y :: ys then f(x, y) :: map2(f, xs, ys) + Nil then Nil + +fun score(board, win) = eval of sum of map of + sum + map2((x, y) => map2(scorePiece, x, y), board, win) + +fun static(board) = interpret(0, map(x => score(board, x), wins)) + +fun repTree(f, g, a) = Branch(a, map(x => repTree(g, f, x), f(a))) + +fun mapTree(f, t) = if t is Branch(a, l) then Branch(f(a), map(x => mapTree(f, x), l)) + +fun prune(n, t) = if t is Branch(a, l) and n + === 0 then Branch(a, Nil) + < 0 then throw Error("Tree.prune: < 0") + else Branch(a, map(x => prune(n - 1, x), l)) + +fun opposite(p) = if p is + X then O + O then X + else throw Error("opposite") + +fun best(f, bs, ss) = if bs is b :: bs and ss is s :: ss then + fun best_(b, s, ls1, ls2) = if ls1 is + Nil and ls2 is Nil then [b, s] + b_ :: bs and ls2 is s_ :: ss and + evaluationEq(s, f(s, s_)) then best_(b, s, bs, ss) + else best_(b_, s_, bs, ss) + best_(b, s, bs, ss) + +fun showMove(m) = if m is [b, e] then + showEvaluation(e) +: nofibStringToList("\n") +: showBoard(b) + +fun max_(e1, e2) = if + e1 is XWin then XWin + e2 is XWin then XWin + e2 is OWin then e1 + e1 is OWin then e2 + e1 is Score(x) and e2 is Score(y) and + x > y then Score(x) + else Score(y) + +fun min_(e1, e2) = if + e1 is OWin then OWin + e2 is OWin then OWin + e2 is XWin then e1 + e1 is XWin then e2 + e1 is Score(x) and e2 is Score(y) and + x < y then Score(x) + else Score(y) + +fun mise(f, g, t) = if t is + Branch(a, Nil) then a + Branch(_, l) then foldr(f, g(OWin, XWin), map(x => mise(g, f, x), l)) + +fun searchTree(p, board) = + prune of + 5 + repTree of + x => newPositions(p, x), + x => newPositions(opposite(p), x), + board + +fun cropTree(t) = if t is + Branch(a, Nil) then Branch(a, Nil) + Branch(Score(x), l) then Branch(Score(x), map(cropTree, l)) + Branch(x, l) then Branch(x, Nil) + +fun bestMove(p, f, g, b) = + mise(f, g, cropTree(mapTree(static, searchTree(p, b)))) + + +fun alternate(player, f, g, board) = if + fullBoard(board) then Nil + evaluationEq(static(board), XWin) then Nil + evaluationEq(static(board), OWin) then Nil + let opposition = opposite(player) + let possibles = newPositions(player, board) + let scores = map(x => bestMove(opposition, g, f, x), possibles) + let boardd_eval = best(f, possibles, scores) + boardd_eval is [boardd, eval] then + [boardd, eval] :: alternate(opposition, g, f, boardd) + +fun prog(input) = + let testBoard = + (Empty :: O :: Empty :: Nil) :: + (Empty :: X :: Empty :: Nil) :: + (Empty :: Empty :: Empty :: Nil) :: Nil + fun board(x) = if x === + "doesn't happen" then testBoard +: testBoard + else testBoard + let game = alternate(X, max_, min_, board(input)) + nofibStringToList("OXO\n") +: + concat of map(showMove, game) + +fun main() = nofibListToString(prog("180000")) +//│ > OXO +//│ > XWin +//│ > X|O| +//│ > ------ +//│ > |X| +//│ > ------ +//│ > | | +//│ > +//│ > XWin +//│ > X|O|O +//│ > ------ +//│ > |X| +//│ > ------ +//│ > | | +//│ > +//│ > XWin +//│ > X|O|O +//│ > ------ +//│ > X|X| +//│ > ------ +//│ > | | +//│ > +//│ > XWin +//│ > X|O|O +//│ > ------ +//│ > X|X|O +//│ > ------ +//│ > | | +//│ > +//│ > XWin +//│ > X|O|O +//│ > ------ +//│ > X|X|O +//│ > ------ +//│ > X| | +//│ > +//│ > diff --git a/benchmark/src/nofib/para.mls b/benchmark/src/nofib/para.mls new file mode 100644 index 000000000..131d4eb32 --- /dev/null +++ b/benchmark/src/nofib/para.mls @@ -0,0 +1,237 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module para with ... + + + +fun unwords(ws) = if ws is + Nil then Nil + w :: ws then + fun go(vs) = if vs is + Nil then Nil + v :: vs then " " :: (v +: go(vs)) + w +: go(ws) + +fun break_(p, xs) = if xs is + Nil then [Nil, Nil] + x :: xs and + p(x) then [Nil, x :: xs] + break_(p, xs) is [ys, zs] then [x :: ys, zs] + +fun isSpace(c) = c === " " + +fun words(s) = if dropWhile(isSpace, s) is + Nil then Nil + h :: t and + break_(isSpace, h :: t) is [w, s_] then w :: words(s_) + +fun lines(s) = if break_(x => x === "\n", s) is [l, s_] then + Cons( + l, + if s_ is + Nil then Nil + _ :: s__ then lines(s__) + ) + +fun unlines(ls) = concat(map(l => l +: nofibStringToList("\n"), ls)) + +fun all(p, xs) = if xs is + Nil then true + x :: xs then p(x) && all(p, xs) + +fun fold1(f, g, xs) = if xs is + a :: Nil then g(a) + a :: x then f(a, fold1(f, g, x)) + +fun scan1(f, g, xs) = fold1((a, s) => f(a, head(s)) :: s, a => g(a) :: Nil, xs) + +fun tails(xs) = scan1((a, s) => a :: s, a => a :: Nil, xs) + +fun single(xs) = if xs is + a :: Nil then true + _ then false + +fun minWith(f, xs) = fold1((a, b) => if f(a) < f(b) then a else b, x => x, xs) + +fun new_(w, ls) = (w :: Nil) :: ls + +fun glue(w, ls) = if ls is + l :: ls_ then (w :: l) :: ls_ + +fun formats(txt) = fold1 of + (w, ps) => map(p => new_(w, p), ps) +: map(p => glue(w, p), ps) + x => ((x :: Nil) :: Nil) :: Nil + txt + +val maxw = 70 +//│ maxw = 70 + +fun width(ls) = + fun plus(w, n) = listLen(w) + 1 + n + fold1(plus, listLen, ls) + +fun fits(xs) = width(xs) <= maxw + +fun feasible(a) = all(fits, a) + +val optw = 63 +//│ optw = 63 + +fun cost(ls) = + fun linc(l) = let a = optw - width(l) in a * a + fun plus(l, n) = linc(l) + n + fold1(plus, x => 0, ls) + +fun par0(x) = minWith(cost, filter(feasible, formats(x))) + +fun fitH(ls) = fits(head(ls)) + +fun fst3(a_b_c) = if a_b_c is [a, b, c] then a + +fun snd3(a_b_c) = if a_b_c is [a, b, c] then b + +fun thd3(a_b_c) = if a_b_c is [a, b, c] then c + +fun width_tl(a_b_c) = fst3(a_b_c) + +fun cost_tl(a_b_c) = snd3(a_b_c) + +fun len_tl(a_b_c) = thd3(a_b_c) + +fun tile(ws, a_b) = if a_b is + [Nil, n] then Nil + [m :: ms, n] then + let l = n - m + if splitAt(l, ws) is [ws1, ws2] then + ws1 :: tile(ws2, [drop(l, m :: ms), m]) + +fun null__(a_b) = if a_b is [Nil, Nil] then true else false + +fun single_(a_b) = if a_b is [x, y] then (null_(x) && single(y)) || (single(x) && null_(y)) + + +val nil_ = [Nil, Nil] +//│ nil_ = [[], []] + +fun head_(a_b) = if a_b is [x, y] and + not(null_(x)) then head(x) + else head(y) + +fun last_(a_b) = if a_b is [y, x] and + not(null_(x)) then head(x) + else head(y) + +fun cons_(a, a_b) = if a_b is [x, y] and + not(null_(y)) then [a :: x, y] + else [a :: Nil, x] + +fun snoc_(a, a_b) = if a_b is [y, x] and + not(null_(y)) then [y, a :: x] + else [x, a :: Nil] + +fun tail_(a_b) = if a_b is [x, y] and + null_(x) then [Nil, Nil] + single(x) and splitAt(intDiv(listLen(y), 2), y) is [y0, y1] then + [reverse(y1), y0] + else [tail(x), y] + +fun init_(a_b) = if a_b is [y, x] and + null_(x) then [Nil, Nil] + single(x) and splitAt(intDiv(listLen(y), 2), y) is [y0, y1] then + [y0, reverse(y1)] + else [y, tail(x)] + +fun unformat(a, l) = fold1((xs, ys) => xs +: (a :: Nil) +: ys, x => x, l) + +fun format(a, x) = if + x is Nil then Nil :: Nil + else + fun unknownEq(a, b) = a === b + fun breakk(a, b, xs) = + if unknownEq(a, b) + then Nil :: xs + else (b :: head(xs)) :: tail(xs) + fun start(a, b) = breakk(a, b, Nil :: Nil) + fold1((x, y) => breakk(a, x, y), y => start(a, y), x) + +fun unparas(ls) = unformat(Nil, ls) + +fun paras(ls) = filter(x => listNeq(Nil, x), format(Nil, ls)) + +fun parse(ls) = paras(map(words, lines(ls))) + +fun unparse(ls) = unlines(map(unwords, unparas(ls))) + +fun startr(a) = if + a <= maxw then [cons_([0, 0, 0], nil_), a, 1] + else throw Error("startr param error") + +fun ceildiv(n, m) = intDiv(n + m - 1, m) + +fun fmtWith(par) = unparse(map(x => par(concat(x)), parse(par))) + +fun stepr(w, ps_tw_tl) = if ps_tw_tl is [ps, tw, tl] then + let tot_width = w + 1 + tw + let tot_len = 1 + tl + fun single(p) = len_tl(p) === 0 + fun width_hd(p) = if single(p) then tot_width else tot_width - width_tl(p) - 1 + fun cost(p) = if single(p) then 0 else cost_tl(p) + (let a = optw - width_hd(p) in a * a) + fun old_width_hd(p) = if single(p) then tw else tw - width_tl(p) - 1 + fun new_(p) = if single(p) then [tw, 0, tl] else [tw, cost_tl(p) + (let x = optw - old_width_hd(p) in x * x), tl] + fun trim(ps_pq) = if + null__(ps_pq) then ps_pq + single_(ps_pq) then ps_pq + let ps_p = init_(ps_pq) + let q = last_(ps_pq) + let p = last_(ps_p) + cost(p) <= cost(q) then trim(ps_p) + else ps_pq + fun drop_nofit(ps_p) = if + null__(ps_p) then ps_p + width_hd(last_(ps_p)) > maxw then drop_nofit(init_(ps_p)) + else ps_p + fun bf(p, q) = + let wqh = width_hd(q) + let rqh = maxw - wqh + 1 + if + single(q) && cost_tl(p) === 0 then min(optw - width_hd(p), rqh) + single(q) then rqh + else min(ceildiv(cost(p) - cost(q), 2 * (wqh - width_hd(p))), rqh) + fun myAdd(p, qr_rs) = if + single_(qr_rs) || null__(qr_rs) then cons_(p, qr_rs) + let q = head_(qr_rs) + let r_rs = tail_(qr_rs) + let r = head_(r_rs) + bf(p, q) <= bf(q, r) then myAdd(p, r_rs) + else cons_(p, qr_rs) + [trim(drop_nofit(myAdd(new_(last_(ps)), ps))), tot_width, tot_len] + +fun par3(ws) = + let zs = scan1(stepr, startr, map(listLen, ws)) + tile(ws, [map(x => len_tl(last_(fst3(x))), zs), thd3(head(zs))]) + +fun fmt(x) = unparse(map(par3, concat(parse(x)))) + +val test = + concat of + nofibStringToList("In the constructive programming community it is commonplace to see ") :: + nofibStringToList("formal developments of textbook algorithms. In the algorithm design ") :: + nofibStringToList("community, on the other hand, it may be well known that the textbook ") :: + nofibStringToList("solution to a problem is not the most efficient possible. However, in ") :: + nofibStringToList("presenting the more efficient solution, the algorithm designer will ") :: + nofibStringToList("usually omit some of the implementation details, this creating an ") :: + nofibStringToList("algorithm gap between the abstract algorithm and its concrete ") :: + nofibStringToList("implementation. This is in contrast to the formal development, which ") :: + nofibStringToList("usually presents the complete concrete implementation of the less ") :: + nofibStringToList("efficient solution.\n\n") :: Nil +//│ test = ["I","n"," ","t","h","e"," ","c","o","n","s","t","r","u","c","t","i","v","e"," ","p","r","o","g","r","a","m","m","i","n","g"," ","c","o","m","m","u","n","i","t","y"," ","i","t"," ","i","s"," ","c","o","m","m","o","n","p","l","a","c","e"," ","t","o"," ","s","e","e"," ","f","o","r","m","a","l"," ","d","e","v","e","l","o","p","m","e","n","t","s"," ","o","f"," ","t","e","x","t","b","o","o","k"," ","a","l","g","o","r","i","t","h","m","s","."," ","I","n"," ","t","h","e"," ","a","l","g","o","r","i","t","h","m"," ","d","e","s","i","g","n"," ","c","o","m","m","u","n","i","t","y",","," ","o","n"," ","t","h","e"," ","o","t","h","e","r"," ","h","a","n","d",","," ","i","t"," ","m","a","y"," ","b","e"," ","w","e","l","l"," ","k","n","o","w","n"," ","t","h","a","t"," ","t","h","e"," ","t","e","x","t","b","o","o","k"," ","s","o","l","u","t","i","o","n"," ","t","o"," ","a"," ","p","r","o","b","l","e","m"," ","i","s"," ","n","o","t"," ","t","h","e"," ","m","o","s","t"," ","e","f","f","i","c","i","e","n","t"," ","p","o","s","s","i","b","l","e","."," ","H","o","w","e","v","e","r",","," ","i","n"," ","p","r","e","s","e","n","t","i","n","g"," ","t","h","e"," ","m","o","r","e"," ","e","f","f","i","c","i","e","n","t"," ","s","o","l","u","t","i","o","n",","," ","t","h","e"," ","a","l","g","o","r","i","t","h","m"," ","d","e","s","i","g","n","e","r"," ","w","i","l","l"," ","u","s","u","a","l","l","y"," ","o","m","i","t"," ","s","o","m","e"," ","o","f"," ","t","h","e"," ","i","m","p","l","e","m","e","n","t","a","t","i","o","n"," ","d","e","t","a","i","l","s",","," ","t","h","i","s"," ","c","r","e","a","t","i","n","g"," ","a","n"," ","a","l","g","o","r","i","t","h","m"," ","g","a","p"," ","b","e","t","w","e","e","n"," ","t","h","e"," ","a","b","s","t","r","a","c","t"," ","a","l","g","o","r","i","t","h","m"," ","a","n","d"," ","i","t","s"," ","c","o","n","c","r","e","t","e"," ","i","m","p","l","e","m","e","n","t","a","t","i","o","n","."," ","T","h","i","s"," ","i","s"," ","i","n"," ","c","o","n","t","r","a","s","t"," ","t","o"," ","t","h","e"," ","f","o","r","m","a","l"," ","d","e","v","e","l","o","p","m","e","n","t",","," ","w","h","i","c","h"," ","u","s","u","a","l","l","y"," ","p","r","e","s","e","n","t","s"," ","t","h","e"," ","c","o","m","p","l","e","t","e"," ","c","o","n","c","r","e","t","e"," ","i","m","p","l","e","m","e","n","t","a","t","i","o","n"," ","o","f"," ","t","h","e"," ","l","e","s","s"," ","e","f","f","i","c","i","e","n","t"," ","s","o","l","u","t","i","o","n",".","\n","\n"] + +fun testPara_nofib() = + if null_(test) then Nil else fmt(test) + +fun main() = nofibListToString(testPara_nofib()) +//│ = "In the constructive programming community it is commonplace to\nsee formal developments of textbook algorithms. In the algorithm\ndesign community, on the other hand, it may be well known that\nthe textbook solution to a problem is not the most efficient\npossible. However, in presenting the more efficient solution, the\nalgorithm designer will usually omit some of the implementation\ndetails, this creating an algorithm gap between the abstract\nalgorithm and its concrete implementation. This is in contrast\nto the formal development, which usually presents the complete\nconcrete implementation of the less efficient solution.\n" diff --git a/benchmark/src/nofib/power.mls b/benchmark/src/nofib/power.mls new file mode 100644 index 000000000..4b0b1fc96 --- /dev/null +++ b/benchmark/src/nofib/power.mls @@ -0,0 +1,150 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module power with ... + + + +abstract class Pss[T]: Pz | Pc[T] + +type Ps[T] = Lazy[Pss[T]] + +data class Pc[T](f: T, s: Ps[T]) extends Pss[T] + +object Pz extends Pss + +fun list() = lazy of () => Pc(1, list()) + +fun x_() = lazy of () => Pc(0, lazy of () => Pc(1, lazy of () => Pz)) + +fun fromIntegerPs(c) = if + c == 0 then lazy of () => Pz + else lazy of () => Pc(c, lazy of () => Pz) + +fun extract(n, ps) = if + n == 0 then Nil + force(ps) is + Pz then Nil + Pc(x, ps) then x :: extract(n - 1, ps) + +fun dotMult(c, ps) = lazy of () => if force(ps) is + Pz then Pz + Pc(f, fs_) then Pc(c * f, dotMult(c, fs_)) + +fun dotMultSndLz(c, ps) = lazy of () => if force(force(ps)) is + Pz then Pz + Pc(f, fs_) then Pc(c * f, dotMult(c, fs_)) + +fun negatePs(ps) = lazy of () => if force(ps) is + Pz then Pz + Pc(f, fs_) then Pc(-f, negatePs(fs_)) + +fun addPs(fss, gs) = lazy of () => if force(fss) is + Pz then force(gs) + Pc(f, fs_) and force(gs) is + Pz then force(fss) + Pc(g, gs) then Pc(f+g, addPs(fs_, gs)) + +fun minusPs(a, b) = addPs(a, negatePs(b)) + +fun multPs(fss, gss) = lazy of () => if force(fss) is + Pz then Pz + Pc(f, fs_) and force(gss) is + Pz then Pz + Pc(g, gs) then Pc(f*g, addPs(addPs(dotMult(f, gs), dotMult(g, fs_)), multPs(multPs(x_(), fs_), gs))) + +fun multPsFstLz(fss, gss) = lazy of () => if force(force(fss)) is + Pz then Pz + Pc(f, fs_) and force(gss) is + Pz then Pz + Pc(g, gs) then Pc(f*g, addPs(addPs(dotMult(f, gs), dotMult(g, fs_)), multPs(multPs(x_(), fs_), gs))) + +fun powerPs(a, n) = if n <= 0 then fromIntegerPs(1) else multPs(a, powerPs(a, n - 1)) + +fun divPs(fss, gss) = lazy of () => if force(fss) is + Pz and force(gss) is + Pz then throw Error("power series 0/0") + Pc(0, gs) then force(divPs((lazy of () => Pz), gs)) + else Pz + Pc(0, fs_) and force(gss) is + Pc(0, gs) then force(divPs(fs_, gs)) + Pc(g, gs) then + let q = 0 + Pc(q, divPs(addPs(fs_, negatePs(dotMult(q, gs))), lazy of () => Pc(g, gs))) + Pc(f, fs_) and force(gss) is + Pc(g, gs) then + let q = f/g + Pc(q, divPs(addPs(fs_, negatePs(dotMult(q, gs))), lazy of () => Pc(g, gs))) + +fun compose_(fss, gss) = lazy of () => if force(fss) is + Pz then Pz + Pc(f, fs_) and force(gss) is + Pz then Pc(f, lazy of () => Pz) + Pc(0, gs) then Pc(f, multPs(gs, compose_(fs_, lazy of () => Pc(0, gs)))) + else force(addPs((lazy of () => Pc(f, lazy of () => Pz)), multPs(gss, compose_(fs_, gss)))) + +fun composeSndLz_(fss, gss) = lazy of () => if force(fss) is + Pz then Pz + Pc(f, fs_) and force(force(gss)) is + Pz then Pc(f, lazy of () => Pz) + Pc(0, gs) then Pc(f, multPs(gs, compose_(fs_, lazy of () => Pc(0, gs)))) + else force(addPs((lazy of () => Pc(f, lazy of () => Pz)), multPs(gss, composeSndLz_(fs_, gss)))) + +fun revert(fss) = lazy of () => if force(fss) is + Pc(0, fs_) then + fun rs() = lazy of () => Pc(0, divPs(fromIntegerPs(1), compose_(fs_, rs()))) + force(rs()) + Pc(f0, kss) and force(kss) is Pc(f1, gss) and force(gss) is Pz then + Pc(-1/f1, lazy of () => Pc(1/f1, lazy of () => Pz)) + +fun deriv(fss) = lazy of () => if force(fss) is + Pz then Pz + Pc(_, fs_) then + fun deriv1(gss, n) = lazy of () => if force(gss) is + Pz then Pz + Pc(f, fs_) then Pc(n * f, deriv1(fs_, n+1)) + force(deriv1(fs_, 1)) + +fun integral(fs_) = + fun int1(fss, n) = lazy of () => if force(fss) is + Pz then Pz + Pc(f, fs_) then Pc(f/n, int1(fs_, n + 1)) + + lazy of () => Pc(0, int1(fs_, 1)) + + +fun integralLz(fs_) = + fun int1(fss, n) = lazy of () => if force(fss) is + Pz then Pz + Pc(f, fs_) then Pc(f/n, int1(fs_, n + 1)) + + lazy of () => Pc(0, int1(fs_(), 1)) + + +fun sqrtPs(fss) = lazy of () => if force(fss) is + Pz then Pz + Pc(0, gss) and force(gss) is Pc(0, fs_) then Pc(0, sqrtPs(fs_)) + Pc(1, fs_) then + fun qs() = lazy of () => addPs(fromIntegerPs(1), integral(divPs(deriv(lazy of () => Pc(1, fs_)), dotMultSndLz(2, qs())))) + + force(force(qs())) + +fun ts() = lazy of () => Pc(1, multPs(ts(), ts())) + +fun tree() = lazy of () => Pc(0, composeSndLz_(list(), lazy of () => tree())) + +fun cosx() = minusPs((lazy of () => Pc(1, lazy of () => Pz)), integral(integralLz(cosx))) + +fun sinx() = integral(minusPs((lazy of () => Pc(1, lazy of () => Pz)), integralLz(sinx))) + +fun testPower_nofib(p) = + extract(p, minusPs(sinx(), sqrtPs(minusPs(fromIntegerPs(1), powerPs(cosx(), 2))))); + extract(p, minusPs(divPs(sinx(), cosx()), revert(integral(divPs(fromIntegerPs(1), addPs(fromIntegerPs(1), powerPs(x_(), 2))))))); + extract(p, ts()); + extract(p, tree()) + +fun main() = testPower_nofib(14).toString() +//│ = "[0,1,1,2,5,14,42,132,429,1430,4862,16796,58786,208012]" diff --git a/benchmark/src/nofib/pretty.mls b/benchmark/src/nofib/pretty.mls new file mode 100644 index 000000000..3b9d25050 --- /dev/null +++ b/benchmark/src/nofib/pretty.mls @@ -0,0 +1,169 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module pretty with ... + + + +abstract class CSeq: CNil | CAppend | CIndent | CNewline | CStr | CCh + +data + class + CAppend(a: CSeq, b: CSeq) extends CSeq + CIndent(a: Int, b: CSeq) extends CSeq + CStr(a: List[Char]) extends CSeq + CCh(a: Char) extends CSeq + +object + CNil extends CSeq + CNewline extends CSeq + +abstract class PprStyle: PprForUser | PprDebug | PprShowAll | PprInterface + +object + PprForUser extends PprStyle + PprDebug extends PprStyle + PprShowAll extends PprStyle + PprInterface extends PprStyle + +val cNil = CNil +//│ cNil = CNil + +val cNL = CNewline +//│ cNL = CNewline + +fun cAppend(cs1, cs2) = CAppend(cs1, cs2) + +fun cIndent(n, cs) = CIndent(n, cs) + +fun cStr(s) = CStr(s) + +fun cCh(c) = CCh(c) + +fun mkIndent(n, s) = if n + === 0 then s + >= 8 then "\t" :: mkIndent(n - 8, s) + else " " :: mkIndent(n - 1, s) + +//│ ———————————————————————————————————————————————————————————————————————————————— +fun flattenS(nlp, seqs) = if seqs is + Nil then Nil + [col, seq] :: seqs then flatten(col, nlp, seq, seqs) + +fun flatten(n, nlp, cseq, seqs) = if cseq is + CNil then flattenS(nlp, seqs) + CAppend(seq1, seq2) then flatten(n, nlp, seq1, [n, seq2] :: seqs) + CIndent(n_, seq) then flatten(n_ + n, nlp, seq, seqs) + CNewline then "\n" :: flattenS(true, seqs) + CStr(s) and + nlp then mkIndent(n, s +: flattenS(false, seqs)) + else s +: flattenS(false, seqs) + CCh(c) and + nlp then mkIndent(n, c :: flattenS(false, seqs)) + else c :: flattenS(false, seqs) +//│ ———————————————————————————————————————————————————————————————————————————————— + +fun cShow(seq) = flatten(0, true, seq, Nil) + +data class MkPrettyRep(cseq: CSeq, n: Int, b1: Bool, b2: Bool) + +fun ppShow(width, p) = if p(width, false) is + MkPrettyRep(seq, ll, emp, sl) then cShow(seq) + +fun ppUnformatted(p) = if p(80, false) is + MkPrettyRep(seq, ll, emp, sl) then cShow(seq) + +fun ppNil(width, is_vert) = MkPrettyRep(cNil, 0, true, width >= 0) + +fun ppStr(s, width, is_vert) = + let ls = listLen(s) + MkPrettyRep(cStr(s), ls, false, width >= ls) + +fun ppChar(c, width, is_vert) = MkPrettyRep(cCh(c), 1, false, width >= 1) + +fun ppInt(n, width, is_vert) = ppStr(nofibStringToList(stringOfInt(n)), width, is_vert) + +fun pp_SP(a, b) = ppStr(nofibStringToList(", "), a, b) + +fun ppSP(a, b) = ppChar(" ", a, b) + +fun ppLbrack(a, b) = ppChar("[", a, b) + +fun ppRbrack(a, b) = ppChar("]", a, b) + +fun ppLparen(a, b) = ppChar("(", a, b) + +fun ppRparen(a, b) = ppChar(")", a, b) + +fun ppSemi(a, b) = ppChar(";", a, b) + +fun ppComma(a, b) = ppChar(",", a, b) + +fun andL(a, b) = if a then b else false + +fun orL(a, b) = if a then true else b + +fun ppBeside(p1, p2, width, is_vert) = if p1(width, false) is + MkPrettyRep(seq1, ll1, emp1, sl1) and p2(width - ll1, false) is + MkPrettyRep(seq2, ll2, emp2, sl2) then + MkPrettyRep(cAppend(seq1, cIndent(ll1, seq2)), ll1 + ll2, andL(emp1, emp2), andL(width >= 0, andL(sl1, sl2))) + +fun ppBesides(ps) = if ps is + Nil then ppNil + else foldr1((a, b) => (c, d) => ppBeside(a, b, c, d), ps) + +fun ppBesideSP(p1, p2, width, is_vert) = if p1(width, false) is MkPrettyRep(seq1, ll1, emp1, sl1) then + let li = if emp1 then 0 else ll1 + 1 + if p2(width - li, false) is MkPrettyRep(seq2, ll2, emp2, sl2) then + let wi = if emp1 then 0 else 1 + let sp = if orL(emp1, emp2) then cNil else cCh(" ") + MkPrettyRep(cAppend(seq1, cAppend(sp, cIndent(li, seq2))), li + ll2, andL(emp1, emp2), andL(width >= wi, andL(sl1, sl2))) + +fun ppCat(ps) = if ps is Nil then ppNil else foldr1((a, b) => (c, d) => ppBesideSP(a, b, c, d), ps) + +fun ppAbove(p1, p2, width, is_vert) = if p1(width, true) is + MkPrettyRep(seq1, ll1, emp1, sl1) and p2(width, true) is + MkPrettyRep(seq2, ll2, emp2, sl2) then + let nl = if orL(emp1, emp2) then cNil else cNL + MkPrettyRep(cAppend(seq1, cAppend(nl, seq2)), ll2, andL(emp1, emp2), false) + +fun ppAboves(ps, a, b) = if ps is Nil then ppNil(a, b) else foldr1((a, b) => (c, d) => ppAbove(a, b, c, d), ps)(a, b) + +fun ppNest(n, p, width, is_vert) = if + is_vert and p(width - n, true) is MkPrettyRep(seq, ll, emp, sl) then + MkPrettyRep(cIndent(n, seq), ll + n, emp, sl) + else p(width, false) + +fun ppHang(p1, n, p2, width, is_vert) = if p1(width, false) is + MkPrettyRep(seq1, ll1, emp1, sl1) and p2(width - (ll1 + 1), false) is + MkPrettyRep(seq2, ll2, emp2, sl2) and p2(width - n, false) is + MkPrettyRep(seq2_, ll2_, emp2_, sl2_) and + emp1 then p2(width, is_vert) + orL(ll1 <= n, sl2) then + MkPrettyRep(cAppend(seq1, cAppend(cCh(" "), cIndent(ll1 + 1, seq2))), ll1 + 1 + ll2, false, andL(sl1, sl2)) + else MkPrettyRep(cAppend(seq1, cAppend(cNL, cIndent(n, seq2_))), ll2_, false, false) + +fun testPretty_nofib() = + fun pp_word(a, b) = ppStr(nofibStringToList("xxxxx"), a, b) + let pp_words = replicate(50, pp_word) + fun pretty_stuff(a, b) = ppAboves( + ppBesides(((a, b) => ppInt(-42, a, b)) :: ((a, b) => ppChar("@", a, b)) :: ((a, b) => ppStr(nofibStringToList("This is a string"), a, b)) :: Nil) :: + ((a, b) => pp_SP(a, b)) :: + ((a, b) => ppHang( + (a, b) => ppStr(nofibStringToList("This is the label"), a, b), + 8, + ppCat(pp_words), + a, + b + )) :: + Nil, + a, + b + ) + ppShow(80, pretty_stuff) +: nofibStringToList("\n") + +fun main() = nofibListToString(testPretty_nofib()) +//│ = "-42@This is a string\n, \nThis is the label\n\txxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx xxxxx\n" diff --git a/benchmark/src/nofib/primetest.mls b/benchmark/src/nofib/primetest.mls new file mode 100644 index 000000000..bc56fc3c0 --- /dev/null +++ b/benchmark/src/nofib/primetest.mls @@ -0,0 +1,138 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module primetest with ... + + + +fun even(x) = intMod(x, 2) == 0 + +fun int_val_of_char(x) = int_of_char(x) - 48 + +fun int_val_of_string(s) = + fun f(l, a) = if l is + Nil then a + h :: t then f(t, 10 * a + int_val_of_char(h)) + f(s, 0) + +fun break_(p, ls) = if ls is + Nil then [Nil, Nil] + x :: xs and + p(x) then [Nil, x :: xs] + break_(p, xs) is [ys, zs] then [x :: ys, zs] + +fun lines(s) = if break_(x => x == "|", s) is [l, s_] then + let tt = if s_ is + Nil then Nil + _ :: s__ then lines(s__) + + l :: tt + + +fun makeNumber(b, ls) = foldl((a, x) => a * b + x, 0, ls) + +fun chop(b, n) = + fun chop_(a, n) = if divMod(n, b) is [q, r] and + n == 0 then a + else chop_(r :: a, q) + + chop_(Nil, n) + + +fun powerMod(a, b, m) = + fun f(a, b, c) = + fun g(a, b) = if even(b) then g(intMod(a * a, m), intDiv(b, 2)) else f(a, b - 1, intMod(a * c, m)) + if b == 0 then c else g(a, b) + + if + b == 0 then 1 + let a_ = intMod(a, m) + else f(a_, b - 1, a_) + + +fun log2(x) = listLen(chop(2, x)) + +fun rands(s1, s2) = + let k = intDiv(s1, 53668) + let s1_ = ((40014 * (s1 - (k * 53668))) - (k * 12211)) + let s1__ = (if s1_ < 0 then s1_ + 2147483563 else s1_) + let k_ = intDiv(s2, 52774) + let s2_ = ((40692 * (s2 - (k_ * 52774))) - (k_ * 3791)) + let s2__ = (if s2_ < 0 then s2_ + 2147483399 else s2_) + let z = (s1__ - s2__) + + if z < 1 then lazy of () => LzCons(z + 2147483562, rands(s1__, s2__)) + else lazy of () => LzCons(z, rands(s1__, s2__)) + + +fun randomInts(s1, s2) = + if (1 <= s1) and (s1 <= 2147483562) and (1 <= s2) and (s2 <= 2147483398) then rands(s1, s2) + +fun findKQ(n) = + fun f(k, q) = if divMod(q, 2) is [d, r] and + r == 0 then f(k + 1, d) + else [k, q] + + f(0, n - 1) + + +fun uniform(nns, rrs) = if + nns is n :: Nil and rrs is r :: rs then intMod(r, n) :: Nil + nns is n :: ns and rrs is r :: rs and + let t = intMod(r, n + 1) + t == n then t :: uniform(ns, rs) + else t :: map(x => intMod(x, 65536), rs) + +fun random(n, rs) = + let ns = chop(65536, n) + if splitAt_lz(listLen(ns), rs) is [rs1, rs2] then [makeNumber(65536, uniform(ns, rs1)), rs2] + +fun singleTestX(n, kq, x) = + fun square(x) = intMod(x * x, n) + + fun witness(ls) = if ls is + Nil then false + t :: ts and + t == (n - 1) then true + t == 1 then false + else witness(ts) + + if kq is [k, q] and take_lz(k, iterate(square, powerMod(x, q, n))) is t :: ts then + (t == 1) || (t == (n - 1)) || witness(ts) + + +fun singleTest(n, kq, rs) = if random(n - 2, rs) is [x, rs_] then + [singleTestX(n, kq, 2 + x), rs_] + +fun multiTest(k, rs, n) = + fun mTest(k, rs) = if + k == 0 then [true, rs] + singleTest(n, findKQ(n), rs) is [t, rs_] and + t then mTest(k - 1, rs_) + else [false, rs_] + + if ((n <= 1) || even(n)) then [n==2, rs] else mTest(k, rs) + + +fun doLine(cs, cont, rs) = + let n = int_val_of_string(cs) + if multiTest(100, rs, n) is [t, rs_] and + t then "Probably prime" :: (cont(rs_)) + else "Composite" :: (cont(rs_)) + +fun doInput(state, lls) = if lls is + Nil then Nil + l :: ls then doLine(l, state => doInput(state, ls), state) + +fun process(process_arg1) = doInput(randomInts(111, 47), process_arg1) + +fun testPrimetest_nofib(d) = + let cts = nofibStringToList("24|48|47|1317|8901") + process(lines(cts)) + + +fun main() = testPrimetest_nofib(0).toString() +//│ = "[\"Composite\",\"Composite\",\"Probably prime\",\"Composite\",\"Composite\"]" diff --git a/benchmark/src/nofib/puzzle.mls b/benchmark/src/nofib/puzzle.mls new file mode 100644 index 000000000..a1387af40 --- /dev/null +++ b/benchmark/src/nofib/puzzle.mls @@ -0,0 +1,281 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module puzzle with ... + + +abstract class ItemType: Bono | Edge | Larry | Adam + +object + Bono extends ItemType + Edge extends ItemType + Larry extends ItemType + Adam extends ItemType + +fun itemEq(a, b) = if a is + Bono and b is Bono then true + Edge and b is Edge then true + Larry and b is Larry then true + Adam and b is Adam then true + else false + +fun succItem(i) = if i is + Bono then Edge + Edge then Larry + Larry then Adam + +fun isEnd(i) = if i is + Bono then false + Edge then false + Larry then false + Adam then true + +fun itemFromTo(a, b) = if itemEq(a, b) then a :: Nil else a :: itemFromTo(succItem(a), b) + +abstract class BankType: LeftBank | RightBank + +object + LeftBank extends BankType + RightBank extends BankType + +fun bankEq(a, b) = if a is + LeftBank and b is LeftBank then true + RightBank and b is RightBank then true + else false + +data class State(b: BankType, e: BankType, l: BankType, a: BankType) + +fun stateEq(s1, s2) = if s1 is State(a, b, c, d) and s2 is State(e, f, g, h) then + (bankEq(a, e) && bankEq(b, f) && bankEq(c, g) && bankEq(d, h)) + +fun bonoPos(s) = if s is State(a, b, c, d) then a + +fun edgePos(s) = if s is State(a, b, c, d) then b + +fun larryPos(s) = if s is State(a, b, c, d) then c + +fun adamPos(s) = if s is State(a, b, c, d) then d + +val initialState = State(LeftBank, LeftBank, LeftBank, LeftBank) +//│ initialState = State(LeftBank, LeftBank, LeftBank, LeftBank) + +val finalState = State(RightBank, RightBank, RightBank, RightBank) +//│ finalState = State(RightBank, RightBank, RightBank, RightBank) + +fun position(i, s) = if i is + Bono then bonoPos(s) + Edge then edgePos(s) + Larry then larryPos(s) + Adam then adamPos(s) + +fun updateState(s, i, pos) = if s is State(a, b, c, d) and i is + Bono then State(pos, b, c, d) + Edge then State(a, pos, c, d) + Larry then State(a, b, pos, d) + Adam then State(a, b, c, pos) + +fun opposite(b) = if b is + LeftBank then RightBank + RightBank then LeftBank + +fun notSeen(state, states) = + all(case { [_, s] then not(stateEq(state, s)) }, states) + +fun writeItem(i, b, rest) = if i is + Bono and b is LeftBank then nofibStringToList(" Bono | |\n") +: rest + Edge and b is LeftBank then nofibStringToList("The Edge | |\n") +: rest + Larry and b is LeftBank then nofibStringToList(" Larry | |\n") +: rest + Adam and b is LeftBank then nofibStringToList(" Adam | |\n") +: rest + Bono and b is RightBank then nofibStringToList(" | | Bono\n") +: rest + Edge and b is RightBank then nofibStringToList(" | | The Edge\n") +: rest + Larry and b is RightBank then nofibStringToList(" | | Larry\n") +: rest + Adam and b is RightBank then nofibStringToList(" | | Adam\n") +: rest + +fun writeState(state, s) = + nofibStringToList("----------------------------------------\n") +: + writeItem of + Bono + bonoPos(state) + writeItem of + Edge + edgePos(state) + writeItem of + Larry + larryPos(state) + writeItem of + Adam + adamPos(state) + nofibStringToList("----------------------------------------\n") +: s + +fun totalTime(history) = if history is [time, _] :: _ then time + +fun writeHistory(history, x) = if history is + Nil then x + else + foldr( + (timestate, acc) => (s) => if timestate is [time, state] then + nofibStringToList("Time: ") +: nofibStringToList(stringOfInt(totalTime(history) - time)) +: ("\n" :: writeState(state, acc(s))), + x => x, + history + )(x) + +fun writeSolutions(solutions, count, s) = if solutions is + Nil then s + item :: next then + nofibStringToList("Solution ") +: + nofibStringToList(stringOfInt(count)) +: + "\n" :: writeHistory(item, writeSolutions(next, count + 1, s)) + +fun minSolutions(history) = if history is + Nil then Nil + history :: next then + // @tailrec // TODO + fun minAcc(minSoFar, mins, ls) = if ls is + Nil then mins + history :: next then + let total = totalTime(history) + if + minSoFar < total then minAcc(minSoFar, mins, next) + minSoFar === total then minAcc(minSoFar, history :: mins, next) + else minAcc(total, history :: Nil, next) + reverse(minAcc(totalTime(history), history :: Nil, next)) + +fun u2times(i) = if i is + Bono then 10 + Edge then 5 + Larry then 2 + Adam then 1 + +fun transfer(source, dest, location, countdown, history) = + if stateEq(source, dest) then ([countdown, dest] :: history) :: Nil + else + let newHistory = [countdown, dest] :: history + let newLocation = opposite(location) + fun lscomp1(ls) = if ls is + Nil then Nil + item :: xs then + if bankEq(position(item, dest), location) then + let newDest = updateState(dest, item, newLocation) + if notSeen(newDest, history) then + let newTime = countdown + u2times(item) + transfer(source, newDest, newLocation, newTime, newHistory) :: lscomp1(xs) + else lscomp1(xs) + else lscomp1(xs) + let moveOne = concat(lscomp1(itemFromTo(Bono, Adam))) + fun lscomp2(ls) = if ls is + Nil then Nil + i :: xs then + fun lscomp3(ls) = if ls is + Nil then lscomp2(xs) + j :: ys then + if bankEq(position(i, dest), location) and bankEq(position(j, dest), location) then + let newDest = updateState(updateState(dest, i, newLocation), j, newLocation) + if notSeen(newDest, history) then + let newTime = countdown + u2times(i) + transfer(source, newDest, newLocation, newTime, newHistory) :: lscomp3(ys) + else lscomp3(ys) + else lscomp3(ys) + lscomp3(itemFromTo(succItem(i), Adam)) + let moveTwo = concat(lscomp2(itemFromTo(Bono, Larry))) + moveOne +: moveTwo + +fun testPuzzle_nofib(x) = + let time = if listLen(x) === 1 then 0 else throw Error("puzzle expects exactly one argument") + let solutions = transfer(initialState, finalState, RightBank, time, Nil) + let mins = minSolutions(solutions) + writeSolutions(mins, 1, Nil) + +fun main() = nofibListToString(testPuzzle_nofib(2 :: Nil)) +//│ ═══[RUNTIME ERROR] RangeError: Maximum call stack size exceeded + + +// // │ > Solution 1 +// // │ > Time: 0 +// // │ > ---------------------------------------- +// // │ > Bono | | +// // │ > The Edge | | +// // │ > Larry | | +// // │ > Adam | | +// // │ > ---------------------------------------- +// // │ > Time: 2 +// // │ > ---------------------------------------- +// // │ > Bono | | +// // │ > The Edge | | +// // │ > | | Larry +// // │ > | | Adam +// // │ > ---------------------------------------- +// // │ > Time: 3 +// // │ > ---------------------------------------- +// // │ > Bono | | +// // │ > The Edge | | +// // │ > | | Larry +// // │ > Adam | | +// // │ > ---------------------------------------- +// // │ > Time: 13 +// // │ > ---------------------------------------- +// // │ > | | Bono +// // │ > | | The Edge +// // │ > | | Larry +// // │ > Adam | | +// // │ > ---------------------------------------- +// // │ > Time: 15 +// // │ > ---------------------------------------- +// // │ > | | Bono +// // │ > | | The Edge +// // │ > Larry | | +// // │ > Adam | | +// // │ > ---------------------------------------- +// // │ > Time: 17 +// // │ > ---------------------------------------- +// // │ > | | Bono +// // │ > | | The Edge +// // │ > | | Larry +// // │ > | | Adam +// // │ > ---------------------------------------- +// // │ > Solution 2 +// // │ > Time: 0 +// // │ > ---------------------------------------- +// // │ > Bono | | +// // │ > The Edge | | +// // │ > Larry | | +// // │ > Adam | | +// // │ > ---------------------------------------- +// // │ > Time: 2 +// // │ > ---------------------------------------- +// // │ > Bono | | +// // │ > The Edge | | +// // │ > | | Larry +// // │ > | | Adam +// // │ > ---------------------------------------- +// // │ > Time: 4 +// // │ > ---------------------------------------- +// // │ > Bono | | +// // │ > The Edge | | +// // │ > Larry | | +// // │ > | | Adam +// // │ > ---------------------------------------- +// // │ > Time: 14 +// // │ > ---------------------------------------- +// // │ > | | Bono +// // │ > | | The Edge +// // │ > Larry | | +// // │ > | | Adam +// // │ > ---------------------------------------- +// // │ > Time: 15 +// // │ > ---------------------------------------- +// // │ > | | Bono +// // │ > | | The Edge +// // │ > Larry | | +// // │ > Adam | | +// // │ > ---------------------------------------- +// // │ > Time: 17 +// // │ > ---------------------------------------- +// // │ > | | Bono +// // │ > | | The Edge +// // │ > | | Larry +// // │ > | | Adam +// // │ > ---------------------------------------- +// // │ > diff --git a/benchmark/src/nofib/rsa.mls b/benchmark/src/nofib/rsa.mls new file mode 100644 index 000000000..ce9aa21e3 --- /dev/null +++ b/benchmark/src/nofib/rsa.mls @@ -0,0 +1,82 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module rsa with ... + + + +fun z_of_int(x) = globalThis.BigInt(x) +fun string_of_z(x) = nofibStringToList(x + "") +fun z_add(x, y) = x + y +fun z_mul(x, y) = x * y +fun z_sub(x, y) = x - y +fun z_div(x, y) = x / y +fun z_mod(x, y) = x % y +fun z_equal(x, y) = x === y +fun z_sqr(x) = x * x +fun int_if_char(c) = c.codePointAt(0) + +val const0 = z_of_int(0) +//│ const0 = 0 + +val const31 = z_of_int(31) +//│ const31 = 31 + +val const1 = z_of_int(1) +//│ const1 = 1 + +val const2 = z_of_int(2) +//│ const2 = 2 + +val const128 = z_of_int(128) +//│ const128 = 128 + +fun hash(str) = foldl of + (acc, c) => z_add(z_of_int(int_if_char(c)), z_mul(acc, const31)) + const0 + str + +fun and_(ls) = if ls is + Nil then true + h :: t and + h then and_(t) + else false + +fun unlines(ls) = concat of map(l => l +: ("\n" :: Nil), ls) + +fun even(a) = z_mod(a, const2) === const0 + +fun code(ls) = foldl of + (x, y) => z_add(z_mul(const128, x), z_of_int(int_if_char(y))) + const0 + ls + +fun collect(n, xs) = if + n === 0 then Nil + xs is Nil then Nil + else take(n, xs) :: collect(n, drop(n, xs)) + +fun size(n) = intDiv(listLen(string_of_z(n)) * 47, 100) + +fun encrypt(n, e, s) = unlines of map of + c => string_of_z(power(e, n, code(c))) + collect(size(n), s) +fun power(n, m, x) = if + z_equal(n, const0) then const1 + even(n) then z_mod(z_sqr(power(z_div(n, const2), m, x)), m) + else z_mod(z_mul(x, power(z_sub(n, const1), m, x)), m) + +val intput = nofibStringToList of fs.readFileSync("hkmc2/shared/src/test/mlscript/nofib/input/rsa.faststdin").toString() +//│ intput = ["m","o","d","u","l","e"," ","R","s","a"," ","(","e","n","c","r","y","p","t",","," ","d","e","c","r","y","p","t",","," ","m","a","k","e","K","e","y","s",")","\n","w","h","e","r","e","\n","\n","\n","e","n","c","r","y","p","t",","," ","d","e","c","r","y","p","t"," ",":",":"," ","I","n","t","e","g","e","r"," ","-",">"," ","I","n","t","e","g","e","r"," ","-",">"," ","S","t","r","i","n","g"," ","-",">"," ","S","t","r","i","n","g","\n","e","n","c","r","y","p","t"," ","n"," ","e"," ","="," ","u","n","l","i","n","e","s"," ","."," ","m","a","p"," ","(","s","h","o","w"," ","."," ","p","o","w","e","r"," ","e"," ","n"," ","."," ","c","o","d","e",")"," ","."," ","c","o","l","l","e","c","t"," ","(","s","i","z","e"," ","n",")","\n","d","e","c","r","y","p","t"," ","n"," ","d"," ","="," ","c","o","n","c","a","t"," ","."," ","m","a","p"," ","(","d","e","c","o","d","e"," ","."," ","p","o","w","e","r"," ","d"," ","n"," ","."," ","r","e","a","d",")"," ","."," ","l","i","n","e","s","\n","\n","-","-","-","-","-","-","-","-"," ","C","o","n","v","e","r","t","i","n","g"," ","b","e","t","w","e","e","n"," ","S","t","r","i","n","g","s"," ","a","n","d"," ","I","n","t","e","g","e","r","s"," ","-","-","-","-","-","-","-","-","-","-","-","\n","\n","c","o","d","e"," ",":",":"," ","S","t","r","i","n","g"," ","-",">"," ","I","n","t","e","g","e","r","\n","c","o","d","e"," ","="," ","f","o","l","d","l"," ","a","c","c","u","m"," ","0","\n"," "," ","w","h","e","r","e"," ","a","c","c","u","m"," ","x"," ","y"," ","="," ","(","1","2","8"," ","*"," ","x",")"," ","+"," ","f","r","o","m","I","n","t","e","g","r","a","l"," ","(","f","r","o","m","E","n","u","m"," ","y",")","\n"] + +fun testRsa_nofib(_) = hash(encrypt( + z_of_int("2036450659413645137870851576872812267542175329986469156678671505255564383842535488743101632280716717779536712424613501441720195827856504007305662157107"), + z_of_int("387784473137902876992546516170169092918207676456888779623592396031349415024943784869634893342729620092877891356118467738167515879252473323905128540213"), + intput +)) + +fun main() = testRsa_nofib(0) +//│ = 27333540773077035891319648583115426924319682304972207061138531859687685497972324052329603672575247712822051033469833084249533708345668063349995687590898179232348381885068093916042332376874471111951277359240086024689478630903872483533692492045159120070581960228683268092981264305946420008131657132188411691046890656423813430758797867405414254427252889799598265252801351427969270327221859277538276931835433884202770274573975497479910055419604950116998779489424711382329456954759006285308055617249211518517251626537584144819963887585424355716160948313809816237911911714261525254960504461968887058634176692781918761529885191647640353988451378487593523928746420834635489374763284035135024554501992592243054651704669361294874639088141090295124111150498567814209355019358035109087855352831799613561922371560229756096541243234407756387955273981612894548796096568181979612805473591487774278882312329731123289196221054300160041623910405907021509065754120986913156062146884015988300349866352421512547114991188706014109057361892879580430212109312752658248376273202302160796406164353595904770530340704402942462200108055227350082862003023696909347848580847463903352486983305887517122394068078234691266091519485573727824252527733372590392886198860292659649377855405883044150450559660371076194186374359910112808222171852893169058046390627297042238730809765588373104750 diff --git a/benchmark/src/nofib/scc.mls b/benchmark/src/nofib/scc.mls new file mode 100644 index 000000000..c771ebe0e --- /dev/null +++ b/benchmark/src/nofib/scc.mls @@ -0,0 +1,58 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module scc with ... + + + +fun dfs(r, vsns, xs) = if vsns is [vs, ns] and + xs is + Nil then [vs, ns] + x :: xs and + inList(x, vs) then dfs(r, [vs, ns], xs) + dfs(r, [x :: vs, Nil], r(x)) is [vs', ns'] then dfs(r, [vs', (x :: ns') +: ns], xs) + +fun stronglyConnComp(es, vs) = + fun swap(a) = if a is [f, s] then [s, f] + + fun new_range(xys, w) = if xys is + Nil then Nil + [x, y] :: xys and + x == w then y :: new_range(xys, w) + else new_range(xys, w) + + fun span_tree(r, vsns, xs) = if vsns is [vs, ns] and + xs is + Nil then [vs, ns] + x :: xs and + inList(x, vs) then span_tree(r, [vs, ns], xs) + dfs(r, [x :: vs, Nil], r(x)) is [vs', ns'] then span_tree(r, [vs', (x :: ns') :: ns], xs) + + snd of span_tree of + x => new_range(map(swap, es), x) + [Nil, Nil] + snd of dfs of + x => new_range(es, x) + [Nil, Nil] + vs + + +fun testScc_nofib(d) = + let a = 1 + let b = 2 + let c = 3 + let d = 4 + let f = 5 + let g = 6 + let h = 7 + let vertices = a :: b :: c :: d :: f :: g :: h :: Nil + let edges = [b, a] :: [c, b] :: [c, d] :: [c, h] :: [d, c] :: [f, a] :: [f, g] :: [f, h] :: [g, f] :: [h, g] :: Nil + + stronglyConnComp(edges, vertices) + + +fun main() = testScc_nofib(0).toString() +//│ = "[[1],[2],[7,5,6],[3,4]]" diff --git a/benchmark/src/nofib/secretary.mls b/benchmark/src/nofib/secretary.mls new file mode 100644 index 000000000..27a5259bb --- /dev/null +++ b/benchmark/src/nofib/secretary.mls @@ -0,0 +1,47 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module secretary with ... + + + +fun infRand(m, s) = + fun f(x) = lazy(() => LzCons((intMod(x, m) + 1), f(intMod((97 * x + 11), power(2, 7))))) + + f(s) + + +fun simulate(n, m, proc) = + fun lscomp(ls) = if ls is + Nil then Nil + seed :: t then proc(infRand(m, seed)) :: lscomp(t) + + listLen(filter(x => x, lscomp(enumFromTo(1, n)))) / n + + +fun sim(n, k) = + fun proc(rs) = + let xs = take_lz(100, nub_lz(rs)) + let best = 100 + let bestk = maximum(take(k, xs)) + let afterk = dropWhile(x => x < bestk, drop(k, xs)) + listEq(best :: Nil, take(1, afterk)) + + simulate(n, 100, proc) + + +fun testSecretary_nofib(n) = + fun listcomp(ls) = if ls is + Nil then Nil + h :: t then sim(n, h) :: listcomp(t) + + listcomp(enumFromTo(35, 39)) + + + +// NOTE: original input 5000 +fun main() = testSecretary_nofib(50).toString() +//│ = "[0.3,0.3,0.3,0.34,0.36]" diff --git a/benchmark/src/nofib/sorting.mls b/benchmark/src/nofib/sorting.mls new file mode 100644 index 000000000..709ebdbdd --- /dev/null +++ b/benchmark/src/nofib/sorting.mls @@ -0,0 +1,221 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module sorting with ... + + + +fun int_of_char(c) = c.codePointAt(0) + +object + EQ + GT + LT + +fun compareList(xs, ys) = if xs is + Nil and ys is + Nil then EQ + _ :: _ then LT + _ :: _ and ys is Nil then GT + x :: xs_ and ys is y :: ys_ and + int_of_char(x) === int_of_char(y) then compareList(xs_, ys_) + int_of_char(x) < int_of_char(y) then LT + else GT + +fun gtList(a, b) = compareList(a, b) is GT + +fun leList(a, b) = not(gtList(a, b)) + +fun ltList(a, b) = compareList(a, b) is LT + +fun geList(a, b) = not(ltList(a, b)) + +fun eqList(a, b) = compareList(a, b) is EQ + +fun prependToAll(sep, xs) = if xs is + Nil then Nil + x :: xs_ then sep :: x :: prependToAll(sep, xs_) + +fun intersperse(sep, xs) = if xs is + Nil then Nil + x :: xs_ then x :: prependToAll(sep, xs_) + +fun lines(s) = if + s is Nil then Nil + break_(x => x === "\n", s) is [l, s_] then + let tt = if s_ is + Nil then Nil + _ :: s__ then lines(s__) + l :: tt + +fun unlines(ls) = concat(map(l => l +: ("\n" :: Nil), ls)) + +fun odd(x) = intMod(x, 2) === 0 + +fun z_of_int(x) = globalThis.BigInt(x) + +fun hash(str) = foldl( + (acc, c) => z_of_int(int_of_char(c)) + (acc * z_of_int(31)), + z_of_int(0), + str +) + +fun quickSort(xs) = if xs is + Nil then Nil + x :: xs_ then + fun lscomp1(ls) = if ls is + Nil then Nil + h :: t and + leList(h, x) then h :: lscomp1(t) + else lscomp1(t) + fun lscomp2(ls) = if ls is + Nil then Nil + h :: t and + gtList(h, x) then h :: lscomp2(t) + else lscomp2(t) + quickSort(lscomp1(xs_)) +: (x :: quickSort(lscomp2(xs_))) + +fun select(p, x, ts_fs) = if ts_fs is [ts, fs] and + p(x) then [x :: ts, fs] + else [ts, x :: fs] + +fun partition(p, xs) = foldr((x, y) => select(p, x, y), [Nil, Nil], xs) + +fun quickSort2(xs) = if xs is + Nil then Nil + x :: xs_ then + if partition(y => geList(x, y), xs_) is [lo, hi] then + quickSort2(lo) +: (x :: quickSort2(hi)) + +fun quickerSort(xss) = if xss is + Nil then Nil + x :: Nil then x :: Nil + x :: xs then + fun split(x, lo, hi, ys) = if ys is + Nil then quickerSort(lo) +: (x :: quickerSort(hi)) + y :: ys_ and + leList(y, x) then split(x, y :: lo, hi, ys_) + else split(x, lo, y :: hi, ys_) + split(x, Nil, Nil, xs) + +fun insertSort(xss) = if xss is + Nil then Nil + x :: xs then + fun trins(rev, xs, ys) = if xs is + Nil and ys is y :: ys_ then trins(Nil, reverse(rev) +: (y :: Nil), ys_) + xs and ys is Nil then reverse(rev) +: xs + x :: xs_ and ys is y :: ys_ and + ltList(x, y) then trins(x :: rev, xs_, y :: ys_) + else trins(Nil, reverse(rev) +: (y :: x :: xs_), ys_) + trins(Nil, x :: Nil, xs) + +abstract class Tree[T]: Tip | Branch[T] + +object Tip extends Tree[Nothing] + +data class Branch[T](a: T, l: Tree[T], r: Tree[T]) extends Tree[T] + +fun treeSort(param) = + fun mkTree(innerparam) = + fun to_tree(x, t) = if t is + Tip then Branch(x, Tip, Tip) + Branch(y, l, r) and + leList(x, y) then Branch(y, to_tree(x, l), r) + else Branch(y, l, to_tree(x, r)) + foldr(to_tree, Tip, innerparam) + fun readTree(t) = if t is + Tip then Nil + Branch(x, l, r) then readTree(l) +: (x :: readTree(r)) + readTree(mkTree(param)) + +abstract class Tree2[T]: Tip2 | Twig2[T] | Branch2[T] + +object Tip2 extends Tree2[Nothing] + +data + class + Twig2[T](a: T) extends Tree2[T] + Branch2[T](a: T, l: Tree2[T], r: Tree2[T]) extends Tree2[T] + +fun treeSort2(param) = + fun mkTree(innerparam) = + fun to_tree(x, t) = if t is + Tip2 then Twig2(x) + Twig2(y) and + leList(x, y) then Branch2(y, Twig2(x), Tip2) + else Branch2(y, Tip2, Twig2(x)) + Branch2(y, l, r) and + leList(x, y) then Branch2(y, to_tree(x, l), r) + else Branch2(y, l, to_tree(x, r)) + foldr(to_tree, Tip2, innerparam) + fun readTree(t) = if t is + Tip2 then Nil + Twig2(x) then x :: Nil + Branch2(x, l, r) then readTree(l) +: (x :: readTree(r)) + readTree(mkTree(param)) + +fun heapSort(xs) = + fun heap(k, xs) = if xs is + Nil then Tip + x :: xs_ then to_heap(k, x, heap(k + 1, xs_)) + fun to_heap(k, x, t) = if t is + Tip then Branch(x, Tip, Tip) + Branch(y, l, r) and + leList(x, y) and odd(k) then Branch(x, to_heap(intDiv(k, 2), y, l), r) + leList(x, y) then Branch(x, l, to_heap(intDiv(k, 2), y, r)) + odd(k) then Branch(y, to_heap(intDiv(k, 2), x, l), r) + else Branch(y, l, to_heap(intDiv(k, 2), x, r)) + fun clear(t) = if t is + Tip then Nil + Branch(x, l, r) then x :: clear(mix(l, r)) + fun mix(l, r) = if + l is Tip then r + r is Tip then l + l is Branch(x, l1, r1) and r is Branch(y, l2, r2) and + leList(x, y) then Branch(x, mix(l1, r1), Branch(y, l2, r2)) + else Branch(y, Branch(x, l1, r1), mix(l2, r2)) + clear(heap(0, xs)) + +fun mergeSort(param) = + fun runsplit(run, xs) = if + run is Nil and xs is Nil then Nil + xs is Nil then run :: Nil + run is Nil and xs is x :: xs_ then runsplit(x :: Nil, xs_) + run is r :: rs and xs is x :: xs_ and rs is + Nil and + gtList(x, r) then runsplit(r :: x :: Nil, xs_) + leList(x, r) then runsplit(x :: r :: rs, xs_) + else (r :: rs) :: runsplit(x :: Nil, xs_) + rs and + leList(x, r) then runsplit(x :: r :: rs, xs_) + else (r :: rs) :: runsplit(x :: Nil, xs_) + fun merge_lists(xs) = if xs is + Nil then Nil + x :: xs_ then merge(x, merge_lists(xs_)) + fun merge(xs, ys) = if + xs is Nil then ys + ys is Nil then xs + xs is x :: xs_ and ys is y :: ys_ and + eqList(x, y) then x :: y :: merge(xs_, ys_) + ltList(x, y) then x :: merge(xs_, y :: ys_) + else y :: merge(x :: xs_, ys_) + merge_lists(runsplit(Nil, param)) + +fun mangle(inpt) = + fun sort(param) = + foldr( + (f, g) => x => f(g(x)), + x => x, + intersperse(reverse, (heapSort :: insertSort :: mergeSort :: quickSort :: quickSort2 :: quickerSort :: treeSort :: treeSort2 :: Nil)), + )(param) + unlines(sort(lines(inpt))) + +fun testSorting_nofib(d) = + let f = nofibStringToList of fs.readFileSync("hkmc2/shared/src/test/mlscript/nofib/input/Main.hs").toString() + hash(mangle(f)) + +fun main() = testSorting_nofib(0) +//│ = 51324117188054929115411819706576305711291550658570113274291768822777898552447837804420193403034280334581113235670099168108057310001444698188883902000871912629747889286942274533143362191347715770581074120684028066661549409447053566864805982796651442411825424058139343253169753750307013113236996387277789074623630137288987589869641913268610508598505040964906263227437054452571059796961267985287441539342423613634888118731387934522320394294636575704912348025851038478882488022787377510287490741895262233989080994241592338442788051616303082788441666485156091668196999668892850523930511918729736856089560984406499736606084171798216360770991023233180481976810767432750226966921480421914178641779179040473344962763594357880599983085435482161632405644389584578524102239884780307588440751057343783694537559222924711205140877849398042544407611747227163056408231621727687968160470282720794027470616537695447289808133239223198869 diff --git a/benchmark/src/nofib/sphere.mls b/benchmark/src/nofib/sphere.mls new file mode 100644 index 000000000..faa4b4eb9 --- /dev/null +++ b/benchmark/src/nofib/sphere.mls @@ -0,0 +1,387 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module sphere with ... + + + +val pi = globalThis.Math.PI +val epsilon = 0.000001 +val infinity = 100000000.0 +//│ epsilon = 0.000001 +//│ infinity = 100000000 +//│ pi = 3.141592653589793 + +fun vecadd(a1, a2) = + if a1 is [x1, y1, z1] and a2 is [x2, y2, z2] then + [x1 + x2, y1 + y2, z1 + z2] + +fun vecsub(a1, a2) = + if a1 is [x1, y1, z1] and a2 is [x2, y2, z2] then + [x1 - x2, y1 - y2, z1 - z2] + +fun vecmult(a1, a2) = + if a1 is [x1, y1, z1] and a2 is [x2, y2, z2] then + [x1 * x2, y1 * y2, z1 * z2] + +fun vecsum(param) = foldr(vecadd, [0.0, 0.0, 0.0], param) + +fun vecnorm(xyz) = if xyz is [x, y, z] then + let len = sqrt(x * x + y * y + z * z) + [[x / len , y / len, z / len], len] + +fun vecscale(xyz, a) = if xyz is [x, y, z] then [a * x, a * y, a * z] + +fun vecdot(x1, x2) = if x1 is [x1, y1, z1] and x2 is [x2, y2, z2] then x1 * x2 + y1 * y2 + z1 * z2 + +fun veccross(x1, x2) = if x1 is [x1, y1, z1] and x2 is [x2, y2, z2] then + [(y1 * z2) - (y2 * z1), (z1 * x2) - (z2 * x1), (x1 * y2) - (x2 * y1)] + +fun is_zerovector(x) = if x is [x, y, z] then (x < epsilon) && (y < epsilon) && (z < epsilon) + +abstract class Light: Directional | Point + +data + class + Directional(x: [Num, Num, Num], y: [Num, Num, Num]) extends Light + Point(x: [Num, Num, Num], y: [Num, Num, Num]) extends Light + +fun lightpos(p) = if p is Point(pos, col) then pos + +fun lightdir(d) = if d is Directional(dir, col) then fst(vecnorm(dir)) + +fun lightcolour(x) = if x is + Directional(dir, col) then col + Point(pos, col) then col + +abstract class Surfspec: Ambient | Diffuse | Specular | Specpow | Reflect | Transmit | Refract | Body + +data + class + Ambient(v: [Num, Num, Num]) extends Surfspec + Diffuse(v: [Num, Num, Num]) extends Surfspec + Specular(v: [Num, Num, Num]) extends Surfspec + Specpow(v: Num) extends Surfspec + Reflect(v: Num) extends Surfspec + Transmit(v: Num) extends Surfspec + Refract(v: Num) extends Surfspec + Body(v: [Num, Num, Num]) extends Surfspec + +fun ambientsurf(ss) = + fun lscomp(ls) = if ls is + Nil then Nil + x :: t and + x is Ambient(s) then s :: lscomp(t) + else lscomp(t) + + head(append(lscomp(ss), ([0.0, 0.0, 0.0] :: Nil))) + + +fun diffusesurf(ss) = + fun lscomp(ls) = if ls is + Nil then Nil + x :: t and + x is Diffuse(s) then s :: lscomp(t) + else lscomp(t) + + head(append(lscomp(ss), ([0.0, 0.0, 0.0] :: Nil))) + + +fun specularsurf(ss) = + fun lscomp(ls) = if ls is + Nil then Nil + x :: t and + x is Specular(s) then s :: lscomp(t) + else lscomp(t) + + head(append(lscomp(ss), ([0.0, 0.0, 0.0] :: Nil))) + + +fun specpowsurf(ss) = + fun lscomp(ls) = if ls is + Nil then Nil + x :: t and + x is Specpow(s) then s :: lscomp(t) + else lscomp(t) + + head(append(lscomp(ss), (8.0 :: Nil))) + + +fun reflectsurf(ss) = + fun lscomp(ls) = if ls is + Nil then Nil + x :: t and + x is Reflect(s) then s :: lscomp(t) + else lscomp(t) + + head(append(lscomp(ss), (0.0 :: Nil))) + + +fun transmitsurf(ss) = + fun lscomp(ls) = if ls is + Nil then Nil + x :: t and + x is Transmit(s) then s :: lscomp(t) + else lscomp(t) + + head(append(lscomp(ss), (0.0 :: Nil))) + + +fun refractsurf(ss) = + fun lscomp(ls) = if ls is + Nil then Nil + x :: t and + x is Refract(s) then s :: lscomp(t) + else lscomp(t) + + head(append(lscomp(ss), (1.0 :: Nil))) + + +fun bodysurf(ss) = + fun lscomp(ls) = if ls is + Nil then Nil + x :: t and + x is Body(s) then s :: lscomp(t) + else lscomp(t) + + head(append(lscomp(ss), ([1.0, 1.0, 1.0] :: Nil))) + + +data class Sphere(pos: [Num, Num, Num], radius: Num, surface: List[Surfspec]) + +fun spheresurf(s) = if s is Sphere(pos, rad, surf) then surf + +val lookat = [0.0, 0.0, 0.0] +val vup = [0.0, 0.0, 1.0] +val fov = 45.0 +val s2 = + Ambient([0.035, 0.0325, 0.025]) :: + Diffuse([0.5, 0.45, 0.35]) :: + Specular([0.8, 0.8, 0.8]) :: + Specpow(3.0) :: + Reflect(0.5) :: + Nil +val testspheres = + Sphere([0.0, 0.0, 0.0], 0.5, s2) :: + Sphere([0.272166, 0.272166, 0.544331], 0.166667, s2) :: + Sphere([0.643951, 0.172546, 0.0], 0.166667, s2) :: + Sphere([0.172546, 0.643951, 0.0], 0.166667, s2) :: + Sphere([-0.371785, 0.0996195, 0.544331], 0.166667, s2) :: + Sphere([-0.471405, 0.471405, 0.0], 0.166667, s2) :: + Sphere([-0.643951, -0.172546, 0.0], 0.166667, s2) :: + Sphere([0.0996195, -0.371785, 0.544331], 0.166667, s2) :: + Sphere([-0.172546, -0.643951, 0.0], 0.166667, s2) :: + Sphere([0.471405, -0.471405, 0.0], 0.166667, s2) :: + Nil +val testlights = + Point([4.0, 3.0, 2.0], [0.288675, 0.288675, 0.288675]) :: + Point([1.0, -4.0, 4.0], [0.288675, 0.288675, 0.288675]) :: + Point([-3.0, 1.0, 5.0], [0.288675, 0.288675, 0.288675]) :: + Nil +val lookfrom = [2.1, 1.3, 1.7] +val background = [0.078, 0.361, 0.753] +//│ background = [0.078, 0.361, 0.753] +//│ fov = 45 +//│ lookat = [0, 0, 0] +//│ lookfrom = [2.1, 1.3, 1.7] +//│ s2 = [Ambient([0.035, 0.0325, 0.025]),Diffuse([0.5, 0.45, 0.35]),Specular([0.8, 0.8, 0.8]),Specpow(3),Reflect(0.5)] +//│ testlights = [Point([4, 3, 2], [0.288675, 0.288675, 0.288675]),Point([1, -4, 4], [0.288675, 0.288675, 0.288675]),Point([-3, 1, 5], [0.288675, 0.288675, 0.288675])] +//│ testspheres = [Sphere([0, 0, 0], 0.5, [Ambient([0.035, 0.0325, 0.025]),Diffuse([0.5, 0.45, 0.35]),Specular([0.8, 0.8, 0.8]),Specpow(3),Reflect(0.5)]),Sphere([0.272166, 0.272166, 0.544331], 0.166667, [Ambient([0.035, 0.0325, 0.025]),Diffuse([0.5, 0.45, 0.35]),Specular([0.8, 0.8, 0.8]),Specpow(3),Reflect(0.5)]),Sphere([0.643951, 0.172546, 0], 0.166667, [Ambient([0.035, 0.0325, 0.025]),Diffuse([0.5, 0.45, 0.35]),Specular([0.8, 0.8, 0.8]),Specpow(3),Reflect(0.5)]),Sphere([0.172546, 0.643951, 0], 0.166667, [Ambient([0.035, 0.0325, 0.025]),Diffuse([0.5, 0.45, 0.35]),Specular([0.8, 0.8, 0.8]),Specpow(3),Reflect(0.5)]),Sphere([-0.371785, 0.0996195, 0.544331], 0.166667, [Ambient([0.035, 0.0325, 0.025]),Diffuse([0.5, 0.45, 0.35]),Specular([0.8, 0.8, 0.8]),Specpow(3),Reflect(0.5)]),Sphere([-0.471405, 0.471405, 0], 0.166667, [Ambient([0.035, 0.0325, 0.025]),Diffuse([0.5, 0.45, 0.35]),Specular([0.8, 0.8, 0.8]),Specpow(3),Reflect(0.5)]),Sphere([-0.643951, -0.172546, 0], 0.166667, [Ambient([0.035, 0.0325, 0.025]),Diffuse([0.5, 0.45, 0.35]),Specular([0.8, 0.8, 0.8]),Specpow(3),Reflect(0.5)]),Sphere([0.0996195, -0.371785, 0.544331], 0.166667, [Ambient([0.035, 0.0325, 0.025]),Diffuse([0.5, 0.45, 0.35]),Specular([0.8, 0.8, 0.8]),Specpow(3),Reflect(0.5)]),Sphere([-0.172546, -0.643951, 0], 0.166667, [Ambient([0.035, 0.0325, 0.025]),Diffuse([0.5, 0.45, 0.35]),Specular([0.8, 0.8, 0.8]),Specpow(3),Reflect(0.5)]),Sphere([0.471405, -0.471405, 0], 0.166667, [Ambient([0.035, 0.0325, 0.025]),Diffuse([0.5, 0.45, 0.35]),Specular([0.8, 0.8, 0.8]),Specpow(3),Reflect(0.5)])] +//│ vup = [0, 0, 1] + +fun spherenormal(pos, sp) = if sp is Sphere(spos, rad, _) then + vecscale(vecsub(pos, spos), 1 / rad) + +fun dtor(x) = x * pi / 180.0 + +fun camparams(lookfrom, lookat, vup, fov, winsize) = + let initfirstray = vecsub(lookat, lookfrom) + if vecnorm(initfirstray) is + [lookdir, dist] and vecnorm(veccross(lookdir, vup)) is [scrni, _] and vecnorm(veccross(scrni, lookdir)) is [scrnj, _] then + let xfov = fov + let yfov = fov + let xwinsize = winsize + let ywinsize = winsize + let magx = 2.0 * dist * tan(dtor(xfov/2)) / xwinsize + let magy = 2.0 * dist * tan(dtor(yfov/2)) / ywinsize + let scrnx = vecscale(scrni, magx) + let scrny = vecscale(scrnj, magy) + let firstray = vecsub(initfirstray, vecadd(vecscale(scrnx, (0.5 * xwinsize)), vecscale(scrny, (0.5 * ywinsize)))) + [firstray, scrnx, scrny] + +fun sphereintersect(pos, dir, sp) = + if sp is Sphere(spos, rad, _) then + let m = vecsub(pos, spos) + let bm = vecdot(m, dir) + let m2 = vecdot(m, m) + let disc = (bm * bm) - m2 + (rad * rad) + let slo = -bm - sqrt(disc) + let shi = -bm + sqrt(disc) + if + disc < 0.0 then [false, 0.0] + slo < 0.0 and + shi < 0.0 then [false, 0.0] + else [true, shi] + else [true, slo] + +fun trace(spheres, pos, dir) = + fun f(d1s1, d2s2) = + if d1s1 is [d1, s1] and d2s2 is [d2, s2_] and + d1 < d2 then [d1, s1] + else [d2, s2_] + + fun sphmap(xss) = + if xss is + Nil then Nil + x :: xs and sphereintersect(pos, dir, x) is [is_hit, where_hit] and + is_hit then [where_hit, x] :: sphmap(xs) + else sphmap(xs) + + let dists = sphmap(spheres) + + if (null_(dists)) then + [false, infinity, head(spheres)] + else + if foldr(f, head(dists), tail(dists)) is [mindist, sp] then + [true, mindist, sp] + + +fun refractray(newindex, olddir, innorm) = + let dotp = -vecdot(olddir, innorm) + let matchIdent_17 = if dotp < 0.0 then + [vecscale(innorm, -1.0), -dotp, 1.0 / newindex] + else + [innorm, dotp, newindex] + if matchIdent_17 is + [norm, k, nr] then + let disc = 1.0 - nr * nr * (1.0 - (k * k)) + let t = (nr * k) - sqrt(disc) + if disc < 0.0 then + [true, [0.0, 0.0, 0.0]] + else + ([false, vecadd(vecscale(norm, t), vecscale(olddir, nr))]) + +fun lightdirection(l, pt) = if l is + Directional(dir, col) then [fst(vecnorm(dir)), infinity] + Point(pos, col) then vecnorm(vecsub(pos, pt)) + +fun shadowed(pos, dir, lcolour) = + if trace(testspheres, vecadd(pos, vecscale(dir, epsilon)), dir) is + [is_hit, dist, sp] then + if not(is_hit) then + [false, lcolour] + else + [true, lcolour] + +fun lightray(l, pos, norm, refl, surf) = + if lightdirection(l, pos) is + [ldir, dist] then + let cosangle = vecdot(ldir, norm) + if shadowed(pos, ldir, lightcolour(l)) is + [is_inshadow, lcolour] then + if + is_inshadow then [0.0, 0.0, 0.0] + let diff = diffusesurf(surf) + let spow = specpowsurf(surf) + cosangle <= 0.0 then + let bodycol = bodysurf(surf) + let cosalpha = -vecdot(refl, ldir) + let diffcont = vecmult(vecscale(diff, -cosangle), lcolour) + let speccont = if cosalpha <= 0.0 then [0.0, 0.0, 0.0] else (vecmult(vecscale(bodycol, power(cosalpha, spow)), lcolour)) + vecadd(diffcont, speccont) + let spec = specularsurf(surf) + let cosalpha = vecdot(refl, ldir) + let diffcont = vecmult(vecscale(diff, cosangle), lcolour) + let speccont = if cosalpha < 0.0 then [0.0, 0.0, 0.0] else (vecmult(vecscale(spec, power(cosalpha, spow)), lcolour)) + else vecadd(diffcont, speccont) + +//│ ———————————————————————————————————————————————————————————————————————————————— +fun shade(lights, sp, lookpos, dir, dist, contrib) = + let hitpos = vecadd(lookpos, vecscale(dir, dist)) + let ambientlight = [1.0, 1.0, 1.0] + let surf = spheresurf(sp) + let amb = vecmult(ambientlight, ambientsurf(surf)) + let norm = spherenormal(hitpos, sp) + let refl = vecadd(dir, vecscale(norm, -2.0 * vecdot(dir, norm))) + let diff = vecsum(map(l => (lightray(l, hitpos, norm, refl, surf)), lights)) + let transmitted = transmitsurf(surf) + let simple = vecadd(amb, diff) + let trintensity = vecscale(bodysurf(surf), transmitted) + let matchIdent_1 = + if transmitted < epsilon then + [false, simple] + else + transmitray(lights, simple, hitpos, dir, refractsurf(surf), trintensity, contrib, norm) + if matchIdent_1 is [is_tir, trcol] then + let reflsurf = vecscale(specularsurf(surf), reflectsurf(surf)) + let reflectiv = if is_tir then vecadd(trintensity, reflsurf) else reflsurf + let rcol = if is_zerovector(reflectiv) then trcol else (reflectray(hitpos, refl, lights, reflectiv, contrib, trcol)) + rcol + +fun transmitray(lights, colour, pos, dir, index, intens, contrib, norm) = + let newcontrib = vecmult(intens, contrib) + if refractray(index, dir, norm) is + [is_tir, newdir] then + let nearpos = vecadd(pos, vecscale(newdir, epsilon)) + if trace(testspheres, nearpos, newdir) is + [is_hit, dist, sp] then + let newcol = + if is_hit then + shade(lights, sp, nearpos, newdir, dist, newcontrib) + else + background + if is_zerovector(newcontrib) then + [false, colour] + else + ([false, vecadd(vecmult(newcol, intens), colour)]) + +fun reflectray(pos, newdir, lights, intens, contrib, colour) = + let newcontrib = vecmult(intens, contrib) + let nearpos = vecadd(pos, vecscale(newdir, epsilon)) + if trace(testspheres, nearpos, newdir) is [is_hit, dist, sp] then + let newcol = + if is_hit then + shade(lights, sp, nearpos, newdir, dist, newcontrib) + else + background + if is_zerovector(newcontrib) then + colour + else + (vecadd(colour, vecmult(newcol, intens))) +//│ ———————————————————————————————————————————————————————————————————————————————— + +fun tracepixel(spheres, lights, x, y, firstray, scrnx, scrny) = + let pos = lookfrom + if vecnorm(vecadd(vecadd(firstray, vecscale(scrnx, x)), vecscale(scrny, y))) is [dir, tracepixel_Tup2_1] and trace(spheres, pos, dir) is [hit, dist, sp] and + hit then shade(lights, sp, pos, dir, dist, [1.0, 1.0, 1.0]) + else background + +fun z_of_int(x) = globalThis.BigInt(x) + +fun hash(param) = + fun u8(x) = z_of_int(round(255 * x)) + foldr(((rgb, acc) => if rgb is [r, g, b] then u8(r) + (u8(g) * z_of_int(7)) + (u8(b) * z_of_int(23)) + (acc * z_of_int(61))), z_of_int(0), param) + +fun ray(winsize) = + let lights = testlights + if camparams(lookfrom, lookat, vup, fov, winsize) is [firstray, scrnx, scrny] then + fun f(i, j) = tracepixel(testspheres, lights, i, j, firstray, scrnx, scrny) + fun lscomp1(ls1) = if ls1 is + Nil then Nil + i :: t1 then + fun lscomp2(ls2) = if ls2 is + Nil then lscomp1(t1) + j :: t2 then [[i, j], f(i, j)] :: lscomp2(t2) + lscomp2(enumFromTo(0, winsize - 1)) + lscomp1(enumFromTo(0, winsize - 1)) + +fun run(winsize) = hash(map(snd, ray(winsize))) + +fun testSphere_nofib(n) = run(n) + + +fun main() = testSphere_nofib(30) +//│ = 5303517076988315313332949801059915491159227238911114869988477691048042454660240028235263286419219487056215941279053460510402913638191134284712332734906453769177119866479549825710564164275378353165954211251783583776613466486364346857260327927988942302708582821755390617347892889203137614326710267631036346563969292879841889783895830486185094255970382302038580666396338511666737651046972647664365680026395064916507788381669683616268208254545568013323075147569343527502482992453415977736934966646039451380029114116189124196276320031764844380624699920031305131672697387138852897706575918870327168611841752330951914241998117147850328297747558099955601889252104175852174057287066122859365466714696330034330699419079661953966001855819730466637347813009964893758393398194456345159379187006376036876209312080525632387380670119254556148852520127502599030787981579016179740021934386773631075580149533017386555553650112461351624483964765154488441338857870911043358714412530793575995251653967501366725439356901586292297118595437194582661104059821332957540366106419721198265755243343224842512131366898546251377194773492369372328808207397107344802194547364640358333075609512226775541628703229778371160920064859614452908773471314342954366183109912759985134547433205776906834992238207194263830836275456360444786309396200054415810563334317160702817096977297265083167419253864506146719603442916146256166128051227049046678660445048488558024838465181996990391375870148258607829684558969016638984826787347541150003498463027973936442463090071589323955227296902474986841480537918878837478902992973202305608637036765245465738479448312 diff --git a/benchmark/src/nofib/treejoin.mls b/benchmark/src/nofib/treejoin.mls new file mode 100644 index 000000000..3cf579018 --- /dev/null +++ b/benchmark/src/nofib/treejoin.mls @@ -0,0 +1,85 @@ +import "../precompiled/NofibPrelude.mls" +import "../precompiled/BenchmarkPrelude.mls" +import "fs" +open NofibPrelude +open BenchmarkPrelude + +module treejoin with ... + + + +fun isSpace(c) = c === " " || c === "\n" + +fun isDigit(c) = + let n = c.codePointAt(0) + in n >= 48 && n <= 57 + +abstract class Tree[E]: Node | Leaf | Empty + +data + class + Node[E](k: Int, l: Tree[E], r: Tree[E]) extends Tree[E] + Leaf[E](k: Int, e: E) extends Tree[E] + +object Empty extends Tree + +fun insertT(k, e, t) = if t is + Node(k_, l, r) and + k <= k_ then Node(k_, insertT(k, e, l), r) + else Node(k_, l, insertT(k, e, r)) + Leaf(k_, k__) then + let l_ = Leaf(k, e) + if k + < k_ then Node(k, l_, Leaf(k_, k__)) + > k_ then Node(k_, Leaf(k_, k__), l_) + else throw Error("already exist") + Empty then Leaf(k, e) + +fun lookupT(k, t) = if t is + Node(k_, l, r) and + k <= k_ then lookupT(k, l) + else lookupT(k, r) + Leaf(k_, e) then if k === k_ then Some(e) else None + Empty then None + +fun readInt(s) = + fun readInt_(n, cs) = if cs is + c :: cs_ and + isDigit(c) then readInt_(n * 10 + c.codePointAt(0) - 48, cs_) + else let s_ = dropWhile(isSpace, c :: cs) in [n, s_] + else + let s_ = dropWhile(isSpace, cs) in [n, s_] + readInt_(0, s) + +fun join(t1, t2, j) = if + t1 is Empty then j + t2 is Empty then j + t1 is Leaf(k, [a, b, c]) and lookupT(c, t2) is + None then j + Some([d, e, f]) then insertT(c, [a, b, c, d, e], j) + t1 is Node(k, l, r) then join(l, t2, join(r, t2, j)) + +fun readTree(fk, s, t) = if + s is Nil then t + readInt(s) is [f, s_] and + readInt(s_) is [g, s__] and + readInt(s__) is [h, s___] then + let e = [f, g, h] + let k = fk(e) + readTree(fk, s___, insertT(k, e, t)) + + +fun testTreejoin_nofib(n) = + let c1 = nofibStringToList of fs.readFileSync("hkmc2/shared/src/test/mlscript/nofib/input/1500.1").toString() + let c2 = nofibStringToList of fs.readFileSync("hkmc2/shared/src/test/mlscript/nofib/input/1500.2").toString() + let a = readTree(case { [xx, _, _] then xx }, c1, Empty) + let b = readTree(case { [xx, _, _] then xx }, c2, Empty) + join(a, b, Empty) + +fun main() = testTreejoin_nofib(0).toString() +//│ ═══[RUNTIME ERROR] RangeError: Maximum call stack size exceeded + + +// //│ = 'Node(26790, Node(25449, Node(24977, Node(24359, Node(24314, Leaf(24314, (9658,1890,24314,24314,7755)), Leaf(24359, (17282,5066,24359,24359,134))), Node(24452, Leaf(24452, (13985,4700,24452,24452,8400)), Node(24776, Leaf(24776, (9392,18824,24776,24776,25492)), Leaf(24977, (21044,6260,24977,24977,3296))))), Node(25347, Node(25087, Leaf(25087, (9226,22666,25087,25087,19595)), Leaf(25347, (9331,1734,25347,25347,12071))), Leaf(25449, (24361,14401,25449,25449,5552)))), Node(26770, Node(26207, Node(25780, Node(25457, Leaf(25457, (5457,5273,25457,25457,5149)), Leaf(25780, (21801,92,25780,25780,2781))), Leaf(26207, (22839,18759,26207,26207,20366))), Node(26436, Node(26274, Node(26222, Leaf(26222, (11315,3470,26222,26222,23055)), Leaf(26274, (19231,20706,26274,26274,24107))), Node(26276, Leaf(26276, (3545,169,26276,26276,7584)), Leaf(26436, (22148,24244,26436,26436,2448)))), Node(26473, Leaf(26473, (13180,15097,26473,26473,16469)), Leaf(26770, (23746,15943,26770,26770,1467))))), Leaf(26790, (25643,16230,26790,26790,970)))), Leaf(26932, (24868,11500,26932,26932,3741)))' + + diff --git a/benchmark/src/precompiled/BenchmarkPrelude.instr.mls b/benchmark/src/precompiled/BenchmarkPrelude.instr.mls new file mode 100644 index 000000000..30831ac73 --- /dev/null +++ b/benchmark/src/precompiled/BenchmarkPrelude.instr.mls @@ -0,0 +1,43 @@ +import "./Runtime.mls" +import "./Predef.mls" +import "./NofibPrelude.mls" +import "benchmark" +open Predef +open NofibPrelude + +let b = benchmark + +module BenchmarkPrelude with ... + +fun not(x) = x === false + +fun print(s) = s + +fun maybeStackSafe(f) = + Runtime.runStackSafe(2000, f) + +fun helper(f) = + let success = true + js.try_catch of () => maybeStackSafe(f), (e) => + set success = false + Predef.print("Error: " + e) + success + +fun benchmark(fn) = + // print(helper(fn)) + // print("benchmarking...") + // set Runtime.stackSafeCounter = 0 + helper(fn) + // Predef.print("stackSafeCounter: " + Runtime.stackSafeCounter) + let suite = new b.Suite() + suite.add("main", () => helper(fn)) + let settings = {} + set settings.async = false + suite.run(settings) + Predef.print("Time: " + suite.0.stats.mean * 1000 + "ms") + // let start = globalThis.performance.now() + // let res = helper(fn) + // let end = globalThis.performance.now() + // Predef.print("Time: " + (end - start) + "ms") + +// set globalThis.Predef = Predef diff --git a/benchmark/src/precompiled/BenchmarkPrelude.mls b/benchmark/src/precompiled/BenchmarkPrelude.mls new file mode 100644 index 000000000..1212b9575 --- /dev/null +++ b/benchmark/src/precompiled/BenchmarkPrelude.mls @@ -0,0 +1,6 @@ +module BenchmarkPrelude with + fun not(x) + fun print(s) + fun maybeStackSafe(f) + fun helper(f) + fun benchmark(fn) diff --git a/benchmark/src/precompiled/BenchmarkPrelude.noinstr.mls b/benchmark/src/precompiled/BenchmarkPrelude.noinstr.mls new file mode 100644 index 000000000..3cdc93816 --- /dev/null +++ b/benchmark/src/precompiled/BenchmarkPrelude.noinstr.mls @@ -0,0 +1,38 @@ +import "./Runtime.mls" +import "./Predef.mls" +import "./NofibPrelude.mls" +import "benchmark" +open Predef +open NofibPrelude + +let b = benchmark + +module BenchmarkPrelude with ... + +fun not(x) = x === false + +fun print(s) = s + +fun maybeStackSafe(f) = f() + +fun helper(f) = + let success = true + js.try_catch of () => maybeStackSafe(f), (e) => + set success = false + Predef.print("Error: " + e) + success + +fun benchmark(fn) = + // print(helper(fn)) + // print("benchmarking...") + let suite = new b.Suite() + suite.add("main", fn) + let settings = {} + set settings.async = false + suite.run(settings) + if suite.0.stats.sample.length > 0 do + Predef.print("Time: " + suite.0.stats.mean * 1000 + "ms") + // if res do + // Predef.print("Time: " + (end - start) + "ms") + +// set globalThis.Predef = Predef diff --git a/benchmark/src/precompiled/NofibPrelude.mls b/benchmark/src/precompiled/NofibPrelude.mls new file mode 100644 index 000000000..af67b16ec --- /dev/null +++ b/benchmark/src/precompiled/NofibPrelude.mls @@ -0,0 +1,367 @@ +import "./Predef.mls" +open Predef + +module NofibPrelude with ... +type Char = String + +abstract class Option[out T]: Some[T] | None +data class Some[out T](x: T) extends Option[T] +object None extends Option + +fun fromSome(s) = if s is Some(x) then x + +data class Lazy[out A](init: () -> A) with + mut val cached: Option[A] = None + fun get() = + if cached is + Some(v) then v + else + let v = init() + set cached = Some(v) + v +fun lazy(x) = Lazy(x) +fun force(x) = if x is Lazy then x.Lazy#get() + +abstract class List[out T]: Cons[T] | Nil +data class (::) Cons[out T](head: T, tail: List[T]) extends List[T] with + fun toString() = + "[" + _internal_cons_to_str(Cons(head, tail)) + "]" +object Nil extends List with + fun toString() = "[]" +fun _internal_cons_to_str(ls) = if ls is + Nil then "" + h :: Nil then render(h) + h :: t then render(h) + "," + _internal_cons_to_str(t) +fun ltList(xs, ys, lt, gt) = if xs is + Nil and + ys is Nil then false + else true + x :: xs and ys is + Nil then false + y :: ys and + lt(x, y) then true + gt(x, y) then false + else ltList(xs, ys, lt, gt) +fun list(...args) = if args is + [] then Nil + [x, ...xs] then x :: list(...xs) + +type LazyList[out T] = Lazy[LzList[T]] +abstract class LzList[out T]: LzCons[T] | LzNil +data class LzCons[out T](head: T, tail: LazyList[T]) extends LzList[T] +object LzNil extends LzList + +fun ltTup2(t1, t2, lt1, gt1, lt2) = if t1 is [a, b] and t2 is [c, d] and + lt1(a, c) then true + gt1(a, c) then false + else lt2(b, d) +fun eqTup2(t1, t2) = if t1 is [a, b] and t2 is [c, d] then a == c and b == d + +fun compose(f, g) = x => f(g(x)) + +fun snd(x) = if x is [f, s] then s +fun fst(x) = if x is [f, s] then f + +fun until(p, f, i) = if p(i) then i else until(p, f, f(i)) + +fun flip(f, x, y) = f(y)(x) + +fun power(a, n) = globalThis.Math.pow(a, n) + +fun intDiv(a, b) = globalThis.Math.floor(a / b) +fun intQuot(a, b) = globalThis.Math.trunc(a / b) + +fun intMod(a, b) = a - (b * intDiv(a, b)) +fun intRem(a, b) = a - (b * intQuot(a, b)) + +fun quotRem(a, b) = [intQuot(a, b), intRem(a, b)] +fun divMod(a, b) = [intDiv(a, b), intMod(a, b)] + +fun max(a, b) = globalThis.Math.max(a, b) +fun min(a, b) = globalThis.Math.min(a, b) + +fun abs(x) = globalThis.Math.abs(x) + +fun head(l) = if l is h :: t then h +fun tail(l) = if l is h :: t then t + +fun while_(p, f, x) = if p(x) then while_(p, f, f(x)) else x + +fun reverse(l) = + fun r(l', l) = if l is x :: xs then r(x :: l', xs) else l' + r(Nil, l) + +fun map(f, xs) = if xs is + x :: xs then f(x) :: map(f, xs) + Nil then Nil + +fun listLen(ls) = + fun l(ls, a) = if ls is + Nil then a + h :: t then l(t, a + 1) + l(ls, 0) + +fun listEq(xs, ys) = if + xs is Nil and ys is Nil then true + xs is hx :: tx and ys is hy :: ty and (hx == hy) then listEq(tx, ty) + else false + +fun listEqBy(f, a, b) = if a is + Nil and b is Nil then true + x :: xs and b is y :: ys then f(x, y) && listEqBy(f, xs, ys) + else false + +fun listNeq(xs, ys) = if + xs is Nil and ys is Nil then false + xs is hx :: tx and ys is hy :: ty and (hx == hy) then listNeq(tx, ty) + else true + +fun enumFromTo(a, b) = if a <= b then a :: enumFromTo(a + 1, b) else Nil + +fun enumFromThenTo(a, t, b) = if a <= b then a :: enumFromThenTo(t, 2 * t - a, b) else Nil + +fun drop(n, ls) = if ls is + Nil then Nil + h :: t and + n <= 0 then ls + else drop(n - 1, t) + +fun take(n, ls) = if ls is + Nil then Nil + h :: t and + n <= 0 then Nil + else h :: take(n - 1, t) + +fun splitAt(n, ls) = [take(n, ls), drop(n, ls)] + +fun zip(xs, ys) = if xs is + x :: xs and ys is y :: ys then [x, y] :: zip(xs, ys) + else Nil + +fun inList(x, ls) = if ls is + h :: t and + x === h then true + else inList(x, t) + Nil then false + +fun notElem(x, ls) = not(inList(x, ls)) + +fun (+:) append(xs, ys) = if xs is + Nil then ys + x :: xs then x :: append(xs, ys) + +fun concat(ls) = if ls is + Nil then Nil + x :: xs then append(x, concat(xs)) + +fun filter(f, ls) = if ls is + Nil then Nil + h :: t and + f(h) then h :: filter(f, t) + else filter(f, t) + +fun all(p, ls) = if ls is + Nil then true + h :: t and + p(h) then all(p, t) + else false + +fun orList(ls) = if ls is + Nil then false + h :: t and + h then true + else orList(t) + +fun dropWhile(f, ls) = if ls is + Nil then Nil + h :: t and + f(h) then dropWhile(f, t) + else h :: t + +fun foldl(f, a, xs) = if xs is + Nil then a + h :: t then foldl(f, f(a, h), t) + +fun scanl(f, q, ls) = if ls is + Nil then q :: Nil + x :: xs then q :: scanl(f, f(q, x), xs) + +fun scanr(f, q, ls) = if ls is + Nil then q :: Nil + x :: xs and scanr(f, q, xs) is q :: t then f(x, q) :: q :: t + +fun foldr(f, z, xs) = if xs is + Nil then z + h :: t then f(h, foldr(f, z, t)) + +fun foldl1(f, ls) = if + ls is x :: xs then foldl(f, x, xs) + +fun foldr1(f, ls) = if ls is + x :: Nil then x + x :: xs then f(x, foldr1(f, xs)) + +fun maximum(xs) = foldl1((x, y) => if x > y then x else y, xs) + +fun nubBy(eq, ls) = if ls is + Nil then Nil + h :: t then h :: nubBy(eq, filter(y => not(eq(h, y)), t)) + +fun zipWith(f, xss, yss) = if + xss is x :: xs and yss is y :: ys then f(x, y) :: zipWith(f, xs, ys) + else Nil + +fun deleteBy(eq, x, ys) = if ys is + Nil then Nil + y :: ys and + eq(x, y) then ys + else y :: deleteBy(eq, x, ys) + +fun unionBy(eq, xs, ys) = append(xs, foldl((acc, y) => deleteBy(eq, y, acc), nubBy(eq, ys), xs)) + +fun union(xs, ys) = unionBy((x, y) => x == y, xs, ys) + +fun atIndex(i, ls) = if ls is + h :: t and + i == 0 then h + else atIndex(i - 1, t) + +fun sum(xs) = + fun go(xs, a) = if xs is + Nil then a + h :: t then go(t, a + h) + go(xs, 0) + +fun null_(ls) = if ls is + Nil then true + else false + +fun replicate(n, x) = if n == 0 then Nil else x :: replicate(n - 1, x) + +fun unzip(l) = + fun f(l, a, b) = if l is + Nil then [reverse(a), reverse(b)] + [x, y] :: t then f(t, x :: a, y :: b) + f(l, Nil, Nil) + +fun zip3(xs, ys, zs) = if + xs is x :: xs and ys is y :: ys and zs is z :: zs then [x, y, z] :: zip3(xs, ys, zs) + else Nil + +fun transpose(xss) = + fun lscomp(ls) = if ls is + Nil then Nil + h :: t and h is + hd :: tl then [hd, tl] :: lscomp(t) + else lscomp(t) + fun combine(y, h, ys, t) = (y :: h) :: transpose(ys :: t) + if xss is + Nil then Nil + Nil :: xss then transpose(xss) + (x :: xs) :: xss and unzip(lscomp(xss)) is [hds, tls] then combine(x, hds, xs, tls) + +fun break_(p, ls) = if ls is + Nil then [Nil, Nil] + x :: xs and + p(x) then [Nil, x :: xs] + break_(p, xs) is [ys, zs] then [x :: ys, zs] + +fun flatMap(f, ls) = if ls is + Nil then Nil + h :: t then append(f(h), flatMap(f, t)) + +// ===================== + +fun map_lz(f, ls) = lazy of () => + if force(ls) is + LzNil then LzNil + LzCons(h, t) then LzCons(f(h), map_lz(f, t)) + +fun filter_lz(p, ls) = Lazy of () => + if force(ls) is + LzNil then LzNil + LzCons(h, t) and + p(h) then LzCons(h, filter_lz(p, t)) + else force(filter_lz(p, t)) + +fun nubBy_lz(eq, ls) = Lazy of () => + if force(ls) is + LzNil then LzNil + LzCons(h, t) then LzCons(h, nubBy_lz(eq, filter_lz(y => not(eq(h, y)), t))) + +fun nub_lz(ls) = nubBy_lz((x, y) => x == y, ls) + +fun take_lz(n, ls) = if + n > 0 and force(ls) is + LzNil then Nil + LzCons(h, t) then h :: take_lz(n - 1, t) + else Nil + +fun take_lz_lz(n, ls) = lazy of () => + if n > 0 and force(ls) is + LzNil then LzNil + LzCons(h, t) then LzCons(h, take_lz_lz(n - 1, t)) + else LzNil + +fun drop_lz(n, ls) = if + n <= 0 then ls + force(ls) is + LzNil then lazy of () => LzNil + LzCons(h, t) then drop_lz(n - 1, t) + +fun splitAt_lz(n, ls) = [take_lz(n, ls), drop_lz(n, ls)] + +fun zip_lz_nl(xs, ys) = if + force(xs) is LzCons(x, xs) and ys is y :: ys then [x, y] :: zip_lz_nl(xs, ys) + else Nil + +fun zip_lz_lz(xs, ys) = if + force(xs) is LzCons(x, xs) and force(ys) is LzCons(y, ys) then lazy of () => LzCons([x, y], zip_lz_lz(xs, ys)) + else lazy of () => LzNil + +fun zipWith_lz_lz(f, xss, yss) = lazy of () => if + force(xss) is LzCons(x, xs) and (force(yss)) is LzCons(y, ys) then LzCons(f(x, y), zipWith_lz_lz(f, xs, ys)) + else LzNil + +fun zipWith_lz_nl(f, xss, yss) = if + force(xss) is LzCons(x, xs) and yss is y :: ys then f(x, y) :: zipWith_lz_nl(f, xs, ys) + else Nil + +fun iterate(f, x) = lazy of () => LzCons(x, iterate(f, f(x))) + +fun append_nl_lz(xs, ys) = if xs is + Nil then ys + h :: t then lazy of () => LzCons(h, append_nl_lz(t, ys)) + +fun append_lz_lz(xs, ys) = lazy of () => if force(xs) is + LzNil then force(ys) + LzCons(h, t) then LzCons(h, append_lz_lz(t, ys)) + +fun replicate_lz(n, x) = if n == 0 then lazy of () => LzNil else lazy of () => LzCons(x, replicate_lz(n - 1, x)) + +fun enumFrom(a) = lazy of () => LzCons(a, enumFrom(a + 1)) + +fun head_lz(ls) = if force(ls) is LzCons(h, t) then h + +fun repeat(x) = lazy of () => LzCons(x, repeat(x)) +// ===================== + + +fun stringOfFloat(x) = x + "" +fun stringOfInt(x) = x + "" +fun stringConcat(x, y) = x + y +fun stringListConcat(ls) = if ls is + Nil then "" + h :: t then stringConcat(h, stringListConcat(t)) +fun sqrt(x) = globalThis.Math.sqrt(x) +fun tan(x) = globalThis.Math.tan(x) +fun sin(x) = globalThis.Math.sin(x) +fun cos(x) = globalThis.Math.cos(x) +fun round(x) = globalThis.Math.round(x) +fun int_of_char(x) = x.charCodeAt(0) +fun nofibStringToList(s) = + fun go(i) = if i < s.length then s.charAt(i) :: go(i + 1) else Nil + go(0) +fun nofibListToString(ls) = if ls is + Nil then "" + h :: t then h + nofibListToString(t) diff --git a/benchmark/src/precompiled/Predef.mls b/benchmark/src/precompiled/Predef.mls new file mode 120000 index 000000000..cf6bc2beb --- /dev/null +++ b/benchmark/src/precompiled/Predef.mls @@ -0,0 +1 @@ +../../../hkmc2/shared/src/test/mlscript-compile/Predef.mls \ No newline at end of file diff --git a/benchmark/src/precompiled/Rendering.mls b/benchmark/src/precompiled/Rendering.mls new file mode 120000 index 000000000..e4f9a99fd --- /dev/null +++ b/benchmark/src/precompiled/Rendering.mls @@ -0,0 +1 @@ +../../../hkmc2/shared/src/test/mlscript-compile/Rendering.mls \ No newline at end of file diff --git a/benchmark/src/precompiled/Runtime.mls b/benchmark/src/precompiled/Runtime.mls new file mode 120000 index 000000000..4015ede92 --- /dev/null +++ b/benchmark/src/precompiled/Runtime.mls @@ -0,0 +1 @@ +../../../hkmc2/shared/src/test/mlscript-compile/Runtime.mls \ No newline at end of file diff --git a/benchmark/src/precompiled/RuntimeJS.mjs b/benchmark/src/precompiled/RuntimeJS.mjs new file mode 120000 index 000000000..177e88094 --- /dev/null +++ b/benchmark/src/precompiled/RuntimeJS.mjs @@ -0,0 +1 @@ +../../../hkmc2/shared/src/test/mlscript-compile/RuntimeJS.mjs \ No newline at end of file diff --git a/benchmark/src/test/nofib/ansi.mls b/benchmark/src/test/nofib/ansi.mls new file mode 100644 index 000000000..6441acb04 --- /dev/null +++ b/benchmark/src/test/nofib/ansi.mls @@ -0,0 +1,16 @@ +:js +:nofib ansi + +BenchmarkPrelude.maybeStackSafe(ansi.main) +//│ Processing noInstr: +//│ BenchmarkPrelude = BenchmarkPrelude +//│ ansi = ansi +//│ = "LE[5;17HESC[7mDemonstration programESC[0mE[5;48HVersion 1.0E[7;17HThis program illustrates a simple approachE[8;17Hto screen-based interactive programs usingE[9;17Hthe Hugs functional programming system.E[11;17HPlease press any key to continue ...E[15;17HPlease enter your name: E[15;41H__________________E[15;41HesttesttestE[18;31HHello esttesttest!E[23;1HI'm waiting..." +//│ Processing effectOnly: +//│ BenchmarkPrelude = BenchmarkPrelude +//│ ansi = ansi +//│ = "LE[5;17HESC[7mDemonstration programESC[0mE[5;48HVersion 1.0E[7;17HThis program illustrates a simple approachE[8;17Hto screen-based interactive programs usingE[9;17Hthe Hugs functional programming system.E[11;17HPlease press any key to continue ...E[15;17HPlease enter your name: E[15;41H__________________E[15;41HesttesttestE[18;31HHello esttesttest!E[23;1HI'm waiting..." +//│ Processing stackSafe: +//│ BenchmarkPrelude = BenchmarkPrelude +//│ ansi = ansi +//│ = "LE[5;17HESC[7mDemonstration programESC[0mE[5;48HVersion 1.0E[7;17HThis program illustrates a simple approachE[8;17Hto screen-based interactive programs usingE[9;17Hthe Hugs functional programming system.E[11;17HPlease press any key to continue ...E[15;17HPlease enter your name: E[15;41H__________________E[15;41HesttesttestE[18;31HHello esttesttest!E[23;1HI'm waiting..." diff --git a/benchmark/src/test/nofib/cryptarithm1.mls b/benchmark/src/test/nofib/cryptarithm1.mls new file mode 100644 index 000000000..7c93bdf1b --- /dev/null +++ b/benchmark/src/test/nofib/cryptarithm1.mls @@ -0,0 +1,17 @@ +:js +:nofib cryptarithm1 + +:re +BenchmarkPrelude.maybeStackSafe(cryptarithm1.main) +//│ Processing noInstr: +//│ BenchmarkPrelude = BenchmarkPrelude +//│ cryptarithm1 = cryptarithm1 +//│ ═══[RUNTIME ERROR] RangeError: Maximum call stack size exceeded +//│ Processing effectOnly: +//│ BenchmarkPrelude = BenchmarkPrelude +//│ cryptarithm1 = cryptarithm1 +//│ ═══[RUNTIME ERROR] RangeError: Maximum call stack size exceeded +//│ Processing stackSafe: +//│ BenchmarkPrelude = BenchmarkPrelude +//│ cryptarithm1 = cryptarithm1 +//│ = [[[1,9,4,2,5,3,0,7,6,8]]] diff --git a/benchmark/src/test/scala/hkmc2/NofibDiffMaker.scala b/benchmark/src/test/scala/hkmc2/NofibDiffMaker.scala new file mode 100644 index 000000000..2c441eb2a --- /dev/null +++ b/benchmark/src/test/scala/hkmc2/NofibDiffMaker.scala @@ -0,0 +1,22 @@ +package hkmc2 + +import mlscript.utils._, shorthands._ +import hkmc2.syntax.Tree +import hkmc2.syntax.Keyword + +class NofibDiffMaker(val rootPath: Str, val file: os.Path, val preludeFile: os.Path, val predefFile: os.Path, val relativeName: Str) + extends LlirDiffMaker +: + val nofib = Command[Str]("nofib", false)(x => x.stripLeading()) + + override def processOrigin(origin: Origin)(using Raise): Unit = + given Config = mkConfig + nofib.get.fold(super.processOrigin(origin)): nofibFile => + ("noInstr" :: "effectOnly" :: "stackSafe" :: Nil).foreach: config => + output(s"Processing $config:") + val nofibPath = os.pwd/"benchmark"/"target"/config/"nofib"/(nofibFile+".mjs") + val benchmarkPrelude = os.pwd/"benchmark"/"target"/config/"precompiled"/"BenchmarkPrelude.mjs" + super.processTrees( + Tree.Modified(Keyword.`import`, N, Tree.StrLit(nofibPath.toString)) :: + Tree.Modified(Keyword.`import`, N, Tree.StrLit(benchmarkPrelude.toString)) :: Nil) + super.processOrigin(origin) diff --git a/benchmark/src/test/scala/hkmc2/NofibTestRunner.scala b/benchmark/src/test/scala/hkmc2/NofibTestRunner.scala new file mode 100644 index 000000000..3fb68064f --- /dev/null +++ b/benchmark/src/test/scala/hkmc2/NofibTestRunner.scala @@ -0,0 +1,17 @@ +package hkmc2 + +import org.scalatest.{funsuite, ParallelTestExecution} +import org.scalatest.time._ + +import mlscript.utils._ +import os.Path + +class NofibTestRunner + extends DiffTestRunnerBase(DiffTestRunner.State) + with ParallelTestExecution +: + override protected lazy val diffTestFiles = os.list(os.pwd/"benchmark"/"src"/"test"/"nofib") + + override protected def createDiffMaker(file: Path, preludePath: Path, predefPath: Path, relativeName: String): DiffMaker = + new NofibDiffMaker((os.pwd/"benchmark").toString, file, preludePath, predefPath, relativeName) + diff --git a/build.sbt b/build.sbt index 6c575b908..b4f1b2ccf 100644 --- a/build.sbt +++ b/build.sbt @@ -153,3 +153,14 @@ lazy val compiler = crossProject(JSPlatform, JVMPlatform).in(file("compiler")) lazy val compilerJVM = compiler.jvm lazy val compilerJS = compiler.js +lazy val benchmark = project.in(file("benchmark")) + .settings( + name := "benchmark", + scalaVersion := scala3Version, + sourceDirectory := baseDirectory.value/"src", + libraryDependencies += "org.scalatest" %%% "scalatest" % "3.2.18" % "test", + watchSources += WatchSource( + baseDirectory.value/"src"/"test"/"nofib", "*.mls", NothingFilter), + ) + .dependsOn(hkmc2JVM) + .dependsOn(hkmc2DiffTests % "compile->compile;test->test") diff --git a/hkmc2/shared/src/main/scala/hkmc2/MLsCompiler.scala b/hkmc2/shared/src/main/scala/hkmc2/MLsCompiler.scala index 35aad9f72..3a453cc35 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/MLsCompiler.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/MLsCompiler.scala @@ -40,9 +40,6 @@ class ParserSetup(file: os.Path, dbgParsing: Bool)(using Elaborator.State, Raise // * The weird type of `mkOutput` is to allow wrapping the reporting of diagnostics in synchronized blocks class MLsCompiler(preludeFile: os.Path, mkOutput: ((Str => Unit) => Unit) => Unit)(using Config): - val runtimeFile: os.Path = preludeFile/os.up/os.up/os.up/"mlscript-compile"/"Runtime.mjs" - val termFile: os.Path = preludeFile/os.up/os.up/os.up/"mlscript-compile"/"Term.mjs" - val report = ReportFormatter: outputConsumer => mkOutput: output => @@ -59,7 +56,7 @@ class MLsCompiler(preludeFile: os.Path, mkOutput: ((Str => Unit) => Unit) => Uni var dbgParsing = false - def compileModule(file: os.Path): Unit = + def compileModule(file: os.Path, outFile: Opt[os.Path] = N, exportName: Opt[Str] = N, runtimeImportPath: Opt[os.Path] = N, skipTerm: Bool = false): Unit = val wd = file / os.up @@ -85,8 +82,10 @@ class MLsCompiler(preludeFile: os.Path, mkOutput: ((Str => Unit) => Unit) => Uni val (blk0, _) = elab.importFrom(parsed) val resolver = Resolver(rtl) resolver.traverseBlock(blk0)(using Resolver.ICtx.empty) + val runtimeFile: os.Path = runtimeImportPath.getOrElse(preludeFile/os.up/os.up/os.up/"mlscript-compile"/"Runtime.mjs") + val termFile: os.Path = preludeFile/os.up/os.up/os.up/"mlscript-compile"/"Term.mjs" val blk = new semantics.Term.Blk( - semantics.Import(State.runtimeSymbol, runtimeFile.toString) :: semantics.Import(State.termSymbol, termFile.toString) :: blk0.stats, + semantics.Import(State.runtimeSymbol, runtimeFile.toString) :: (if !skipTerm then semantics.Import(State.termSymbol, termFile.toString) :: blk0.stats else blk0.stats), blk0.res ) val low = ltl.givenIn: @@ -101,13 +100,13 @@ class MLsCompiler(preludeFile: os.Path, mkOutput: ((Str => Unit) => Unit) => Uni // * Having `module id"import" with ...` in `prelude.mls` will generate `globalThis.import` that is undefined. baseScp.bindings += Elaborator.State.importSymbol -> "import" val nestedScp = baseScp.nest - val nme = file.baseName + val nme = exportName.getOrElse(file.baseName) val exportedSymbol = parsed.definedSymbols.find(_._1 === nme).map(_._2) val je = nestedScp.givenIn: jsb.program(le, exportedSymbol, wd) val jsStr = je.stripBreaks.mkString(100) - val out = file / os.up / (file.baseName + ".mjs") - os.write.over(out, jsStr) + val out = outFile.getOrElse(file / os.up / (file.baseName + ".mjs")) + os.write.over(out, jsStr, createFolders = true) end MLsCompiler diff --git a/hkmc2/shared/src/test/mlscript-compile/Runtime.mjs b/hkmc2/shared/src/test/mlscript-compile/Runtime.mjs index f36edd8c4..395eb5791 100644 --- a/hkmc2/shared/src/test/mlscript-compile/Runtime.mjs +++ b/hkmc2/shared/src/test/mlscript-compile/Runtime.mjs @@ -732,25 +732,24 @@ let Runtime1; } } static resumeContTrace(contTrace2, value) { - let cont4, handlerCont, scrut, scrut1, tmp, tmp1, tmp2, tmp3, tmp4; - cont4 = contTrace2.next; - handlerCont = contTrace2.nextHandler; + let scrut, scrut1, scrut2, scrut3, tmp, tmp1, tmp2, tmp3, tmp4; tmp5: while (true) { - if (cont4 instanceof Runtime.FunctionContFrame.class) { - tmp = runtime.safeCall(cont4.resume(value)); + scrut1 = contTrace2.next; + if (scrut1 instanceof Runtime.FunctionContFrame.class) { + tmp = runtime.safeCall(contTrace2.next.resume(value)); value = tmp; if (value instanceof Runtime.EffectSig.class) { - value.contTrace.last.next = cont4.next; - value.contTrace.lastHandler.nextHandler = handlerCont; - scrut = contTrace2.last !== cont4; - if (scrut === true) { + value.contTrace.last.next = contTrace2.next.next; + value.contTrace.lastHandler.nextHandler = contTrace2.nextHandler; + scrut2 = contTrace2.last !== contTrace2.next; + if (scrut2 === true) { value.contTrace.last = contTrace2.last; tmp1 = runtime.Unit; } else { tmp1 = runtime.Unit; } - scrut1 = handlerCont !== null; - if (scrut1 === true) { + scrut3 = contTrace2.nextHandler !== null; + if (scrut3 === true) { value.contTrace.lastHandler = contTrace2.lastHandler; tmp2 = runtime.Unit; } else { @@ -758,15 +757,16 @@ let Runtime1; } return value } else { - cont4 = cont4.next; + contTrace2.next = contTrace2.next.next; tmp3 = runtime.Unit; } tmp4 = tmp3; continue tmp5; } else { - if (handlerCont instanceof Runtime.HandlerContFrame.class) { - cont4 = handlerCont.next; - handlerCont = handlerCont.nextHandler; + scrut = contTrace2.nextHandler; + if (scrut instanceof Runtime.HandlerContFrame.class) { + contTrace2.next = contTrace2.nextHandler.next; + contTrace2.nextHandler = contTrace2.nextHandler.nextHandler; tmp4 = runtime.Unit; continue tmp5; } else { diff --git a/hkmc2/shared/src/test/mlscript-compile/Runtime.mls b/hkmc2/shared/src/test/mlscript-compile/Runtime.mls index 381e7ccfe..268c7ebde 100644 --- a/hkmc2/shared/src/test/mlscript-compile/Runtime.mls +++ b/hkmc2/shared/src/test/mlscript-compile/Runtime.mls @@ -320,25 +320,23 @@ fun resume(contTrace)(value) = handleEffects(resumeContTrace(contTrace, value)) fun resumeContTrace(contTrace, value) = - let cont = contTrace.next - let handlerCont = contTrace.nextHandler while - cont is FunctionContFrame then - set value = cont.resume(value) + contTrace.next is FunctionContFrame then + set value = contTrace.next.resume(value) if value is EffectSig then set - value.contTrace.last.next = cont.next - value.contTrace.lastHandler.nextHandler = handlerCont - if contTrace.last !== cont do + value.contTrace.last.next = contTrace.next.next + value.contTrace.lastHandler.nextHandler = contTrace.nextHandler + if contTrace.last !== contTrace.next do set value.contTrace.last = contTrace.last - if handlerCont !== null do + if contTrace.nextHandler !== null do set value.contTrace.lastHandler = contTrace.lastHandler return value else - set cont = cont.next - handlerCont is HandlerContFrame then - set cont = handlerCont.next - set handlerCont = handlerCont.nextHandler + set contTrace.next = contTrace.next.next + contTrace.nextHandler is HandlerContFrame then + set contTrace.next = contTrace.nextHandler.next + set contTrace.nextHandler = contTrace.nextHandler.nextHandler else return value diff --git a/hkmc2/shared/src/test/mlscript-compile/RuntimeJS.mjs b/hkmc2/shared/src/test/mlscript-compile/RuntimeJS.mjs index b421f5e3a..b4a054419 100644 --- a/hkmc2/shared/src/test/mlscript-compile/RuntimeJS.mjs +++ b/hkmc2/shared/src/test/mlscript-compile/RuntimeJS.mjs @@ -1,4 +1,3 @@ -import Predef from "./Predef.mjs"; const RuntimeJS = { try_catch(computation, onError) { diff --git a/hkmc2/shared/src/test/mlscript/HkScratch.mls b/hkmc2/shared/src/test/mlscript/HkScratch.mls index 446cd427b..0fc55ab39 100644 --- a/hkmc2/shared/src/test/mlscript/HkScratch.mls +++ b/hkmc2/shared/src/test/mlscript/HkScratch.mls @@ -9,4 +9,3 @@ :todo - diff --git a/hkmc2/shared/src/test/mlscript/nofib/boyer2.mls b/hkmc2/shared/src/test/mlscript/nofib/boyer2.mls index 4c7d88b06..840d38566 100644 --- a/hkmc2/shared/src/test/mlscript/nofib/boyer2.mls +++ b/hkmc2/shared/src/test/mlscript/nofib/boyer2.mls @@ -202,12 +202,12 @@ let statement = mkLispList(strToToken( fun subterm(i) = let c = stringConcat("c", stringOfInt(i)) let str = stringConcat( - nofibStringToList("( ( x f ( plus ( plus a b )( plus "), + "( ( x f ( plus ( plus a b )( plus ", stringConcat( c, stringConcat( - nofibStringToList(" ( zero ) ) ) )( y f ( times ( times a b )( plus "), - stringConcat(c, nofibStringToList(" d ) ) )( z f ( reverse ( append ( append a b ) ( [] ) ) ) )(u equal ( plus a b ) ( difference x y ) )(w lessp ( remainder a b )( member a ( length b ) ) ) )")) + " ( zero ) ) ) )( y f ( times ( times a b )( plus ", + stringConcat(c, " d ) ) )( z f ( reverse ( append ( append a b ) ( [] ) ) ) )(u equal ( plus a b ) ( difference x y ) )(w lessp ( remainder a b )( member a ( length b ) ) ) )") ) ) ) diff --git a/hkmc2DiffTests/src/test/scala/hkmc2/DiffTestRunner.scala b/hkmc2DiffTests/src/test/scala/hkmc2/DiffTestRunner.scala index 98ca7894e..91f11ecd3 100644 --- a/hkmc2DiffTests/src/test/scala/hkmc2/DiffTestRunner.scala +++ b/hkmc2DiffTests/src/test/scala/hkmc2/DiffTestRunner.scala @@ -112,6 +112,14 @@ class DiffTestRunnerBase(state: DiffTestRunner.State) && filter(file.relativeTo(state.workingDir)) ) + protected def createDiffMaker( + file: os.Path, + preludePath: os.Path, + predefPath: os.Path, + relativeName: String + ): DiffMaker = + new MainDiffMaker(workingDir.toString, file, preludePath, predefPath, relativeName) + diffTestFiles.foreach: file => val basePath = file.segments.drop(dir.segmentCount).toList.init @@ -122,7 +130,7 @@ class DiffTestRunnerBase(state: DiffTestRunner.State) val preludePath = dir/"mlscript"/"decls"/"Prelude.mls" val predefPath = dir/"mlscript-compile"/"Predef.mls" - val dm = new MainDiffMaker(workingDir.toString, file, preludePath, predefPath, relativeName) + val dm = createDiffMaker(file, preludePath, predefPath, relativeName) dm.run() diff --git a/package-lock.json b/package-lock.json index 636e503a3..567ef3485 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,36 @@ { "name": "mlscript", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { "dependencies": { + "benchmark": "^2.1.4", "typescript": "^4.7.4" } }, + "node_modules/benchmark": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz", + "integrity": "sha512-l9MlfN4M1K/H2fbhfMy3B7vJd6AGKJVQn2h6Sg/Yx+KckoUA7ewS5Vv6TjSq18ooE1kS9hhAlQRH3AkXIh/aOQ==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.4", + "platform": "^1.3.3" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/platform": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", + "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==", + "license": "MIT" + }, "node_modules/typescript": { "version": "4.7.4", "resolved": "https://registry.npmmirror.com/typescript/-/typescript-4.7.4.tgz", @@ -20,12 +43,5 @@ "node": ">=4.2.0" } } - }, - "dependencies": { - "typescript": { - "version": "4.7.4", - "resolved": "https://registry.npmmirror.com/typescript/-/typescript-4.7.4.tgz", - "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==" - } } } diff --git a/package.json b/package.json index bc371fcd6..2b8030bf6 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,6 @@ { "dependencies": { + "benchmark": "^2.1.4", "typescript": "^4.7.4" } }