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.
This commit is contained in:
Fedor Isakov 2019-09-10 13:08:53 +02:00
parent 5478b2e070
commit af212ca92e
9 changed files with 62 additions and 94 deletions

View File

@ -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<ParameterKey<*>, *>?) : EvaluationSession()
{
abstract fun controller(): Controller
override fun program(): Program = program
override fun supervisor(): Supervisor = supervisor
@Suppress("UNCHECKED_CAST")
override fun <T : Any> parameter(key: ParameterKey<T>): T? = params ?.get(key) as T
override fun ask(invocation: PredicateInvocation): Boolean =
controller().ask(invocation)
override fun tell(invocation: PredicateInvocation) =
controller().tell(invocation)
}

View File

@ -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)
}

View File

@ -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<ParameterKey<*>, *>?) : EvaluationSessionEx(program, supervisor, trace, params)
val program: Program,
val supervisor: Supervisor,
val trace: EvaluationTrace,
val params: Map<ParameterKey<*>, *>?) : EvaluationSession()
{
lateinit var controller: ControllerImpl
override fun controller() = controller
override fun program(): Program = program
override fun supervisor(): Supervisor = supervisor
@Suppress("UNCHECKED_CAST")
override fun <T : Any> parameter(key: ParameterKey<T>): T? = params ?.get(key) as T
private fun launch(
main: Constraint, profiler: Profiler?,

View File

@ -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.
* <p>
@ -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> T parameter(ParameterKey<T> key);
public static class ParameterKey<T> {
private final String name;
private final String name;
public static <T> ParameterKey<T> of(String name, Class<T> klass) {
return new ParameterKey<T>(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 <T> Config withParameter(ParameterKey<T> key, T value);
@ -104,8 +102,8 @@ public abstract class EvaluationSession {
public abstract EvaluationResult start(Supervisor supervisor);
}
protected static void setBackend(EvaluationSession.Backend<? extends EvaluationSession> 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<? extends EvaluationSession> ourBackend;
}

View File

@ -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();
}

View File

@ -36,4 +36,5 @@ public interface PredicateInvocation {
LogicalContext logicalContext();
InvocationContext invocationContext();
}

View File

@ -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 : Any> T.is_eq(value: T): Boolean = EvaluationSession.current().let { session ->
fun <T : Any> 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 : Any> T.eq(value: T) = EvaluationSession.current().let { session ->
fun <T : Any> 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 {

View File

@ -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<ParameterKey<*>, 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 <T : Any?> parameter(key: ParameterKey<T>?): T = TODO()
class MockBackend(val session: MockSession) : Backend<MockSession> {
override fun current(): MockSession = session
@ -93,9 +97,9 @@ class TestController {
occurrences.filter { it.constraint().symbol() == symbol }
}
private fun <T : Any> eq(left: T, right: T) = left eq right
private fun <T : Any> PredicateInvocation.eq(left: T, right: T) = invocationContext().tellEquals(left, right)
private fun <T : Any> is_eq(left: T, right: T): Boolean = left is_eq right
private fun <T : Any> PredicateInvocation.is_eq(left: T, right: T): Boolean = invocationContext().askEquals(left, right)
@Test
fun processSingle() {

View File

@ -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 <T : Any> PredicateInvocation.eq(left: T, right: T) = invocationContext().tellEquals(left, right)
private fun <T : Any> 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)
)
)