package prolog.builtins

import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.Test
import prolog.ast.terms.Atom
import prolog.ast.arithmetic.Integer
import prolog.ast.terms.Variable

class UnificationOperatorsTests {
    /**
     * ?- X == a.
     * false.
     */
    @Test
    fun equivalent_variable_and_atom() {
        val variable = Variable("X")
        val atom = Atom("a")

        val result = Equivalent(variable, atom).satisfy(emptyMap())

        assertFalse(result.any(), "Variable and atom should not be equivalent")
    }

    /**
     * ?- a == a.
     * true.
     */
    @Test
    fun equivalent_atom_and_atom() {
        val atom1 = Atom("a")
        val atom2 = Atom("a")

        val result = Equivalent(atom1, atom2).satisfy(emptyMap())

        assertTrue(result.any(), "Identical atoms should be equivalent")
        assertTrue(result.first().isSuccess, "Result should be successful")
        assertEquals(0, result.first().getOrNull()!!.size, "No substitutions should be made")
    }

    /**
     * ?- 1 + 2 == 3.
     * false.
     */
    @Test
    fun simple_addition_equivalence() {
        val addition = Add(Integer(1), Integer(2))
        val solution = Integer(3)

        val result = Equivalent(addition, solution).satisfy(emptyMap())

        assertFalse(result.any(), "Addition should be equivalent")
    }
}
