From af212ca92efeabc052ec75d00ca46ac253ce2f59 Mon Sep 17 00:00:00 2001 From: Fedor Isakov Date: Tue, 10 Sep 2019 13:08:53 +0200 Subject: [PATCH] Refactoring EvaluationSession(Ex): drop controller accessor. The inverse reference to controller from Evaluation session considered harmful. Drop controller from EvaluationSession, drop ask/tell from EvaluationSession, extend InvocationContext with controller and supervisor accessors. --- .../logic/reactor/core/EvaluationSessionEx.kt | 50 ------------------- .../reactor/core/internal/ControllerImpl.kt | 6 ++- .../core/internal/EvaluationSessionImpl.kt | 17 ++++--- .../reactor/evaluation/EvaluationSession.java | 18 +++---- .../reactor/evaluation/InvocationContext.java | 7 ++- .../evaluation/PredicateInvocation.java | 1 + reactor/Test/src/solver/EqualsSolver.kt | 27 ++++------ reactor/Test/test/TestController.kt | 18 ++++--- reactor/Test/test/TestProgram.kt | 12 +++-- 9 files changed, 62 insertions(+), 94 deletions(-) delete mode 100644 reactor/Core/src/jetbrains/mps/logic/reactor/core/EvaluationSessionEx.kt diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/EvaluationSessionEx.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/EvaluationSessionEx.kt deleted file mode 100644 index ec909749..00000000 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/EvaluationSessionEx.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2014-2019 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package jetbrains.mps.logic.reactor.core - -import jetbrains.mps.logic.reactor.evaluation.EvaluationSession -import jetbrains.mps.logic.reactor.evaluation.EvaluationTrace -import jetbrains.mps.logic.reactor.evaluation.PredicateInvocation -import jetbrains.mps.logic.reactor.evaluation.Supervisor -import jetbrains.mps.logic.reactor.program.Program - -/** - * An extension of [EvaluationSession] with ability to access [Controller]. - * @author Fedor Isakov - */ -abstract class EvaluationSessionEx(val program: Program, - val supervisor: Supervisor, - val trace: EvaluationTrace, - val params: Map, *>?) : EvaluationSession() -{ - - abstract fun controller(): Controller - - override fun program(): Program = program - - override fun supervisor(): Supervisor = supervisor - - @Suppress("UNCHECKED_CAST") - override fun parameter(key: ParameterKey): T? = params ?.get(key) as T - - override fun ask(invocation: PredicateInvocation): Boolean = - controller().ask(invocation) - - override fun tell(invocation: PredicateInvocation) = - controller().tell(invocation) - -} \ No newline at end of file diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ControllerImpl.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ControllerImpl.kt index 0ea82fc8..0d681dd6 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ControllerImpl.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ControllerImpl.kt @@ -248,7 +248,7 @@ internal class ControllerImpl ( private fun RuleMatch.allStored() = (matchHeadKept() + matchHeadReplaced()).all { co -> (co as Occurrence).stored } - private class Context(inStatus: FeedbackStatus, + inner private class Context(inStatus: FeedbackStatus, val logicalContext: LogicalContext, val trace: EvaluationTrace = EvaluationTrace.NULL) : InvocationContext { @@ -264,6 +264,10 @@ internal class ControllerImpl ( } } + override fun supervisor(): Supervisor = supervisor + + override fun controller(): Controller = this@ControllerImpl + inline fun withStatus(block: (FeedbackStatus) -> Unit) { block.invoke(status) } diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/EvaluationSessionImpl.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/EvaluationSessionImpl.kt index d3eb9c5d..ab8e8931 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/EvaluationSessionImpl.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/EvaluationSessionImpl.kt @@ -24,23 +24,26 @@ import jetbrains.mps.logic.reactor.program.IncrementalProgramSpec import jetbrains.mps.logic.reactor.program.Program import jetbrains.mps.logic.reactor.util.Profiler import java.util.* -import com.github.andrewoma.dexx.collection.LinkedList as PLinkedList -import com.github.andrewoma.dexx.collection.List as PList /** * @author Fedor Isakov */ internal class EvaluationSessionImpl private constructor ( - program: Program, - supervisor: Supervisor, - trace: EvaluationTrace, - params: Map, *>?) : EvaluationSessionEx(program, supervisor, trace, params) + val program: Program, + val supervisor: Supervisor, + val trace: EvaluationTrace, + val params: Map, *>?) : EvaluationSession() { lateinit var controller: ControllerImpl - override fun controller() = controller + override fun program(): Program = program + + override fun supervisor(): Supervisor = supervisor + + @Suppress("UNCHECKED_CAST") + override fun parameter(key: ParameterKey): T? = params ?.get(key) as T private fun launch( main: Constraint, profiler: Profiler?, diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/EvaluationSession.java b/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/EvaluationSession.java index e7c7a9cc..a35f152d 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/EvaluationSession.java +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/EvaluationSession.java @@ -21,6 +21,8 @@ import jetbrains.mps.logic.reactor.core.RulesDiff; import jetbrains.mps.logic.reactor.program.IncrementalProgramSpec; import jetbrains.mps.logic.reactor.program.Program; +import java.util.Map; + /** * The starting point to evaluate a program. *

@@ -50,17 +52,13 @@ public abstract class EvaluationSession { public abstract Program program(); public abstract Supervisor supervisor(); - - public abstract boolean ask(PredicateInvocation invocation); - - public abstract void tell(PredicateInvocation invocation); - + public abstract T parameter(ParameterKey key); public static class ParameterKey { - private final String name; + private final String name; public static ParameterKey of(String name, Class klass) { return new ParameterKey(name); } @@ -82,8 +80,8 @@ public abstract class EvaluationSession { public int hashCode() { return name != null ? name.hashCode() : 0; } - } + } public static abstract class Config { public abstract Config withParameter(ParameterKey key, T value); @@ -104,8 +102,8 @@ public abstract class EvaluationSession { public abstract EvaluationResult start(Supervisor supervisor); + } - protected static void setBackend(EvaluationSession.Backend backend) { if (ourBackend != null) throw new IllegalStateException("backend already assigned"); ourBackend = backend; @@ -122,7 +120,9 @@ public abstract class EvaluationSession { EvaluationSession.Config createConfig(Program program); + } - + private static EvaluationSession.Backend ourBackend; + } diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/InvocationContext.java b/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/InvocationContext.java index 9649c306..3774a611 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/InvocationContext.java +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/InvocationContext.java @@ -16,14 +16,19 @@ package jetbrains.mps.logic.reactor.evaluation; +import jetbrains.mps.logic.reactor.core.Controller; + /** + * Provides context for a predicate invocation. + * * @author Fedor Isakov */ public interface InvocationContext { void report(EvaluationFeedback feedback); + Supervisor supervisor(); - + Controller controller(); } diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/PredicateInvocation.java b/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/PredicateInvocation.java index b2ea085d..4bfb5a1a 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/PredicateInvocation.java +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/PredicateInvocation.java @@ -36,4 +36,5 @@ public interface PredicateInvocation { LogicalContext logicalContext(); InvocationContext invocationContext(); + } diff --git a/reactor/Test/src/solver/EqualsSolver.kt b/reactor/Test/src/solver/EqualsSolver.kt index 5d3c3c2a..4b093e9d 100644 --- a/reactor/Test/src/solver/EqualsSolver.kt +++ b/reactor/Test/src/solver/EqualsSolver.kt @@ -1,5 +1,6 @@ package solver +import jetbrains.mps.logic.reactor.core.Controller import jetbrains.mps.logic.reactor.core.invocation import jetbrains.mps.logic.reactor.evaluation.* import jetbrains.mps.logic.reactor.logical.Logical @@ -109,26 +110,20 @@ class EqualsSolver : Solver { } -infix fun T.is_eq(value: T): Boolean = EvaluationSession.current().let { session -> +fun InvocationContext.askEquals(thisValue: T, thatValue: T): Boolean { val logicalContext = mockLogicalContext() - val predicate = EqualsSolver.eq(this, value) - val invocationContext: InvocationContext = object : InvocationContext { - override fun report(feedback: EvaluationFeedback) = TODO() - } - val args = session.supervisor().instantiateArguments(predicate.arguments(), logicalContext, invocationContext) - val inv = predicate.invocation(args, logicalContext, invocationContext) - session.ask(inv) + val predicate = EqualsSolver.eq(thisValue, thatValue) + val args = supervisor().instantiateArguments(predicate.arguments(), logicalContext, this) + val inv = predicate.invocation(args, logicalContext, this) + return controller().ask(inv) } -infix fun T.eq(value: T) = EvaluationSession.current().let { session -> +fun InvocationContext.tellEquals(thisValue: T, thatValue: T) { val logicalContext = mockLogicalContext() - val predicate = EqualsSolver.eq(this, value) - val invocationContext: InvocationContext = object : InvocationContext { - override fun report(feedback: EvaluationFeedback) = TODO() - } - val args = session.supervisor().instantiateArguments(predicate.arguments(), logicalContext, invocationContext) - val inv = predicate.invocation(args, logicalContext, invocationContext) - session.tell(inv) + val predicate = EqualsSolver.eq(thisValue, thatValue) + val args = supervisor().instantiateArguments(predicate.arguments(), logicalContext, this) + val inv = predicate.invocation(args, logicalContext, this) + controller().tell(inv) } private fun mockLogicalContext(): LogicalContext { diff --git a/reactor/Test/test/TestController.kt b/reactor/Test/test/TestController.kt index 2e71a59c..f9345019 100644 --- a/reactor/Test/test/TestController.kt +++ b/reactor/Test/test/TestController.kt @@ -12,8 +12,8 @@ import org.junit.After import org.junit.Assert.* import org.junit.Before import org.junit.Test -import solver.eq -import solver.is_eq +import solver.askEquals +import solver.tellEquals /** @@ -32,11 +32,15 @@ class TestController { MockSession.deinit() } - private class MockSession(program: Program, supervisor: Supervisor) : - EvaluationSessionEx(program, supervisor, EvaluationTrace.NULL, params = mapOf, Any>()) { + private class MockSession(val program: Program, val supervisor: Supervisor) : EvaluationSession() + { lateinit var controller: Controller + + override fun program(): Program = program - override fun controller(): Controller = controller + override fun supervisor(): Supervisor = supervisor + + override fun parameter(key: ParameterKey?): T = TODO() class MockBackend(val session: MockSession) : Backend { override fun current(): MockSession = session @@ -93,9 +97,9 @@ class TestController { occurrences.filter { it.constraint().symbol() == symbol } } - private fun eq(left: T, right: T) = left eq right + private fun PredicateInvocation.eq(left: T, right: T) = invocationContext().tellEquals(left, right) - private fun is_eq(left: T, right: T): Boolean = left is_eq right + private fun PredicateInvocation.is_eq(left: T, right: T): Boolean = invocationContext().askEquals(left, right) @Test fun processSingle() { diff --git a/reactor/Test/test/TestProgram.kt b/reactor/Test/test/TestProgram.kt index 3d15700c..13e64f47 100644 --- a/reactor/Test/test/TestProgram.kt +++ b/reactor/Test/test/TestProgram.kt @@ -1,5 +1,6 @@ import jetbrains.mps.logic.reactor.core.ReactorLifecycle import jetbrains.mps.logic.reactor.evaluation.EvaluationSession +import jetbrains.mps.logic.reactor.evaluation.PredicateInvocation import jetbrains.mps.logic.reactor.evaluation.StoreView import jetbrains.mps.logic.reactor.logical.Logical import jetbrains.mps.logic.reactor.program.Constraint @@ -9,7 +10,8 @@ import org.junit.Assert.assertEquals import org.junit.BeforeClass import org.junit.Test import program.MockConstraint -import solver.eq +import solver.askEquals +import solver.tellEquals /** * @author Fedor Isakov @@ -38,6 +40,10 @@ class TestProgram { return session.storeView() } + private fun PredicateInvocation.eq(left: T, right: T) = invocationContext().tellEquals(left, right) + + private fun PredicateInvocation.is_eq(left: T, right: T): Boolean = invocationContext().askEquals(left, right) + @Test fun replace() { programWithRules( @@ -70,7 +76,7 @@ class TestProgram { constraint("main") ), body( - statement({ z -> z eq 33 }, Z), + statement({ z -> eq(z, 33) }, Z), constraint("foo", Z) ) ), @@ -79,7 +85,7 @@ class TestProgram { constraint("foo", X) ), body( - statement({ x, y -> y eq (x.get() * 2) }, X, Y), + statement({ x, y -> eq(y, (x.get() * 2)) }, X, Y), constraint("bar", Y) ) )