fix: Evaluation

This commit is contained in:
Tibo De Peuter 2025-04-06 17:29:23 +02:00
parent d702b9b081
commit 1acd1cfb67
Signed by: tdpeuter
GPG key ID: 38297DE43F75FFE2
17 changed files with 189 additions and 120 deletions

View file

@ -101,21 +101,28 @@ class EvaluationTest {
val father = Fact(Structure(Atom("father"), listOf(Atom("john"), Atom("jimmy"))))
val mother = Fact(Structure(Atom("mother"), listOf(Atom("jane"), Atom("jimmy"))))
val variable1 = Variable("X")
val variable2 = Variable("Y")
val parent = Rule(
Structure(Atom("parent"), listOf(Variable("X"), Variable("Y"))),
Structure(Atom("parent"), listOf(variable1, variable2)),
/* :- */ Disjunction(
Structure(Atom("father"), listOf(Variable("X"), Variable("Y"))),
Structure(Atom("father"), listOf(variable1, variable2)),
/* ; */
Structure(Atom("mother"), listOf(Variable("X"), Variable("Y")))
Structure(Atom("mother"), listOf(variable1, variable2))
))
Program.load(listOf(father, mother, parent))
assertTrue(Program.query(Structure(Atom("parent"), listOf(Atom("john"), Atom("jimmy")))))
assertTrue(Program.query(Structure(Atom("parent"), listOf(Atom("jane"), Atom("jimmy")))))
val result1 = Program.query(Structure(Atom("parent"), listOf(Atom("john"), Atom("jimmy"))))
assertTrue(result1)
val result2 = Program.query(Structure(Atom("parent"), listOf(Atom("jane"), Atom("jimmy"))))
assertTrue(result2)
assertFalse(Program.query(Structure(Atom("parent"), listOf(Atom("john"), Atom("jane")))))
assertFalse(Program.query(Structure(Atom("father"), listOf(Atom("john"), Atom("jane")))))
val result3 = Program.query(Structure(Atom("parent"), listOf(Atom("john"), Atom("jane"))))
assertFalse(result3)
val result4 = Program.query(Structure(Atom("father"), listOf(Atom("john"), Atom("jane"))))
assertFalse(result4)
}
/**
@ -130,18 +137,25 @@ class EvaluationTest {
val parent1 = Fact(Structure(Atom("parent"), listOf(Atom("john"), Atom("jimmy"))))
val parent2 = Fact(Structure(Atom("parent"), listOf(Atom("jane"), Atom("jimmy"))))
val variable1 = Variable("X")
val variable2 = Variable("Y")
val isFather = Rule(
Structure(Atom("isFather"), listOf(Variable("X"), Variable("Y"))),
Structure(Atom("isFather"), listOf(variable1, variable2)),
Conjunction(
Structure(Atom("parent"), listOf(Variable("X"), Variable("Y"))),
Structure(Atom("male"), listOf(Variable("X")))
Structure(Atom("parent"), listOf(variable1, variable2)),
Structure(Atom("male"), listOf(variable1))
)
)
val variable3 = Variable("X")
val variable4 = Variable("Y")
val isMother = Rule(
Structure(Atom("isMother"), listOf(Variable("X"), Variable("Y"))),
Structure(Atom("isMother"), listOf(variable3, variable4)),
Conjunction(
Structure(Atom("parent"), listOf(Variable("X"), Variable("Y"))),
Structure(Atom("female"), listOf(Variable("X")))
Structure(Atom("parent"), listOf(variable3, variable4)),
Structure(Atom("female"), listOf(variable3))
)
)

View file

@ -1,7 +1,9 @@
package prolog
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Test
import prolog.builtins.equivalent
import prolog.components.terms.Atom
import prolog.components.terms.Structure
import prolog.components.terms.Variable
@ -31,6 +33,10 @@ class UnifyTest {
assertFalse(result.isPresent, "Different atoms should not unify")
}
/**
* ?- X = X.
* true.
*/
@Test
fun identical_variables_unify() {
val variable1 = Variable("X")
@ -97,6 +103,10 @@ class UnifyTest {
assertFalse(result.isPresent, "Compound terms with different functors should not unify")
}
/**
* ?- X = f(a, b).
* X = f(a, b).
*/
@Test
fun variable_unifies_with_compound_term() {
val variable = Variable("X")
@ -106,7 +116,10 @@ class UnifyTest {
assertTrue(result.isPresent, "Variable should unify with compound term")
assertEquals(1, result.get().size, "There should be one substitution")
assertEquals(structure, variable.alias().get(), "Variable should be substituted with compound term")
assertTrue(
equivalent(Structure(Atom("f"), listOf(Atom("a"), Atom("b"))), variable.alias().get()),
"Variable should be substituted with compound term"
)
}
@Test
@ -119,7 +132,8 @@ class UnifyTest {
assertTrue(result.isPresent, "Compound term with variable should unify with part")
assertEquals(1, result.get().size, "There should be one substitution")
assertEquals(Atom("b"), variable.alias().get(), "Variable should be substituted with atom")
val equivalence = equivalent(Atom("b"), variable.alias().get())
assertTrue(equivalence, "Variable should be substituted with atom")
}
@Test
@ -151,7 +165,8 @@ class UnifyTest {
}
/**
* f(g(X)) = f(Y)
* ?- f(g(X)) = f(Y).
* Y = g(X).
*/
@Test
fun nested_compound_terms_with_variables_unify() {
@ -164,11 +179,16 @@ class UnifyTest {
assertTrue(result.isPresent, "Nested compound terms with variables should unify")
assertEquals(1, result.get().size, "There should be one substitution")
assertEquals(Structure(Atom("g"), listOf(Variable("X"))), variable2.alias().get(), "Variable should be substituted with compound term")
assertTrue(
equivalent(Structure(Atom("g"), listOf(Variable("X"))), variable2.alias().get()),
"Variable should be substituted with compound term"
)
}
/**
* f(g(X), X) = f(Y, a)
* ?- f(g(X), X) = f(Y, a).
* X = a,
* Y = g(a).
*/
@Test
fun compound_terms_with_more_variables() {
@ -183,8 +203,12 @@ class UnifyTest {
assertTrue(result.isPresent, "Compound terms with more variables should unify")
assertEquals(2, result.get().size, "There should be two substitutions")
assertEquals(Atom("a"), variable1.alias().get(), "Variable 1 should be substituted with atom")
assertEquals(Structure(Atom("g"), listOf(Atom("a"))), variable2.alias().get(), "Variable 2 should be substituted with compound term")
assertTrue(
equivalent(Atom("a"), variable1.alias().get()),
"Variable 1 should be substituted with atom"
)
val equivalence = equivalent(Structure(Atom("g"), listOf(Atom("a"))), variable2.alias().get())
assertTrue(equivalence, "Variable 2 should be substituted with compound term")
}
/**
@ -205,7 +229,9 @@ class UnifyTest {
/**
* ?- X = bar, Y = bar, X = Y.
* X = Y, Y = bar.
*/
@Disabled
@Test
fun multiple_unification() {
val variable1 = Variable("X")