diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/CompositeFeedback.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/CompositeFeedback.kt index 067ec167..6b541d5d 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/CompositeFeedback.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/CompositeFeedback.kt @@ -33,12 +33,12 @@ class CompositeFeedback private constructor(private val elements: List this.severity = maxSeverity(elements) } - override fun handle(currentRuleMatch: RuleMatch, parentPrincipalMatch: RuleMatch, supervisor: Supervisor): Boolean { + override fun handle(currentRuleMatch: RuleMatch, feedbackKey: Any, supervisor: Supervisor): Boolean { var unhandled = 0 for (feedback in elements) { if (!feedback.alreadyHandled()) { unhandled += 1 - if (supervisor.handleFeedback(currentRuleMatch, parentPrincipalMatch, feedback)) { + if (supervisor.handleFeedback(currentRuleMatch, feedbackKey, feedback)) { feedback.setHandled() unhandled -= 1 } diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/Feedback.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/Feedback.kt index 63882b2f..02ee78c9 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/Feedback.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/Feedback.kt @@ -40,8 +40,8 @@ abstract class Feedback : EvaluationFeedback() { /** * Returns true if the feedback has been handled. */ - open fun handle(currentRuleMatch: RuleMatch, parentPrincipalMatch: RuleMatch, supervisor: Supervisor): Boolean { - if (!alreadyHandled() && supervisor.handleFeedback(currentRuleMatch, parentPrincipalMatch, this)) { + open fun handle(currentRuleMatch: RuleMatch, feedbackKey: Any, supervisor: Supervisor): Boolean { + if (!alreadyHandled() && supervisor.handleFeedback(currentRuleMatch, feedbackKey, this)) { setHandled() } return alreadyHandled() @@ -54,3 +54,7 @@ abstract class Feedback : EvaluationFeedback() { } } + +typealias FeedbackKeySet = Set + +internal val RuleMatch.feedbackKey: Any get() = System.identityHashCode(this) 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 c508699b..c0bf641e 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 @@ -51,7 +51,7 @@ internal class ConstraintsProcessing(private var dispatchingFront: Dispatcher.Di private val activationQueue: ContinuedActivationQueue = ContinuedActivationQueue(journalIndex, RuleOrdering(ruleIndex)) - private val invalidatedRulesTags: MutableSet = mutableSetOf() + private val invalidFeedbackKeys: MutableSet = mutableSetOf() private data class MatchCandidate(val rule: Rule, val occChunk: MatchJournal.OccChunk) @@ -116,7 +116,7 @@ internal class ConstraintsProcessing(private var dispatchingFront: Dispatcher.Di val validOccs: Sequence if (chunk is MatchJournal.MatchChunk) { trace.invalidate(chunk.match) - invalidatedRulesTags.add(chunk.ruleUniqueTag) + invalidFeedbackKeys.add(chunk.match.feedbackKey) dispatchingFront = dispatchingFront.forget(chunk.match as RuleMatchEx) // Valid head occurrences could match more rules @@ -195,7 +195,7 @@ internal class ConstraintsProcessing(private var dispatchingFront: Dispatcher.Di * and returns [SessionToken] with session results. */ fun endSession(): SessionToken { - invalidatedRulesTags.clear() + invalidFeedbackKeys.clear() val histView = view() resetStore() // clear observers val rules = ArrayList().apply { ruleIndex.forEach { add(it) } } @@ -206,7 +206,7 @@ internal class ConstraintsProcessing(private var dispatchingFront: Dispatcher.Di return SessionTokenImpl(histView, rules, principalState, logicalState.clear()) } - fun invalidatedRules(): Set = HashSet(invalidatedRulesTags) + fun invalidatedFeedback(): FeedbackKeySet = HashSet(invalidFeedbackKeys) /** * Called to update the state with the currently active constraint occurrence. 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 326b47cd..27711707 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 @@ -54,7 +54,7 @@ internal class ControllerImpl ( return storeView() } - fun incrLaunch(constraint: Constraint, rulesDiff: RulesDiff): Pair> { + fun incrLaunch(constraint: Constraint, rulesDiff: RulesDiff): Pair { if (rulesDiff.removed.isNotEmpty()) { profiler.profile("invalidation") { @@ -73,7 +73,7 @@ internal class ControllerImpl ( processing.launchQueue(this) } - return status to processing.invalidatedRules() + return status to processing.invalidatedFeedback() } fun activate(constraint: Constraint) : FeedbackStatus { @@ -180,7 +180,7 @@ internal class ControllerImpl ( if (itemOk) { context.withStatus { status -> if (status.feedback?.alreadyHandled() == false) { - status.feedback.handle(match, newParent.match, supervisor) + status.feedback.handle(match, newParent.match.feedbackKey, supervisor) } } @@ -201,7 +201,7 @@ internal class ControllerImpl ( // if failure can be handled here then recover } else if (status.feedback?.alreadyHandled() == false - && status.failure.handle(match, newParent.match, supervisor)) { + && status.failure.handle(match, newParent.match.feedbackKey, supervisor)) { status.recover() @@ -280,7 +280,6 @@ internal class ControllerImpl ( it.first.patternPredicates(it.second.arguments()) }.toList() - inner private class Context(inStatus: FeedbackStatus, val checking: Boolean, val logicalContext: LogicalContext, 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 952830fa..b203055f 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 @@ -46,7 +46,7 @@ internal class EvaluationSessionImpl private constructor ( val newToken: SessionToken val status: FeedbackStatus - val invalidatedTags: Set + val invalidFeedbackKeys: Set val ruleIndex = RuleIndex(program.rulesLists()) @@ -63,7 +63,7 @@ internal class EvaluationSessionImpl private constructor ( status = controller.activate(main) newToken = processing.endSession() - invalidatedTags = emptySet() + invalidFeedbackKeys = emptySet() } else { val tkn = token as SessionTokenImpl @@ -80,14 +80,14 @@ internal class EvaluationSessionImpl private constructor ( val status2tags = controller.incrLaunch(main, rulesDiff) newToken = processing.endSession() status = status2tags.first - invalidatedTags = status2tags.second + invalidFeedbackKeys = status2tags.second } return object : EvaluationResult { override fun token(): SessionToken = newToken override fun storeView(): StoreView = newToken.journalView.storeView override fun feedback(): EvaluationFeedback? = if (status is FAILED) status.failure else null - override fun invalidatedTags(): Collection = invalidatedTags + override fun invalidFeedbackKeys(): Collection = invalidFeedbackKeys } } diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/EvaluationResult.java b/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/EvaluationResult.java index b2d5cafa..afb88fc9 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/EvaluationResult.java +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/EvaluationResult.java @@ -29,6 +29,6 @@ public interface EvaluationResult { public EvaluationFeedback feedback(); - public Collection invalidatedTags(); + public Collection invalidFeedbackKeys(); } diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/Supervisor.java b/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/Supervisor.java index e8425b98..aca896bd 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/Supervisor.java +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/Supervisor.java @@ -34,7 +34,7 @@ public interface Supervisor { * Override this method in order to "handle" the feedback. * Returns true if the method has handled (consumed) the feedback. */ - default boolean handleFeedback(RuleMatch ruleMatch, RuleMatch parentPrincipalMatch, EvaluationFeedback feedback) { + default boolean handleFeedback(RuleMatch ruleMatch, Object feedbackKey, EvaluationFeedback feedback) { return false; } diff --git a/reactor/Test/test/TestController.kt b/reactor/Test/test/TestController.kt index e2fb3758..cf09278d 100644 --- a/reactor/Test/test/TestController.kt +++ b/reactor/Test/test/TestController.kt @@ -1,12 +1,10 @@ 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.* import jetbrains.mps.logic.reactor.logical.Logical import jetbrains.mps.logic.reactor.program.ConstraintSymbol import jetbrains.mps.logic.reactor.program.Program -import jetbrains.mps.logic.reactor.program.Rule import jetbrains.mps.unification.Term import jetbrains.mps.unification.test.MockTerm.* import org.junit.After @@ -70,7 +68,7 @@ class TestController { vararg occurrences: ConstraintOccurrence): Controller { val program = MockProgram("test", rulesLists, registry = MockConstraintRegistry()) val supervisor = object : MockSupervisor() { - override fun handleFeedback(ruleMatch: RuleMatch, parentPrincipalMatch: RuleMatch, feedback: EvaluationFeedback): Boolean = + override fun handleFeedback(ruleMatch: RuleMatch, feedbackKey: Any, feedback: EvaluationFeedback): Boolean = feedbackHandler(ruleMatch, feedback) } MockSession.init(program, supervisor)