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 7c032581..62ac2720 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 @@ -46,12 +46,7 @@ internal class ConstraintsProcessing(private var dispatchingFront: Dispatcher.Di val profiler: Profiler? = null) : StoreAwareJournalImpl(journal, logicalState) { - private val ruleOrdering: RuleOrdering = RuleOrdering(ruleIndex) - - private val journalIndex: MatchJournal.Index = journal.index() - - private val execQueue: ExecutionQueue = ExecutionQueue(journalIndex, ruleOrdering) - + private val execQueue: ExecutionQueue = ExecutionQueue(journal.index(), RuleOrdering(ruleIndex)) private data class MatchCandidate(val rule: Rule, val occChunk: MatchJournal.OccChunk) @@ -165,19 +160,15 @@ internal class ConstraintsProcessing(private var dispatchingFront: Dispatcher.Di while (aIt.hasNext()) { val (candRule, occChunk) = aIt.next() - // Place to activate candidate: - // either according to the ordering between rules. - // or as the last one, after all existing activations - val placeToInsertFound = - chunk is MatchJournal.MatchChunk && ruleOrdering.isEarlierThan(candRule, chunk.match.rule()) - val childChunksEnded = !chunk.isDescendantOf(occChunk.id) - val pos = - // We need the previous chunk as pos here (i.e. adding after it). - if (childChunksEnded || placeToInsertFound) prevChunk.toPos() - // Case when adding at the very end - else if (!it.hasNext()) chunk.toPos() - else continue + if (execQueue.canBeInserted(candRule, occChunk, chunk)) + // We need the previous chunk as pos here (i.e. adding after it). + prevChunk.toPos() + else if (!it.hasNext()) + // Case when adding at the very end + chunk.toPos() + else + continue execQueue.offer(pos, occChunk.occ) trace.potentialMatch(occChunk.occ, candRule) 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 26150678..1d2b061a 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 @@ -19,6 +19,7 @@ package jetbrains.mps.logic.reactor.core.internal import jetbrains.mps.logic.reactor.core.Controller import jetbrains.mps.logic.reactor.core.Occurrence import jetbrains.mps.logic.reactor.core.RuleMatchEx +import jetbrains.mps.logic.reactor.program.Rule import jetbrains.mps.logic.reactor.util.Id import java.util.* @@ -103,6 +104,23 @@ internal class ExecutionQueue( return currentMatches } + /** + * 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 { + // Place to try activating candidate rule is: + // either according to the ordering between rules. + // or as the last one, after all existing activations + + val placeToInsertFound = beforeChunk is MatchJournal.MatchChunk + && ruleOrdering.isEarlierThan(candidateRule, beforeChunk.match.rule()) + val childChunksEnded = !beforeChunk.isDescendantOf(parentChunk.id) + + return (childChunksEnded || placeToInsertFound) + } + // todo: do need to reactivate only the main, matching~activating match? // (i.e. don't reactivate additional, inactive heads that only completed the match?)