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

commonMain.it.unibo.tuprolog.solve.concurrent.ConcurrentResolutionHandle.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

import it.unibo.tuprolog.core.Struct
import it.unibo.tuprolog.solve.Solution
import it.unibo.tuprolog.solve.SolveOptions
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.cancel
import kotlinx.coroutines.channels.SendChannel

data class ConcurrentResolutionHandle(
    val solveOptions: SolveOptions,
    val solutionChannel: SendChannel,
    val solutionCounter: AtomicInt = AtomicInt.zero()
) {

    @OptIn(ExperimentalCoroutinesApi::class)
    fun terminateResolution(resolutionScope: CoroutineScope) {
        if (!solutionChannel.isClosedForSend) {
            solutionChannel.close()
        }
        resolutionScope.cancel("Solution limit has been reached: ${solveOptions.limit}")
        closeExecution()
    }

    @OptIn(ExperimentalCoroutinesApi::class)
    suspend fun publishSolutionAndTerminateResolutionIfNeed(
        solution: Solution,
        resolutionScope: CoroutineScope
    ): Boolean {
        if (solutionChannel.isClosedForSend) return false
        solutionChannel.send(solution)
        if (!solution.isNo && solutionCounter.incAndGet() >= solveOptions.limit && solveOptions.isLimited) {
            terminateResolution(resolutionScope)
        }
        return true
    }

    @OptIn(ExperimentalCoroutinesApi::class)
    val isSolutionChannelClosed: Boolean
        get() = solutionChannel.isClosedForSend

    suspend fun publishNoSolution(goal: Struct) {
        solutionChannel.send(Solution.no(goal))
    }

    @OptIn(ExperimentalCoroutinesApi::class)
    suspend fun closeSolutionChannelWithNoSolutionIfNeeded(goal: Struct): Boolean {
        if (!isSolutionChannelClosed) {
            if (solutionCounter.value == 0) {
                publishNoSolution(goal)
            }
            return solutionChannel.close()
        }
        return false
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy