package prolog.builtins import com.sun.source.tree.EmptyStatementTree import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test import prolog.ast.lists.List.Cons import prolog.ast.lists.List.Empty import prolog.ast.terms.Atom import prolog.ast.terms.Term import prolog.ast.terms.Variable class ListOperatorsTests { @Test fun `size empty list is 0`() { assertEquals(0, Empty.size.value, "Expected size of empty list to be 0") } @Test fun `size of singleton is 1`() { val list = Cons(Atom("a"), Empty) assertEquals(1, list.size.value, "Expected size of singleton list to be 1") } @Test fun `size of list with five elements is 5`() { val list = Cons(Atom("a"), Cons(Atom("b"), Cons(Atom("c"), Cons(Atom("d"), Cons(Atom("e"), Empty))))) assertEquals(5, list.size.value, "Expected size of list with five elements to be 5") } @Test fun `member(a, list of a)`() { val atom = Atom("a") val list = Cons(atom, Empty) val member = Member(atom, list) val result = member.satisfy(emptyMap()).toList() assertEquals(1, result.size, "Expected one solution") assertTrue(result[0].isSuccess, "Expected success") assertTrue(result[0].getOrNull()!!.isEmpty(), "Expected empty substitution map") } @Test fun `member should only check shallow`() { val list = Cons(Atom("a"), Cons(Cons(Atom("b"), Empty), Empty)) var result = Member(Atom("a"), list).satisfy(emptyMap()).toList() assertEquals(1, result.size, "Expected one solution") assertTrue(result[0].isSuccess, "Expected success") assertTrue(result[0].getOrNull()!!.isEmpty(), "Expected empty substitution map") result = Member(Atom("b"), list).satisfy(emptyMap()).toList() assertEquals(0, result.size, "Expected no solution") } @Test fun `member with variable in list`() { val atom = Atom("a") val variable = Variable("X") val list = Cons(variable, Empty) val member = Member(atom, list) val result = member.satisfy(emptyMap()).toList() assertEquals(1, result.size, "Expected one solution") assertTrue(result[0].isSuccess, "Expected success") assertEquals(atom, result[0].getOrNull()!![variable], "Expected variable to be unified with atom") } @Disabled("Not implemented yet") @Test fun `appended empty lists is an empty list`() { val append = Append(Empty, Empty, Empty) val result = append.satisfy(emptyMap()).toList() assertEquals(1, result.size, "Expected one solution") assertTrue(result[0].isSuccess, "Expected success") assertTrue(result[0].getOrNull()!!.isEmpty(), "Expected empty substitution map") } @Disabled("Not implemented yet") @Test fun `appending two empty lists gives an empty list`() { val list1 = Empty val list2 = Empty val list12 = Variable("Result") val append = Append(list1, list2, list12) val result = append.satisfy(emptyMap()).toList() assertEquals(1, result.size, "Expected one solution") assertTrue(result[0].isSuccess, "Expected success") val subs = result[0].getOrNull()!! assertEquals(1, subs.size, "Expected one substitution") assertEquals(Empty, subs[list12], "Expected result to be empty list") } @Disabled("Not implemented yet") @Test fun `appending an empty list to another list gives that list`() { val nonempty = Cons(Atom("a"), Empty) var append = Append(nonempty, Empty, Empty) var result = append.satisfy(emptyMap()).toList() assertEquals(1, result.size, "Expected one solution") assertTrue(result[0].isSuccess, "Expected success") assertTrue(result[0].getOrNull()!!.isEmpty(), "Expected empty substitution map") append = Append(Empty, nonempty, Empty) result = append.satisfy(emptyMap()).toList() assertEquals(1, result.size, "Expected one solution") assertTrue(result[0].isSuccess, "Expected success") assertTrue(result[0].getOrNull()!!.isEmpty(), "Expected empty substitution map") val variable = Variable("List1AndList2") append = Append(Empty, nonempty, variable) result = append.satisfy(emptyMap()).toList() assertEquals(1, result.size, "Expected one solution") assertTrue(result[0].isSuccess, "Expected success") var subs = result[0].getOrNull()!! assertEquals(1, subs.size, "Expected one substitution") assertEquals(nonempty, subs[variable], "Expected result to be nonempty list") append = Append(nonempty, Empty, variable) result = append.satisfy(emptyMap()).toList() assertEquals(1, result.size, "Expected one solution") assertTrue(result[0].isSuccess, "Expected success") subs = result[0].getOrNull()!! assertEquals(1, subs.size, "Expected one substitution") } @Disabled("Not implemented yet") @Test fun `appending two lists gives combined list`() { val list1 = Cons(Atom("a"), Cons(Atom("b"), Empty)) val list2 = Cons(Atom("c"), Cons(Atom("d"), Empty)) val list3 = Cons(Atom("a"), Cons(Atom("b"), Cons(Atom("c"), Cons(Atom("d"), Empty)))) val list4 = Cons(Atom("c"), Cons(Atom("d"), Cons(Atom("a"), Cons(Atom("b"), Empty)))) var append = Append(list1, list2, list3) var result = append.satisfy(emptyMap()).toList() assertEquals(1, result.size, "Expected one solution") assertTrue(result[0].isSuccess, "Expected success") assertTrue(result[0].getOrNull()!!.isEmpty(), "Expected empty substitution map") val variable = Variable("List1AndList2") append = Append(list1, list2, variable) result = append.satisfy(emptyMap()).toList() assertEquals(1, result.size, "Expected one solution") assertTrue(result[0].isSuccess, "Expected success") var subs = result[0].getOrNull()!! assertEquals(1, subs.size, "Expected one substitution") assertEquals(list3, subs[variable], "Expected result to be combined list") append = Append(list2, list1, variable) result = append.satisfy(emptyMap()).toList() assertEquals(1, result.size, "Expected one solution") assertTrue(result[0].isSuccess, "Expected success") subs = result[0].getOrNull()!! assertEquals(1, subs.size, "Expected one substitution") assertEquals(list4, subs[variable], "Expected result to be combined list") } @Disabled("Not implemented yet") @Test fun `you can find the appended list`() { val list1 = Cons(Atom("a"), Cons(Atom("b"), Empty)) val list2: Term = Variable("List2") val list3 = Cons(Atom("a"), Cons(Atom("b"), Cons(Atom("c"), Cons(Atom("d"), Empty)))) var append = Append(list1, list2, list1) var result = append.satisfy(emptyMap()).toList() assertEquals(1, result.size, "Expected one solution") assertTrue(result[0].isSuccess, "Expected success") var subs = result[0].getOrNull()!! assertEquals(1, subs.size, "Expected one substitution") assertEquals(Empty, subs[list2], "Expected result to be empty list") append = Append(list1, list2, list3) result = append.satisfy(emptyMap()).toList() assertEquals(1, result.size, "Expected one solution") assertTrue(result[0].isSuccess, "Expected success") subs = result[0].getOrNull()!! assertEquals(1, subs.size, "Expected one substitution") assertEquals(Cons(Atom("c"), Cons(Atom("d"), Empty)), subs[list2], "Expected result to be list with c and d") } @Disabled("Not implemented yet") @Test fun `you can find the prepended list`() { val list1 = Variable("List1") val list2 = Cons(Atom("c"), Cons(Atom("d"), Empty)) val list3 = Cons(Atom("a"), Cons(Atom("b"), Cons(Atom("c"), Cons(Atom("d"), Empty)))) var append = Append(list1, list2, list2) var result = append.satisfy(emptyMap()).toList() assertEquals(1, result.size, "Expected one solution") assertTrue(result[0].isSuccess, "Expected success") var subs = result[0].getOrNull()!! assertEquals(1, subs.size, "Expected one substitution") assertEquals(Empty, subs[list1], "Expected result to be empty list") append = Append(list1, list2, list3) result = append.satisfy(emptyMap()).toList() assertEquals(1, result.size, "Expected one solution") assertTrue(result[0].isSuccess, "Expected success") subs = result[0].getOrNull()!! assertEquals(1, subs.size, "Expected one substitution") assertEquals(Cons(Atom("a"), Cons(Atom("b"), Empty)), subs[list1], "Expected result to be list with a and b") } }