refactor: Rework

This commit is contained in:
Tibo De Peuter 2025-04-15 12:32:59 +02:00
parent ac55ed4c64
commit 6469dd6ced
Signed by: tdpeuter
GPG key ID: 38297DE43F75FFE2
34 changed files with 593 additions and 552 deletions

View file

@ -3,9 +3,10 @@ package prolog.builtins
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import prolog.Substitutions
import prolog.ast.terms.Integer
import prolog.ast.terms.Term
import prolog.ast.terms.Variable
import prolog.logic.between
import prolog.logic.equivalent
class ArithmeticOperatorsTests {
@ -16,18 +17,21 @@ class ArithmeticOperatorsTests {
Integer(1)
)
var result = op1.evaluate(emptyMap()).first
var result = op1.satisfy(emptyMap()).toList()
assertEquals(True, result, "1 should be equal to 1")
assertEquals(1, result.size, "1 should be equal to 1")
assertTrue(result[0].isSuccess, "1 should be equal to 1")
val subs = result[0].getOrNull()!!
assertTrue(subs.isEmpty(), "1 should not be rebound")
val op2 = EvaluatesToDifferent(
Integer(1),
Integer(1)
)
result = op2.evaluate(emptyMap()).first
result = op2.satisfy(emptyMap()).toList()
assertEquals(False, result, "1 should not be different from 1")
assertEquals(0, result.size, "1 should not be different from 1")
}
@Test
@ -37,18 +41,21 @@ class ArithmeticOperatorsTests {
Integer(2)
)
var result = op1.evaluate(emptyMap()).first
var result = op1.satisfy(emptyMap()).toList()
assertEquals(0, result.size, "1 should not be equal to 2")
assertEquals(False, result, "1 should not be equal to 2")
val op2 = EvaluatesToDifferent(
Integer(1),
Integer(2)
)
result = op2.evaluate(emptyMap()).first
result = op2.satisfy(emptyMap()).toList()
assertEquals(True, result, "1 should be different from 2")
assertEquals(1, result.size, "1 should be different from 2")
assertTrue(result[0].isSuccess, "1 should be different from 2")
val subs = result[0].getOrNull()!!
assertTrue(subs.isEmpty(), "1 should not be rebound")
}
@Test
@ -58,18 +65,21 @@ class ArithmeticOperatorsTests {
Integer(5)
)
var result = op.evaluate(emptyMap()).first
var result = op.satisfy(emptyMap()).toList()
assertEquals(True, result, "2 + 3 should be equal to 5")
assertEquals(1, result.size, "2 + 3 should be equal to 5")
assertTrue(result[0].isSuccess, "2 + 3 should be equal to 5")
val subs = result[0].getOrNull()!!
assertTrue(subs.isEmpty(), "2 + 3 should not be rebound")
val op2 = EvaluatesToDifferent(
Add(Integer(2), Integer(3)),
Integer(5)
)
result = op2.evaluate(emptyMap()).first
result = op2.satisfy(emptyMap()).toList()
assertEquals(False, result, "2 + 3 should not be different from 5")
assertEquals(0, result.size, "2 + 3 should not be different from 5")
}
@Test
@ -79,18 +89,21 @@ class ArithmeticOperatorsTests {
Add(Integer(4), Integer(1))
)
var result = op.evaluate(emptyMap()).first
var result = op.satisfy(emptyMap()).toList()
assertEquals(True, result, "2 + 3 should be equal to 4 + 1")
assertEquals(1, result.size, "2 + 3 should be equal to 4 + 1")
assertTrue(result[0].isSuccess, "2 + 3 should be equal to 4 + 1")
val subs = result[0].getOrNull()!!
assertTrue(subs.isEmpty(), "2 + 3 should not be rebound")
val op2 = EvaluatesToDifferent(
Add(Integer(2), Integer(3)),
Add(Integer(4), Integer(1))
)
result = op2.evaluate(emptyMap()).first
result = op2.satisfy(emptyMap()).toList()
assertEquals(False, result, "2 + 3 should not be different from 4 + 1")
assertEquals(0, result.size, "2 + 3 should not be different from 4 + 1")
}
@Test
@ -100,14 +113,24 @@ class ArithmeticOperatorsTests {
Variable("X")
)
assertThrows<IllegalArgumentException> { op.evaluate(emptyMap()) }
var result = op.satisfy(emptyMap()).toList()
assertEquals(1, result.size, "One exception should be thrown")
assertTrue(result[0].isFailure, "One exception should be thrown")
var exceptions = result[0].exceptionOrNull()
assertTrue(exceptions is IllegalArgumentException, "One exception should be thrown")
val op2 = EvaluatesToDifferent(
Integer(1),
Variable("X")
)
assertThrows<IllegalArgumentException> { op2.evaluate(emptyMap()) }
result = op2.satisfy(emptyMap()).toList()
assertEquals(1, result.size, "One exception should be thrown")
assertTrue(result[0].isFailure, "One exception should be thrown")
exceptions = result[0].exceptionOrNull()
assertTrue(exceptions is IllegalArgumentException, "One exception should be thrown")
}
@Test
@ -117,14 +140,14 @@ class ArithmeticOperatorsTests {
Integer(1)
)
assertThrows<IllegalArgumentException> { op.evaluate(emptyMap()) }
assertThrows<IllegalArgumentException> { op.satisfy(emptyMap()) }
val op2 = EvaluatesToDifferent(
Add(Integer(1), Variable("X")),
Integer(1)
)
assertThrows<IllegalArgumentException> { op2.evaluate(emptyMap()) }
assertThrows<IllegalArgumentException> { op2.satisfy(emptyMap()) }
}
@Test
@ -134,7 +157,7 @@ class ArithmeticOperatorsTests {
Integer(1)
)
val result = op.prove(emptyMap())
val result = op.satisfy(emptyMap())
assertTrue(result.any(), "1 should be equal to 1")
}
@ -146,7 +169,7 @@ class ArithmeticOperatorsTests {
Integer(2)
)
val result = op.prove(emptyMap()).toList()
val result = op.satisfy(emptyMap()).toList()
assertTrue(result.isEmpty(), "1 should not be equal to 2")
}
@ -159,12 +182,11 @@ class ArithmeticOperatorsTests {
Integer(1)
)
t1.bind(Integer(1))
val result = op.satisfy(mapOf(t1 to Integer(1))).toList()
val result = op.prove(emptyMap())
assertTrue(result.any(), "X should be equal to 1")
assertTrue(result.first().isEmpty(), "X should not be rebound")
assertEquals(1, result.size, "X should be equal to 1")
assertTrue(result.first().isSuccess, "X should be equal to 1")
assertTrue(result.first().getOrNull()!!.isEmpty(), "X should not be rebound")
}
@Test
@ -175,9 +197,7 @@ class ArithmeticOperatorsTests {
Integer(1)
)
t1.bind(Integer(2))
val result = op.prove(emptyMap())
val result = op.satisfy(mapOf(t1 to Integer(2)))
assertFalse(result.any(), "X should not be equal to 1")
}
@ -189,11 +209,12 @@ class ArithmeticOperatorsTests {
Integer(1)
)
val result = op.prove(emptyMap()).toList()
val result = op.satisfy(emptyMap()).toList()
assertFalse(result.isEmpty(), "X should be equal to 1")
assertEquals(1, result[0].size, "X should be rebound")
assertTrue(equivalent(Integer(1), result[0][Variable("X")]!!), "X should be equal to 1")
assertTrue(result.first().isSuccess, "X should be equal to 1")
assertEquals(1, result[0].getOrNull()!!.size, "X should be rebound")
assertTrue(equivalent(Integer(1), result[0].getOrNull()!![Variable("X")]!!, emptyMap()), "X should be equal to 1")
}
@Test
@ -203,11 +224,18 @@ class ArithmeticOperatorsTests {
Add(Integer(1), Integer(2))
)
val result = op.prove(emptyMap()).toList()
val result = op.satisfy(emptyMap()).toList()
assertFalse(result.isEmpty(), "X should be equal to 3")
assertEquals(1, result[0].size, "X should be rebound")
assertTrue(equivalent(Integer(3), result[0][Variable("X")]!!), "X should be equal to 3")
assertTrue(result.first().isSuccess, "X should be equal to 3")
val subs = result[0].getOrNull()!!
assertEquals(1, subs.size, "X should be rebound")
assertTrue(
equivalent(Integer(3), subs[Variable("X")]!!, emptyMap()),
"X should be equal to 3"
)
}
@Test
@ -217,7 +245,12 @@ class ArithmeticOperatorsTests {
Variable("Y")
)
assertThrows<IllegalArgumentException> { op.prove(emptyMap()) }
val result = op.satisfy(emptyMap()).toList()
assertEquals(1, result.size, "One exception should be thrown")
assertTrue(result[0].isFailure, "One exception should be thrown")
val exceptions = result[0].exceptionOrNull()
assertTrue(exceptions is IllegalArgumentException, "One exception should be thrown")
}
@Test
@ -227,23 +260,29 @@ class ArithmeticOperatorsTests {
Variable("X")
)
assertThrows<IllegalArgumentException> { op.prove(emptyMap()) }
val result = op.satisfy(emptyMap()).toList()
assertEquals(1, result.size, "One exception should be thrown")
assertTrue(result[0].isFailure, "One exception should be thrown")
val exceptions = result[0].exceptionOrNull()
assertTrue(exceptions is IllegalArgumentException, "One exception should be thrown")
}
/**
* ?- X = 1, Y = 1 + 2, X is Y.
* false.
*/
@Test
fun `var is bound-to-sum-var`() {
val t1 = Variable("X")
val t2 = Variable("Y")
t2.bind(Add(Integer(1), Integer(2)))
val op = Is(t1, t2)
val map: Substitutions = mapOf(t1 to Integer(1), t2 to Add(Integer(1), Integer(2)))
val result = op.prove(emptyMap()).toList()
val result = op.satisfy(map).toList()
assertTrue(result.isNotEmpty(), "X should be equal to 3")
assertEquals(1, result[0].size, "X should be rebound, Y should not")
assertTrue(equivalent(Integer(3), result[0][t1]!!), "X should be equal to 3")
assertEquals(0, result.size, "X should not be equal to Y")
}
/**
@ -268,47 +307,38 @@ class ArithmeticOperatorsTests {
fun `negate 1 to get -1`() {
val t1 = Integer(1)
val result = Negate(t1).evaluate(emptyMap()).first
val result = Negate(t1).simplify(emptyMap())
assertEquals(Integer(-1), result, "negate(1) should be equal to -1")
assertEquals(Integer(-1), result.to, "negate(1) should be equal to -1")
}
@Test
fun `negate 0 to get 0`() {
val t1 = Integer(0)
val result = Negate(t1).evaluate(emptyMap()).first
val result = Negate(t1).simplify(emptyMap())
assertEquals(Integer(0), result, "negate(0) should be equal to 0")
assertEquals(Integer(0), result.to, "negate(0) should be equal to 0")
}
@Test
fun `negate -1 to get 1`() {
val t1 = Integer(-1)
val result = Negate(t1).evaluate(emptyMap()).first
val result = Negate(t1).simplify(emptyMap())
assertEquals(Integer(1), result, "negate(-1) should be equal to 1")
assertEquals(Integer(1), result.to, "negate(-1) should be equal to 1")
}
@Test
fun `negate bound-to-1-var to get -1`() {
val t1 = Variable("X")
t1.bind(Integer(1))
val map: Substitutions = mapOf(t1 to Integer(1))
val result = Negate(t1).evaluate(emptyMap()).first
val result = Negate(t1).simplify(map)
assertEquals(Integer(-1), result, "negate(1) should be equal to -1")
}
@Test
fun `negate bound-to-1-var to get -1 by map`() {
val t1 = Variable("X")
val result = Negate(t1).evaluate(mapOf(t1 to Integer(1))).first
assertEquals(Integer(-1), result, "negate(1) should be equal to -1")
assertEquals(Integer(-1), result.to, "negate(1) should be equal to -1")
}
@Test
@ -316,9 +346,9 @@ class ArithmeticOperatorsTests {
val t1 = Integer(1)
val t2 = Integer(3)
val result = Negate(Add(t1, t2)).evaluate(emptyMap()).first
val result = Negate(Add(t1, t2)).simplify(emptyMap())
assertEquals(Integer(-4), result, "negate(1 + 3) should be equal to -4")
assertEquals(Integer(-4), result.to, "negate(1 + 3) should be equal to -4")
}
@Test
@ -326,9 +356,9 @@ class ArithmeticOperatorsTests {
val t1 = Integer(1)
val t2 = Integer(2)
val result = Add(t1, t2).evaluate(emptyMap()).first
val result = Add(t1, t2).simplify(emptyMap())
assertEquals(Integer(3), result, "1 + 2 should be equal to 3")
assertEquals(Integer(3), result.to, "1 + 2 should be equal to 3")
}
@Test
@ -336,21 +366,10 @@ class ArithmeticOperatorsTests {
val t1 = Integer(1)
val t2 = Variable("X")
t2.bind(Integer(2))
val subs: Substitutions = mapOf(t2 to Integer(2))
val result = Add(t1, t2).simplify(subs)
val result = Add(t1, t2).evaluate(emptyMap()).first
assertEquals(Integer(3), result, "1 + 2 should be equal to 3")
}
@Test
fun `Add 1 and bound-to-2-var to get 3 by map`() {
val t1 = Integer(1)
val t2 = Variable("X")
val result = Add(t1, t2).evaluate(mapOf(t2 to Integer(2))).first
assertEquals(Integer(3), result, "1 + 2 should be equal to 3")
assertEquals(Integer(3), result.to, "1 + 2 should be equal to 3")
}
@Test
@ -358,9 +377,9 @@ class ArithmeticOperatorsTests {
val t1 = Integer(1)
val t2 = Integer(2)
val result = Subtract(t1, t2).evaluate(emptyMap()).first
val result = Subtract(t1, t2).simplify(emptyMap())
assertEquals(Integer(-1), result, "1 - 2 should be equal to -1")
assertEquals(Integer(-1), result.to, "1 - 2 should be equal to -1")
}
@Test
@ -368,9 +387,9 @@ class ArithmeticOperatorsTests {
val t1 = Integer(3)
val t2 = Integer(1)
val result = Subtract(t1, t2).evaluate(emptyMap()).first
val result = Subtract(t1, t2).simplify(emptyMap())
assertEquals(Integer(2), result, "3 - 1 should be equal to 2")
assertEquals(Integer(2), result.to, "3 - 1 should be equal to 2")
}
@Test
@ -378,9 +397,9 @@ class ArithmeticOperatorsTests {
val t1 = Integer(0)
val t2 = Integer(0)
val result = Multiply(t1, t2).evaluate(emptyMap()).first
val result = Multiply(t1, t2).simplify(emptyMap())
assertEquals(Integer(0), result, "0 * 0 should be equal to 0")
assertEquals(Integer(0), result.to, "0 * 0 should be equal to 0")
}
@Test
@ -388,9 +407,9 @@ class ArithmeticOperatorsTests {
val t1 = Integer(1)
val t2 = Integer(0)
val result = Multiply(t1, t2).evaluate(emptyMap()).first
val result = Multiply(t1, t2).simplify(emptyMap())
assertEquals(Integer(0), result, "1 * 0 should be equal to 0")
assertEquals(Integer(0), result.to, "1 * 0 should be equal to 0")
}
@Test
@ -398,9 +417,9 @@ class ArithmeticOperatorsTests {
val t1 = Integer(0)
val t2 = Integer(1)
val result = Multiply(t1, t2).evaluate(emptyMap()).first
val result = Multiply(t1, t2).simplify(emptyMap())
assertEquals(Integer(0), result, "0 * 1 should be equal to 0")
assertEquals(Integer(0), result.to, "0 * 1 should be equal to 0")
}
@Test
@ -408,9 +427,9 @@ class ArithmeticOperatorsTests {
val t1 = Integer(3)
val t2 = Integer(1)
val result = Multiply(t1, t2).evaluate(emptyMap()).first
val result = Multiply(t1, t2).simplify(emptyMap())
assertEquals(Integer(3), result, "3 * 1 should be equal to 3")
assertEquals(Integer(3), result.to, "3 * 1 should be equal to 3")
}
@Test
@ -418,8 +437,8 @@ class ArithmeticOperatorsTests {
val t1 = Integer(2)
val t2 = Integer(3)
val result = Multiply(t1, t2).evaluate(emptyMap())
val result = Multiply(t1, t2).simplify(emptyMap())
assertEquals(Integer(6), result.first, "2 * 3 should be equal to 6")
assertEquals(Integer(6), result.to, "2 * 3 should be equal to 6")
}
}