This repository has been archived on 2025-09-23. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
2025LogProg-project-GhentPr.../tests/prolog/logic/ArithmeticTests.kt
2025-04-11 21:11:59 +02:00

404 lines
12 KiB
Kotlin

package prolog.logic
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.RepeatedTest
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import prolog.ast.terms.Integer
import prolog.ast.terms.Term
import prolog.ast.terms.Variable
class ArithmeticTests {
@Test
fun `1_between_0_and_2`() {
val result = between(Integer(0), Integer(2), Integer(1))
assertTrue(result.any(), "Expected 1 to be between 0 and 2")
assertEquals(emptyMap<Variable, Term>(), result.first(), "Expected no substitutions")
}
@Test
fun `3_not_between_0_and_2`() {
val result = between(Integer(0), Integer(2), Integer(3))
assertTrue(result.none(), "Expected 3 not to be between 0 and 2")
}
@Test
fun numbers_between_0_and_2() {
val result = between(Integer(0), Integer(2), Variable("X"))
val expectedResults = listOf(
mapOf(Variable("X") to Integer(0)),
mapOf(Variable("X") to Integer(1)),
mapOf(Variable("X") to Integer(2))
)
val actualResults = result.toList()
assertEquals(expectedResults.size, actualResults.size, "Expected 3 results")
for ((expected, actual) in expectedResults.zip(actualResults)) {
for ((key, value) in expected) {
assertTrue(actual.containsKey(key), "Expected key $key to be present")
assertTrue(
equivalent(value, actual[key]!!),
"Expected value $value for key $key, but got ${actual[key]}"
)
}
}
}
@Test
fun `succ(0) is 1`() {
val t1 = Integer(0)
val expected = Integer(1)
val result = succ(t1, expected, emptyMap()).toList()
assertEquals(1, result.size, "Expected 0 + 1 to be equal to 1")
assertTrue(result[0].isSuccess, "Expected success")
assertTrue(result[0].getOrNull()!!.isEmpty(), "Expected no substitutions")
}
@Test
fun `succ(1) is 2`() {
val t1 = Integer(1)
val expected = Integer(2)
val result = succ(t1, expected, emptyMap()).toList()
assertEquals(1, result.size, "Expected 1 + 1 to be equal to 2")
assertTrue(result[0].isSuccess, "Expected success")
assertTrue(result[0].getOrNull()!!.isEmpty(), "Expected no substitutions")
}
@Test
fun `succ(1) is var`() {
val t1 = Integer(1)
val t2 = Variable("X")
val expected = Integer(2)
val result = succ(t1, t2, emptyMap()).toList()
assertEquals(1, result.size, "Expected 1 + 1 to be equal to X")
assertTrue(result[0].isSuccess, "Expected success")
assertEquals(expected, result[0].getOrNull()!![t2], "Expected X to be equal to 2")
}
@Test
fun `succ(bound-to-1-var) is 2`() {
val t1 = Variable("X")
val t2 = Integer(2)
t1.bind(Integer(1))
val result = succ(t1, t2, emptyMap()).toList()
assertEquals(1, result.size, "Expected X + 1 to be equal to 2")
assertTrue(result[0].isSuccess, "Expected success")
assertTrue(result[0].getOrNull()!!.isEmpty(), "Expected no substitutions")
}
@Test
fun `succ(bound-to-1-var) is 2 by map`() {
val t1 = Variable("X")
val t2 = Integer(2)
val result = succ(t1, t2, mapOf(t1 to Integer(1))).toList()
assertEquals(1, result.size, "Expected X + 1 to be equal to 2")
assertTrue(result[0].isSuccess, "Expected success")
assertTrue(result[0].getOrNull()!!.isEmpty(), "Expected no substitutions")
}
@Test
fun `succ(bound-to-1-var) is var`() {
val t1 = Variable("X")
val t2 = Variable("Y")
t1.bind(Integer(1))
val result = succ(t1, t2, emptyMap()).toList()
assertEquals(1, result.size, "Expected X + 1 to be equal to Y")
assertTrue(result[0].isSuccess, "Expected success")
assertEquals(Integer(2), result[0].getOrNull()!![t2], "Expected Y to be equal to 2")
}
@Test
fun `succ(bound-to-1-var) is var by map`() {
val t1 = Variable("X")
val t2 = Variable("Y")
val result = succ(t1, t2, mapOf(t1 to Integer(1))).toList()
assertEquals(1, result.size, "Expected X + 1 to be equal to Y")
assertTrue(result[0].isSuccess, "Expected success")
assertEquals(Integer(2), result[0].getOrNull()!![t2], "Expected Y to be equal to 2")
}
@Test
fun `succ(var, 0) fails silently`() {
val t1 = Variable("X")
val t2 = Integer(0)
val result = succ(t1, t2, emptyMap()).toList()
assertTrue(result.isEmpty(), "Expected X + 1 to fail")
}
@Test
fun `1_plus_2_is_3`() {
val t1 = Integer(1)
val t2 = Integer(2)
val t3 = Integer(3)
val result = plus(t1, t2, t3, emptyMap()).toList()
assertEquals(1, result.size, "1 + 2 should be equal to 3")
assertTrue(result[0].isSuccess, "Expected success")
assertTrue(result[0].getOrNull()!!.isEmpty(), "1 + 2 should be equal to 3")
}
@Test
fun `1_plus_2_is_not_4`() {
val t1 = Integer(1)
val t2 = Integer(2)
val t3 = Integer(4)
val result = plus(t1, t2, t3, emptyMap())
assertTrue(result.none(), "1 + 2 should not be equal to 4")
}
@Test
fun `1_plus_2_is_variable`() {
val t1 = Integer(1)
val t2 = Integer(2)
val t3 = Variable("X")
val result = plus(t1, t2, t3, emptyMap()).toList()
assertEquals(1, result.size, "1 + 2 should be equal to X")
assertTrue(result[0].isSuccess, "Expected success")
assertEquals(Integer(3), result[0].getOrNull()!![t3], "X should be equal to 3")
}
@Test
fun `1_plus_variable_is_3`() {
val t1 = Integer(1)
val t2 = Variable("X")
val t3 = Integer(3)
val result = plus(t1, t2, t3, emptyMap()).toList()
assertEquals(1, result.size, "1 + X should be equal to 3")
assertTrue(result[0].isSuccess, "Expected success")
assertEquals(Integer(2), result[0].getOrNull()!![t2], "X should be equal to 2")
}
@Test
fun variable_plus_2_is_3() {
val t1 = Variable("X")
val t2 = Integer(2)
val t3 = Integer(3)
val result = plus(t1, t2, t3, emptyMap()).toList()
assertEquals(1, result.size, "X + 2 should be equal to 3")
assertTrue(result[0].isSuccess, "Expected success")
assertEquals(Integer(1), result[0].getOrNull()!![t1], "X should be equal to 1")
}
@Test
fun `1 plus 2 is bound-to-3-var`() {
val t1 = Integer(1)
val t2 = Integer(2)
val t3 = Variable("X")
t3.bind(Integer(3))
val result = plus(t1, t2, t3, emptyMap()).toList()
assertEquals(1, result.size, "1 + 2 should be equal to X")
assertTrue(result[0].isSuccess, "Expected success")
assertTrue(result[0].getOrNull()!!.isEmpty(), "t3 should not be rebound")
}
@Test
fun `1 plus 2 is bound-to-3-var by map`() {
val t1 = Integer(1)
val t2 = Integer(2)
val t3 = Variable("X")
val result = plus(t1, t2, t3, mapOf(Variable("X") to Integer(3))).toList()
assertEquals(1, result.size, "1 + 2 should be equal to X")
assertTrue(result[0].isSuccess, "Expected success")
assertTrue(result[0].getOrNull()!!.isEmpty(), "t3 should not be rebound")
}
@Test
fun `1 plus 2 is bound-to-4-var`() {
val t1 = Integer(1)
val t2 = Integer(2)
val t3 = Variable("X")
t3.bind(Integer(4))
val result = plus(t1, t2, t3, emptyMap())
assertTrue(result.none(), "1 + 2 should not be equal to X")
}
@Test
fun `1 plus bound-to-2-var is 3`() {
val t1 = Integer(1)
val t2 = Variable("X")
val t3 = Integer(3)
t2.bind(Integer(2))
val result = plus(t1, t2, t3, emptyMap()).toList()
assertEquals(1, result.size, "1 + X should be equal to 3")
assertTrue(result[0].isSuccess, "Expected success")
assertTrue(result[0].getOrNull()!!.isEmpty(), "t2 should not be rebound")
}
@Test
fun `1 plus bound-to-2-var is not 4`() {
val t1 = Integer(1)
val t2 = Variable("X")
val t3 = Integer(4)
t2.bind(Integer(2))
val result = plus(t1, t2, t3, emptyMap())
assertTrue(result.none(), "1 + X should not be equal to 4")
}
@Test
fun `bound-to-1-var plus 2 is 3`() {
val t1 = Variable("X")
val t2 = Integer(2)
val t3 = Integer(3)
t1.bind(Integer(1))
val result = plus(t1, t2, t3, emptyMap()).toList()
assertEquals(1, result.size, "X + 2 should be equal to 3")
assertTrue(result[0].isSuccess, "Expected success")
assertTrue(result[0].getOrNull()!!.none(), "t1 should not be rebound")
}
@Test
fun `bound-to-1-var plus 2 is not 4`() {
val t1 = Variable("X")
val t2 = Integer(2)
val t3 = Integer(4)
t1.bind(Integer(1))
val result = plus(t1, t2, t3, emptyMap())
assertTrue(result.none(), "X + 2 should not be equal to 4")
}
@Test
fun `two unbound vars plus should throw`() {
val t1 = Variable("X")
val t2 = Variable("Y")
val t3 = Integer(3)
val result = plus(t1, t2, t3, emptyMap()).toList()
assertEquals(1, result.size, "There should be one solution")
assertTrue(result[0].isFailure, "Expected failure")
assertTrue(result[0].exceptionOrNull() is IllegalArgumentException, "Expected IllegalArgumentException")
}
@Test
fun `bound-to-1-var plus bound-to-2-var is variable`() {
val t1 = Variable("X")
val t2 = Variable("Y")
val t3 = Variable("Z")
t1.bind(Integer(1))
t2.bind(Integer(2))
val result = plus(t1, t2, t3, emptyMap()).toList()
assertTrue(result.isNotEmpty(), "X + Y should be equal to Z")
assertTrue(result[0].isSuccess, "Expected success")
assertTrue(equivalent(result[0].getOrThrow()[t3]!!, Integer(3)), "Z should be equal to 3")
}
@Test
fun `1 times 1 is 1`() {
val t1 = Integer(1)
val t2 = Integer(1)
val t3 = Integer(1)
val result = mul(t1, t2, t3, emptyMap()).toList()
assertEquals(1, result.size, "There should be one solution")
assertTrue(result[0].isSuccess, "Expected success")
assertTrue(result[0].getOrNull()!!.isEmpty(), "1 * 1 should already be equal to 1")
}
@Test
fun `1 times 2 is 2`() {
val t1 = Integer(1)
val t2 = Integer(2)
val t3 = Integer(2)
val result = mul(t1, t2, t3, emptyMap()).toList()
assertEquals(1, result.size, "There should be one solution")
assertTrue(result[0].isSuccess, "Expected success")
assertTrue(result[0].getOrNull()!!.isEmpty(), "1 * 2 should already be equal to 2")
}
@Test
fun `2 times 3 is 6`() {
val t1 = Integer(2)
val t2 = Integer(3)
val t3 = Integer(6)
val result = mul(t1, t2, t3, emptyMap()).toList()
assertEquals(1, result.size, "There should be one solution")
assertTrue(result[0].isSuccess, "Expected success")
assertTrue(result[0].getOrNull()!!.isEmpty(), "2 * 3 should already be equal to 6")
}
@Test
fun `2 times 3 is not 4`() {
val t1 = Integer(2)
val t2 = Integer(3)
val t3 = Integer(4)
val result = mul(t1, t2, t3, emptyMap())
assertTrue(result.none(), "2 * 3 should not be equal to 4")
}
@RepeatedTest(100)
fun `random test for mul`() {
val t1 = Integer((0..1000).random())
val t2 = Integer((0..1000).random())
val t3 = Variable("X")
val result = mul(t1, t2, t3, emptyMap()).toList()
assertEquals(1, result.size, "There should be one solution")
assertTrue(result[0].isSuccess, "Expected success")
assertEquals(Integer(t1.value * t2.value), result[0].getOrNull()!![t3], "X should be equal to ${t1.value * t2.value}")
}
}