Add ReactivateBlock in Rete Matcher to correctly handle reactivation. Fixes MPSCR-17

This commit is contained in:
Grigorii Kirgizov 2019-11-19 14:38:20 +03:00
parent 32a1ef77c9
commit f96155496f
1 changed files with 25 additions and 3 deletions

View File

@ -291,6 +291,24 @@ internal class ReteRuleMatcherImpl(private var ruleLookup: RuleLookup,
occurrence !== occ && from.containsOccurrence(occ) // reference neq!
}
inner class ReactivateBlock (occurrence: Occurrence, val from: Layer) : DelayedBlock(occurrence) {
override fun proto(): Layer? = null
override fun complete(droppedFootprint: Footprint?, sink: (ReteNode) -> Unit) {
if (droppedFootprint?.contains(occurrence.identity) ?: false) return
for (n in from.allNodes(droppedFootprint)) {
if (n.containsOccurrence(occurrence)) {
sink(n)
}
}
}
override fun containsOccurrence(occ: Occurrence): Boolean =
occurrence === occ || from.containsOccurrence(occ) // reference eq!
}
/**
* Collection of [Layer] instances.
* The new layers are prepended to the [layers] list.
@ -315,14 +333,18 @@ internal class ReteRuleMatcherImpl(private var ruleLookup: RuleLookup,
var lastLayer: Layer? = null
for (currLayer in layers) {
if (!currLayer.final) {
// `!reactivated` is to avoid adding new IntroBlock for InitialNode-s on reactivated
if (!currLayer.final && !reactivated) {
newLayers.add(Layer(
currLayer.vacancies - 1,
IntroBlock(occurrence, headPosMask, currLayer),
lastLayer))
} else if (reactivated) {
newLayers.add(currLayer)
} else if (currLayer.final && reactivated) {
newLayers.add(Layer(
currLayer.vacancies, // == 0
ReactivateBlock(occurrence, currLayer),
lastLayer))
}
lastLayer = currLayer