Package-level declarations
Types
Common base of every :solve-concurrent State: wraps computeNext with a shared timeout check, so no concrete state has to implement SolveOptions.timeout handling itself.
A State carrying a ResolutionException: StateException (still being handled/propagated) or StateHalt (unrecoverable, terminal).
One location of the :solve-concurrent finite-state machine: an explicit, inspectable representation of "where resolution currently is" along one branch of the search tree, carrying the ConcurrentExecutionContext it operates on. Mirrors :solve-classic's own State (see that module's "state-machine" explanation for the formal model this is based on: StateGoalSelection, StatePrimitiveSelection, StatePrimitiveExecution, StateRuleSelection, StateRuleExecution, StateException, StateEnd and StateHalt).
The EndState a branch reaches upon successfully proving the root ConcurrentExecutionContext.query (solution is a Solution.Yes) or exhausting every alternative without proving it (solution is a Solution.No).
The state a branch transitions into whenever resolution raises a ResolutionException: for a LogicError, it looks for an enclosing catch/3 goal along ConcurrentExecutionContext.pathToRoot that unifies with the error, and either resumes the branch inside the catcher's recovery goal (StateGoalSelection), or propagates the exception one level up towards the parent context (recursing into another StateException); any other ResolutionException (or a LogicError that reaches an unhandled ConcurrentExecutionContext.isRoot) ends the branch in a StateHalt.
"Goal Selection": the entry point of every resolution step, deciding what to do with ConcurrentExecutionContext.goals. If the current context's goals are exhausted, either the whole branch succeeded (root context: moves to a successful StateEnd) or control returns to the parent context to resolve its remaining goals; otherwise, the current substitution is applied to the remaining goals and the branch moves on to StatePrimitiveSelection to resolve the next one.
The terminal, unrecoverable EndState a branch reaches when exception could not be handled by any enclosing catch/3 (or was a timeout, see AbstractState): solution is a Solution.Halt. Reaching a StateHalt does not, by itself, stop sibling branches of the search tree -- it is up to the coroutine driving this branch (and, ultimately, whoever consumes the resolution's solution channel) to decide whether a halted branch should abort the whole resolution.
"Primitive Execution": applies the outcome of one Solve.Response produced by a primitive (see StatePrimitiveSelection) to the branch's context -- a successful response's side effects and substitution are merged in and resolution continues with StateGoalSelection on the remaining goals; a failed response (Solution.No) ends this branch as a failure; a halting response, or an uncaught ResolutionException thrown while computing it, moves to StateException.
"Primitive Selection": inspects ConcurrentExecutionContext.currentGoal and either raises an it.unibo.tuprolog.solve.exception.error.InstantiationError/it.unibo.tuprolog.solve.exception.error.TypeError (goal is a variable or not callable), invokes the matching it.unibo.tuprolog.solve.primitive.Primitive if one is registered for the goal's signature in it.unibo.tuprolog.solve.library.Runtime, or falls through to StateRuleSelection otherwise (the goal is a user-/library-defined predicate).
"Rule Execution": unifies ConcurrentExecutionContext.currentGoal against the head of the clause selected by StateRuleSelection (ConcurrentExecutionContext.rule); on success, moves to StateGoalSelection to resolve the (substituted) clause body prepended to the remaining goals, otherwise this branch ends as a failure.
"Rule Selection", the clause-resolution counterpart of StatePrimitiveSelection: true/false succeed/fail without touching the knowledge base at all; goals that don't exist anywhere end the branch as a failure or move it to StateException, depending on the Unknown flag (error/fail/warning); otherwise every clause in the static/dynamic knowledge bases and libraries whose head matches the current goal is freshCopy()'d (to rename variables apart) and turned into its own StateRuleExecution.
Functions
Creates a new ConcurrentExecutionContext descending into ConcurrentExecutionContext.currentGoal as a sub-goal: the new context's ConcurrentExecutionContext.goals become just that goal, its ConcurrentExecutionContext.parent is this context, and its ConcurrentExecutionContext.depth/ ConcurrentExecutionContext.step are incremented by one. Used by StatePrimitiveSelection/StateRuleSelection when a goal is not last-call-optimizable, so it gets its own stack frame to backtrack into.
Same as createChild, additionally attaching rule as the clause StateRuleExecution will unify against.
Same as createChild, but keeps ConcurrentExecutionContext.parent unchanged instead of pointing it at this context -- used for the last-call-optimized case (see ConcurrentExecutionContext and LastCallOptimization), reusing the current stack frame rather than growing the chain of ConcurrentExecutionContext.parents.
Same as replaceWithChild, additionally attaching rule as the clause StateRuleExecution will unify against.
Converts this term into the Cursor of goals ConcurrentExecutionContext.goals is built from: unfoldGoals flattens conjunctions, and every variable goal is wrapped into call(X) so that StatePrimitiveSelection always sees a callable Struct.
Builds the Solve.Request a it.unibo.tuprolog.solve.primitive.Primitive matching signature is invoked with, for goal.
Flattens this term into a Sequence of its top-level conjuncts, recursively unfolding nested tuples (,/2).