diff --git a/coderules/languages/jetbrains.mps.lang.coderules/generator/template/main@generator.mps b/coderules/languages/jetbrains.mps.lang.coderules/generator/template/main@generator.mps index aeebecee..d3e807b6 100644 --- a/coderules/languages/jetbrains.mps.lang.coderules/generator/template/main@generator.mps +++ b/coderules/languages/jetbrains.mps.lang.coderules/generator/template/main@generator.mps @@ -5067,21 +5067,25 @@ - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - @@ -5090,6 +5094,14 @@ + + + + + + + + diff --git a/reactor/.idea/misc.xml b/reactor/.idea/misc.xml index e28f1b3a..8f4acde0 100644 --- a/reactor/.idea/misc.xml +++ b/reactor/.idea/misc.xml @@ -45,7 +45,7 @@ - + \ No newline at end of file diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/Dispatcher.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/Dispatcher.kt index 37d4e8b1..4b79cb2e 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/Dispatcher.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/Dispatcher.kt @@ -17,21 +17,24 @@ package jetbrains.mps.logic.reactor.core -typealias DispatchingFrontState = Map +typealias DispatchingFrontState = Map /** * A front-end interface to [RuleMatcher]. * * @author Fedor Isakov */ -class Dispatcher (val ruleIndex: RuleIndex) { +class Dispatcher (val ruleIndex: RuleIndex, prevState: DispatchingFrontState = emptyMap()) { private val ruletag2matcher = HashMap() init { ruleIndex.forEach { rule -> - val matcher = createRuleMatcher(ruleIndex, rule.uniqueTag()) - ruletag2matcher.put(rule.uniqueTag(), matcher); + val ruletag = rule.uniqueTag() + // reset references to stale RuleIndex instances + val matcher = prevState[ruletag]?.apply { setRuleLookup(ruleIndex) } + ?: createRuleMatcher(ruleIndex, ruletag) + ruletag2matcher.put(ruletag, matcher); } } @@ -40,8 +43,6 @@ class Dispatcher (val ruleIndex: RuleIndex) { */ fun front() = DispatchingFront() - fun frontFromState(predState: DispatchingFrontState) = DispatchingFront(predState) - inner class DispatchingFront { private val ruletag2probe : HashMap @@ -56,14 +57,6 @@ class Dispatcher (val ruleIndex: RuleIndex) { } } - constructor(predState: DispatchingFrontState) { - this.ruletag2probe = hashMapOf() - this.matching = null - ruletag2matcher.entries.forEach { e -> - ruletag2probe[e.key] = predState[e.key] ?: e.value.probe() - } - } - private constructor(pred: DispatchingFront, matching: Iterable? = null) { this.ruletag2probe = pred.ruletag2probe this.matching = matching @@ -83,7 +76,7 @@ class Dispatcher (val ruleIndex: RuleIndex) { return allMatches } - fun state() : DispatchingFrontState = ruletag2probe //.asMap() + fun state() : DispatchingFrontState = ruletag2matcher //.asMap() /** * Returns a [DispatchingFront] instance that is "expanded" with matches corresponding to the diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/RuleMatcher.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/RuleMatcher.kt index 35f7737a..856d14e3 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/RuleMatcher.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/RuleMatcher.kt @@ -26,14 +26,19 @@ import jetbrains.mps.logic.reactor.program.Rule * Abstracts a rule matching algorithm. * * A RuleMatcher corresponds to a single rule. - * The method [probe] provides a factory of [RuleMatchingProbe], which is the main handler of match operations. + * The method [newProbe] provides a factory of [RuleMatchingProbe], which is the main handler of match operations. + * The method [probe] provides access to a last created instance of [RuleMatchingProbe] or creates a first one. * * @author Fedor Isakov */ interface RuleMatcher { + fun newProbe(): RuleMatchingProbe + fun probe(): RuleMatchingProbe + fun setRuleLookup(ruleLookup: RuleLookup): Unit + } fun createRuleMatcher(lookup: RuleLookup, tag: Any): RuleMatcher = ReteRuleMatcherImpl(lookup, tag) 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 b200fd5a..10d1e982 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 @@ -47,11 +47,10 @@ internal class EvaluationSessionImpl private constructor ( ) : FeedbackStatus { val ruleIndex = RuleIndex(program.handlers()) - val dispatcher = Dispatcher(ruleIndex) if (ispec is IncrementalProgramSpec.NonIncrSpec || token == null) { val state = ProcessingStateImpl( - dispatcher.front(), + Dispatcher(ruleIndex).front(), MatchJournalImpl(ispec), ruleIndex, ispec, trace, profiler ) @@ -62,7 +61,7 @@ internal class EvaluationSessionImpl private constructor ( } else { val tkn = token as SessionTokenImpl val state = ProcessingStateImpl( - dispatcher.frontFromState(tkn.frontState), + Dispatcher(ruleIndex, tkn.getFrontState()).front(), MatchJournalImpl(ispec, tkn.journalView), ruleIndex, ispec, trace, profiler ) diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ReteRuleMatcherImpl.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ReteRuleMatcherImpl.kt index 0c3f694c..d2f3a28e 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ReteRuleMatcherImpl.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ReteRuleMatcherImpl.kt @@ -41,7 +41,7 @@ fun footprintOf(): Footprint = TIntHashSet() fun Signature.toFootprint() = TIntHashSet(this) -internal class ReteRuleMatcherImpl(private val ruleLookup: RuleLookup, +internal class ReteRuleMatcherImpl(private var ruleLookup: RuleLookup, private val tag: Any) : RuleMatcher { @@ -51,7 +51,13 @@ internal class ReteRuleMatcherImpl(private val ruleLookup: RuleLookup, fun lookupRule(): Rule = ruleLookup.lookupRuleByTag(tag) ?: throw IllegalStateException("can't lookup rule by tag: '${tag}'") - override fun probe(): ReteNetwork = ReteNetwork(head.size) + override fun setRuleLookup(ruleLookup: RuleLookup) { this.ruleLookup = ruleLookup } + + override fun newProbe(): RuleMatchingProbe = ReteNetwork(head.size).also { probe = it } + + override fun probe(): RuleMatchingProbe = probe ?: newProbe() + + private var probe: RuleMatchingProbe? = null inner class ReteNetwork(val headSize: Int) : RuleMatchingProbe { diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/RuleMatcherImpl.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/RuleMatcherImpl.kt index 7846d17e..f8904475 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/RuleMatcherImpl.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/RuleMatcherImpl.kt @@ -33,7 +33,7 @@ import kotlin.collections.ArrayList * * @author Fedor Isakov */ -internal class RuleMatcherImpl(private val ruleLookup: RuleLookup, +internal class RuleMatcherImpl(private var ruleLookup: RuleLookup, private val tag: Any) : RuleMatcher { @@ -43,12 +43,19 @@ internal class RuleMatcherImpl(private val ruleLookup: RuleLookup, fun lookupRule(): Rule = ruleLookup.lookupRuleByTag(tag) ?: throw IllegalStateException("can't lookup rule by tag: '${tag}'") - override fun probe(): RuleMatchingProbe = + override fun setRuleLookup(ruleLookup: RuleLookup) { this.ruleLookup = ruleLookup } + + override fun newProbe(): RuleMatchingProbe = RuleMatchFront(emptyList(), emptyList(), Sets.of(IntArray(head.size).toSignature()), Sets.of(), Sets.of()) + .also { probe = it } + + override fun probe(): RuleMatchingProbe = probe ?: newProbe() + + private var probe: RuleMatchingProbe? = null inner class RuleMatchFront(private val trunkNodes: List, private val leafNodes: List, diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/SessionTokenImpl.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/SessionTokenImpl.kt index c7da708e..d3b90555 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/SessionTokenImpl.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/SessionTokenImpl.kt @@ -27,5 +27,5 @@ data class SessionTokenImpl( ) : SessionToken { override fun getJournalView(): MatchJournalView = journalView override fun getRuleTags(): Iterable = ruleTags - override fun getFrontState(): DispatchingFrontState = frontState + fun getFrontState(): DispatchingFrontState = frontState } diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/SessionToken.java b/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/SessionToken.java index 159e6b47..b4b7f0f5 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/SessionToken.java +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/evaluation/SessionToken.java @@ -24,6 +24,4 @@ public interface SessionToken { MatchJournalView getJournalView(); @NotNull() Iterable getRuleTags(); - @NotNull() - Map getFrontState(); }