Checkpoint

This commit is contained in:
Tibo De Peuter 2025-05-02 13:28:00 +02:00
parent 23b2ce9362
commit f9017da734
Signed by: tdpeuter
GPG key ID: 38297DE43F75FFE2
18 changed files with 814 additions and 412 deletions

View file

@ -0,0 +1,17 @@
package prolog.ast.terms
import io.Logger
class AnonymousVariable(id: Int) : Variable("_$id") {
companion object {
private var counter = 0
fun create(): AnonymousVariable {
val id = counter
counter++
Logger.debug("Creating anonymous variable: _${id}")
return AnonymousVariable(id)
}
}
override fun toString(): String = "_"
}

View file

@ -6,7 +6,7 @@ import prolog.ast.arithmetic.Expression
import prolog.ast.arithmetic.Simplification
import prolog.ast.logic.LogicOperand
data class Variable(val name: String) : Term, Body, Expression, LogicOperand() {
open class Variable(val name: String) : Term, Body, Expression, LogicOperand() {
override fun simplify(subs: Substitutions): Simplification {
// If the variable is bound, return the value of the binding
// If the variable is not bound, return the variable itself
@ -28,5 +28,15 @@ data class Variable(val name: String) : Term, Body, Expression, LogicOperand() {
return sequenceOf(Result.failure(IllegalArgumentException("Unbound variable: $this")))
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || other !is Variable) return false
return name == other.name
}
override fun hashCode(): Int {
return name.hashCode()
}
override fun toString(): String = name
}

View file

@ -3,10 +3,10 @@ package prolog.builtins
import prolog.Answers
import prolog.Substitutions
import prolog.ast.logic.LogicOperand
import prolog.ast.logic.LogicOperator
import prolog.ast.terms.Atom
import prolog.ast.terms.Body
import prolog.ast.terms.Goal
import prolog.ast.logic.LogicOperator
import prolog.flags.AppliedCut
/**

View file

@ -18,12 +18,7 @@ import prolog.logic.unifyLazy
*/
class Write(private val term: Term) : Operator(Atom("write"), null, term), Satisfiable {
override fun satisfy(subs: Substitutions): Answers {
var t = term
var temp = applySubstitution(t, subs)
while (t != temp) {
t = temp
temp = applySubstitution(t, subs)
}
val t = applySubstitution(term, subs)
Terminal().say(t.toString())

View file

@ -58,7 +58,7 @@ fun succ(term1: Expression, term2: Expression, subs: Substitutions): Answers {
it.fold(
onSuccess = { result ->
val t1 = applySubstitution(term1, result)
if (t1 in result) {
if (t1 in result || t1 in result.values) {
val e1 = t1.simplify(result)
if (e1.to is Integer && e1.to.value < 0) {
return@sequence

View file

@ -13,7 +13,15 @@ import prolog.ast.arithmetic.Float
// Apply substitutions to a term
fun applySubstitution(term: Term, subs: Substitutions): Term = when {
variable(term, emptyMap()) -> subs[(term as Variable)] ?: term
variable(term, emptyMap()) -> {
var result = subs[(term as Variable)]
while (result != null && result is Variable && result in subs) {
result = subs[result]
}
result ?: term
}
atomic(term, subs) -> term
compound(term, subs) -> {
val structure = term as Structure
@ -25,7 +33,7 @@ fun applySubstitution(term: Term, subs: Substitutions): Term = when {
//TODO Combine with the other applySubstitution function
fun applySubstitution(expr: Expression, subs: Substitutions): Expression = when {
variable(expr, subs) -> applySubstitution(expr as Term, subs) as Expression
variable(expr, emptyMap()) -> applySubstitution(expr as Term, subs) as Expression
atomic(expr, subs) -> expr
expr is LogicOperator -> {
expr.arguments = expr.arguments.map { applySubstitution(it, subs) }