feat: Floating point arithmetic

This commit is contained in:
Tibo De Peuter 2025-04-15 18:23:04 +02:00
parent f9950a3fd3
commit 4a6850527f
Signed by: tdpeuter
GPG key ID: 38297DE43F75FFE2
13 changed files with 527 additions and 55 deletions

View file

@ -4,8 +4,8 @@ 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.arithmetic.Float
import prolog.ast.arithmetic.Integer
import prolog.ast.terms.Variable
import prolog.logic.equivalent
@ -285,6 +285,111 @@ class ArithmeticOperatorsTests {
assertEquals(0, result.size, "X should not be equal to Y")
}
@Test
fun `var is mul`() {
val op = Is(
Variable("X"),
Multiply(Integer(2), Integer(3))
)
val result = op.satisfy(emptyMap()).toList()
assertEquals(1, result.size, "X should be equal to 6")
assertTrue(result[0].isSuccess, "X should be equal to 6")
val subs = result[0].getOrNull()!!
assertEquals(1, subs.size, "X should be rebound")
assertTrue(
equivalent(Integer(6), subs[Variable("X")]!!, emptyMap()),
"X should be equal to 6"
)
}
@Test
fun `bound-var is mul`() {
val t1 = Variable("X")
val op = Is(
t1,
Multiply(Integer(2), Integer(3))
)
val map: Substitutions = mapOf(t1 to Integer(6))
val result = op.satisfy(map).toList()
assertEquals(1, result.size, "X should be equal to 6")
assertTrue(result[0].isSuccess, "X should be equal to 6")
val subs = result[0].getOrNull()!!
assertTrue(subs.isEmpty(), "X should not be rebound")
}
@Test
fun `var is bound-to-mul`() {
val t1 = Variable("X")
val t2 = Variable("Y")
val op = Is(t1, t2)
val map: Substitutions = mapOf(t1 to Integer(6), t2 to Multiply(Integer(2), Integer(3)))
val result = op.satisfy(map).toList()
assertEquals(1, result.size, "X should be equal to Y")
assertTrue(result[0].isSuccess, "X should be equal to Y")
val subs = result[0].getOrNull()!!
assertTrue(subs.isEmpty(), "X should not be rebound")
}
@Test
fun `2 is 4 div 2`() {
val op = Is(
Integer(2),
Divide(Integer(4), Integer(2))
)
val result = op.satisfy(emptyMap()).toList()
assertEquals(1, result.size, "2 should be equal to 4 / 2")
assertTrue(result[0].isSuccess, "2 should be equal to 4 / 2")
val subs = result[0].getOrNull()!!
assertTrue(subs.isEmpty(), "2 should not be rebound")
}
@Test
fun `4 div 2 is var`() {
val op = Is(
Variable("X"),
Divide(Integer(4), Integer(2))
)
val result = op.satisfy(emptyMap()).toList()
assertEquals(1, result.size, "X should be equal to 2")
assertTrue(result[0].isSuccess, "X should be equal to 2")
val subs = result[0].getOrNull()!!
assertEquals(1, subs.size, "X should be rebound")
assertTrue(
equivalent(Integer(2), subs[Variable("X")]!!, emptyMap()),
"X should be equal to 2"
)
}
@Test
fun `bound-var is 4 div 2`() {
val t1 = Variable("X")
val op = Is(
t1,
Divide(Integer(4), Integer(2))
)
val map: Substitutions = mapOf(t1 to Integer(2))
val result = op.satisfy(map).toList()
assertEquals(1, result.size, "X should be equal to 2")
assertTrue(result[0].isSuccess, "X should be equal to 2")
val subs = result[0].getOrNull()!!
assertTrue(subs.isEmpty(), "X should not be rebound")
}
/**
* ?- between(1, 2, X), Y is 1 + X.
* X = 1, Y = 2 ;
@ -441,4 +546,44 @@ class ArithmeticOperatorsTests {
assertEquals(Integer(6), result.to, "2 * 3 should be equal to 6")
}
@Test
fun `Divide 1 and 1 to get 1`() {
val t1 = Integer(1)
val t2 = Integer(1)
val result = Divide(t1, t2).simplify(emptyMap())
assertEquals(Integer(1), result.to, "1 / 1 should be equal to 1")
}
@Test
fun `Divide 2 and 2 to get 1`() {
val t1 = Integer(2)
val t2 = Integer(2)
val result = Divide(t1, t2).simplify(emptyMap())
assertEquals(Integer(1), result.to, "2 / 2 should be equal to 1")
}
@Test
fun `Divide 12 and 3 to get 4`() {
val t1 = Integer(12)
val t2 = Integer(3)
val result = Divide(t1, t2).simplify(emptyMap())
assertEquals(Integer(4), result.to, "12 / 3 should be equal to 4")
}
@Test
fun `Divide 1 and 2 to get float`() {
val t1 = Integer(1)
val t2 = Integer(2)
val result = Divide(t1, t2).simplify(emptyMap())
assertTrue(equivalent(result.to, Float(0.5f), emptyMap()), "1 / 2 should be equal to 0.5")
}
}

View file

@ -8,7 +8,7 @@ import prolog.ast.logic.Fact
import prolog.ast.logic.Rule
import prolog.ast.terms.Atom
import prolog.ast.terms.CompoundTerm
import prolog.ast.terms.Integer
import prolog.ast.arithmetic.Integer
import prolog.ast.terms.Variable
class ControlOperatorsTests {

View file

@ -3,7 +3,7 @@ package prolog.builtins
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.Test
import prolog.ast.terms.Atom
import prolog.ast.terms.Integer
import prolog.ast.arithmetic.Integer
import prolog.ast.terms.Variable
class UnificationTest {