Coverage Summary for Class: State (it.unibo.tuprolog.argumentation.core.engine.fsm)

Class Class, % Method, % Branch, % Line, % Instruction, %
State 100% (1/1) 66.7% (2/3) 50% (1/2) 66.7% (2/3) 31.2% (5/16)


 // Forked from 2p-kt's solve-prolog 3.0.2 (Apache License 2.0): see README.md in this package
 package it.unibo.tuprolog.argumentation.core.engine.fsm
 
 import it.unibo.tuprolog.argumentation.core.engine.PrologExecutionContext
 import kotlin.js.JsName
 
 /**
  * One location of the `:solve-prolog` finite-state machine: an explicit, inspectable representation of "where
  * resolution currently is", carrying the [PrologExecutionContext] it operates on.
  *
  * The nine concrete states -- `StateGoalSelection`, `StatePrimitiveSelection`, `StatePrimitiveExecution`,
  * `StateRuleSelection`, `StateRuleExecution`, `StateBacktracking`, `StateException`, `StateEnd` and `StateHalt`
  * (plus a bootstrap `StateInit`) -- correspond one-to-one to the nine "locations" of the formal model in
  * Ciatto's 2021 paper "Formal Modelling of a Prolog Solver as a State Machine", which traces the approach back
  * to Piancastelli's original state-machine design for tuProlog; see the project's "state-machine" explanation
  * page for the full walk-through of every transition and why cut/catch/backtracking are implemented the way
  * they are. [next] computes the successor state as a pure function of [context]; a [it.unibo.tuprolog.argumentation.core.engine.SolutionIterator]
  * drives this loop and turns every visit to an [EndState] ([isEndState]) into a [it.unibo.tuprolog.solve.Solution].
  *
  * Modelling a resolution step as a value (rather than as a stack frame of host-language recursion) is what
  * allows a step to be paused, resumed, inspected or hijacked (as the `MutableSolutionIterator` of tuProlog's classic solver)
  * without unwinding or rebuilding a JVM/JS call stack, and sidesteps host stack-depth limits for deeply
  * recursive Prolog programs, since the "call stack" here is the [PrologExecutionContext] parent chain --
  * ordinary heap data, not native stack frames.
  */
 interface State {
     /** Whether this state is a terminal one for the current resolution step, i.e. an [EndState]. */
     @JsName("isEndState")
     val isEndState: Boolean
         get() = false
 
     /** This state as an [EndState], or `null` if [isEndState] is `false`. */
     @JsName("asEndState")
     fun asEndState(): EndState? = null
 
     /** This state as an [EndState].
      * @throws ClassCastException if [isEndState] is `false`.
      */
     @JsName("castToEndState")
     fun castToEndState(): EndState = asEndState() ?: throw ClassCastException("Cannot cast $this to ${EndState::class.simpleName}")
 
     /** The execution context this state operates on. */
     @JsName("context")
     val context: PrologExecutionContext
 
     /** Computes the state the machine transitions into from here -- a pure function of [context]. */
     @JsName("next")
     fun next(): State
 }