Compare commits

...

1 commit

Author SHA1 Message Date
095659cf30
Checkpoint 2025-04-27 11:08:28 +02:00
4 changed files with 70 additions and 15 deletions

View file

@ -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
} }

View file

@ -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 <

View file

@ -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).

View file

@ -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())
}
} }