66 lines
2.2 KiB
Kotlin
66 lines
2.2 KiB
Kotlin
/**
|
|
* Comparison and Unification of Terms
|
|
*
|
|
* [SWI Prolog Documentation](https://www.swi-prolog.org/pldoc/man?section=compare)
|
|
*/
|
|
package prolog.builtins
|
|
|
|
import prolog.Answers
|
|
import prolog.Substitutions
|
|
import prolog.ast.terms.Atom
|
|
import prolog.ast.terms.Operator
|
|
import prolog.ast.terms.Term
|
|
import prolog.logic.applySubstitution
|
|
import prolog.logic.equivalent
|
|
import prolog.logic.unifyLazy
|
|
|
|
/**
|
|
* Unify Term1 with Term2. True if the unification succeeds.
|
|
*/
|
|
class Unify(private val term1: Term, private val term2: Term): Operator(Atom("="), term1, term2) {
|
|
override fun satisfy(subs: Substitutions): Answers = sequence {
|
|
val t1 = applySubstitution(term1, subs)
|
|
val t2 = applySubstitution(term2, subs)
|
|
|
|
yieldAll(unifyLazy(t1, t2, subs))
|
|
}
|
|
|
|
override fun applySubstitution(subs: Substitutions): Unify = Unify(
|
|
applySubstitution(term1, subs),
|
|
applySubstitution(term2, subs)
|
|
)
|
|
}
|
|
|
|
class NotUnify(private val term1: Term, private val term2: Term) : Operator(Atom("\\="), term1, term2) {
|
|
private val not = Not(Unify(term1, term2))
|
|
override fun satisfy(subs: Substitutions): Answers = not.satisfy(subs)
|
|
override fun applySubstitution(subs: Substitutions): NotUnify = NotUnify(
|
|
applySubstitution(term1, subs),
|
|
applySubstitution(term2, subs)
|
|
)
|
|
}
|
|
|
|
class Equivalent(private val term1: Term, private val term2: Term) : Operator(Atom("=="), term1, term2) {
|
|
override fun satisfy(subs: Substitutions): Answers = sequence {
|
|
val t1 = applySubstitution(term1, subs)
|
|
val t2 = applySubstitution(term2, subs)
|
|
|
|
if (equivalent(t1, t2, subs)) {
|
|
yield(Result.success(emptyMap()))
|
|
}
|
|
}
|
|
|
|
override fun applySubstitution(subs: Substitutions): Equivalent = Equivalent(
|
|
applySubstitution(term1, subs),
|
|
applySubstitution(term2, subs)
|
|
)
|
|
}
|
|
|
|
class NotEquivalent(private val term1: Term, private val term2: Term) : Operator(Atom("\\=="), term1, term2) {
|
|
private val not = Not(Equivalent(term1, term2))
|
|
override fun satisfy(subs: Substitutions): Answers = not.satisfy(subs)
|
|
override fun applySubstitution(subs: Substitutions): NotEquivalent = NotEquivalent(
|
|
applySubstitution(term1, subs),
|
|
applySubstitution(term2, subs)
|
|
)
|
|
}
|