Coverage Summary for Class: ClauseResolver (it.unibo.tuprolog.argumentation.core.engine.fsm)
| Class |
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
| ClauseResolver$Companion |
100%
(1/1)
|
100%
(2/2)
|
100%
(1/1)
|
100%
(11/11)
|
| Total |
100%
(1/1)
|
100%
(2/2)
|
100%
(1/1)
|
100%
(11/11)
|
package it.unibo.tuprolog.argumentation.core.engine.fsm
import it.unibo.tuprolog.argumentation.core.runtime.Arg2pUnificator
import it.unibo.tuprolog.core.Rule
import it.unibo.tuprolog.core.Substitution
import it.unibo.tuprolog.core.Term
import it.unibo.tuprolog.core.Var
import it.unibo.tuprolog.core.prepareForExecution
import it.unibo.tuprolog.unify.Unificator
/**
* The resolution of a goal with a clause: the bindings it gives the variables of the goal (those of the clause are
* renamed apart, and only occur in its body), and the body to execute in place of the goal, prepared for execution.
*/
internal class Resolution(
val goalBindings: Substitution.Unifier,
val body: Term,
) {
/** [substitution], the one of the resolution, extended with the bindings of the goal (see [extendedWith]) */
fun extend(substitution: Substitution.Unifier): Substitution.Unifier = substitution.extendedWith(goalBindings)
}
/** How the engine resolves a goal with one of the clauses selected for it (arg2p) */
internal interface ClauseResolver {
/** The resolution of [goal] with [rule], as stored in its theory; null if the head of [rule] does not unify with [goal] */
fun resolve(
rule: Rule,
goal: Term,
): Resolution?
companion object {
/**
* The resolver for the unificator of a resolution: the one of arg2p resolves the clauses as stored
* ([StoredClauseResolver]), any other one renamed ([RenamingClauseResolver])
*/
fun of(unificator: Unificator): ClauseResolver =
if (unificator === Arg2pUnificator) StoredClauseResolver else RenamingClauseResolver(unificator)
}
}
/**
* Resolution as in tuProlog, through any [unificator]: the clause renamed as a whole, its head unified with the goal
* (the head first, so that a variable of the clause meeting one of the goal is bound to it), its body prepared for
* execution and built with the unifier.
*/
internal class RenamingClauseResolver(
private val unificator: Unificator,
) : ClauseResolver {
override fun resolve(
rule: Rule,
goal: Term,
): Resolution? {
val renamed = rule.freshCopy()
val substitution = unificator.mgu(renamed.head, goal)
if (!substitution.isSuccess) return null
val unifier = substitution.castToUnifier()
val ruleVariables = HashSet<Var>().also { renamed.head.collectVariables(it) }
val goalBindings = unifier.filter { (variable, _) -> variable !in ruleVariables }.castToUnifier()
return Resolution(goalBindings, renamed.prepareForExecution(unifier).body[unifier])
}
}