Assert{a,z,}

This commit is contained in:
Tibo De Peuter 2025-05-02 21:51:34 +02:00
parent f9017da734
commit 80fb3d1e60
Signed by: tdpeuter
GPG key ID: 38297DE43F75FFE2
11 changed files with 373 additions and 79 deletions

View file

@ -6,6 +6,8 @@ import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import parser.grammars.TermsGrammar
import prolog.ast.arithmetic.Integer
import prolog.ast.logic.Fact
import prolog.ast.logic.Rule
import prolog.ast.terms.*
import prolog.builtins.*
@ -498,4 +500,34 @@ class PreprocessorTests {
)
}
}
@Nested
class `Database operators` {
private val preprocessor = OpenPreprocessor()
@Test
fun `assert(fact)`() {
val input = Structure(
Atom("assert"), listOf(
Structure(
Atom(":-"), listOf(
Atom("a"),
Atom("b")
)
)
)
)
val expected = Assert(
Rule(
Atom("a"),
Atom("b")
)
)
val result = preprocessor.preprocess(input)
assertEquals(expected, result)
}
}
}

View file

@ -0,0 +1,65 @@
package parser.builtins
import com.github.h0tk3y.betterParse.grammar.Grammar
import com.github.h0tk3y.betterParse.grammar.parseToEnd
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import parser.grammars.TermsGrammar
import prolog.ast.terms.Atom
import prolog.ast.terms.Structure
import prolog.ast.terms.Term
import kotlin.test.assertEquals
class DatabaseOperatorsParserTests {
private lateinit var parser: Grammar<Term>
@BeforeEach
fun setup() {
parser = TermsGrammar() as Grammar<Term>
}
@Test
fun `parse assert(rule)`() {
val input = "assert((a :- b))"
val expected = Structure(Atom("assert"), listOf(
Structure(Atom(":-"), listOf(
Atom("a"),
Atom("b")
))
))
val result = parser.parseToEnd(input)
assertEquals(expected, result)
}
@Test
fun `parse assertA(rule)`() {
val input = "assertA((a :- b))"
val expected = Structure(Atom("assertA"), listOf(
Structure(Atom(":-"), listOf(
Atom("a"),
Atom("b")
))
))
val result = parser.parseToEnd(input)
assertEquals(expected, result)
}
@Test
fun `parse assertZ(rule)`() {
val input = "assertZ((a :- b))"
val expected = Structure(Atom("assertZ"), listOf(
Structure(Atom(":-"), listOf(
Atom("a"),
Atom("b")
))
))
val result = parser.parseToEnd(input)
assertEquals(expected, result)
}
}

View file

@ -0,0 +1,174 @@
package prolog.builtins
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.ValueSource
import prolog.Program
import prolog.ast.logic.Clause
import prolog.ast.logic.Fact
import prolog.ast.logic.Rule
import prolog.ast.terms.Atom
import prolog.ast.terms.Structure
import prolog.ast.terms.Variable
import kotlin.test.assertTrue
class DatabaseOperatorsTests {
abstract class AssertTestsBase<T : Structure> {
protected abstract fun createAssert(clause: Clause): Structure
@BeforeEach
fun setup() {
Program.clear()
}
@ParameterizedTest
@ValueSource(classes = [AssertA::class, AssertZ::class, Assert::class])
fun `assert(fact atom)`(assertKind: Class<*>) {
val fact = Fact(Atom("a"))
createAssert(fact).satisfy(emptyMap())
assertEquals(1, Program.internalDb.predicates.size, "Expected 1 predicate")
assertEquals(fact, Program.internalDb.predicates["a/_"]!!.clauses[0])
}
@Test
fun `assert(fact structure)`() {
val fact = Fact(Structure(Atom("a"), listOf(Atom("b"))))
createAssert(fact).satisfy(emptyMap())
assertEquals(1, Program.internalDb.predicates.size, "Expected 1 predicate")
assertEquals(fact, Program.internalDb.predicates["a/1"]!!.clauses[0])
}
@Test
fun `assert(rule)`() {
val rule = Rule(
Structure(Atom("a"), listOf(Atom("b"))),
Atom("c")
)
createAssert(rule).satisfy(emptyMap())
assertEquals(1, Program.internalDb.predicates.size, "Expected 1 predicate")
assertEquals(rule, Program.internalDb.predicates["a/1"]!!.clauses[0])
}
}
@Nested
class AssertTests : AssertTestsBase<Assert>() {
override fun createAssert(clause: Clause): Structure {
return Assert(clause)
}
}
@Nested
class AssertATests : AssertTestsBase<AssertA>() {
override fun createAssert(clause: Clause): Structure {
return AssertA(clause)
}
@Test
fun `asserta adds to the beginning`() {
val rule1 = Rule(
Structure(Atom("a"), listOf(Atom("b"))),
Atom("c")
)
val rule2 = Rule(
Structure(Atom("a"), listOf(Atom("d"))),
Atom("e")
)
AssertA(rule1).satisfy(emptyMap())
AssertA(rule2).satisfy(emptyMap())
assertEquals(1, Program.internalDb.predicates.size, "Expected 1 predicate")
assertEquals(rule2, Program.internalDb.predicates["a/1"]!!.clauses[0])
assertEquals(rule1, Program.internalDb.predicates["a/1"]!!.clauses[1])
}
}
@Nested
class AssertZTests : AssertTestsBase<AssertZ>() {
override fun createAssert(clause: Clause): Structure {
return AssertZ(clause)
}
@Test
fun `assertz adds to the end`() {
val rule1 = Rule(
Structure(Atom("a"), listOf(Atom("b"))),
Atom("c")
)
val rule2 = Rule(
Structure(Atom("a"), listOf(Atom("d"))),
Atom("e")
)
AssertZ(rule1).satisfy(emptyMap())
AssertZ(rule2).satisfy(emptyMap())
assertEquals(1, Program.internalDb.predicates.size, "Expected 1 predicate")
assertEquals(rule1, Program.internalDb.predicates["a/1"]!!.clauses[0])
assertEquals(rule2, Program.internalDb.predicates["a/1"]!!.clauses[1])
}
}
@Test
fun `custom example`() {
var query = Structure(Atom("likes"), listOf(Atom("alice"), Atom("pizza")))
var result = Program.query(query).toList()
assertEquals(0, result.size, "Expected 0 results")
var assert: Structure = Assert(Fact(query))
assert.satisfy(emptyMap())
result = Program.query(query).toList()
assertEquals(1, result.size, "Expected 1 result")
assertTrue(result[0].getOrNull()!!.isEmpty())
assert = AssertZ(Fact(Structure(Atom("likes"), listOf(Atom("bob"), Atom("sushi")))))
assert.satisfy(emptyMap())
query = Structure(Atom("likes"), listOf(Atom("bob"), Variable("X")))
result = Program.query(query).toList()
assertEquals(1, result.size, "Expected 1 result")
assertTrue(result[0].isSuccess, "Expected success")
assertEquals(Atom("sushi"), result[0].getOrNull()!![Variable("X")], "Expected sushi")
query = Structure(Atom("likes"), listOf(Variable("X"), Variable("Y")))
result = Program.query(query).toList()
assertEquals(2, result.size, "Expected 2 results")
assertTrue(result[0].isSuccess, "Expected success")
var result0 = result[0].getOrNull()!!
assertEquals(Atom("alice"), result0[Variable("X")], "Expected alice")
assertEquals(Atom("pizza"), result0[Variable("Y")], "Expected pizza")
assertTrue(result[1].isSuccess, "Expected success")
var result1 = result[1].getOrNull()!!
assertEquals(Atom("bob"), result1[Variable("X")], "Expected bob")
assertEquals(Atom("sushi"), result1[Variable("Y")], "Expected sushi")
assert = AssertA(Rule(
Structure(Atom("likes"), listOf(Variable("X"), Atom("italian"))),
Structure(Atom("likes"), listOf(Variable("X"), Atom("pizza")))
))
assert.satisfy(emptyMap())
result = Program.query(query).toList()
assertEquals(3, result.size, "Expected 3 results")
assertTrue(result[0].isSuccess, "Expected success")
result0 = result[0].getOrNull()!!
assertEquals(Atom("alice"), result0[Variable("X")], "Expected alice")
assertEquals(Atom("italian"), result0[Variable("Y")], "Expected italian")
assertTrue(result[1].isSuccess, "Expected success")
result1 = result[1].getOrNull()!!
assertEquals(Atom("alice"), result1[Variable("X")], "Expected alice")
assertEquals(Atom("pizza"), result1[Variable("Y")], "Expected pizza")
assertTrue(result[2].isSuccess, "Expected success")
val result2 = result[2].getOrNull()!!
assertEquals(Atom("bob"), result2[Variable("X")], "Expected bob")
assertEquals(Atom("sushi"), result2[Variable("Y")], "Expected sushi")
}
}