From f2d1f089adcb7c971bead52449774917be86b01c Mon Sep 17 00:00:00 2001 From: Grigorii Kirgizov Date: Mon, 20 Jul 2020 19:00:48 +0300 Subject: [PATCH] Use rule match identity as feedback key for TypesIndex instead of rule unique tag It seems to reflect the exact information needed: there's one-to-one correspondence between feedback and its match. While using rule unique tag as feedback key in TypesIndex relied on several assumptions. Also there's less use of MatchJournal information with this. Previously parent principal match was passed to FeedbackConsumer. --- .../mps/logic/reactor/core/CompositeFeedback.kt | 4 ++-- .../src/jetbrains/mps/logic/reactor/core/Feedback.kt | 8 ++++++-- .../logic/reactor/core/internal/ConstraintsProcessing.kt | 8 ++++---- .../mps/logic/reactor/core/internal/ControllerImpl.kt | 9 ++++----- .../logic/reactor/core/internal/EvaluationSessionImpl.kt | 8 ++++---- .../mps/logic/reactor/evaluation/EvaluationResult.java | 2 +- .../mps/logic/reactor/evaluation/Supervisor.java | 2 +- reactor/Test/test/TestController.kt | 4 +--- 8 files changed, 23 insertions(+), 22 deletions(-) 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)