commonMain.it.unibo.tuprolog.collections.rete.generic.AbstractIntermediateReteNode.kt Maven / Gradle / Ivy
package it.unibo.tuprolog.collections.rete.generic
import it.unibo.tuprolog.core.Clause
/** A non-leaf Rete Node */
internal abstract class AbstractIntermediateReteNode(
override val children: MutableMap> = mutableMapOf(),
) : AbstractReteNode(children) {
override val indexedElements: Sequence
get() = children.asSequence().flatMap { it.value.indexedElements }
/** Selects correct children, according to [element], onto which to propagate received method calls */
protected abstract fun selectChildren(element: E): Sequence?>
override fun get(element: E): Sequence = selectChildren(element).flatMap { it?.get(element) ?: emptySequence() }
override fun removeAll(element: E): Sequence =
selectChildren(element).toList().flatMap {
it?.removeAll(element)?.toList() ?: emptyList()
}.asSequence()
/** Retrieves from receiver map those values of [ChildNodeType] that have a key respecting [keyFilter] */
protected fun MutableMap>.retrieve(
keyFilter: (K) -> Boolean,
typeChecker: (ReteNode<*, E>) -> Boolean,
caster: (ReteNode<*, E>) -> ChildNodeType,
): Sequence =
filterValues(typeChecker)
.filterKeys(keyFilter)
.values
.asSequence()
.map(caster)
/**
* A [Sequence.fold] function that stops when accumulated operation results' count becomes greater or equal to [limit];
*
* if negative [limit] this behaves actually like normal [Sequence.fold]
*/
protected inline fun > Sequence.foldWithLimit(
initial: R,
limit: Int,
operation: (acc: R, T) -> R,
) = if (limit < 0) {
fold(initial, operation)
} else {
fold(initial) { accumulator, element ->
if (accumulator.count() < limit) {
operation(accumulator, element)
} else {
return@foldWithLimit accumulator
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy