Compare commits
1 commit
a937b1bc44
...
095659cf30
Author | SHA1 | Date | |
---|---|---|---|
095659cf30 |
4 changed files with 70 additions and 15 deletions
31
src/Main.kt
31
src/Main.kt
|
@ -1,14 +1,7 @@
|
||||||
import better_parser.PrologParser
|
|
||||||
import better_parser.SimpleReplParser
|
import better_parser.SimpleReplParser
|
||||||
import interpreter.SourceFileReader
|
import interpreter.SourceFileReader
|
||||||
import prolog.Answer
|
import prolog.Answer
|
||||||
import prolog.Program
|
import kotlin.system.exitProcess
|
||||||
import prolog.ast.logic.Fact
|
|
||||||
import prolog.ast.logic.Rule
|
|
||||||
import prolog.ast.terms.Atom
|
|
||||||
import prolog.ast.terms.CompoundTerm
|
|
||||||
import prolog.ast.terms.Variable
|
|
||||||
import prolog.builtins.Conjunction
|
|
||||||
|
|
||||||
fun help(): String {
|
fun help(): String {
|
||||||
println("Unknown command. Type 'h' for help.")
|
println("Unknown command. Type 'h' for help.")
|
||||||
|
@ -27,10 +20,26 @@ fun say(message: String) {
|
||||||
|
|
||||||
fun prompt(message: String): String {
|
fun prompt(message: String): String {
|
||||||
print("$message ")
|
print("$message ")
|
||||||
var input: String = readlnOrNull() ?: help()
|
var input = readlnOrNull()
|
||||||
while (input.isBlank()) {
|
|
||||||
input = readlnOrNull() ?: help()
|
while (input.isNullOrBlank()) {
|
||||||
|
if (input == null) {
|
||||||
|
println("Exiting Prolog REPL.")
|
||||||
|
exitProcess(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input.isBlank()) {
|
||||||
|
print("$message ")
|
||||||
|
}
|
||||||
|
|
||||||
|
input = readlnOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (input == "exit") {
|
||||||
|
println("Exiting Prolog REPL.")
|
||||||
|
exitProcess(0)
|
||||||
|
}
|
||||||
|
|
||||||
return input
|
return input
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,23 @@ import prolog.ast.terms.*
|
||||||
import prolog.logic.*
|
import prolog.logic.*
|
||||||
|
|
||||||
// TODO >
|
// TODO >
|
||||||
|
class GreaterThan(private val left: Expression, private val right: Expression) :
|
||||||
|
Operator(Atom(">"), left, right), Satisfiable {
|
||||||
|
override fun satisfy(subs: Substitutions): Answers {
|
||||||
|
val t1 = left.simplify(subs)
|
||||||
|
val t2 = right.simplify(subs)
|
||||||
|
|
||||||
|
if (!atomic(t1.to, subs) || !atomic(t2.to, subs)) {
|
||||||
|
return sequenceOf(Result.failure(IllegalArgumentException("Both operands must be instantiated")))
|
||||||
|
}
|
||||||
|
|
||||||
|
return if (0 < compare(t1.to, t2.to, subs)) {
|
||||||
|
sequenceOf(Result.success(emptyMap()))
|
||||||
|
} else {
|
||||||
|
emptySequence()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO <
|
// TODO <
|
||||||
|
|
||||||
|
|
|
@ -6,4 +6,5 @@ parent(mary, jimmy).
|
||||||
father(X, Y) :- parent(X, Y), male(X).
|
father(X, Y) :- parent(X, Y), male(X).
|
||||||
mother(X, Y) :- parent(X, Y), female(X).
|
mother(X, Y) :- parent(X, Y), female(X).
|
||||||
|
|
||||||
kan_goed_koken(miriam).
|
foo(0).
|
||||||
|
foo(X) :- X > 0, Y is X - 1, foo(Y).
|
||||||
|
|
|
@ -3,15 +3,14 @@ package prolog
|
||||||
import org.junit.jupiter.api.Assertions.*
|
import org.junit.jupiter.api.Assertions.*
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
import prolog.ast.arithmetic.Integer
|
||||||
import prolog.ast.logic.Fact
|
import prolog.ast.logic.Fact
|
||||||
import prolog.ast.logic.Rule
|
import prolog.ast.logic.Rule
|
||||||
import prolog.builtins.Conjunction
|
|
||||||
import prolog.builtins.Disjunction
|
|
||||||
import prolog.builtins.Query
|
|
||||||
import prolog.logic.equivalent
|
import prolog.logic.equivalent
|
||||||
import prolog.ast.terms.Atom
|
import prolog.ast.terms.Atom
|
||||||
import prolog.ast.terms.Structure
|
import prolog.ast.terms.Structure
|
||||||
import prolog.ast.terms.Variable
|
import prolog.ast.terms.Variable
|
||||||
|
import prolog.builtins.*
|
||||||
|
|
||||||
class EvaluationTests {
|
class EvaluationTests {
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
|
@ -215,4 +214,33 @@ class EvaluationTests {
|
||||||
assertTrue(expectedResults[i].all { actualResults[i].getOrNull()!![it.key]?.let { it1 -> equivalent(it.value, it1, emptyMap()) } ?: false }, "Substitution values should match")
|
assertTrue(expectedResults[i].all { actualResults[i].getOrNull()!![it.key]?.let { it1 -> equivalent(it.value, it1, emptyMap()) } ?: false }, "Substitution values should match")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
foo(0).
|
||||||
|
foo(X) :- X > 0, Y is X - 1, foo(Y).
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
fun recursive_query() {
|
||||||
|
val fact = Fact(Structure(Atom("foo"), listOf(Integer(0))))
|
||||||
|
val rule = Rule(
|
||||||
|
Structure(Atom("foo"), listOf(Variable("X"))),
|
||||||
|
Conjunction(
|
||||||
|
GreaterThan(Variable("X"), Integer(0)),
|
||||||
|
Conjunction(
|
||||||
|
Is(Variable("Y"), Subtract(Variable("X"), Integer(1))),
|
||||||
|
Structure(Atom("foo"), listOf(Variable("Y")))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
Program.load(listOf(fact, rule))
|
||||||
|
|
||||||
|
val result = Program.query(Structure(Atom("foo"), listOf(Integer(0)))).toList()
|
||||||
|
|
||||||
|
val result5 = Program.query(Structure(Atom("foo"), listOf(Integer(5)))).toList()
|
||||||
|
|
||||||
|
assertTrue(Program.query(Structure(Atom("foo"), listOf(Atom("1")))).any())
|
||||||
|
assertTrue(Program.query(Structure(Atom("foo"), listOf(Atom("2")))).any())
|
||||||
|
assertFalse(Program.query(Structure(Atom("foo"), listOf(Atom("-1")))).any())
|
||||||
|
}
|
||||||
}
|
}
|
Reference in a new issue