From ab3eb716ae55773943136d2e71e0ef89e99bb817 Mon Sep 17 00:00:00 2001 From: Grigorii Kirgizov Date: Mon, 3 Feb 2020 13:59:56 +0300 Subject: [PATCH] Refactor ExecPos from ExecQueue to work with OccChunk instead of any Occurrence This interface change it means that only Occurrences from previous session can be reexecuted. --- .../core/internal/ConstraintsProcessing.kt | 2 +- .../reactor/core/internal/ExecutionQueue.kt | 28 +++++++++++++------ .../reactor/core/internal/MatchJournal.kt | 3 +- .../reactor/core/internal/MatchJournalImpl.kt | 4 +-- 4 files changed, 25 insertions(+), 12 deletions(-) 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 62ac2720..3b5cb526 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 @@ -170,7 +170,7 @@ internal class ConstraintsProcessing(private var dispatchingFront: Dispatcher.Di else continue - execQueue.offer(pos, occChunk.occ) + execQueue.offer(pos, occChunk) trace.potentialMatch(occChunk.occ, candRule) // Drop the candidate if appropriate activation place is found. aIt.remove() 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 9b2dc323..15ecf020 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 @@ -28,7 +28,18 @@ internal class ExecutionQueue( private val ruleOrdering: RuleOrdering ) { - private data class ExecPos(val pos: MatchJournal.Pos, val activeOcc: Occurrence) + /** + * Specifies position in [MatchJournal] for continuing Coderules program evaluation, + * where it's supposed that [pos] must be a descendant of [ancestor]. + * (i.e. `pos.isDescendantOf(ancestor.id) == true`) + */ + private data class ExecPos(val pos: MatchJournal.Pos, val ancestor: MatchJournal.OccChunk) { + + constructor(active: MatchJournal.OccChunk) : this(active.toPos(), active) + + val activeOcc: Occurrence + get() = ancestor.occ + } // It is a position in Journal from previous session, // from which incremental execution continues. @@ -94,7 +105,7 @@ internal class ExecutionQueue( // if it is a future match if (pos2occ != null && journalIndex.compare(lastIncrementalRootPos, pos2occ.first) < 0) { - val idOcc = Id(pos2occ.second) + val idOcc = Id(pos2occ.second.occ) postponedMatches[idOcc] = (postponedMatches[idOcc] ?: emptyList()) + listOf(m) offer(pos2occ.first, pos2occ.second) } else { @@ -135,21 +146,22 @@ internal class ExecutionQueue( // (i.e. don't reactivate additional, inactive heads that only completed the match?) fun offerAll(occs: Iterable): Boolean = execQueue.addAll(occs.mapNotNull { occ -> - journalIndex.activatingChunkOf(Id(occ))?.let { chunk -> - ExecPos(chunk.toPos(), occ).let { + journalIndex.activatingChunkOf(Id(occ))?.let { occChunk -> + ExecPos(occChunk).let { if (seen.add(it)) it else null } } }) - fun offer(posInJournal: MatchJournal.Pos, activeOcc: Occurrence): Boolean = - ExecPos(posInJournal, activeOcc).let { + fun offer(posInJournal: MatchJournal.Pos, ancestor: MatchJournal.OccChunk): Boolean = + ExecPos(posInJournal, ancestor).let { if (seen.add(it)) execQueue.offer(it) else false } + // todo: remove // special case when position in trace corresponds to position of activated occurrence - fun offer(posInJournal: MatchJournal.Pos): Boolean = - offer(posInJournal, posInJournal.occ) +// fun offer(posInJournal: MatchJournal.Pos): Boolean = +// offer(posInJournal, posInJournal.occ) fun isEmpty(): Boolean = execQueue.isEmpty() 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 d1dcdba3..e4305d8c 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 @@ -128,7 +128,7 @@ interface MatchJournal : MutableIterable { * according to its indexed head [Occurrence]s. * May return null for matches of non-principal rules. */ - fun activationPos(match: RuleMatchEx): Pair? + fun activationPos(match: RuleMatchEx): Pair? /** * Length of the indexed [MatchJournal] @@ -198,6 +198,7 @@ interface MatchJournal : MutableIterable { } open class Pos(val chunk: Chunk, val entriesCount: Int) { + // todo: remove val occ: Occurrence get() = chunk.entriesLog()[entriesCount - 1].occ() 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 75872b32..adcebcda 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 @@ -256,7 +256,7 @@ internal open class MatchJournalImpl( override fun lastDescendantOf(occChunk: OccChunk): Chunk? = occChunk2LastDescendant[occChunk.id] - override fun activationPos(match: RuleMatchEx): Pair? { + override fun activationPos(match: RuleMatchEx): Pair? { // The latest matched occurrence from match's head is // (by definition) the occurrence which activated this match. @@ -277,7 +277,7 @@ internal open class MatchJournalImpl( lastDescendantOf(activatingChunk)!! else activatingChunk - return posChunk.toPos() to activatingChunk.occ + return posChunk.toPos() to activatingChunk } // todo: throw for invalid positions?