From be7283190f017ad0370c020859c03ff32383dd32 Mon Sep 17 00:00:00 2001 From: Grigorii Kirgizov Date: Thu, 11 Jul 2019 12:41:02 +0300 Subject: [PATCH] Propagate FeedbackStatus out of reactivate for incremental execution. --- .../mps/logic/reactor/core/Controller.kt | 2 +- .../mps/logic/reactor/core/Occurrence.kt | 18 +++++++++++---- .../reactor/core/internal/ControllerImpl.kt | 10 ++------ .../reactor/core/internal/ExecutionQueue.kt | 13 +++++++---- .../core/internal/ProcessingStateImpl.kt | 23 ++++++++----------- reactor/Test/test/RulesHelper.kt | 2 +- 6 files changed, 36 insertions(+), 32 deletions(-) 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 990336db..4848b1bd 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/Controller.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/Controller.kt @@ -31,7 +31,7 @@ interface Controller { fun tell(invocation: PredicateInvocation) - fun reactivate(occ: Occurrence) + fun reactivate(occ: Occurrence): FeedbackStatus fun state(): ProcessingState diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/Occurrence.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/Occurrence.kt index 4470d696..12359540 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/Occurrence.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/Occurrence.kt @@ -18,6 +18,7 @@ package jetbrains.mps.logic.reactor.core import gnu.trove.set.TIntSet import gnu.trove.set.hash.TIntHashSet +import jetbrains.mps.logic.reactor.core.internal.FeedbackStatus import jetbrains.mps.logic.reactor.evaluation.ConstraintOccurrence import jetbrains.mps.logic.reactor.logical.Logical @@ -35,15 +36,22 @@ fun justsCopy(other: Justs) = TIntHashSet(other) data class OccurrenceObserver(val occurrence: Occurrence, val controller: Controller) : LogicalObserver { - override fun valueUpdated(logical: Logical<*>) { + + override fun valueUpdated(logical: Logical<*>) = doReactivate() + + override fun parentUpdated(logical: Logical<*>) = doReactivate() + + private fun doReactivate() { if (occurrence.alive) { - controller.reactivate(occurrence) + val status = controller.reactivate(occurrence) + // FIXME propagate the status further up the call stack + handleFeedbackStatus(status) } } - override fun parentUpdated(logical: Logical<*>) { - if (occurrence.alive) { - controller.reactivate(occurrence) + private fun handleFeedbackStatus(status: FeedbackStatus) { + if (status is FeedbackStatus.FAILED) { + throw status.failure.failureCause() } } } 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 b852bc3f..b4312947 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 @@ -88,14 +88,8 @@ internal class ControllerImpl ( solver.tell(invocation) } - override fun reactivate(occ: Occurrence) { - // FIXME propagate the status further up the call stack - - val status = state.processActivated(this, occ, NORMAL()) - if (status is FAILED) { - throw status.failure.failureCause() - } - } + override fun reactivate(occ: Occurrence): FeedbackStatus = + state.processActivated(this, occ, NORMAL()) override fun offerMatch(match: RuleMatchEx, inStatus: FeedbackStatus) : FeedbackStatus = inStatus.then { checkMatchPreconditions(match, it) } diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ExecutionQueue.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ExecutionQueue.kt index eb002cf3..34aac132 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ExecutionQueue.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ExecutionQueue.kt @@ -43,7 +43,8 @@ internal class ExecutionQueue( private val seen: MutableSet = HashSet() - fun run(controller: Controller, state: ProcessingStateImpl): FeedbackStatus.NORMAL { + fun run(controller: Controller, state: ProcessingStateImpl): FeedbackStatus { + var status: FeedbackStatus = FeedbackStatus.NORMAL() if (execQueue.isNotEmpty()) { state.resetStore() @@ -59,13 +60,17 @@ internal class ExecutionQueue( } prevPos = execPos.pos - state.reactivate(controller, execPos.activeOcc) + // If the occurrence is still in the store after replay (i.e. if it's valid to activate it) + if (execPos.activeOcc.stored) { + status = state.reactivate(controller, execPos.activeOcc) + // Leave journal state as it was at the point of failure + if (!status.operational) return status + } } while (execQueue.isNotEmpty()) } // Also replay to the end after queue is fully executed state.replay(controller, state.last().toPos()) - // fixme: get FeedbackStatus out of reactivate() - return FeedbackStatus.NORMAL() + return status } fun withPostponedMatches(active: Occurrence, matches: List): List = diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ProcessingStateImpl.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ProcessingStateImpl.kt index cfdb125c..8bca17d0 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ProcessingStateImpl.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ProcessingStateImpl.kt @@ -22,10 +22,8 @@ import jetbrains.mps.logic.reactor.program.IncrementalProgramSpec import jetbrains.mps.logic.reactor.evaluation.RuleMatch import jetbrains.mps.logic.reactor.evaluation.SessionToken import jetbrains.mps.logic.reactor.program.Rule -import jetbrains.mps.logic.reactor.util.Id import jetbrains.mps.logic.reactor.util.Profiler import jetbrains.mps.logic.reactor.util.profile -import java.util.* /** @@ -60,16 +58,15 @@ internal class ProcessingStateImpl(private var dispatchingFront: Dispatcher.Disp private data class MatchCandidate(val rule: Rule, val occChunk: MatchJournal.OccChunk) - fun reactivate(controller: Controller, activeOcc: Occurrence) { - // If the occurrence is still in the store after replay (i.e. if it's valid to activate it) - if (activeOcc.stored) { - // Forget that occ was seen. - // Incremental reactivation isn't like the usual reactivation, - // it should proceed more like usual activation. - this.dispatchingFront = dispatchingFront.forgetSeen(activeOcc) - trace.reactivateIncremental(activeOcc) - controller.reactivate(activeOcc) - } + fun reactivate(controller: Controller, activeOcc: Occurrence): FeedbackStatus { + assert(activeOcc.stored) + + // Forget that occ was seen. Otherwise it will be + // processed as with reactivation through observers. + // Incremental reactivation should proceed more like usual activation. + this.dispatchingFront = dispatchingFront.forgetSeen(activeOcc) + trace.reactivateIncremental(activeOcc) + return controller.reactivate(activeOcc) } fun invalidateDependentRules(ruleIds: Set) { @@ -203,7 +200,7 @@ internal class ProcessingStateImpl(private var dispatchingFront: Dispatcher.Disp } } - fun launchQueue(controller: Controller): FeedbackStatus.NORMAL = + fun launchQueue(controller: Controller): FeedbackStatus = execQueue.run(controller, this) fun snapshot(): SessionToken = diff --git a/reactor/Test/test/RulesHelper.kt b/reactor/Test/test/RulesHelper.kt index 75a2e00c..b4f0038f 100644 --- a/reactor/Test/test/RulesHelper.kt +++ b/reactor/Test/test/RulesHelper.kt @@ -188,7 +188,7 @@ class MockController : Controller { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } - override fun reactivate(occ: Occurrence) { + override fun reactivate(occ: Occurrence): FeedbackStatus { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. }