diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/Controller.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/Controller.kt index f7d2c338..328ea966 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/Controller.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/Controller.kt @@ -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 diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/LogicalStateObservable.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/LogicalStateObservable.kt index 484bf09d..481132eb 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/LogicalStateObservable.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/LogicalStateObservable.kt @@ -28,14 +28,6 @@ interface LogicalStateObservable { fun removeForwardingObserver(logical: Logical<*>, observer: ForwardingLogicalObserver) - fun init(controller: Controller): InitToken - - interface InitToken { - - fun clear() - - } - } interface ForwardingLogicalObserver { diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ConstraintsProcessing.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ConstraintsProcessing.kt index 5e122342..6c2392e1 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ConstraintsProcessing.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ConstraintsProcessing.kt @@ -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().apply { ruleIndex.forEach { add(it) } } - return SessionTokenImpl(histView, rules, dispatchingFront.state(), logicalState) + return SessionTokenImpl(histView, rules, dispatchingFront.state(), logicalState.clear()) } /** 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 b8979f4d..0d1d29e9 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 @@ -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 variable(metaLogical: MetaLogical): Logical? = 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("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 +} 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 44538d27..b6bf9f22 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 @@ -36,39 +36,42 @@ internal class EvaluationSessionImpl private constructor ( val params: Map, *>?) : EvaluationSession() { - lateinit var controller: ControllerImpl - @Suppress("UNCHECKED_CAST") override fun parameter(key: ParameterKey): T? = params ?.get(key) as T private fun launch( main: Constraint, profiler: Profiler?, token: SessionToken?, rulesDiff: RulesDiff, ispec: IncrementalProgramSpec - ) : FeedbackStatus { + ) : Pair { 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 - } } } diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/LogicalState.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/LogicalState.kt index b9bc3f23..2a8b421c 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/LogicalState.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/LogicalState.kt @@ -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) } diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/StoreAwareJournal.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/StoreAwareJournal.kt index efe5b4b9..bd11704b 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/StoreAwareJournal.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/StoreAwareJournal.kt @@ -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() diff --git a/reactor/Test/test/RulesHelper.kt b/reactor/Test/test/RulesHelper.kt index a9ac09c4..36056acf 100644 --- a/reactor/Test/test/RulesHelper.kt +++ b/reactor/Test/test/RulesHelper.kt @@ -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, 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 { diff --git a/reactor/Test/test/TestController.kt b/reactor/Test/test/TestController.kt index 1df6db6d..52c8d143 100644 --- a/reactor/Test/test/TestController.kt +++ b/reactor/Test/test/TestController.kt @@ -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.* diff --git a/reactor/Test/test/TestStoreAwareJournal.kt b/reactor/Test/test/TestStoreAwareJournal.kt index 4a62c561..d0f19409 100644 --- a/reactor/Test/test/TestStoreAwareJournal.kt +++ b/reactor/Test/test/TestStoreAwareJournal.kt @@ -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() - 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() @@ -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"))