Checkpoint
This commit is contained in:
parent
23b2ce9362
commit
f9017da734
18 changed files with 814 additions and 412 deletions
9
tests/interpreter/OpenPreprocessor.kt
Normal file
9
tests/interpreter/OpenPreprocessor.kt
Normal file
|
@ -0,0 +1,9 @@
|
|||
package interpreter
|
||||
|
||||
import prolog.ast.terms.Term
|
||||
|
||||
class OpenPreprocessor : Preprocessor() {
|
||||
public override fun preprocess(term: Term, nested: Boolean): Term {
|
||||
return super.preprocess(term, nested)
|
||||
}
|
||||
}
|
93
tests/interpreter/ParserPreprocessorIntegrationTests.kt
Normal file
93
tests/interpreter/ParserPreprocessorIntegrationTests.kt
Normal file
|
@ -0,0 +1,93 @@
|
|||
package interpreter
|
||||
|
||||
import com.github.h0tk3y.betterParse.grammar.parseToEnd
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.params.ParameterizedTest
|
||||
import org.junit.jupiter.params.provider.ValueSource
|
||||
import parser.grammars.TermsGrammar
|
||||
import prolog.Program
|
||||
import prolog.ast.arithmetic.Float
|
||||
import prolog.ast.arithmetic.Integer
|
||||
import prolog.ast.terms.Atom
|
||||
import prolog.ast.terms.Goal
|
||||
import prolog.ast.terms.Structure
|
||||
import prolog.ast.terms.Term
|
||||
import prolog.ast.terms.Variable
|
||||
import prolog.builtins.Is
|
||||
import prolog.builtins.Subtract
|
||||
|
||||
class ParserPreprocessorIntegrationTests {
|
||||
@Nested
|
||||
class `Arithmetic`() {
|
||||
val parser = TermsGrammar()
|
||||
val preprocessor = OpenPreprocessor()
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = ["-1", "-1.0", "-1.5"])
|
||||
fun `can parse negative numbers`(input: String) {
|
||||
val number = if (input.contains('.')) {
|
||||
Float(input.substring(1).toFloat())
|
||||
} else {
|
||||
Integer(input.substring(1).toInt())
|
||||
}
|
||||
val negativeNumber = if (input.contains('.')) {
|
||||
Float(input.toFloat())
|
||||
} else {
|
||||
Integer(input.toInt())
|
||||
}
|
||||
|
||||
// Check if parser returns the same result
|
||||
|
||||
val parsed = parser.parseToEnd("X is $input") as Term
|
||||
|
||||
assertEquals(
|
||||
Structure(Atom("is"), listOf(
|
||||
Variable("X"),
|
||||
Structure(Atom("-"), listOf(number)),
|
||||
)),
|
||||
parsed
|
||||
)
|
||||
|
||||
// Check if preprocessor returns the same result
|
||||
|
||||
val prepped = preprocessor.preprocess(parsed)
|
||||
|
||||
val expected = Is(
|
||||
Variable("X"),
|
||||
Subtract(Integer(0), number)
|
||||
)
|
||||
|
||||
assertEquals(expected, prepped)
|
||||
assertEquals(expected.toString(), prepped.toString())
|
||||
|
||||
// Check if evaluation is correct
|
||||
|
||||
val solutions = (prepped as Is).satisfy(emptyMap()).toList()
|
||||
|
||||
assertEquals(1, solutions.size)
|
||||
assertEquals(negativeNumber, solutions[0].getOrNull()!![Variable("X")])
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = ["X is 1 - 2", "X is 1-2"])
|
||||
fun `can add negative numbers`(input: String) {
|
||||
val result = parser.parseToEnd(input) as Term
|
||||
|
||||
assertEquals(
|
||||
Structure(Atom("is"), listOf(Variable("X"), Structure(Atom("-"), listOf(Integer(1), Integer(2))))),
|
||||
result
|
||||
)
|
||||
|
||||
val prepped = preprocessor.preprocess(result)
|
||||
|
||||
val expected = Is(
|
||||
Variable("X"),
|
||||
Subtract(Integer(1), Integer(2))
|
||||
)
|
||||
|
||||
assertEquals(expected, prepped)
|
||||
assertEquals(expected.toString(), prepped.toString())
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,32 +1,80 @@
|
|||
package interpreter
|
||||
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import com.github.h0tk3y.betterParse.grammar.parseToEnd
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
import parser.grammars.TermsGrammar
|
||||
import prolog.ast.arithmetic.Integer
|
||||
import prolog.ast.terms.Atom
|
||||
import prolog.ast.terms.CompoundTerm
|
||||
import prolog.ast.terms.Term
|
||||
import prolog.ast.terms.Variable
|
||||
import prolog.ast.terms.*
|
||||
import prolog.builtins.*
|
||||
|
||||
class PreprocessorTests {
|
||||
class OpenPreprocessor : Preprocessor() {
|
||||
public override fun preprocess(term: Term, nested: Boolean): Term {
|
||||
return super.preprocess(term, nested)
|
||||
}
|
||||
}
|
||||
val preprocessor = OpenPreprocessor()
|
||||
|
||||
companion object {
|
||||
val preprocessor = OpenPreprocessor()
|
||||
|
||||
fun test(tests: Map<Term, Term>) {
|
||||
for ((input, expected) in tests) {
|
||||
val result = OpenPreprocessor().preprocess(input)
|
||||
val result = preprocessor.preprocess(input)
|
||||
assertEquals(expected, result, "Expected preprocessed")
|
||||
assertEquals(expected::class, result::class, "Expected same class")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can preprocess anonymous variable`() {
|
||||
val input = Variable("_")
|
||||
|
||||
val result = preprocessor.preprocess(input)
|
||||
|
||||
assertInstanceOf(AnonymousVariable::class.java, result, "Expected anonymous variable")
|
||||
assertTrue((result as Variable).name.matches("_\\d+".toRegex()), "Expected anonymous variable name")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `multiple anonymous variables should be unique`() {
|
||||
val input = CompoundTerm(Atom("foo"), listOf(Variable("_"), Variable("_")))
|
||||
|
||||
val result = preprocessor.preprocess(input)
|
||||
|
||||
assertInstanceOf(CompoundTerm::class.java, result, "Expected compound term")
|
||||
assertEquals(2, (result as CompoundTerm).arguments.size, "Expected two terms")
|
||||
for (argument in result.arguments) {
|
||||
assertTrue(
|
||||
(argument as Variable).name.matches("_\\d+".toRegex()),
|
||||
"Expected anonymous variable name, but got ${argument.name}"
|
||||
)
|
||||
}
|
||||
val first = result.arguments[0] as Variable
|
||||
val second = result.arguments[1] as Variable
|
||||
assertNotEquals(first.name, second.name, "Expected different anonymous variable names")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `can preprocess nested anonymous variables`() {
|
||||
val input = TermsGrammar().parseToEnd("name(character(Name, _, _, _))") as Term
|
||||
|
||||
val result = preprocessor.preprocess(input)
|
||||
|
||||
assertInstanceOf(CompoundTerm::class.java, result, "Expected compound term")
|
||||
assertEquals(1, (result as CompoundTerm).arguments.size, "Expected one term")
|
||||
assertInstanceOf(CompoundTerm::class.java, result.arguments[0], "Expected compound term")
|
||||
val inner = result.arguments[0] as CompoundTerm
|
||||
assertEquals(4, inner.arguments.size, "Expected four terms")
|
||||
for (argument in inner.arguments) {
|
||||
if ((argument as Variable).name != "Name") {
|
||||
assertTrue(
|
||||
(argument as Variable).name.matches("_\\d+".toRegex()),
|
||||
"Expected anonymous variable name, but got ${argument.name}"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
class `Arithmetic operators` {
|
||||
@Test
|
||||
|
@ -432,5 +480,22 @@ class PreprocessorTests {
|
|||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `is`() {
|
||||
test(
|
||||
mapOf(
|
||||
CompoundTerm(Atom("is"), listOf(Variable("T"), Integer(1))) to Is(Variable("T"), Integer(1)),
|
||||
CompoundTerm(Atom("is"), listOf(Variable("T"), Add(Variable("HP"), Integer(5)))) to Is(
|
||||
Variable("T"),
|
||||
Add(Variable("HP"), Integer(5))
|
||||
),
|
||||
CompoundTerm(Atom("is"), listOf(Variable("T"), Subtract(Variable("HP"), Integer(5)))) to Is(
|
||||
Variable("T"),
|
||||
Subtract(Variable("HP"), Integer(5))
|
||||
),
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue