/** * 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) ) }