Package-level declarations
Types
A tiny, multiplatform abstraction over a mutable integer counter that multiple coroutines may update concurrently. ConcurrentResolutionHandle uses it as ConcurrentResolutionHandle.solutionCounter, to count how many solutions have been produced so far by the many coroutines exploring a goal's search tree in parallel, so that resolution can be stopped once it.unibo.tuprolog.solve.SolveOptions.limit is reached.
The Kotlin/JS AtomicInt implementation: a plain, non-atomic var. Safe only because JS coroutines are cooperatively scheduled on a single thread and never preempted mid-operation, not a general-purpose atomic counter.
The JVM AtomicInt implementation, delegating every operation to a java.util.concurrent.atomic.AtomicInteger.
The ExecutionContext implementation for :solve-concurrent: an immutable node of the resolution tree that it.unibo.tuprolog.solve.concurrent.fsm.States carry around and derive from, chained back to the root goal via parent. Each concurrently-running coroutine spawned while resolving a goal (see ConcurrentSolver) owns its own chain of these, so no synchronization is needed to read pathToRoot/logicStackTrace from within a single branch -- only knowledge-base mutation shared across branches (see ConcurrentSolver's concurrency caveat) is unsynchronized.
The piece of shared, cross-coroutine state that lets the many concurrently-running branches of a single :solve-concurrent resolution (see ConcurrentSolver.solveConcurrently) agree on a single solutionChannel to publish Solutions to, and on when enough solutions have been produced to stop exploring the search tree altogether.
A Solver whose resolution strategy explores the alternatives of a goal's search tree -- matching clauses at a choice point, the branches of a disjunction, the several solutions of a backtracking primitive -- concurrently, as independent Kotlin coroutines, rather than one at a time as :solve-classic/:solve-streams do. Obtained via ConcurrentSolverFactory or, generically, via it.unibo.tuprolog.solve.Solver.concurrent.
The SolverFactory for :solve-concurrent, backing it.unibo.tuprolog.solve.Solver.concurrent: every Solver/MutableSolver it produces is a ConcurrentSolver that resolves goals by running the alternatives of the search tree (matching clauses, disjunction branches, backtracking primitive solutions) as concurrent Kotlin coroutines rather than one at a time -- see ConcurrentSolver for the resulting caveats around solution ordering and concurrent knowledge-base mutation.
Functions
Blocks (on the JVM) until the thread pools backing createScope/backgroundScope have finished executing every pending coroutine, then shuts them down. Called once at the end of ConcurrentResolutionHandle.terminateResolution, after a resolution's solution limit has been reached, to make sure no orphaned coroutine keeps running (or holding threads) past that point.
Blocks (on the JVM) until the thread pools backing createScope/backgroundScope have finished executing every pending coroutine, then shuts them down. Called once at the end of ConcurrentResolutionHandle.terminateResolution, after a resolution's solution limit has been reached, to make sure no orphaned coroutine keeps running (or holding threads) past that point.
Blocks (on the JVM) until the thread pools backing createScope/backgroundScope have finished executing every pending coroutine, then shuts them down. Called once at the end of ConcurrentResolutionHandle.terminateResolution, after a resolution's solution limit has been reached, to make sure no orphaned coroutine keeps running (or holding threads) past that point.
Creates a fresh, platform-specific CoroutineScope to run one :solve-concurrent resolution in -- one call per ConcurrentSolver.solveConcurrently invocation, so that cancelling the scope (e.g. once it.unibo.tuprolog.solve.SolveOptions.limit is hit, see ConcurrentResolutionHandle.terminateResolution) only affects the coroutines spawned for that particular resolution.
Creates a fresh, platform-specific CoroutineScope to run one :solve-concurrent resolution in -- one call per ConcurrentSolver.solveConcurrently invocation, so that cancelling the scope (e.g. once it.unibo.tuprolog.solve.SolveOptions.limit is hit, see ConcurrentResolutionHandle.terminateResolution) only affects the coroutines spawned for that particular resolution.
Creates a fresh, platform-specific CoroutineScope to run one :solve-concurrent resolution in -- one call per ConcurrentSolver.solveConcurrently invocation, so that cancelling the scope (e.g. once it.unibo.tuprolog.solve.SolveOptions.limit is hit, see ConcurrentResolutionHandle.terminateResolution) only affects the coroutines spawned for that particular resolution.
Converts this ReceiveChannel into a (blocking) Sequence, draining the channel from a coroutine launched on coroutineScope. This is what lets ConcurrentSolver implement the synchronous it.unibo.tuprolog.solve.Solver.solve contract in terms of the channel-based ConcurrentSolver.solveConcurrently: elements produced by concurrently running branches of the search tree are funnelled through a queue and replayed, one at a time, to whichever thread iterates the returned Sequence.
Converts this ReceiveChannel into a (blocking) Sequence, draining the channel from a coroutine launched on coroutineScope. This is what lets ConcurrentSolver implement the synchronous it.unibo.tuprolog.solve.Solver.solve contract in terms of the channel-based ConcurrentSolver.solveConcurrently: elements produced by concurrently running branches of the search tree are funnelled through a queue and replayed, one at a time, to whichever thread iterates the returned Sequence.
Converts this ReceiveChannel into a (blocking) Sequence, draining the channel from a coroutine launched on coroutineScope. This is what lets ConcurrentSolver implement the synchronous it.unibo.tuprolog.solve.Solver.solve contract in terms of the channel-based ConcurrentSolver.solveConcurrently: elements produced by concurrently running branches of the search tree are funnelled through a queue and replayed, one at a time, to whichever thread iterates the returned Sequence.