commonMain.it.unibo.tuprolog.solve.fsm.Utils.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of solve-classic-metadata Show documentation
Show all versions of solve-classic-metadata Show documentation
Stable, state-machine-based implementation of Prolog's SLDNF resolution principle
package it.unibo.tuprolog.solve.fsm
import it.unibo.tuprolog.core.Clause
import it.unibo.tuprolog.core.Rule
import it.unibo.tuprolog.core.Struct
import it.unibo.tuprolog.core.Term
import it.unibo.tuprolog.core.Tuple
import it.unibo.tuprolog.core.Var
import it.unibo.tuprolog.solve.ClassicExecutionContext
import it.unibo.tuprolog.solve.Signature
import it.unibo.tuprolog.solve.appendPrimitives
import it.unibo.tuprolog.solve.appendRules
import it.unibo.tuprolog.solve.primitive.Solve
import it.unibo.tuprolog.utils.Cursor
import it.unibo.tuprolog.utils.cursor
fun Sequence.ensureRules(): Cursor =
@Suppress("USELESS_CAST")
map { require(it is Rule); it as Rule }.cursor()
fun Term.unfoldGoals(): Sequence =
when (this) {
is Tuple -> toSequence().flatMap { it.unfoldGoals() }
else -> sequenceOf(this)
}
fun Term.toGoals(): Cursor =
unfoldGoals().map {
when (it) {
is Var -> Struct.of("call", it)
else -> it
}
}.cursor()
fun ClassicExecutionContext.createTempChild(inferProcedureFromGoals: Boolean = true): ClassicExecutionContext {
val currentGoal = this.currentGoal as Struct
return copy(
goals = currentGoal.toGoals(),
procedure = if (inferProcedureFromGoals) currentGoal else procedure,
parent = this,
depth = depth + 1,
step = step + 1
)
}
fun ClassicExecutionContext.appendRulesAndChoicePoints(rules: Cursor): ClassicExecutionContext {
val newChoicePointContext = if (rules.hasNext) {
choicePoints.appendRules(rules.next, this)
} else {
choicePoints.appendRules(Cursor.empty(), this)
}
return copy(
rules = rules,
choicePoints = newChoicePointContext
)
}
fun ClassicExecutionContext.appendPrimitivesAndChoicePoints(primitiveExecutions: Cursor): ClassicExecutionContext {
val newChoicePointContext = if (primitiveExecutions.hasNext) {
choicePoints.appendPrimitives(primitiveExecutions.next, this)
} else {
choicePoints.appendPrimitives(Cursor.empty(), this)
}
return copy(
primitives = primitiveExecutions,
choicePoints = newChoicePointContext
)
}
fun ClassicExecutionContext.createChildAppendingRulesAndChoicePoints(
rules: Cursor,
inferProcedureFromGoals: Boolean = true
): ClassicExecutionContext {
val tempExecutionContext = createTempChild(inferProcedureFromGoals)
return tempExecutionContext.appendRulesAndChoicePoints(rules)
}
fun ClassicExecutionContext.createChildAppendingPrimitivesAndChoicePoints(
primitiveExecutions: Cursor,
inferProcedureFromGoals: Boolean = true
): ClassicExecutionContext {
val tempExecutionContext = createTempChild(inferProcedureFromGoals)
return tempExecutionContext.appendPrimitivesAndChoicePoints(primitiveExecutions)
}
// TODO Giovanni's review needed!! with Git > Show History
fun ClassicExecutionContext.toRequest(
goal: Struct,
signature: Signature
): Solve.Request =
Solve.Request(
signature,
goal.argsList,
copy(
libraries = libraries,
flags = flags,
staticKb = staticKb,
dynamicKb = dynamicKb,
inputChannels = inputChannels,
outputChannels = outputChannels,
substitution = substitution
),
executionMaxDuration = maxDuration
)