package prolog.builtins import org.junit.jupiter.api.Assertions.assertFalse import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test import prolog.ast.terms.Atom import prolog.ast.terms.Structure import prolog.ast.terms.Variable import kotlin.test.assertEquals class VerificationBuiltinsTest { @Test fun unbound_variable_is_var() { val variable = Variable("X") assertTrue(variable(variable)) assertTrue(variable.alias().isEmpty) } @Test fun variable_bound_to_atom_is_not_var() { val variable = Variable("X") assertTrue(variable(variable)) val atom = Atom("a") variable.bind(atom) assertFalse(variable(variable)) assertEquals(atom, variable.alias().get()) } @Test fun variable_bound_to_compound_term_is_not_var() { val variable = Variable("X") assertTrue(variable(variable)) val structure = Structure(Atom("a"), listOf(Atom("b"))) variable.bind(structure) assertFalse(variable(variable)) assertEquals(structure, variable.alias().get()) } /** * ?- X = X, var(X). * true. */ @Test fun variable_bound_to_itself_is_var() { val variable = Variable("X") variable.bind(variable) assertTrue(variable(variable)) } /** * ?- X = Y, var(X). * X = Y. */ @Test fun variable_bound_to_another_variable_is_var() { val variable1 = Variable("X") val variable2 = Variable("Y") variable1.bind(variable2) assertTrue(variable(variable1)) assertEquals(variable2, variable1.alias().get()) } /** * ?- Y = a, X = Y, var(X). * false. */ @Test fun variable_bound_to_bound_variable_is_not_var() { val variable1 = Variable("X") val variable2 = Variable("Y") variable2.bind(Atom("a")) variable1.bind(variable2) assertFalse(variable(variable1)) } @Test fun atom_is_not_var() { val atom = Atom("a") assertFalse(variable(atom)) } @Test fun compound_term_is_not_var() { val structure = Structure(Atom("a"), listOf(Atom("b"))) assertFalse(variable(structure)) } @Test fun compound_term_with_var_is_not_var() { val structure = Structure(Atom("a"), listOf(Variable("X"))) assertFalse(variable(structure)) } @Test fun unbound_variable_is_not_nonvar() { val variable = Variable("X") assertFalse(nonvariable(variable)) } /** * ?- A = a, nonvar(A). * A = a. */ @Test fun variable_bound_to_atom_is_nonvar() { val variable = Variable("X") assertFalse(nonvariable(variable)) val atom = Atom("a") variable.bind(atom) assertTrue(nonvariable(variable)) assertEquals(atom, variable.alias().get()) } /** * ?- A = f(b), nonvar(A). * A = f(b). */ @Test fun variable_bound_to_compound_term_is_nonvar() { val variable = Variable("X") assertFalse(nonvariable(variable)) val structure = Structure(Atom("a"), listOf(Atom("b"))) variable.bind(structure) assertTrue(nonvariable(variable)) assertEquals(structure, variable.alias().get()) } /** * ?- X = X, nonvar(X). * false. */ @Test fun variable_bound_to_itself_is_not_nonvar() { val variable = Variable("X") variable.bind(variable) assertFalse(nonvariable(variable)) } /** * ?- X = Y, nonvar(X). * false. */ @Test fun variable_bound_to_another_variable_is_not_nonvar() { val variable1 = Variable("X") val variable2 = Variable("Y") variable1.bind(variable2) assertFalse(nonvariable(variable1)) } @Test fun atom_is_nonvar() { val atom = Atom("a") assertTrue(nonvariable(atom)) } @Test fun compound_term_is_nonvar() { val structure = Structure(Atom("a"), listOf(Atom("b"))) assertTrue(nonvariable(structure)) } @Test fun compound_term_with_var_is_nonvar() { val structure = Structure(Atom("a"), listOf(Variable("X"))) assertTrue(nonvariable(structure)) } @Test fun unbound_variable_is_not_compound() { val variable = Variable("X") assertFalse(compound(variable)) } /** * ?- A = a, compound(A). * false. */ @Test fun bound_variable_to_atom_is_not_compound() { val variable = Variable("X") val atom = Atom("a") variable.bind(atom) assertFalse(compound(variable)) } /** * ?- A = f(b), compound(A). * A = f(b). */ @Test fun bound_variable_to_compound_term_is_compound() { val variable = Variable("X") val structure = Structure(Atom("a"), listOf(Atom("b"))) variable.bind(structure) assertTrue(compound(variable)) } /** * ?- Y = f(b), X = Y, compound(X). * Y = X, X = f(b). */ @Test fun variable_bound_to_bound_variable_is_compound() { val variable1 = Variable("X") val variable2 = Variable("Y") val structure = Structure(Atom("a"), listOf(Atom("b"))) variable2.bind(structure) variable1.bind(variable2) assertTrue(compound(variable1)) assertEquals(structure, variable2.alias().get()) assertEquals(variable2, variable1.alias().get()) } @Test fun atom_is_not_compound() { val atom = Atom("a") assertFalse(compound(atom)) } @Test fun compound_term_is_compound() { val structure = Structure(Atom("a"), listOf(Atom("b"))) assertTrue(compound(structure)) } /** * ?- compound(a()). * true. */ @Test fun compound_term_with_no_arguments_is_compound() { val structure = Structure(Atom("a"), emptyList()) assertTrue(compound(structure)) } }