Checkpoint
This commit is contained in:
parent
23b2ce9362
commit
f9017da734
18 changed files with 814 additions and 412 deletions
|
@ -133,6 +133,21 @@ class LogicGrammarTests {
|
|||
assertEquals("invited/2", l2.functor, "Expected functor 'invited/2'")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `parse check_identical(X, Y)`() {
|
||||
var input = "check_identical(X, Y) :- X == Y."
|
||||
|
||||
assertDoesNotThrow {
|
||||
val result = parser.parseToEnd(input)
|
||||
}
|
||||
|
||||
input = "check_identical(X, Y) :- X = Y, !, write('X == Y succeeded'), nl."
|
||||
|
||||
assertDoesNotThrow {
|
||||
val result = parser.parseToEnd(input)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `parse constraints`() {
|
||||
val input = ":- a."
|
||||
|
|
|
@ -17,6 +17,7 @@ import prolog.ast.terms.Atom
|
|||
import prolog.ast.terms.Structure
|
||||
import prolog.ast.terms.Term
|
||||
import prolog.ast.terms.Variable
|
||||
import prolog.builtins.Is
|
||||
import prolog.logic.equivalent
|
||||
|
||||
class TermsGrammarTests {
|
||||
|
@ -60,7 +61,16 @@ class TermsGrammarTests {
|
|||
fun `parse variable`(name: String) {
|
||||
val result = parser.parseToEnd(name)
|
||||
|
||||
assertEquals(Variable(name), result, "Expected atom '$name'")
|
||||
assertEquals(Variable(name), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `parse anonymous variable`() {
|
||||
val input = "_"
|
||||
|
||||
val result = parser.parseToEnd(input)
|
||||
|
||||
assertEquals(Variable("_"), result, "Expected anonymous variable")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -100,24 +110,33 @@ class TermsGrammarTests {
|
|||
|
||||
val result = parser.parseToEnd(input)
|
||||
|
||||
assertTrue(
|
||||
equivalent(Structure(Atom("f"), listOf(Atom("a"), Variable("X"))), result, emptyMap()),
|
||||
assertEquals(
|
||||
Structure(Atom("f"), listOf(Atom("a"), Variable("X"))),
|
||||
result,
|
||||
"Expected atom 'f(a, X)'"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `parse compound term with var and int`() {
|
||||
val input = "check_identical(A, 13)"
|
||||
val result = parser.parseToEnd(input)
|
||||
assertEquals(
|
||||
Structure(Atom("check_identical"), listOf(Variable("A"), Integer(13))),
|
||||
result,
|
||||
"Expected atom 'check_identical(A, 13)'"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `parse nested compound term f(a, g(b))`() {
|
||||
val input = "f(a, g(b))"
|
||||
|
||||
val result = parser.parseToEnd(input)
|
||||
|
||||
Assertions.assertTrue(
|
||||
equivalent(
|
||||
Structure(Atom("f"), listOf(Atom("a"), Structure(Atom("g"), listOf(Atom("b"))))),
|
||||
result,
|
||||
emptyMap()
|
||||
),
|
||||
assertEquals(
|
||||
Structure(Atom("f"), listOf(Atom("a"), Structure(Atom("g"), listOf(Atom("b"))))),
|
||||
result,
|
||||
"Expected atom 'f(a, g(b))'"
|
||||
)
|
||||
}
|
||||
|
@ -128,24 +147,63 @@ class TermsGrammarTests {
|
|||
|
||||
val result = parser.parseToEnd(input)
|
||||
|
||||
Assertions.assertTrue(
|
||||
equivalent(
|
||||
Structure(Atom("f"), listOf(Atom("a"), Structure(Atom("g"), listOf(Variable("X"))))),
|
||||
result,
|
||||
emptyMap()
|
||||
),
|
||||
assertEquals(
|
||||
Structure(Atom("f"), listOf(Atom("a"), Structure(Atom("g"), listOf(Variable("X"))))),
|
||||
result,
|
||||
"Expected atom 'f(a, g(X))'"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `parse nested compound term with variables`() {
|
||||
val input = "hit(character(Name, Class, Level, HP), character(Name, Class, Level, T))"
|
||||
|
||||
val result = parser.parseToEnd(input)
|
||||
|
||||
assertEquals(
|
||||
Structure(
|
||||
Atom("hit"),
|
||||
listOf(
|
||||
Structure(Atom("character"), listOf(Variable("Name"), Variable("Class"), Variable("Level"), Variable("HP"))),
|
||||
Structure(Atom("character"), listOf(Variable("Name"), Variable("Class"), Variable("Level"), Variable("T")))
|
||||
)
|
||||
),
|
||||
result,
|
||||
"Expected atom 'hit(character(Name, Class, Level, HP), character(Name, Class, Level, T))'"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `parse compound term with anonymous variables`() {
|
||||
val input = "f(a, _, g(X))"
|
||||
|
||||
val result = parser.parseToEnd(input)
|
||||
|
||||
assertEquals(
|
||||
Structure(Atom("f"), listOf(Atom("a"), Variable("_"), Structure(Atom("g"), listOf(Variable("X"))))),
|
||||
result,
|
||||
"Expected atom 'f(a, _, g(X))'"
|
||||
)
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(ints = [-987654321, -543, -21, -1, 0, 1, 5, 12, 345, 123456789])
|
||||
fun `parse integer`(number: Int) {
|
||||
@ValueSource(ints = [0, 1, 5, 12, 345, 123456789])
|
||||
fun `parse positive integer`(number: Int) {
|
||||
val input = number.toString()
|
||||
|
||||
val result = parser.parseToEnd(input)
|
||||
|
||||
Assertions.assertEquals(Integer(number), result, "Expected integer '$number'")
|
||||
assertEquals(Integer(number), result, "Expected integer '$number'")
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(ints = [-987654321, -543, -21, -1])
|
||||
fun `parse negative integer`(number: Int) {
|
||||
val input = number.toString()
|
||||
|
||||
val result = parser.parseToEnd(input)
|
||||
|
||||
assertEquals(Structure(Atom("-"), listOf(Integer(0 - number))), result, "Expected integer '$number'")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -154,10 +212,7 @@ class TermsGrammarTests {
|
|||
|
||||
val result = parser.parseToEnd(input)
|
||||
|
||||
Assertions.assertTrue(
|
||||
equivalent(Float(42.0f), result, emptyMap()),
|
||||
"Expected float '42.0'"
|
||||
)
|
||||
assertEquals(Float(42.0f), result, "Expected float '42.0'")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -166,7 +221,7 @@ class TermsGrammarTests {
|
|||
|
||||
val result = parser.parseToEnd(input)
|
||||
|
||||
assertEquals(Float(-42.0f), result, "Expected float '-42.0'")
|
||||
assertEquals(Structure(Atom("-"), listOf(Float(42.0f))), result, "Expected float '-42.0'")
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
|
@ -176,7 +231,7 @@ class TermsGrammarTests {
|
|||
}
|
||||
|
||||
@Nested
|
||||
class `Operator precedence` {
|
||||
class `Operators and precedence` {
|
||||
private lateinit var parser: Grammar<Term>
|
||||
|
||||
@BeforeEach
|
||||
|
@ -184,6 +239,74 @@ class TermsGrammarTests {
|
|||
parser = TermsGrammar() as Grammar<Term>
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can parse equivalent`() {
|
||||
val input = "X == Y"
|
||||
|
||||
val result = parser.parseToEnd(input)
|
||||
|
||||
assertEquals(
|
||||
Structure(Atom("=="), listOf(Variable("X"), Variable("Y"))),
|
||||
result,
|
||||
"Expected equivalent operator"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can parse cut`() {
|
||||
val input = "!"
|
||||
val result = parser.parseToEnd(input)
|
||||
assertEquals(Atom("!"), result, "Expected cut operator")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can parse 'is'`() {
|
||||
val input = "T is 1"
|
||||
val result = parser.parseToEnd(input)
|
||||
assertEquals(
|
||||
Structure(Atom("is"), listOf(Variable("T"), Integer(1))),
|
||||
result
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can parse 'is' with addition`() {
|
||||
val input = "T is 1 + 2"
|
||||
val result = parser.parseToEnd(input)
|
||||
assertEquals(
|
||||
Structure(Atom("is"), listOf(Variable("T"), Structure(Atom("+"), listOf(Integer(1), Integer(2))))),
|
||||
result
|
||||
)
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = ["+", "-", "*", "/"])
|
||||
fun `can parse with spaces`(operator: String) {
|
||||
val input = "1 $operator 2"
|
||||
|
||||
val result = parser.parseToEnd(input)
|
||||
|
||||
assertEquals(
|
||||
Structure(Atom(operator), listOf(Integer(1), Integer(2))),
|
||||
result,
|
||||
"Expected operator '$operator'"
|
||||
)
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = ["+", "-", "*", "/"])
|
||||
fun `can parse without spaces`(operator: String) {
|
||||
val input = "1${operator}2"
|
||||
|
||||
val result = parser.parseToEnd(input)
|
||||
|
||||
assertEquals(
|
||||
Structure(Atom(operator), listOf(Integer(1), Integer(2))),
|
||||
result,
|
||||
"Expected operator '$operator' without spaces"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `parse addition and multiplication`() {
|
||||
val input = "1 + 2 * 3"
|
||||
|
|
Reference in a new issue