Functor
This commit is contained in:
parent
dff53b4e68
commit
65c4d925d3
15 changed files with 270 additions and 83 deletions
|
@ -612,7 +612,7 @@ class PreprocessorTests {
|
|||
Atom("declaration/1")
|
||||
)
|
||||
)
|
||||
val expected = Dynamic("declaration/1")
|
||||
val expected = Dynamic(FunctorInfo.of("declaration/1"))
|
||||
|
||||
val result = preprocessor.preprocess(input)
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import prolog.ast.terms.CompoundTerm
|
|||
import prolog.ast.terms.Structure
|
||||
import prolog.ast.terms.Variable
|
||||
import prolog.builtins.Conjunction
|
||||
import prolog.ast.terms.FunctorInfo
|
||||
|
||||
class LogicGrammarTests {
|
||||
private lateinit var parser: Grammar<List<Clause>>
|
||||
|
@ -94,13 +95,13 @@ class LogicGrammarTests {
|
|||
|
||||
assertTrue(rule.head is Structure, "Expected head to be a structure")
|
||||
val head = rule.head as Structure
|
||||
assertEquals("parent/2", head.functor, "Expected functor 'parent/2'")
|
||||
assertEquals(FunctorInfo.of("parent/2"), head.functor, "Expected functor 'parent/2'")
|
||||
assertEquals(Variable("X"), head.arguments[0], "Expected first argument 'X'")
|
||||
assertEquals(Variable("Y"), head.arguments[1], "Expected second argument 'Y'")
|
||||
|
||||
assertTrue(rule.body is Structure, "Expected body to be a structure")
|
||||
val body = rule.body as Structure
|
||||
assertEquals("father/2", body.functor, "Expected functor 'father/2'")
|
||||
assertEquals(FunctorInfo.of("father/2"), body.functor, "Expected functor 'father/2'")
|
||||
assertEquals(Variable("X"), body.arguments[0], "Expected first argument 'X'")
|
||||
assertEquals(Variable("Y"), body.arguments[1], "Expected second argument 'Y'")
|
||||
}
|
||||
|
@ -125,12 +126,12 @@ class LogicGrammarTests {
|
|||
|
||||
assertEquals(1, result.size, "Expected 1 rule")
|
||||
val rule = result[0] as Rule
|
||||
assertEquals("guest/2", rule.head.functor, "Expected functor 'guest/2'")
|
||||
assertEquals(",/2", (rule.body as CompoundTerm).functor, "Expected functor ',/2'")
|
||||
assertEquals(FunctorInfo.of("guest/2"), rule.head.functor, "Expected functor 'guest/2'")
|
||||
assertEquals(FunctorInfo.of(",/2"), (rule.body as CompoundTerm).functor, "Expected functor ',/2'")
|
||||
val l1 = (rule.body as CompoundTerm).arguments[0] as CompoundTerm
|
||||
assertEquals(",/2", l1.functor, "Expected functor ',/2'")
|
||||
assertEquals(FunctorInfo.of(",/2"), l1.functor, "Expected functor ',/2'")
|
||||
val l2 = l1.arguments[0] as CompoundTerm
|
||||
assertEquals("invited/2", l2.functor, "Expected functor 'invited/2'")
|
||||
assertEquals(FunctorInfo.of("invited/2"), l2.functor, "Expected functor 'invited/2'")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -157,6 +158,6 @@ class LogicGrammarTests {
|
|||
assertEquals(1, result.size, "Expected 1 rule")
|
||||
assertTrue(result[0] is Rule, "Expected a rule")
|
||||
val rule = result[0] as Rule
|
||||
assertEquals("/_", rule.head.functor, "Expected a constraint")
|
||||
assertEquals(FunctorInfo.of("/0"), rule.head.functor, "Expected a constraint")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
package prolog.builtins
|
||||
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertInstanceOf
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.Test
|
||||
import prolog.ast.arithmetic.Integer
|
||||
import prolog.ast.terms.AnonymousVariable
|
||||
import prolog.ast.terms.Atom
|
||||
import prolog.ast.terms.Structure
|
||||
import prolog.ast.terms.Variable
|
||||
|
||||
class AnalysingAndConstructionOperatorsTests {
|
||||
@Test
|
||||
fun `functor(foo, foo, 0)`() {
|
||||
val functor = Functor(Atom("foo"), Atom("foo"), Integer(0))
|
||||
|
||||
val result = functor.satisfy(emptyMap()).toList()
|
||||
|
||||
assertEquals(1, result.size, "Expected 1 result")
|
||||
assertTrue(result[0].isSuccess, "Expected success")
|
||||
assertTrue(result[0].getOrNull()!!.isEmpty(), "Expected empty substitutions")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `functor(foo(X), foo, Y)`() {
|
||||
val functor = Functor(
|
||||
Structure(Atom("foo"), listOf(Variable("X"))),
|
||||
Atom("foo"),
|
||||
Variable("Y")
|
||||
)
|
||||
|
||||
val result = functor.satisfy(emptyMap()).toList()
|
||||
|
||||
assertEquals(1, result.size, "Expected 1 result")
|
||||
assertTrue(result[0].isSuccess, "Expected success")
|
||||
val subs = result[0].getOrNull()!!
|
||||
assertEquals(1, subs.size, "Expected 1 substitution")
|
||||
assertEquals(Integer(1), subs[Variable("Y")])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `functor(foo, X, Y)`() {
|
||||
val atom = Atom("foo")
|
||||
val functor = Functor(atom, Variable("X"), Variable("Y"))
|
||||
|
||||
val result = functor.satisfy(emptyMap()).toList()
|
||||
|
||||
assertEquals(1, result.size, "Expected 1 result")
|
||||
assertTrue(result[0].isSuccess, "Expected success")
|
||||
val subs = result[0].getOrNull()!!
|
||||
assertEquals(2, subs.size, "Expected 2 substitutions")
|
||||
assertEquals(atom.functor.name, subs[Variable("X")])
|
||||
assertEquals(atom.functor.arity, subs[Variable("Y")])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `functor(X, foo, 1)`() {
|
||||
val functor = Functor(Variable("X"), Atom("foo"), Integer(1))
|
||||
|
||||
val result = functor.satisfy(emptyMap()).toList()
|
||||
|
||||
assertEquals(1, result.size, "Expected 1 result")
|
||||
assertTrue(result[0].isSuccess, "Expected success")
|
||||
val subs = result[0].getOrNull()!!
|
||||
assertEquals(1, subs.size, "Expected 1 substitution")
|
||||
assertInstanceOf(Structure::class.java, subs[Variable("X")])
|
||||
val structure = subs[Variable("X")] as Structure
|
||||
assertEquals(Atom("foo"), structure.name)
|
||||
assertEquals(1, structure.arguments.size)
|
||||
assertInstanceOf(AnonymousVariable::class.java, structure.arguments[0])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `functor(foo(a), foo, 0)`() {
|
||||
val functor = Functor(Structure(Atom("foo"), listOf(Atom("a"))), Atom("foo"), Integer(0))
|
||||
|
||||
val result = functor.satisfy(emptyMap()).toList()
|
||||
|
||||
assertTrue(result.isEmpty(), "Expected no results")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `functor(foo(X), foo, 0)`() {
|
||||
val functor = Functor(Structure(Atom("foo"), listOf(Variable("X"))), Atom("foo"), Integer(0))
|
||||
|
||||
val result = functor.satisfy(emptyMap()).toList()
|
||||
|
||||
assertTrue(result.isEmpty(), "Expected no results")
|
||||
}
|
||||
}
|
|
@ -8,14 +8,13 @@ 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.ast.Database
|
||||
import prolog.ast.Database.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.Functor
|
||||
import prolog.ast.terms.FunctorInfo
|
||||
import prolog.ast.terms.Structure
|
||||
import prolog.ast.terms.Variable
|
||||
|
||||
|
@ -40,7 +39,7 @@ class DatabaseOperatorsTests {
|
|||
createAssert(fact).satisfy(emptyMap())
|
||||
|
||||
assertEquals(1, Program.db.predicates.size, "Expected 1 predicate")
|
||||
assertEquals(fact, Program.db.predicates["a/_"]!!.clauses[0])
|
||||
assertEquals(fact, Program.db.predicates[FunctorInfo.of("a/_")]!!.clauses[0])
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -49,7 +48,7 @@ class DatabaseOperatorsTests {
|
|||
createAssert(fact).satisfy(emptyMap())
|
||||
|
||||
assertEquals(1, Program.db.predicates.size, "Expected 1 predicate")
|
||||
assertEquals(fact, Program.db.predicates["a/1"]!!.clauses[0])
|
||||
assertEquals(fact, Program.db.predicates[FunctorInfo.of("a/1")]!!.clauses[0])
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -61,7 +60,7 @@ class DatabaseOperatorsTests {
|
|||
createAssert(rule).satisfy(emptyMap())
|
||||
|
||||
assertEquals(1, Program.db.predicates.size, "Expected 1 predicate")
|
||||
assertEquals(rule, Program.db.predicates["a/1"]!!.clauses[0])
|
||||
assertEquals(rule, Program.db.predicates[FunctorInfo.of("a/1")]!!.clauses[0])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,8 +91,8 @@ class DatabaseOperatorsTests {
|
|||
AssertA(rule2).satisfy(emptyMap())
|
||||
|
||||
assertEquals(1, Program.db.predicates.size, "Expected 1 predicate")
|
||||
assertEquals(rule2, Program.db.predicates["a/1"]!!.clauses[0])
|
||||
assertEquals(rule1, Program.db.predicates["a/1"]!!.clauses[1])
|
||||
assertEquals(rule2, Program.db.predicates[FunctorInfo.of("a/1")]!!.clauses[0])
|
||||
assertEquals(rule1, Program.db.predicates[FunctorInfo.of("a/1")]!!.clauses[1])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,8 +116,8 @@ class DatabaseOperatorsTests {
|
|||
AssertZ(rule2).satisfy(emptyMap())
|
||||
|
||||
assertEquals(1, Program.db.predicates.size, "Expected 1 predicate")
|
||||
assertEquals(rule1, Program.db.predicates["a/1"]!!.clauses[0])
|
||||
assertEquals(rule2, Program.db.predicates["a/1"]!!.clauses[1])
|
||||
assertEquals(rule1, Program.db.predicates[FunctorInfo.of("a/1")]!!.clauses[0])
|
||||
assertEquals(rule2, Program.db.predicates[FunctorInfo.of("a/1")]!!.clauses[1])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -309,20 +308,20 @@ class DatabaseOperatorsTests {
|
|||
|
||||
val control = Program.query(Structure(Atom("a"), listOf(Variable("X")))).toList()
|
||||
assertEquals(3, control.size, "Expected 3 results")
|
||||
assertEquals(3, Program.db.predicates["a/1"]!!.clauses.size, "Expected 3 clauses")
|
||||
assertEquals(3, Program.db.predicates[FunctorInfo.of("a/1")]!!.clauses.size, "Expected 3 clauses")
|
||||
|
||||
val retract = RetractAll(Structure(Atom("a"), listOf(Variable("X"))))
|
||||
val result = retract.satisfy(emptyMap()).toList()
|
||||
|
||||
assertEquals(1, result.size, "Expected 1 result")
|
||||
assertTrue(result[0].isSuccess, "Expected success")
|
||||
assertEquals(0, Program.db.predicates["a/1"]!!.clauses.size, "Expected 0 clauses")
|
||||
assertEquals(0, Program.db.predicates[FunctorInfo.of("a/1")]!!.clauses.size, "Expected 0 clauses")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `If Head refers to a predicate that is not defined, it is implicitly created as a dynamic predicate`() {
|
||||
val predicateName = "idonotyetexist"
|
||||
val predicateFunctor = "$predicateName/1"
|
||||
val predicateFunctor = FunctorInfo.of("$predicateName/1")
|
||||
|
||||
assertFalse(predicateFunctor in Program.db.predicates, "Expected predicate to not exist before")
|
||||
|
||||
|
|
Reference in a new issue