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

commonMain.it.unibo.tuprolog.solve.concurrent.fsm.StateException.kt Maven / Gradle / Ivy

Go to download

Experimental, state-machine-based implementation of an OR-Concurrent, Prolog-like logic solver, based on Kotlin coroutines

There is a newer version: 1.0.4
Show newest version
package it.unibo.tuprolog.solve.concurrent.fsm

import it.unibo.tuprolog.core.Struct
import it.unibo.tuprolog.core.Substitution
import it.unibo.tuprolog.core.Term
import it.unibo.tuprolog.solve.concurrent.ConcurrentExecutionContext
import it.unibo.tuprolog.solve.concurrent.stdlib.rule.Catch
import it.unibo.tuprolog.solve.exception.LogicError
import it.unibo.tuprolog.solve.exception.ResolutionException
import it.unibo.tuprolog.solve.exception.error.MessageError
import it.unibo.tuprolog.solve.exception.error.SystemError
import it.unibo.tuprolog.unify.Unificator.Companion.mguWith
import it.unibo.tuprolog.utils.plus

data class StateException(
    override val exception: ResolutionException,
    override val context: ConcurrentExecutionContext
) : ExceptionalState {

    private fun Struct.isCatch(): Boolean =
        arity == 3 && functor == Catch.functor

    private fun LogicError.getExceptionContent(): Term {
        return when (this) {
            is MessageError -> content
            else -> errorStruct
        }
    }

    private fun ResolutionException.toPublicException(): ResolutionException =
        when (this) {
            is MessageError -> SystemError.forUncaughtError(this)
            else -> this
        }

    private val finalState: EndState
        get() = StateHalt(
            exception.toPublicException(),
            context.copy(step = nextStep())
        )

    private val handleExceptionInParentContext: StateException
        get() = StateException(
            exception,
            context.parent!!.copy(step = nextStep())
        )

    private fun handleStruct(catchGoal: Struct, error: LogicError): State =
        when {
            catchGoal.isCatch() -> {
                val catcher = catchGoal[1] mguWith error.getExceptionContent()
                handleCatch(catchGoal, catcher)
            }
            context.isRoot -> finalState
            else -> handleExceptionInParentContext
        }

    private fun handleCatch(catchGoal: Struct, catcher: Substitution) =
        when {
            catcher.isSuccess -> {
                val newSubstitution =
                    (context.substitution + catcher).filter(context.interestingVariables)
                val subGoals = catchGoal[2][newSubstitution]
                val newGoals = subGoals.toGoals() + context.goals.next

                StateGoalSelection(
                    context.copy(
                        goals = newGoals,
                        rule = null,
                        primitive = null,
                        substitution = newSubstitution.castToUnifier(),
                        step = nextStep()
                    )
                )
            }
            context.isRoot -> finalState
            else -> handleExceptionInParentContext
        }

    override fun next(): Iterable {
        return listOf(
            when (exception) {
                is LogicError -> {
                    val catchGoal = context.currentGoal!!
                    when {
                        catchGoal.isStruct -> handleStruct(catchGoal.castToStruct(), exception)
                        context.isRoot -> finalState
                        else -> handleExceptionInParentContext
                    }
                }
                else -> finalState
            }
        )
    }

    override fun clone(context: ConcurrentExecutionContext): State = copy(exception = exception, context = context)
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy