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

commonMain.it.unibo.tuprolog.solve.function.AbstractEvaluator.kt Maven / Gradle / Ivy

package it.unibo.tuprolog.solve.function

import it.unibo.tuprolog.core.Atom
import it.unibo.tuprolog.core.Indicator
import it.unibo.tuprolog.core.Struct
import it.unibo.tuprolog.core.Term
import it.unibo.tuprolog.core.TermVisitor
import it.unibo.tuprolog.solve.ExecutionContext
import it.unibo.tuprolog.solve.extractSignature
import it.unibo.tuprolog.solve.primitive.Solve

abstract class AbstractEvaluator(
    protected val request: Solve.Request,
    protected val index: Int?
) : TermVisitor {

    /** Shorthand to access context loaded functions */
    @Suppress("MemberVisibilityCanBePrivate")
    protected val loadedFunctions by lazy { request.context.libraries.functions }

    @Suppress("UNCHECKED_CAST")
    private inline fun casting(f: () -> Term): T = f() as T

    override fun defaultValue(term: Term): T = casting { term }

    override fun visit(term: Term): T =
        super.visit(term.apply { staticCheck() })

    override fun visitAtom(term: Atom): T = casting {
        visitStruct(term)
    }

    override fun visitIndicator(term: Indicator): T = casting {
        visitStruct(term)
    }

    override fun visitStruct(term: Struct): T = casting {
        val functionSignature = term.extractSignature()
        loadedFunctions[functionSignature]?.let {
            it(
                Compute.Request(
                    functionSignature,
                    term.argsSequence.map { it.accept(this).apply { dynamicCheck(term) } }.toList(),
                    request.context
                )
            ).result
        } ?: unevaluable(term)
    }

    protected open fun unevaluable(struct: Struct): T = casting { struct }

    /**
     * Template method to implement static checks, i.e. those checks that can be made before evaluating sub-expressions
     *
     * This is a stub implementation, that does nothing
     */
    protected open fun Term.staticCheck(): Unit = Unit

    /**
     * Template method to implement dynamic checks, i.e. those checks that must be made after sub-expression evaluation, on its result
     *
     * This is a stub implementation, that does nothing
     */
    protected open fun Term.dynamicCheck(enclosingTerm: Struct): Unit = Unit
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy