package prolog.builtins import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertInstanceOf import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test import prolog.ast.arithmetic.Integer import prolog.ast.terms.AnonymousVariable import prolog.ast.terms.Atom import prolog.ast.terms.Structure import prolog.ast.terms.Variable class AnalysingAndConstructionOperatorsTests { @Test fun `functor(foo, foo, 0)`() { val functor = Functor(Atom("foo"), Atom("foo"), Integer(0)) val result = functor.satisfy(emptyMap()).toList() assertEquals(1, result.size, "Expected 1 result") assertTrue(result[0].isSuccess, "Expected success") assertTrue(result[0].getOrNull()!!.isEmpty(), "Expected empty substitutions") } @Test fun `functor(foo(X), foo, Y)`() { val functor = Functor( Structure(Atom("foo"), listOf(Variable("X"))), Atom("foo"), Variable("Y") ) val result = functor.satisfy(emptyMap()).toList() assertEquals(1, result.size, "Expected 1 result") assertTrue(result[0].isSuccess, "Expected success") val subs = result[0].getOrNull()!! assertEquals(1, subs.size, "Expected 1 substitution") assertEquals(Integer(1), subs[Variable("Y")]) } @Test fun `functor(foo, X, Y)`() { val atom = Atom("foo") val functor = Functor(atom, Variable("X"), Variable("Y")) val result = functor.satisfy(emptyMap()).toList() assertEquals(1, result.size, "Expected 1 result") assertTrue(result[0].isSuccess, "Expected success") val subs = result[0].getOrNull()!! assertEquals(2, subs.size, "Expected 2 substitutions") assertEquals(atom.functor.name, subs[Variable("X")]) assertEquals(atom.functor.arity, subs[Variable("Y")]) } @Test fun `functor(X, foo, 1)`() { val functor = Functor(Variable("X"), Atom("foo"), Integer(1)) val result = functor.satisfy(emptyMap()).toList() assertEquals(1, result.size, "Expected 1 result") assertTrue(result[0].isSuccess, "Expected success") val subs = result[0].getOrNull()!! assertEquals(1, subs.size, "Expected 1 substitution") assertInstanceOf(Structure::class.java, subs[Variable("X")]) val structure = subs[Variable("X")] as Structure assertEquals(Atom("foo"), structure.name) assertEquals(1, structure.arguments.size) assertInstanceOf(AnonymousVariable::class.java, structure.arguments[0]) } @Test fun `functor(foo(a), foo, 0)`() { val functor = Functor(Structure(Atom("foo"), listOf(Atom("a"))), Atom("foo"), Integer(0)) val result = functor.satisfy(emptyMap()).toList() assertTrue(result.isEmpty(), "Expected no results") } @Test fun `functor(foo(X), foo, 0)`() { val functor = Functor(Structure(Atom("foo"), listOf(Variable("X"))), Atom("foo"), Integer(0)) val result = functor.satisfy(emptyMap()).toList() assertTrue(result.isEmpty(), "Expected no results") } }