Retract
This commit is contained in:
parent
80fb3d1e60
commit
5bfa1691dd
10 changed files with 276 additions and 17 deletions
|
@ -9,6 +9,7 @@ import org.junit.jupiter.params.provider.ValueSource
|
|||
import prolog.Program
|
||||
import prolog.ast.logic.Clause
|
||||
import prolog.ast.logic.Fact
|
||||
import prolog.ast.logic.Predicate
|
||||
import prolog.ast.logic.Rule
|
||||
import prolog.ast.terms.Atom
|
||||
import prolog.ast.terms.Structure
|
||||
|
@ -16,6 +17,11 @@ import prolog.ast.terms.Variable
|
|||
import kotlin.test.assertTrue
|
||||
|
||||
class DatabaseOperatorsTests {
|
||||
@BeforeEach
|
||||
fun setup() {
|
||||
Program.clear()
|
||||
}
|
||||
|
||||
abstract class AssertTestsBase<T : Structure> {
|
||||
protected abstract fun createAssert(clause: Clause): Structure
|
||||
|
||||
|
@ -114,7 +120,111 @@ class DatabaseOperatorsTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `custom example`() {
|
||||
fun `retract fails silently for unknown predicates`() {
|
||||
val retract = Retract(Atom("unknown"))
|
||||
val result = retract.satisfy(emptyMap())
|
||||
|
||||
assertTrue(result.none(), "Expected no results")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `simple retract`() {
|
||||
val predicate = Predicate(listOf(Fact(Atom("a"))))
|
||||
Program.internalDb.load(predicate)
|
||||
|
||||
assertEquals(1, Program.query(Atom("a")).count())
|
||||
|
||||
val retract = Retract(Atom("a"))
|
||||
|
||||
assertTrue(retract.satisfy(emptyMap()).any(), "Expected 1 result")
|
||||
assertEquals(0, predicate.clauses.size, "Expected 0 clauses")
|
||||
|
||||
assertTrue(retract.satisfy(emptyMap()).none())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `retract atom`() {
|
||||
val predicate = Predicate(listOf(
|
||||
Fact(Atom("a")),
|
||||
Fact(Atom("a")),
|
||||
Fact(Atom("a"))
|
||||
))
|
||||
Program.internalDb.load(predicate)
|
||||
|
||||
val control = Program.query(Atom("a")).toList()
|
||||
|
||||
assertEquals(3, control.size, "Expected 3 results")
|
||||
|
||||
val retract = Retract(Atom("a"))
|
||||
|
||||
val result = retract.satisfy(emptyMap())
|
||||
|
||||
assertEquals(3, predicate.clauses.size, "Expected 3 clauses")
|
||||
|
||||
var answer = result.first()
|
||||
|
||||
assertTrue(answer.isSuccess, "Expected success")
|
||||
var subs = answer.getOrNull()!!
|
||||
assertTrue(subs.isEmpty(), "Expected no substitutions")
|
||||
assertEquals(2, predicate.clauses.size, "Expected 2 clauses")
|
||||
|
||||
assertTrue(result.first().isSuccess)
|
||||
assertTrue(result.first().isSuccess)
|
||||
|
||||
assertEquals(0, predicate.clauses.size, "Expected no remaining clauses")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `retract compound with variable`() {
|
||||
val predicate = Predicate(listOf(
|
||||
Fact(Structure(Atom("a"), listOf(Atom("b")))),
|
||||
Fact(Structure(Atom("a"), listOf(Atom("c")))),
|
||||
Fact(Structure(Atom("a"), listOf(Atom("d"))))
|
||||
))
|
||||
Program.internalDb.load(predicate)
|
||||
|
||||
val control = Program.query(Structure(Atom("a"), listOf(Variable("X")))).toList()
|
||||
|
||||
assertEquals(3, control.size, "Expected 3 results")
|
||||
|
||||
val retract = Retract(Structure(Atom("a"), listOf(Variable("X"))))
|
||||
|
||||
val result = retract.satisfy(emptyMap())
|
||||
|
||||
assertEquals(3, predicate.clauses.size, "Expected 3 clauses")
|
||||
|
||||
var answer = result.first()
|
||||
|
||||
assertTrue(answer.isSuccess, "Expected success")
|
||||
var subs = answer.getOrNull()!!
|
||||
assertTrue(subs.isNotEmpty(), "Expected substitutions")
|
||||
assertTrue(Variable("X") in subs, "Expected variable X")
|
||||
assertEquals(Atom("b"), subs[Variable("X")], "Expected b")
|
||||
assertEquals(2, predicate.clauses.size, "Expected 2 clauses")
|
||||
|
||||
answer = result.first()
|
||||
|
||||
assertTrue(answer.isSuccess, "Expected success")
|
||||
subs = answer.getOrNull()!!
|
||||
assertTrue(subs.isNotEmpty(), "Expected substitutions")
|
||||
assertTrue(Variable("X") in subs, "Expected variable X")
|
||||
assertEquals(Atom("c"), subs[Variable("X")], "Expected c")
|
||||
assertEquals(1, predicate.clauses.size, "Expected 1 clause")
|
||||
|
||||
answer = result.first()
|
||||
|
||||
assertTrue(answer.isSuccess, "Expected success")
|
||||
subs = answer.getOrNull()!!
|
||||
assertTrue(subs.isNotEmpty(), "Expected substitutions")
|
||||
assertTrue(Variable("X") in subs, "Expected variable X")
|
||||
assertEquals(Atom("d"), subs[Variable("X")], "Expected d")
|
||||
assertEquals(0, predicate.clauses.size, "Expected no clauses")
|
||||
|
||||
assertEquals(0, result.count(), "Expected no remaining results")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `custom assert example`() {
|
||||
var query = Structure(Atom("likes"), listOf(Atom("alice"), Atom("pizza")))
|
||||
|
||||
var result = Program.query(query).toList()
|
||||
|
@ -150,10 +260,12 @@ class DatabaseOperatorsTests {
|
|||
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 = 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()
|
||||
|
|
Reference in a new issue