Refactoring: simplify contract b/w controller and logical state.
This commit is contained in:
parent
0fbc7f6571
commit
8af582f9b2
|
|
@ -33,9 +33,7 @@ interface Controller {
|
|||
|
||||
fun reactivate(occ: Occurrence): FeedbackStatus
|
||||
|
||||
fun logicalState(): LogicalStateObservable
|
||||
|
||||
fun clearState()
|
||||
fun logicalStateObservable(): LogicalStateObservable
|
||||
|
||||
/** For tests only */
|
||||
fun evaluate(occ: Occurrence): StoreView
|
||||
|
|
|
|||
|
|
@ -28,14 +28,6 @@ interface LogicalStateObservable {
|
|||
|
||||
fun removeForwardingObserver(logical: Logical<*>, observer: ForwardingLogicalObserver)
|
||||
|
||||
fun init(controller: Controller): InitToken
|
||||
|
||||
interface InitToken {
|
||||
|
||||
fun clear()
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
interface ForwardingLogicalObserver {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ import jetbrains.mps.logic.reactor.util.profile
|
|||
internal class ConstraintsProcessing(private var dispatchingFront: Dispatcher.DispatchingFront,
|
||||
journal: MatchJournalImpl,
|
||||
private val ruleIndex: RuleIndex,
|
||||
val logicalState: LogicalState = LogicalState(),
|
||||
val logicalState: LogicalState,
|
||||
private val ispec: IncrementalProgramSpec = IncrementalProgramSpec.DefaultSpec,
|
||||
val trace: EvaluationTrace = EvaluationTrace.NULL,
|
||||
val profiler: Profiler? = null)
|
||||
|
|
@ -200,7 +200,7 @@ internal class ConstraintsProcessing(private var dispatchingFront: Dispatcher.Di
|
|||
val histView = view()
|
||||
resetStore() // clear observers
|
||||
val rules = ArrayList<Rule>().apply { ruleIndex.forEach { add(it) } }
|
||||
return SessionTokenImpl(histView, rules, dispatchingFront.state(), logicalState)
|
||||
return SessionTokenImpl(histView, rules, dispatchingFront.state(), logicalState.clear())
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -36,15 +36,13 @@ internal class ControllerImpl (
|
|||
val profiler: Profiler? = null) : Controller
|
||||
{
|
||||
|
||||
private val initToken: LogicalStateObservable.InitToken = processing.init(this)
|
||||
|
||||
/** For tests only */
|
||||
override fun storeView(): StoreView = processing.storeView()
|
||||
|
||||
/** For tests only */
|
||||
override fun evaluate(occ: Occurrence): StoreView {
|
||||
// create the internal occurrence
|
||||
val active = occ.constraint().occurrence(logicalState(), occ.arguments(), occ.justifications(), object: LogicalContext {
|
||||
val active = occ.constraint().occurrence(logicalStateObservable(), occ.arguments(), occ.justifications(), object: LogicalContext {
|
||||
override fun <V : Any> variable(metaLogical: MetaLogical<V>): Logical<V>? = null
|
||||
})
|
||||
|
||||
|
|
@ -79,13 +77,9 @@ internal class ControllerImpl (
|
|||
return context.currentStatus()
|
||||
}
|
||||
|
||||
override fun logicalState(): LogicalStateObservable =
|
||||
override fun logicalStateObservable(): LogicalStateObservable =
|
||||
processing
|
||||
|
||||
override fun clearState() {
|
||||
initToken.clear()
|
||||
}
|
||||
|
||||
override fun ask(invocation: PredicateInvocation): Boolean {
|
||||
val solver = invocation.predicate().symbol().solver()
|
||||
val result = solver.ask(invocation)
|
||||
|
|
@ -223,7 +217,7 @@ internal class ControllerImpl (
|
|||
|
||||
profiler.profile<FeedbackStatus>("activate_${constraint.symbol()}") {
|
||||
|
||||
constraint.occurrence(logicalState(), args, justsCopy(justs), context.logicalContext, context.ruleUniqueTag).let { occ ->
|
||||
constraint.occurrence(logicalStateObservable(), args, justsCopy(justs), context.logicalContext, context.ruleUniqueTag).let { occ ->
|
||||
trace.activate(occ)
|
||||
processing.processActivated(this, occ, status)
|
||||
}
|
||||
|
|
@ -336,15 +330,16 @@ fun createController(
|
|||
supervisor: Supervisor,
|
||||
ruleIndex: RuleIndex,
|
||||
trace: EvaluationTrace = EvaluationTrace.NULL,
|
||||
profiler: Profiler? = null) : Controller =
|
||||
|
||||
ControllerImpl(
|
||||
profiler: Profiler? = null) : Controller
|
||||
{
|
||||
val logicalState = LogicalState()
|
||||
val controller = ControllerImpl(
|
||||
supervisor,
|
||||
ConstraintsProcessing(
|
||||
Dispatcher(ruleIndex).front(),
|
||||
MatchJournalImpl(),
|
||||
ruleIndex,
|
||||
LogicalState(),
|
||||
logicalState,
|
||||
IncrementalProgramSpec.DefaultSpec,
|
||||
trace,
|
||||
profiler
|
||||
|
|
@ -353,3 +348,6 @@ fun createController(
|
|||
trace,
|
||||
profiler
|
||||
)
|
||||
logicalState.init(controller)
|
||||
return controller
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,39 +36,42 @@ internal class EvaluationSessionImpl private constructor (
|
|||
val params: Map<ParameterKey<*>, *>?) : EvaluationSession()
|
||||
{
|
||||
|
||||
lateinit var controller: ControllerImpl
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : Any> parameter(key: ParameterKey<T>): T? = params ?.get(key) as T
|
||||
|
||||
private fun launch(
|
||||
main: Constraint, profiler: Profiler?,
|
||||
token: SessionToken?, rulesDiff: RulesDiff, ispec: IncrementalProgramSpec
|
||||
) : FeedbackStatus {
|
||||
) : Pair<FeedbackStatus, SessionToken> {
|
||||
|
||||
val ruleIndex = RuleIndex(program.rulesLists())
|
||||
|
||||
if (ispec is IncrementalProgramSpec.NonIncrSpec || token == null) {
|
||||
val processing
|
||||
= ConstraintsProcessing(
|
||||
val logicalState = LogicalState()
|
||||
|
||||
val processing = ConstraintsProcessing(
|
||||
Dispatcher(ruleIndex).front(),
|
||||
MatchJournalImpl(ispec),
|
||||
ruleIndex, LogicalState(), ispec, trace, profiler
|
||||
ruleIndex, logicalState, ispec, trace, profiler
|
||||
)
|
||||
|
||||
this.controller = ControllerImpl(supervisor, processing, ispec, trace, profiler)
|
||||
return controller.activate(main)
|
||||
val controller = ControllerImpl(supervisor, processing, ispec, trace, profiler)
|
||||
logicalState.init(controller)
|
||||
return controller.activate(main) to processing.endSession()
|
||||
|
||||
} else {
|
||||
val tkn = token as SessionTokenImpl
|
||||
val logicalState = tkn.logicalState
|
||||
|
||||
val processing = ConstraintsProcessing(
|
||||
Dispatcher(ruleIndex, tkn.getFrontState()).front(),
|
||||
MatchJournalImpl(ispec, tkn.journalView),
|
||||
ruleIndex, tkn.logicalState, ispec, trace, profiler
|
||||
ruleIndex, logicalState, ispec, trace, profiler
|
||||
)
|
||||
|
||||
this.controller = ControllerImpl(supervisor, processing, ispec, trace, profiler)
|
||||
return controller.incrLaunch(main, rulesDiff)
|
||||
val controller = ControllerImpl(supervisor, processing, ispec, trace, profiler)
|
||||
logicalState.init(controller)
|
||||
return controller.incrLaunch(main, rulesDiff) to processing.endSession()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -117,16 +120,20 @@ internal class EvaluationSessionImpl private constructor (
|
|||
|
||||
session = EvaluationSessionImpl(program, supervisor, evaluationTrace, parameters)
|
||||
Backend.ourBackend.ourSession.set(session)
|
||||
var failure: Feedback? = null
|
||||
try {
|
||||
val main = parameters[ParameterKey.of("main", Constraint::class.java)] as Constraint
|
||||
val status = session.launch(main, profiler, token, program.incrementalDiff(), ispec)
|
||||
if (status is FAILED) {
|
||||
failure = status.failure
|
||||
val (status, token) = session.launch(main, profiler, token, program.incrementalDiff(), ispec)
|
||||
|
||||
return object : EvaluationResult {
|
||||
|
||||
override fun token(): SessionToken = token
|
||||
|
||||
override fun storeView(): StoreView = token.journalView.storeView
|
||||
|
||||
override fun feedback(): EvaluationFeedback? = if (status is FAILED) status.failure else null
|
||||
}
|
||||
}
|
||||
finally {
|
||||
session.controller.clearState()
|
||||
try {
|
||||
profiler?.run {
|
||||
formattedData().entries.forEach { e -> durations.put(e.key, e.value) }
|
||||
|
|
@ -139,15 +146,6 @@ internal class EvaluationSessionImpl private constructor (
|
|||
Backend.ourBackend.ourSession.set(null)
|
||||
}
|
||||
|
||||
return object : EvaluationResult {
|
||||
private val token = session.controller.processing.endSession()
|
||||
|
||||
override fun token(): SessionToken = token
|
||||
|
||||
override fun storeView(): StoreView = token.journalView.storeView
|
||||
|
||||
override fun feedback(): EvaluationFeedback? = failure
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,16 +49,15 @@ class LogicalState : LogicalStateObservable, LogicalObserver
|
|||
stateFrames.push(LogicalStateFrame())
|
||||
}
|
||||
|
||||
override fun init(controller: Controller): LogicalStateObservable.InitToken {
|
||||
assert(this@LogicalState.controller === null)
|
||||
fun init(controller: Controller) {
|
||||
assert(this.controller === null)
|
||||
this.controller = controller
|
||||
}
|
||||
|
||||
return object : LogicalStateObservable.InitToken {
|
||||
override fun clear() {
|
||||
assert(this@LogicalState.controller !== null)
|
||||
this@LogicalState.controller = null
|
||||
}
|
||||
}
|
||||
fun clear() : LogicalState {
|
||||
assert(this.controller !== null)
|
||||
this.controller = null
|
||||
return this
|
||||
}
|
||||
|
||||
fun currentFrame() : LogicalStateFrame =
|
||||
|
|
@ -73,9 +72,9 @@ class LogicalState : LogicalStateObservable, LogicalObserver
|
|||
|
||||
fun reset() {
|
||||
// Clear logicals from this forwarding observer on full reset
|
||||
currentFrame().observed().forEach {
|
||||
it.removeObserver(this)
|
||||
}
|
||||
// currentFrame().observed().forEach {
|
||||
// it.removeObserver(this)
|
||||
// }
|
||||
reset(stateFrames.last)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ interface StoreAwareJournal : MatchJournal, LogicalStateObservable {
|
|||
|
||||
|
||||
internal open class StoreAwareJournalImpl(private val journal: MatchJournal,
|
||||
private val state: LogicalState = LogicalState())
|
||||
: MatchJournal by journal, StoreAwareJournal, LogicalStateObservable by state
|
||||
private val logicalState: LogicalState = LogicalState())
|
||||
: MatchJournal by journal, StoreAwareJournal, LogicalStateObservable by logicalState
|
||||
{
|
||||
|
||||
private class FramePos(
|
||||
|
|
@ -53,25 +53,25 @@ internal open class StoreAwareJournalImpl(private val journal: MatchJournal,
|
|||
) : MatchJournal.Pos(chunk, entriesCount)
|
||||
|
||||
|
||||
fun push() = state.push()
|
||||
fun push() = logicalState.push()
|
||||
|
||||
override fun testPush() { state.push() }
|
||||
override fun testPush() { logicalState.push() }
|
||||
|
||||
// Reset only store & history position, don't modify history
|
||||
override fun resetStore() {
|
||||
state.reset()
|
||||
logicalState.reset()
|
||||
this.resetPos()
|
||||
}
|
||||
|
||||
|
||||
override fun currentPos(): MatchJournal.Pos =
|
||||
FramePos(state.currentFrame(), journal.currentPos().chunk, journal.currentPos().entriesCount)
|
||||
FramePos(logicalState.currentFrame(), journal.currentPos().chunk, journal.currentPos().entriesCount)
|
||||
|
||||
// Throw away recently added chunks and reset store accordingly
|
||||
// NB: not checking that chunks are actually recently added, from this exec session
|
||||
override fun reset(pastPos: MatchJournal.Pos) {
|
||||
if (pastPos is FramePos) {
|
||||
state.reset(pastPos.frame)
|
||||
logicalState.reset(pastPos.frame)
|
||||
journal.reset(pastPos)
|
||||
} else {
|
||||
throw IllegalArgumentException()
|
||||
|
|
|
|||
|
|
@ -174,15 +174,15 @@ fun equals(left: Any, right: Any): ConjBuilder.() -> Unit = {
|
|||
|
||||
fun occurrence(id: String, vararg args: Any): Occurrence =
|
||||
MockConstraint(ConstraintSymbol.symbol(id, args.size))
|
||||
.occurrence(MockController().logicalState(), listOf(* args), justsOf(), noLogicalContext)
|
||||
.occurrence(MockController().logicalStateObservable(), listOf(* args), justsOf(), noLogicalContext)
|
||||
|
||||
fun taggedOccurrence(ruleUniqueTag: Any, id: String, vararg args: Any): Occurrence =
|
||||
MockConstraint(ConstraintSymbol.symbol(id, args.size))
|
||||
.occurrence(MockController().logicalState(), listOf(* args), justsOf(), noLogicalContext, ruleUniqueTag)
|
||||
.occurrence(MockController().logicalStateObservable(), listOf(* args), justsOf(), noLogicalContext, ruleUniqueTag)
|
||||
|
||||
fun justifiedOccurrence(id: String, justs: Justs, vararg args: Any): Occurrence =
|
||||
MockConstraint(ConstraintSymbol.symbol(id, args.size), true)
|
||||
.occurrence(MockController().logicalState(), listOf(* args), justs, noLogicalContext)
|
||||
.occurrence(MockController().logicalStateObservable(), listOf(* args), justs, noLogicalContext)
|
||||
|
||||
fun justifiedOccurrence(id: String, justs: Collection<Int>, vararg args: Any): Occurrence =
|
||||
justifiedOccurrence(id, justsFromCollection(justs), * args)
|
||||
|
|
@ -201,11 +201,7 @@ private val noLogicalContext = object : LogicalContext {
|
|||
}
|
||||
|
||||
class MockController : Controller {
|
||||
|
||||
override fun clearState() {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
|
||||
override fun ask(invocation: PredicateInvocation): Boolean {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
|
@ -222,16 +218,12 @@ class MockController : Controller {
|
|||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun logicalState(): LogicalStateObservable = object : LogicalStateObservable {
|
||||
override fun logicalStateObservable(): LogicalStateObservable = object : LogicalStateObservable {
|
||||
override fun addForwardingObserver(logical: Logical<*>, observer: ForwardingLogicalObserver) {
|
||||
}
|
||||
|
||||
override fun removeForwardingObserver(logical: Logical<*>, observer: ForwardingLogicalObserver) {
|
||||
}
|
||||
|
||||
override fun init(controller: Controller): LogicalStateObservable.InitToken {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
|
||||
override fun storeView(): StoreView {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import jetbrains.mps.logic.reactor.core.*
|
||||
import jetbrains.mps.logic.reactor.core.internal.LogicalState
|
||||
import jetbrains.mps.logic.reactor.core.internal.createController
|
||||
import jetbrains.mps.logic.reactor.core.internal.logical
|
||||
import jetbrains.mps.logic.reactor.evaluation.*
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ class TestStoreAwareJournal {
|
|||
nchunks shouldBe 4 * 2 // 4 rules, each activates 1 principal occurrence
|
||||
|
||||
// try replay the last chunk
|
||||
replay(mockController.logicalState(), lastPos)
|
||||
replay(mockController.logicalStateObservable(), lastPos)
|
||||
|
||||
// should change nothing
|
||||
storeView().constraintSymbols() shouldBe setOf(sym0("qux"), sym0("lax"))
|
||||
|
|
@ -175,11 +175,11 @@ class TestStoreAwareJournal {
|
|||
storeView().allOccurrences().count() shouldBe 0
|
||||
view().chunks.size shouldBe nchunks
|
||||
|
||||
replay(mockController.logicalState(), initPos)
|
||||
replay(mockController.logicalStateObservable(), initPos)
|
||||
|
||||
storeView().constraintSymbols() shouldBe setOf<ConstraintSymbol>()
|
||||
|
||||
replay(mockController.logicalState(), fooPos)
|
||||
replay(mockController.logicalStateObservable(), fooPos)
|
||||
|
||||
storeView().constraintSymbols() shouldBe setOf(sym0("foo"))
|
||||
// although storeView() results change, journal remains the same
|
||||
|
|
@ -231,7 +231,7 @@ class TestStoreAwareJournal {
|
|||
|
||||
storeView().allOccurrences().count() shouldBe 0
|
||||
|
||||
replay(mockController.logicalState(), savedPos)
|
||||
replay(mockController.logicalStateObservable(), savedPos)
|
||||
|
||||
storeView().allOccurrences() shouldBe oldStore
|
||||
currentPos() shouldBe savedPos
|
||||
|
|
@ -473,7 +473,7 @@ class TestStoreAwareJournal {
|
|||
// store is not longer valid after removing chunks from history, so reset it
|
||||
resetStore()
|
||||
// move to the point where we want to insert new rule
|
||||
replay(mockController.logicalState(), continueFrom)
|
||||
replay(mockController.logicalStateObservable(), continueFrom)
|
||||
|
||||
// according to the history 'qux' wasn't activated at this point & 'bar1' wasn't discarded
|
||||
storeView().constraintSymbols() shouldBe setOf<ConstraintSymbol>()
|
||||
|
|
@ -498,7 +498,7 @@ class TestStoreAwareJournal {
|
|||
assertNotEquals(lastPos, currentPos())
|
||||
|
||||
// finally, purely go the the end, applying the rest of the history to the store
|
||||
replay(mockController.logicalState(), lastPos)
|
||||
replay(mockController.logicalStateObservable(), lastPos)
|
||||
|
||||
currentPos().chunk shouldBeSame lastPos.chunk // we inserted in the middle -- the last chunk should remain the same
|
||||
storeView().constraintSymbols() shouldBe setOf(sym0("bar1"), sym0("qux"), sym0("marker"))
|
||||
|
|
|
|||
Loading…
Reference in New Issue