From b90bdc84c4e4eaabd24c74acaa906d6db1a3a2e5 Mon Sep 17 00:00:00 2001 From: Fedor Isakov Date: Thu, 7 Jan 2016 12:56:13 +0100 Subject: [PATCH] MemLogicalPattern. Switch to using MemLogical in tests. --- .../mps/logic/reactor/logical/Logical.java | 2 +- .../mps/logic/reactor/core/Matcher.kt | 2 +- .../reactor/{predicate => core}/MemLogical.kt | 17 +++- reactor/Test/src/program/MemLogicalPattern.kt | 28 ++++++ .../src/solver}/MemSessionSolver.kt | 8 +- reactor/Test/test/EqualsSolver.kt | 50 +++++----- reactor/Test/test/LogicalHelper.kt | 94 +++---------------- reactor/Test/test/TestHandler.kt | 6 +- reactor/Test/test/TestMatcher.kt | 10 +- reactor/Test/test/TestProgram.kt | 2 +- reactor/Test/test/TestProgramBuilder.kt | 2 +- 11 files changed, 99 insertions(+), 122 deletions(-) rename reactor/Core/src/jetbrains/mps/logic/reactor/{predicate => core}/MemLogical.kt (75%) create mode 100644 reactor/Test/src/program/MemLogicalPattern.kt rename reactor/{Core/src/jetbrains/mps/logic/reactor/predicate => Test/src/solver}/MemSessionSolver.kt (79%) diff --git a/reactor/API/src/jetbrains/mps/logic/reactor/logical/Logical.java b/reactor/API/src/jetbrains/mps/logic/reactor/logical/Logical.java index ca4a7f86..dd789cfc 100644 --- a/reactor/API/src/jetbrains/mps/logic/reactor/logical/Logical.java +++ b/reactor/API/src/jetbrains/mps/logic/reactor/logical/Logical.java @@ -15,6 +15,6 @@ public interface Logical { public boolean isWildcard(); - public LogicalPattern> pattern(); + public LogicalPattern pattern(); } diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/Matcher.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/Matcher.kt index b1ebc841..90ca517b 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/Matcher.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/Matcher.kt @@ -99,7 +99,7 @@ class PartialMatch(val rule: Rule) { return var2val[logicalPattern] as V } else { - val logical = logicalPattern.instance() + val logical = logicalPattern.logical() var2val.put(logicalPattern, logical) return logical as V } diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/predicate/MemLogical.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/MemLogical.kt similarity index 75% rename from reactor/Core/src/jetbrains/mps/logic/reactor/predicate/MemLogical.kt rename to reactor/Core/src/jetbrains/mps/logic/reactor/core/MemLogical.kt index 057e17d8..b95c7ccb 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/predicate/MemLogical.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/MemLogical.kt @@ -1,5 +1,5 @@ -package jetbrains.mps.logic.reactor.predicate +package jetbrains.mps.logic.reactor.core import jetbrains.mps.logic.reactor.logical.Logical import jetbrains.mps.logic.reactor.logical.LogicalPattern @@ -9,6 +9,8 @@ import jetbrains.mps.logic.reactor.logical.SolverLogical * @author Fedor Isakov */ +fun LogicalPattern.logical(): Logical = MemLogical(name()) + class MemLogical : SolverLogical { companion object { @@ -17,6 +19,8 @@ class MemLogical : SolverLogical { val name: String + var pattern: LogicalPattern? = null + var _parent: MemLogical? = null var _value: T? = null @@ -32,6 +36,11 @@ class MemLogical : SolverLogical { this.name = name } + constructor(pattern: LogicalPattern) { + this.pattern = pattern + this.name = pattern.name() + } + override fun name(): String = name override fun value(): T? = _value @@ -40,11 +49,13 @@ class MemLogical : SolverLogical { override fun isWildcard(): Boolean = TODO() - override fun pattern(): LogicalPattern> = TODO() + override fun pattern(): LogicalPattern? = pattern override fun findRoot(): SolverLogical = find() - override fun setParent(parent: SolverLogical) { this._parent = parent as MemLogical } + override fun setParent(parent: SolverLogical) { + this._parent = parent as MemLogical + } override fun setValue(newValue: T) { this._value = newValue } diff --git a/reactor/Test/src/program/MemLogicalPattern.kt b/reactor/Test/src/program/MemLogicalPattern.kt new file mode 100644 index 00000000..85c61088 --- /dev/null +++ b/reactor/Test/src/program/MemLogicalPattern.kt @@ -0,0 +1,28 @@ +package program + +import jetbrains.mps.logic.reactor.logical.Logical +import jetbrains.mps.logic.reactor.logical.LogicalPattern +import jetbrains.mps.logic.reactor.logical.NamingContext + +/** + * @author Fedor Isakov + */ + +data class MemLogicalPattern(val name: String, val type: Class, val wildcard: Boolean) : LogicalPattern { + + constructor(name: String, type: Class) : this(name, type, false) {} + + override fun name(): String = name + + override fun name(namingContext: NamingContext): String = TODO() + + override fun isWildcard(): Boolean = wildcard + + override fun type(): Class = type + + override fun instance(): Logical { + // FIXME wrong + throw UnsupportedOperationException("fixme") + } + +} \ No newline at end of file diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/predicate/MemSessionSolver.kt b/reactor/Test/src/solver/MemSessionSolver.kt similarity index 79% rename from reactor/Core/src/jetbrains/mps/logic/reactor/predicate/MemSessionSolver.kt rename to reactor/Test/src/solver/MemSessionSolver.kt index a9ed666f..21a6d98f 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/predicate/MemSessionSolver.kt +++ b/reactor/Test/src/solver/MemSessionSolver.kt @@ -1,4 +1,4 @@ -package jetbrains.mps.logic.reactor.predicate +package solver import jetbrains.mps.logic.reactor.evaluation.EvaluationTrace import jetbrains.mps.logic.reactor.evaluation.Queryable @@ -15,15 +15,15 @@ open class MemSessionSolver(val expressionSolver: Queryable, val equalsSolver: Q override fun solverClass(predicateSymbol: PredicateSymbol): Class { return when (predicateSymbol) { is JavaPredicateSymbol -> expressionSolver.javaClass - PredicateSymbol("equals", 2) -> equalsSolver.javaClass + PredicateSymbol("equals", 2) -> equalsSolver.javaClass else -> throw UnsupportedOperationException("not implemented") } } override fun registerSymbol(predicateSymbol: PredicateSymbol, computingTracer: EvaluationTrace?) { when (predicateSymbol) { - is JavaPredicateSymbol -> registerSolver(predicateSymbol, expressionSolver) - PredicateSymbol("equals", 2) -> registerSolver(predicateSymbol, equalsSolver) + is JavaPredicateSymbol -> registerSolver(predicateSymbol, expressionSolver) + PredicateSymbol("equals", 2) -> registerSolver(predicateSymbol, equalsSolver) else -> throw UnsupportedOperationException("not implemented") } } diff --git a/reactor/Test/test/EqualsSolver.kt b/reactor/Test/test/EqualsSolver.kt index 4b0ef36b..759ced70 100644 --- a/reactor/Test/test/EqualsSolver.kt +++ b/reactor/Test/test/EqualsSolver.kt @@ -1,6 +1,7 @@ import jetbrains.mps.logic.reactor.evaluation.EvaluationSession import jetbrains.mps.logic.reactor.evaluation.Queryable import jetbrains.mps.logic.reactor.logical.Logical +import jetbrains.mps.logic.reactor.logical.SolverLogical import jetbrains.mps.logic.reactor.program.PredicateSymbol import jetbrains.mps.logic.reactor.program.Symbol @@ -11,13 +12,13 @@ class EqualsSolver : Queryable { val left = args[0] val right = args[1] - return if (left is TestLogical<*> && right is TestLogical<*>) { + return if (left is SolverLogical<*> && right is SolverLogical<*>) { ask_logical_logical(left, right) } - else if (left is TestLogical<*>) { + else if (left is SolverLogical<*>) { ask_logical_value(left, right) } - else if (right is TestLogical<*>) { + else if (right is SolverLogical<*>) { ask_value_logical(left, right) } else { @@ -29,29 +30,29 @@ class EqualsSolver : Queryable { if (args.size != 2) ERROR("arity mismatch") val left = args[0] val right = args[1] - if (left is TestLogical<*> && right is TestLogical<*>) { + if (left is SolverLogical<*> && right is SolverLogical<*>) { tell_logical_logical(left, right) } - else if (left is TestLogical<*>) { - tell_logical_value(left, right) + else if (left is SolverLogical<*>) { + tell_logical_value(left as SolverLogical, right) } - else if (right is TestLogical<*>) { - tell_value_logical(left, right) + else if (right is SolverLogical<*>) { + tell_value_logical(left, right as SolverLogical) } else { tell_value_value(left, right) } } - fun ask_logical_logical(left: TestLogical<*>, right: TestLogical<*>): Boolean { + fun ask_logical_logical(left: SolverLogical<*>, right: SolverLogical<*>): Boolean { return left.isBound && right.isBound && left.findRoot().value() == right.findRoot().value() } - fun ask_logical_value(left: TestLogical<*>, right: Any?): Boolean { + fun ask_logical_value(left: SolverLogical<*>, right: Any?): Boolean { return left.isBound && left.findRoot().value() == right } - fun ask_value_logical(left: Any?, right: TestLogical<*>): Boolean { + fun ask_value_logical(left: Any?, right: SolverLogical<*>): Boolean { return right.isBound && right.findRoot().value() == left } @@ -59,39 +60,38 @@ class EqualsSolver : Queryable { return left == right } - fun tell_logical_logical(left: TestLogical<*>, right: TestLogical<*>) { + fun tell_logical_logical(left: SolverLogical<*>, right: SolverLogical<*>) { if (left.isBound && right.isBound) { - check (left.find().value == right.find().value) - left.union(right) + check (left.findRoot().value() == right.findRoot().value()) + // FIXME: use rank!!! + left.setParent(right) } else if (left.isBound) { - right.union(left) + right.setParent(left) } else if (right.isBound) { - left.union(right) + left.setParent(right) } else { - left.union(right) + left.setParent(right) } } - fun tell_logical_value(left: TestLogical<*>, right: Any?) { + fun tell_logical_value(left: SolverLogical, right: T) { if (left.isBound) { - check(left.find().value == right) + check(left.findRoot().value() == right) } else { - // TODO hack! - (left.find() as TestLogical).value = right + left.findRoot().setValue(right) } } - fun tell_value_logical(left: Any?, right: TestLogical<*>) { + fun tell_value_logical(left: T, right: SolverLogical) { if (right.isBound) { - check(right.find().value == left) + check(right.findRoot().value() == left) } else { - // TODO: hack! - (right.find() as TestLogical).value = left + right.findRoot().setValue(left) } } fun tell_value_value(left: Any?, right: Any?) { diff --git a/reactor/Test/test/LogicalHelper.kt b/reactor/Test/test/LogicalHelper.kt index 2f2e92bc..5e66ee3b 100644 --- a/reactor/Test/test/LogicalHelper.kt +++ b/reactor/Test/test/LogicalHelper.kt @@ -1,10 +1,9 @@ +import jetbrains.mps.logic.reactor.core.MemLogical import jetbrains.mps.logic.reactor.evaluation.PredicateInvocation -import jetbrains.mps.logic.reactor.logical.Logical -import jetbrains.mps.logic.reactor.logical.LogicalContext -import jetbrains.mps.logic.reactor.logical.LogicalPattern -import jetbrains.mps.logic.reactor.logical.NamingContext +import jetbrains.mps.logic.reactor.logical.* import jetbrains.mps.logic.reactor.program.Predicate import jetbrains.mps.logic.reactor.program.PredicateSymbol +import program.MemLogicalPattern import java.util.* /** @@ -12,100 +11,35 @@ import java.util.* */ -fun anon(value: T) = TestLogical(value) +fun anon(value: T) = MemLogical(value) -fun logical(name: String) = TestLogical(name) +fun logical(name: String) = MemLogical(name) -fun logical(name1: String, name2: String) = Pair(TestLogical(name1), TestLogical(name2)) +fun logical(name1: String, name2: String) = Pair(MemLogical(name1), MemLogical(name2)) fun logical(name1: String, name2: String, name3: String) = - Triple(TestLogical(name1), TestLogical(name2), TestLogical(name3)) + Triple(MemLogical(name1), MemLogical(name2), MemLogical(name3)) -inline fun logicalPattern(name: String) = TestLogicalPattern(name, T::class.java) +inline fun logicalPattern(name: String) = MemLogicalPattern(name, T::class.java) inline fun logicalPattern(name1: String, name2: String) = - Pair(TestLogicalPattern(name1, T::class.java), TestLogicalPattern(name2, T::class.java)) + Pair(MemLogicalPattern(name1, T::class.java), MemLogicalPattern(name2, T::class.java)) inline fun logicalPattern(name1: String, name2: String, name3: String) = Triple( - TestLogicalPattern(name1, T::class.java), - TestLogicalPattern(name2, T::class.java), - TestLogicalPattern(name3, T::class.java)) + MemLogicalPattern(name1, T::class.java), + MemLogicalPattern(name2, T::class.java), + MemLogicalPattern(name3, T::class.java)) fun Logical.get(): T = findRoot().value() fun Logical.set(t: T) { - if (this is TestLogical) - find().value = t + if (this is SolverLogical) + findRoot().setValue(t) else throw IllegalStateException("unexpected receiver $this") } -data class TestLogical(val name: String, var value: T?, var parent: TestLogical?) : Logical { - - companion object { - var anonIdx = 0 - } - - constructor(value: T) : this("$${anonIdx++}", value, null) - - constructor(name: String) : this(name, null, null) {} - - override fun name(): String = name - - override fun pattern(): LogicalPattern> = TODO() - - override fun findRoot(): Logical = find() - - override fun value(): T? = value - - override fun isBound(): Boolean = find().value != null - - override fun isWildcard(): Boolean { - throw UnsupportedOperationException() - } - - fun find(): TestLogical { - val tmp = parent - if (tmp == null) return this - else { - val root = tmp.find() - this.parent = root - return root - } - } - - fun union(other: TestLogical) { - if (find() != other.find()) find().parent = other - } - - override fun toString(): String = "$name(^${parent?.name ?: null})=$value" -} - -data class TestLogicalPattern(val name: String, val type: Class) : LogicalPattern { - - companion object { - val random = Random() - } - - var wildcard = false - - constructor(type: Class) : this("_${random.nextInt()}", type) { - wildcard = true - } - - override fun name(): String = name - - override fun name(namingContext: NamingContext?): String? = TODO() - - override fun isWildcard(): Boolean = wildcard - - override fun type(): Class = type - - override fun instance(): Logical = TestLogical(name) - -} - data class TestEqPredicate(val left: Any, val right: Any) : Predicate { diff --git a/reactor/Test/test/TestHandler.kt b/reactor/Test/test/TestHandler.kt index 4121a13f..7b7d8634 100644 --- a/reactor/Test/test/TestHandler.kt +++ b/reactor/Test/test/TestHandler.kt @@ -4,7 +4,7 @@ import jetbrains.mps.logic.reactor.evaluation.Queryable import jetbrains.mps.logic.reactor.evaluation.SessionSolver import jetbrains.mps.logic.reactor.logical.Logical import jetbrains.mps.logic.reactor.logical.LogicalPattern -import jetbrains.mps.logic.reactor.predicate.MemSessionSolver +import solver.MemSessionSolver import jetbrains.mps.logic.reactor.program.ConstraintSymbol import jetbrains.mps.logic.reactor.program.JavaPredicateSymbol import jetbrains.mps.logic.reactor.program.PredicateSymbol @@ -124,7 +124,7 @@ class TestHandler { fun basicLogical() { var test : String? = "not initialized" val x = logical("x") - x.value = "expected" + x.setValue("expected") program( rule("main", headKept( @@ -143,7 +143,7 @@ class TestHandler { fun logicalCopy() { var test : String? = "not initialized" val (x,y) = logical("x", "y") - x.value = "expected" + x.setValue("expected") program( rule("main", headKept( diff --git a/reactor/Test/test/TestMatcher.kt b/reactor/Test/test/TestMatcher.kt index c36a13a8..fe15a40e 100644 --- a/reactor/Test/test/TestMatcher.kt +++ b/reactor/Test/test/TestMatcher.kt @@ -1,6 +1,8 @@ import jetbrains.mps.logic.reactor.core.Matcher +import jetbrains.mps.logic.reactor.core.logical import jetbrains.mps.logic.reactor.core.matches import jetbrains.mps.logic.reactor.evaluation.ConstraintOccurrence +import jetbrains.mps.logic.reactor.logical.Logical import jetbrains.mps.logic.reactor.program.Constraint import org.junit.Assert.* import org.junit.Test @@ -180,7 +182,7 @@ class TestMatcher { @Test fun logicalPattern() { val (A, B, C) = logicalPattern("A", "B", "C") - val b = B.instance() + val b = B.logical() program( rule("main", @@ -194,7 +196,8 @@ class TestMatcher { ).matcher().lookupMatches(occurrence("foo", "blah", b)).first().run { assertEquals("blah", logicalContext().valueFor(A)) assertSame(b, logicalContext().valueFor(B)) - assertEquals(C.instance(), logicalContext().valueFor(C)) + assertEquals(C.logical().name(), (logicalContext().valueFor(C) as Logical<*>).name()) + assertEquals(C.logical().pattern(), (logicalContext().valueFor(C) as Logical<*>).pattern()) } } @@ -255,7 +258,8 @@ class TestMatcher { } val (v, w) = logical("v", "w") - w.find().union(v) + // FIXME: use rank!!! + w.findRoot().setParent(v) matcher(occurrence("foo", v)).lookupMatches(occurrence("foo", w)).let { matches -> assertEquals(4, matches.count()) diff --git a/reactor/Test/test/TestProgram.kt b/reactor/Test/test/TestProgram.kt index 1905032f..d253c6ef 100644 --- a/reactor/Test/test/TestProgram.kt +++ b/reactor/Test/test/TestProgram.kt @@ -1,7 +1,7 @@ import jetbrains.mps.logic.reactor.core.MemEvaluationSession import jetbrains.mps.logic.reactor.evaluation.EvaluationSession import jetbrains.mps.logic.reactor.logical.Logical -import jetbrains.mps.logic.reactor.predicate.MemSessionSolver +import solver.MemSessionSolver import jetbrains.mps.logic.reactor.program.ConstraintSymbol import jetbrains.mps.logic.reactor.program.JavaPredicateSymbol import jetbrains.mps.logic.reactor.program.PredicateSymbol diff --git a/reactor/Test/test/TestProgramBuilder.kt b/reactor/Test/test/TestProgramBuilder.kt index 4480a849..8342a458 100644 --- a/reactor/Test/test/TestProgramBuilder.kt +++ b/reactor/Test/test/TestProgramBuilder.kt @@ -1,5 +1,5 @@ import jetbrains.mps.logic.reactor.evaluation.Queryable -import jetbrains.mps.logic.reactor.predicate.MemSessionSolver +import solver.MemSessionSolver import jetbrains.mps.logic.reactor.program.* import org.junit.AfterClass import org.junit.Assert.*