commonMain.it.unibo.tuprolog.solve.solver.fsm.impl.AbstractTimedState.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of solve-streams-jvm Show documentation
Show all versions of solve-streams-jvm Show documentation
Experimental, functional-programming-based implementation of Prolog's SLDNF resolution principle
package it.unibo.tuprolog.solve.solver.fsm.impl
import it.unibo.tuprolog.solve.ExecutionContext
import it.unibo.tuprolog.solve.TimeDuration
import it.unibo.tuprolog.solve.TimeInstant
import it.unibo.tuprolog.solve.currentTimeInstant
import it.unibo.tuprolog.solve.exception.TimeOutException
import it.unibo.tuprolog.solve.primitive.Solve
import it.unibo.tuprolog.solve.primitive.Solve.Response
import it.unibo.tuprolog.solve.solver.fsm.AbstractState
import it.unibo.tuprolog.solve.solver.fsm.IntermediateState
import it.unibo.tuprolog.solve.solver.fsm.State
import it.unibo.tuprolog.solve.solver.fsm.TimedState
/**
* Base class for all States that should have a timed behaviour
*
* @author Enrico
*/
internal abstract class AbstractTimedState(
/** The [Solve.Request] that guides the State behaviour towards [Response]s */
override val solve: Solve.Request
) : AbstractState(solve), IntermediateState, TimedState {
/** Internal cached currentTime at first behave() call, enabling identical re-execution of that state */
private val stateCurrentTime by lazy { currentTimeInstant() }
override fun behave(): Sequence = when {
solve.executionMaxDuration == TimeDuration.MAX_VALUE -> behaveTimed() // optimized without check, when maxDuration is infinite
timeIsOver(stateCurrentTime - solve.requestIssuingInstant, solve.executionMaxDuration) ->
sequenceOf(statEndHaltTimeout())
else -> behaveTimed()
}
/** Called only if executionTimeout has not been reached yet, and computation should go on */
protected abstract fun behaveTimed(): Sequence
/** A function to check if currently the timeout has expired and return the halt state if yes,
* the provided [toYieldState] otherwise*/
protected fun IntermediateState.ifTimeIsNotOver(toYieldState: State): State = when {
timeIsOver(currentTimeInstant() - solve.requestIssuingInstant, solve.executionMaxDuration) ->
statEndHaltTimeout()
else -> toYieldState
}
override fun getCurrentTime(): TimeInstant = stateCurrentTime
/** A function to check if time for execution has ended */
private fun timeIsOver(currentDuration: TimeDuration, maxDuration: TimeDuration) =
currentDuration >= maxDuration
override fun toString(): String = "${this::class} with $solve"
companion object {
/** An utility function to create the end Halt state to be returned upon timeout expiry */
private fun IntermediateState.statEndHaltTimeout(): State =
stateEndHalt(
TimeOutException(
"Given time for `${solve.query}` computation (${solve.executionMaxDuration}) wasn't enough for completion",
context = solve.context,
exceededDuration = solve.executionMaxDuration
)
)
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy