Propagate FeedbackStatus out of reactivate for incremental execution.

This commit is contained in:
Grigorii Kirgizov 2019-07-11 12:41:02 +03:00 committed by Fedor Isakov
parent f7ea5f7a0d
commit be7283190f
6 changed files with 36 additions and 32 deletions

View File

@ -31,7 +31,7 @@ interface Controller {
fun tell(invocation: PredicateInvocation)
fun reactivate(occ: Occurrence)
fun reactivate(occ: Occurrence): FeedbackStatus
fun state(): ProcessingState

View File

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

View File

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

View File

@ -43,7 +43,8 @@ internal class ExecutionQueue(
private val seen: MutableSet<ExecPos> = 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<RuleMatchEx>): List<RuleMatchEx> =

View File

@ -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<Any>) {
@ -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 =

View File

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