All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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