import better_parser.PrologParser import better_parser.SimpleReplParser import interpreter.SourceFileReader import prolog.Answer import prolog.Program 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 { println("Unknown command. Type 'h' for help.") println("Commands:") println(" ; - find next solution") println(" a - abort") println(" . - end query") println(" h - help") println(" exit - exit Prolog REPL") return "" } fun say(message: String) { println(message) } fun prompt(message: String): String { print("$message ") var input: String = readlnOrNull() ?: help() while (input.isBlank()) { input = readlnOrNull() ?: help() } return input } fun prettyResult(result: Answer): String { result.fold( onSuccess = { val subs = result.getOrNull()!! if (subs.isEmpty()) { return "true." } return subs.entries.joinToString(", ") { "${it.key} = ${it.value}" } }, onFailure = { return "Failure: ${result.exceptionOrNull()!!}" } ) } val knownCommands = setOf(";", "a", ".") fun main() { SourceFileReader().readFile("tests/better_parser/resources/parent.pl") val parser = SimpleReplParser(debug = false) say("Prolog REPL. Type 'exit' to quit.") while (true) { val queryString = prompt("?-") try { val query = parser.parse(queryString) val answers = query.satisfy(emptyMap()) if (answers.none()) { say("false.") } else { val iterator = answers.iterator() var previous = iterator.next() while (iterator.hasNext()) { var command = prompt(prettyResult(previous)) while (command !in knownCommands) { say("Unknown action: $command (h for help)") command = prompt("Action?") } when (command) { ";" -> previous = iterator.next() "a" -> break "." -> break } } say(prettyResult(previous)) } } catch (e: Exception) { println("Error: ${e.message}") } } }