/** * 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.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("=", term1, term2) { override fun satisfy(subs: Substitutions): Answers = sequence { val t1 = applySubstitution(term1, subs) val t2 = applySubstitution(term2, subs) yieldAll(unifyLazy(t1, t2, emptyMap())) } override fun applySubstitution(subs: Substitutions): Unify = Unify( applySubstitution(term1, subs), applySubstitution(term2, subs) ) } class NotUnify(private val term1: Term, private val term2: Term) : Not(Unify(term1, term2)) { override fun toString(): String = "($term1 \\= $term2)" } class Equivalent(private val term1: Term, private val term2: Term) : Operator("==", term1, term2) { override fun satisfy(subs: Substitutions): Answers = sequence { val t1 = applySubstitution(term1, subs) val t2 = applySubstitution(term2, subs) if (equivalent(t1, t2, emptyMap())) { 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) : Not(Equivalent(term1, term2)) { override fun toString(): String = "($term1 \\== $term2)" }