Enable EvaluationSession to have arbitrary parameters available at exec time.

Drop two obsolete interfaces.
This commit is contained in:
Fedor Isakov 2019-04-26 00:18:03 +02:00
parent ed6f7a07c2
commit 7dcd683ba5
6 changed files with 83 additions and 176 deletions

View File

@ -19,7 +19,6 @@ 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.SessionSolver
import jetbrains.mps.logic.reactor.program.Program
/**
@ -28,13 +27,15 @@ import jetbrains.mps.logic.reactor.program.Program
*/
abstract class EvaluationSessionEx(val program: Program,
val trace: EvaluationTrace,
val sessionSolver: SessionSolver? = null) : EvaluationSession() {
val params: Map<ParameterKey<*>, *>?) : EvaluationSession()
{
abstract fun controller(): Controller
override fun program(): Program = program
override fun sessionSolver(): SessionSolver = sessionSolver ?: SessionSolver()
@Suppress("UNCHECKED_CAST")
override fun <T : Any> parameter(key: ParameterKey<T>): T? = params ?.get(key) as T
override fun ask(invocation: PredicateInvocation): Boolean {
val solver = invocation.predicate().symbol().solver()

View File

@ -33,7 +33,7 @@ import com.github.andrewoma.dexx.collection.List as PList
internal class EvaluationSessionImpl private constructor (
program: Program,
trace: EvaluationTrace,
sessionSolver: SessionSolver? = null) : EvaluationSessionEx(program, trace, sessionSolver)
params: Map<ParameterKey<*>, *>?) : EvaluationSessionEx(program, trace, params)
{
lateinit var controller: ControllerImpl
@ -46,8 +46,11 @@ internal class EvaluationSessionImpl private constructor (
}
private class Config(val program: Program) : EvaluationSession.Config() {
val parameters = HashMap<String, Any?>()
val parameters = HashMap<ParameterKey<*>, Any>()
var evaluationTrace: EvaluationTrace = EvaluationTrace.NULL
var storeView: StoreView? = null
var feedbackHandler: EvaluationFeedbackHandler? = null
@ -68,28 +71,30 @@ internal class EvaluationSessionImpl private constructor (
}
override fun withParam(key: String, param: Any): EvaluationSession.Config {
this.parameters.put(key, param)
this.parameters.put(ParameterKey.of(key, Any::class.java), param)
return this
}
override fun start(): EvaluationResult = start(SessionSolver())
override fun <T> withParameter(key: ParameterKey<T>, value: T): EvaluationSession.Config {
this.parameters.put(key, value as Any)
return this
}
override fun start(sessionSolver: SessionSolver?): EvaluationResult {
override fun start(): EvaluationResult {
var session = Backend.ourBackend.ourSession.get()
if (session != null) throw IllegalStateException("session already active")
sessionSolver?.init(evaluationTrace)
@Suppress("UNCHECKED_CAST")
val durations =
parameters.get("profiling.data") as MutableMap<String, String>?
val durations = parameters[ParameterKey.of("profiling.data", MutableMap::class.java)]
as MutableMap<String, String>?
val profiler = durations?.let { Profiler() }
session = EvaluationSessionImpl(program, evaluationTrace, sessionSolver)
session = EvaluationSessionImpl(program, evaluationTrace, parameters)
Backend.ourBackend.ourSession.set(session)
var failure: EvaluationFailure? = null
try {
val state = session.launch(parameters["main"] as Constraint, profiler, storeView, feedbackHandler)
val main = parameters[ParameterKey.of("main", Constraint::class.java)] as Constraint
val state = session.launch(main, profiler, storeView, feedbackHandler)
if (state is FAILED) {
failure = state.failure
}

View File

@ -30,81 +30,90 @@ import jetbrains.mps.logic.reactor.program.Program;
*/
public abstract class EvaluationSession {
private static EvaluationSession.Backend<? extends EvaluationSession> ourBackend;
@SuppressWarnings("unchecked")
public static <S extends EvaluationSession> S current(Class<S> sessionClass) {
return (S) current();
}
public static EvaluationSession current() {
if (ourBackend == null) {
throw new IllegalStateException("no backend");
}
if (ourBackend == null) throw new IllegalStateException("no backend");
return ourBackend.current();
}
public static EvaluationSession.Config newSession(Program program) {
if (ourBackend == null) {
throw new IllegalStateException("no backend");
}
if (ourBackend == null) throw new IllegalStateException("no backend");
return ourBackend.createConfig(program);
}
protected static void setBackend(EvaluationSession.Backend<? extends EvaluationSession> backend) {
if (ourBackend != null) {
throw new IllegalStateException("backend already assigned");
}
ourBackend = backend;
}
protected static void clearBackend(EvaluationSession.Backend<? extends EvaluationSession> backend) {
if (ourBackend != backend) {
throw new IllegalStateException("illegal access");
}
ourBackend = null;
}
@Deprecated
public abstract SessionSolver sessionSolver();
public abstract Program program();
public abstract boolean ask(PredicateInvocation invocation);
public abstract void tell(PredicateInvocation invocation);
public interface Backend<S extends EvaluationSession> {
public abstract <T> T parameter(ParameterKey<T> key);
public static class ParameterKey<T> {
private final String name;
public static <T> ParameterKey<T> of(String name, Class<T> klass) {
return new ParameterKey<T>(name);
}
private ParameterKey(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ParameterKey<?> that = (ParameterKey<?>) o;
return name != null ? name.equals(that.name) : that.name == null;
}
@Override
public int hashCode() {
return name != null ? name.hashCode() : 0;
}
}
public static abstract class Config {
public abstract <T> Config withParameter(ParameterKey<T> key, T value);
public abstract Config withTrace(EvaluationTrace computingTracer);
public abstract Config withStoreView(StoreView storeView);
public abstract Config withFeedbackHandler(EvaluationFeedbackHandler handler);
@Deprecated
public abstract Config withParam(String key, Object param);
public abstract EvaluationResult start();
}
protected static void setBackend(EvaluationSession.Backend<? extends EvaluationSession> backend) {
if (ourBackend != null) throw new IllegalStateException("backend already assigned");
ourBackend = backend;
}
protected static void clearBackend(EvaluationSession.Backend<? extends EvaluationSession> backend) {
if (ourBackend != backend) throw new IllegalStateException("illegal access");
ourBackend = null;
}
protected interface Backend<S extends EvaluationSession> {
S current();
EvaluationSession.Config createConfig(Program program);
}
public static abstract class Config {
public EvaluationSession.Config withTrace(EvaluationTrace computingTracer) {
return this;
}
public EvaluationSession.Config withStoreView(StoreView storeView) {
return this;
}
public EvaluationSession.Config withFeedbackHandler(EvaluationFeedbackHandler handler) {
return this;
}
public EvaluationSession.Config withParam(String key, Object param) {
return this;
}
@Deprecated
public abstract EvaluationResult start(SessionSolver sessionSolver);
public abstract EvaluationResult start();
}
private static EvaluationSession.Backend<? extends EvaluationSession> ourBackend;
}

View File

@ -1,45 +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.evaluation;
import jetbrains.mps.logic.reactor.program.Rule;
/**
* @author Fedor Isakov
* @deprecated Use {@link EvaluationFeedbackHandler} instead.
*/
@Deprecated
public interface FailureHandler extends EvaluationFeedbackHandler {
/**
* This method is called in order to decide what to do when a failure occurs during rule evaluation.
* Expected to return either the same failure (the default behaviour), a new failure with more details,
* or null.
* Any non-null returned value implies failure propagation up the evaluation stack.
* If null is returned, the failure is considered to have been handled.
*/
EvaluationFailure handleFailure(EvaluationFailure failure, Rule rule);
@Override
default boolean handleFeedback(Rule rule, EvaluationFeedback feedback) {
// compatibility adapter
if (feedback instanceof EvaluationFailure) {
return handleFailure((EvaluationFailure) feedback, rule) == null;
}
return false;
}
}

View File

@ -1,63 +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.evaluation;
/**
* // FIXME to be merged with EvaluationSession
* Is used to provide an interface for handlers and solvers working together in a single session.
*
*
* @author Fedor Isakov
* @deprecated Use EvalutionSession
*/
@Deprecated
public class SessionSolver implements Solver {
private EvaluationTrace tracer = EvaluationTrace.NULL;
public void init(EvaluationTrace evaluationTrace) {
tracer = evaluationTrace;
}
/**
* @deprecated Use EvaluationSession
* @param invocation
* @return
*/
@Override
@Deprecated
public boolean ask(PredicateInvocation invocation) {
Solver solver = invocation.predicate().symbol().solver();
boolean result = solver.ask(invocation);
tracer.ask(result, invocation);
return result;
}
/**
* @deprecated Use EvaluationSession
* @param invocation
*/
@Override
@Deprecated
public void tell(PredicateInvocation invocation) {
Solver solver = invocation.predicate().symbol().solver();
tracer.tell(invocation);
solver.tell(invocation);
}
}

View File

@ -34,7 +34,7 @@ class TestController {
}
private class MockSession(program: Program) :
EvaluationSessionEx(program, EvaluationTrace.NULL) {
EvaluationSessionEx(program, EvaluationTrace.NULL, params = mapOf<ParameterKey<*>, Any>()) {
lateinit var controller: Controller
override fun controller(): Controller = controller