From d7c2b7f9775c9c40888c9285213f52db30aa5bbc Mon Sep 17 00:00:00 2001 From: Grigorii Kirgizov Date: Sat, 1 Feb 2020 21:43:01 +0300 Subject: [PATCH] Extend MatchJournal with replayUntil method --- .../reactor/core/internal/ExecutionQueue.kt | 13 +++++++++-- .../reactor/core/internal/MatchJournal.kt | 23 +++++++++++++++---- .../reactor/core/internal/MatchJournalImpl.kt | 15 ++++++++++++ 3 files changed, 44 insertions(+), 7 deletions(-) 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 1d2b061a..e792e11e 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 @@ -105,8 +105,17 @@ internal class ExecutionQueue( } /** - * Checks whether [candidateRule] can be inserted in journal as a child of [parentChunk] - * before one of its child chunks, [beforeChunk]. + * Replays [processing] until a match of [matchedRule] can be inserted according to [RuleOrdering] + * If [ConstraintsProcessing.isFront] is true, then no unnecessary work is done. + */ + fun replayToMatch(matchedRule: Rule, activationChunk: MatchJournal.OccChunk, processing: ConstraintsProcessing) = + processing.replayUntil(processing.logicalState) { chunk -> + canBeInserted(matchedRule, activationChunk, chunk) + } + + /** + * Checks whether [candidateRule] can be inserted in journal as a child + * of [parentChunk] before one of its child chunks, [beforeChunk]. * It is assumed that [candidateRule] can be matched by [Occurrence] from [parentChunk]. */ fun canBeInserted(candidateRule: Rule, parentChunk: MatchJournal.OccChunk, beforeChunk: MatchJournal.Chunk): Boolean { diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/MatchJournal.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/MatchJournal.kt index 05f67311..dab32bb3 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/MatchJournal.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/MatchJournal.kt @@ -74,6 +74,11 @@ interface MatchJournal : MutableIterable { */ fun replay(observable: LogicalStateObservable, futurePos: Pos) + /** + * Same as [replay]: replays [Chunk]s until [pred] returns true. + * May replay the whole journal, in which case position will point to the end of journal. + */ + fun replayUntil(observable: LogicalStateObservable, pred: (Chunk) -> Boolean) /** * Returns snapshot of the journal. @@ -102,13 +107,21 @@ interface MatchJournal : MutableIterable { */ fun activatingChunkOf(occId: Id): OccChunk? + // todo: remove /** - * Find [Pos] at which provided match was triggered. - * Returned position specifies [Occurrence] which triggered the match. - * Works not for any match, must work for matches of principal rules. + * Returns [Pos] at which provided [RuleMatch] can be inserted + * according to its indexed head [Occurrence]s and rule ordering. + * Returns for matches of non-principal rules. + */ +// fun positionFor(newMatch: RuleMatchEx): Pos? + + /** + * Returns [Pos] at which provided [RuleMatch] is triggered + * according to its indexed head [Occurrence]s. + * May return null for matches of non-principal rules. */ fun activationPos(match: RuleMatchEx): Pos? = - // The latest matched occurrence from match's head is(by definition) + // The latest matched occurrence from match's head is (by definition) // the occurrence which activated this match. match.signature().mapNotNull { occSig -> occSig?.let { activatingChunkOf(it)?.toPos() } @@ -121,7 +134,7 @@ interface MatchJournal : MutableIterable { } /** - * Immutable snapshot of current state of [MatchJournal]. + * Immutable snapshot of [MatchJournal]. */ data class View(private val chunks: List, private val nextChunkId: Int) : MatchJournalView { override fun getChunks(): List = chunks diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/MatchJournalImpl.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/MatchJournalImpl.kt index ee7aba75..b0e3aee1 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/MatchJournalImpl.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/MatchJournalImpl.kt @@ -141,6 +141,21 @@ internal open class MatchJournalImpl( if (currentPos() != futurePos) throw IllegalStateException() } + override fun replayUntil(observable: LogicalStateObservable, pred: (Chunk) -> Boolean) { + // todo: case when pred(current) == true? need replaying rest of current.entries? + while (posPtr.hasNext()) { + val previous = current + current = posPtr.next() + if (pred(current)) { + // reset ptr so that it points after previous chunk + current = previous + posPtr.previous() + return + } + replayOccurrences(observable, current.entries) + } + } + private fun resetOccurrences(occSpecs: Iterable) = occSpecs.forEach { if (it.discarded) {