From c41180e3b78e6f97ad42fdcfe7ffbdd054123515 Mon Sep 17 00:00:00 2001 From: breandan Date: Sun, 9 Aug 2020 18:47:45 -0400 Subject: [PATCH] use enums instead of string labels --- build.gradle.kts | 2 +- kaliningraph.json | 2 +- .../kotlin/edu/mcgill/kaliningraph/Utils.kt | 8 +- .../kaliningraph/circuits/ComputationGraph.kt | 85 ++++++++++--------- 4 files changed, 52 insertions(+), 45 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 53c4c2f5..ebf84ae9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,7 +7,7 @@ plugins { } group = "edu.mcgill" -version = "0.0.5-SNAPSHOT" +version = "0.0.6-SNAPSHOT" repositories { mavenCentral() diff --git a/kaliningraph.json b/kaliningraph.json index 251b1c3d..565f33dc 100644 --- a/kaliningraph.json +++ b/kaliningraph.json @@ -1,6 +1,6 @@ { "properties": { - "kaliningraphVersion": "0.0.4", + "kaliningraphVersion": "0.0.6", "graphvizVersion": "0.16.0", "jgraphtVersion": "1.4.0", "ejmlVersion": "0.39", diff --git a/src/main/kotlin/edu/mcgill/kaliningraph/Utils.kt b/src/main/kotlin/edu/mcgill/kaliningraph/Utils.kt index 4589de30..c3aae936 100644 --- a/src/main/kotlin/edu/mcgill/kaliningraph/Utils.kt +++ b/src/main/kotlin/edu/mcgill/kaliningraph/Utils.kt @@ -43,11 +43,11 @@ fun Graph<*, *, *>.toGraphviz() = // graph[Rank.dir(Rank.RankDir.LEFT_TO_RIGHT), Color.TRANSPARENT.background()] node[color, color.font(), Font.config("Helvetica", 20), lineWidth(THICKNESS), Attributes.attr("shape", "Mrecord")] - vertices.forEach { node -> - for (neighbor in node.neighbors) { - val source = Factory.mutNode(node.id).add(Label.of(node.toString())).also { if (node.occupied) it[FILLED, RED.fill()] else it[BLACK] } + vertices.forEach { vertex -> + vertex.neighbors.forEach { neighbor -> + val source = Factory.mutNode(vertex.id).add(Label.of(vertex.toString())).also { if (vertex.occupied) it[FILLED, RED.fill()] else it[BLACK] } val target = Factory.mutNode(neighbor.id).add(Label.of(neighbor.toString()))//.also { if (neighbor.occupied) it[RED] else it[BLACK] } - (source - target).add(Label.of("")).also { if (node.occupied) it[RED] else it[BLACK] } + (source - target).add(Label.of("")).also { if (vertex.occupied) it[RED] else it[BLACK] } } } } diff --git a/src/main/kotlin/edu/mcgill/kaliningraph/circuits/ComputationGraph.kt b/src/main/kotlin/edu/mcgill/kaliningraph/circuits/ComputationGraph.kt index 8efb7451..e710bb10 100644 --- a/src/main/kotlin/edu/mcgill/kaliningraph/circuits/ComputationGraph.kt +++ b/src/main/kotlin/edu/mcgill/kaliningraph/circuits/ComputationGraph.kt @@ -1,27 +1,24 @@ package edu.mcgill.kaliningraph.circuits import edu.mcgill.kaliningraph.* +import edu.mcgill.kaliningraph.circuits.Dyad.* import edu.mcgill.kaliningraph.circuits.Gate.Companion.wrap +import edu.mcgill.kaliningraph.circuits.Polyad.* import kotlin.reflect.KProperty // Mutable environment with support for variable overwriting/reassignment class Notebook { var graph = ComputationGraph() - var a by Gate(); var b by Gate(); var c by Gate(); var d by Gate() - var e by Gate(); var f by Gate(); var g by Gate(); var h by Gate() - var i by Gate(); var j by Gate(); var k by Gate(); var l by Gate() + var a by Var(); var b by Var(); var c by Var(); var d by Var() + var e by Var(); var f by Var(); var g by Var(); var h by Var() + var i by Var(); var j by Var(); var k by Var(); var l by Var() operator fun Any.plus(that: Any) = wrap(this, that) { a, b -> a + b } operator fun Any.minus(that: Any) = wrap(this, that) { a, b -> a - b } operator fun Any.times(that: Any) = wrap(this, that) { a, b -> a * b } operator fun Any.div(that: Any) = wrap(this, that) { a, b -> a / b } - operator fun Gate.plus(that: Gate) = join(this, that, "+") - operator fun Gate.minus(that: Gate) = join(this, that, "-") - operator fun Gate.times(that: Gate) = join(this, that, "*") - operator fun Gate.div(that: Gate) = join(this, that, "/") - fun wrap(left: Any, right: Any, op: (Gate, Gate) -> Gate): Gate = op(wrap(left), wrap(right)) @@ -34,58 +31,69 @@ class Notebook { } } -val a by Gate(); val b by Gate(); val c by Gate(); val d by Gate() -val e by Gate(); val f by Gate(); val g by Gate(); val h by Gate() -val i by Gate(); val j by Gate(); val k by Gate(); val l by Gate() +val a by Var(); val b by Var(); val c by Var(); val d by Var() +val e by Var(); val f by Var(); val g by Var(); val h by Var() +val i by Var(); val j by Var(); val k by Var(); val l by Var() fun def(vararg params: Gate, body: (Array) -> Gate) = NFunction(randomString(), params, body) -operator fun Any.plus(that: Any) = wrap(this, that) { a, b -> a + b } -operator fun Any.minus(that: Any) = wrap(this, that) { a, b -> a - b } -operator fun Any.times(that: Any) = wrap(this, that) { a, b -> a * b } -operator fun Any.div(that: Any) = wrap(this, that) { a, b -> a / b } - -operator fun Gate.plus(that: Gate) = join(this, that, "+") -operator fun Gate.minus(that: Gate) = join(this, that, "-") -operator fun Gate.times(that: Gate) = join(this, that, "*") -operator fun Gate.div(that: Gate) = join(this, that, "/") - -fun wrap(left: Any, right: Any, op: (Gate, Gate) -> Gate): Gate = - op(wrap(left), wrap(right)) - -fun join(left: Gate, right: Gate, label: String) = Gate(label, left, right) +operator fun Any.plus(that: Gate) = wrap(this, that) { a, b -> a + b } +operator fun Any.minus(that: Gate) = wrap(this, that) { a, b -> a - b } +operator fun Any.times(that: Gate) = wrap(this, that) { a, b -> a * b } +operator fun Any.div(that: Gate) = wrap(this, that) { a, b -> a / b } class ComputationGraph(override val vertices: Set = setOf()): Graph(vertices) { override fun new(vertices: Set) = ComputationGraph(vertices) } -open class Gate( +interface Op +enum class Monad: Op { `-`, sin, cos, tan, id } +enum class Dyad: Op { `+`, `-`, `*`, `÷`, `=`, pow } +enum class Polyad: Op { λ, Σ, Π } + +open class Gate constructor( id: String = randomString(), - val label: String = id, + val op: Op = Monad.id, override val edgeMap: (Gate) -> Collection ) : Vertex(id) { - constructor(id: String = randomString(), label: String, vararg gates: Gate) : - this(id, label, { s -> gates.toSet().map { t -> UnlabeledEdge(s, t) } }) - constructor(label: String = "", vararg gates: Gate) : this(randomString(), label, *gates) - + constructor(op: Op = Monad.id, vararg gates: Gate) : this(randomString(), op, *gates) + constructor(id: String = randomString(), vararg gates: Gate) : this(id, Monad.id, *gates) + constructor(id: String = randomString(), op: Op = Monad.id, vararg gates: Gate) : + this(id, op, { s -> gates.toSet().map { t -> UnlabeledEdge(s, t) } }) companion object { - fun wrap(value: Any) = if (value is Gate) value else Gate(value.toString()) - fun wrapAll(vararg values: Any) = values.map { wrap(it) }.toTypedArray() + fun wrap(value: Any): Gate = if (value is Gate) value else Gate(value.toString()) + fun wrap(left: Any, right: Any, op: (Gate, Gate) -> Gate): Gate = op(wrap(left), wrap(right)) + fun wrapAll(vararg values: Any): Array = values.map { wrap(it) }.toTypedArray() } - override fun toString() = label + override fun toString() = if(op != Monad.id) op.toString() else id + + operator fun plus(that: Any) = Gate(`+`, this, wrap(that)) + operator fun minus(that: Any) = Gate(`-`, this, wrap(that)) + operator fun times(that: Any) = Gate(`*`, this, wrap(that)) + operator fun div(that: Any) = Gate(`÷`, this, wrap(that)) + infix fun pow(that: Any) = Gate(pow, this, wrap(that)) + + operator fun unaryMinus() = Gate(Monad.`-`, this) + + fun sin() = Gate(Monad.sin, this) + fun cos() = Gate(Monad.cos, this) + fun tan() = Gate(Monad.tan, this) override fun Graph(vertices: Set) = ComputationGraph(vertices) override fun Edge(s: Gate, t: Gate) = UnlabeledEdge(s, t) - override fun Vertex(newId: String, edgeMap: (Gate) -> Collection) = Gate(newId, label, edgeMap) + override fun Vertex(newId: String, edgeMap: (Gate) -> Collection) = + Gate(newId, Monad.id, edgeMap) - override operator fun getValue(a: Any?, prop: KProperty<*>): Gate = Gate(prop.name, prop.name) + override operator fun getValue(a: Any?, prop: KProperty<*>): Gate = Gate(prop.name) open operator fun setValue(builder: Notebook, prop: KProperty<*>, value: Gate) { - builder.graph += Gate(prop.name, prop.name, Gate("=", value)).graph + builder.graph += Gate(prop.name, Gate(`=`, value)).graph } } +class Var(val name: String = randomString()) : Gate(name) + class NFunction( val name: String = randomString(), val params: Array = arrayOf(), @@ -93,7 +101,7 @@ class NFunction( ): Gate(id = name, edgeMap = { s -> setOf(UnlabeledEdge(s, body(params))) }) { operator fun invoke(vararg args: Any): Gate = if (arityMatches(*args)) - Gate("λ", *wrapAll(*args).let { it.plusElement(Gate(name, Gate("=", body(it)))) }) + Gate(λ, *wrapAll(*args).let { it.plusElement(Gate(name, Gate(`=`, body(it)))) }) else throw Exception(invokeError(*args)) fun invokeError(vararg args: Any) = @@ -112,7 +120,6 @@ open class UnlabeledEdge(override val source: Gate, override val target: Gate): fun main() { Notebook { val funA by def(a, b, c) { a + b + c } - j = funA(3, 2, 1) j = b * c d = e * f