Checkpoint

This commit is contained in:
Tibo De Peuter 2025-05-04 21:50:58 +02:00
parent 5bfa1691dd
commit a85169dced
Signed by: tdpeuter
GPG key ID: 38297DE43F75FFE2
27 changed files with 377 additions and 250 deletions

View file

@ -120,7 +120,8 @@ class Bar(leftOperand: LogicOperand, rightOperand: LogicOperand) : Disjunction(l
class Not(private val goal: Goal) : LogicOperator(Atom("\\+"), rightOperand = goal) {
override fun satisfy(subs: Substitutions): Answers {
// If the goal can be proven, return an empty sequence
if (goal.satisfy(subs).toList().isNotEmpty()) {
val goalResults = goal.satisfy(subs).iterator()
if (goalResults.hasNext()) {
return emptySequence()
}
// If the goal cannot be proven, return a sequence with an empty map

View file

@ -6,14 +6,44 @@ import prolog.ast.logic.Clause
import prolog.ast.terms.Atom
import prolog.ast.terms.Structure
import prolog.ast.logic.Predicate
import prolog.Program
import prolog.ast.Database.Program
import prolog.ast.terms.Functor
import prolog.ast.terms.Term
import prolog.ast.logic.Fact
import prolog.ast.Database
import prolog.ast.terms.Body
import prolog.ast.terms.Goal
import prolog.ast.terms.Operator
import prolog.logic.applySubstitution
import prolog.logic.unifyLazy
/**
* (Make) the [Predicate] with the corresponding [Functor] dynamic.
*/
class Dynamic(private val dynamicFunctor: Functor): Goal(), Body {
override val functor: Functor = "dynamic/1"
override fun satisfy(subs: Substitutions): Answers {
val predicate = Program.db.predicates[dynamicFunctor]
if (predicate == null) {
return sequenceOf(Result.failure(Exception("Predicate $dynamicFunctor not found")))
}
predicate.dynamic = true
return sequenceOf(Result.success(emptyMap()))
}
override fun toString(): String = "dynamic $dynamicFunctor"
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is Dynamic) return false
return dynamicFunctor == other.dynamicFunctor
}
override fun hashCode(): Int = super.hashCode()
}
class Assert(clause: Clause) : AssertZ(clause) {
override val functor: Functor = "assert/1"
}
@ -24,7 +54,8 @@ class Assert(clause: Clause) : AssertZ(clause) {
class AssertA(val clause: Clause) : Operator(Atom("asserta"), null, clause) {
override fun satisfy(subs: Substitutions): Answers {
// Add clause to the program
Program.load(listOf(clause), 0)
val evaluatedClause = applySubstitution(clause, subs) as Clause
Program.load(listOf(evaluatedClause), 0)
return sequenceOf(Result.success(emptyMap()))
}
@ -36,7 +67,8 @@ class AssertA(val clause: Clause) : Operator(Atom("asserta"), null, clause) {
open class AssertZ(val clause: Clause) : Operator(Atom("assertz"), null, clause) {
override fun satisfy(subs: Substitutions): Answers {
// Add clause to the program
Program.load(listOf(clause))
val evaluatedClause = applySubstitution(clause, subs) as Clause
Program.load(listOf(evaluatedClause))
return sequenceOf(Result.success(emptyMap()))
}
@ -58,26 +90,24 @@ class Retract(val term: Term) : Operator(Atom("retract"), null, term) {
val functorName = term.functor
Program.databases
.filter { it.predicates.containsKey(functorName) }
.mapNotNull { it.predicates[functorName] }
.map { predicate ->
val clausesIterator = predicate.clauses.iterator()
while (clausesIterator.hasNext()) {
val clause = clausesIterator.next()
unifyLazy(term, clause.head, subs).forEach { unifyResult ->
unifyResult.fold(
onSuccess = { substitutions ->
// If unification is successful, remove the clause
yield(Result.success(substitutions))
clausesIterator.remove()
},
onFailure = {
// If unification fails, do nothing
}
)
val predicate = Program.db.predicates[functorName]
if (predicate == null) {
return@sequence
}
predicate.clauses.toList().forEach { clause ->
unifyLazy(term, clause.head, subs).forEach { unifyResult ->
unifyResult.fold(
onSuccess = { substitutions ->
// If unification is successful, remove the clause
predicate.clauses.remove(clause)
yield(Result.success(substitutions))
},
onFailure = {
// If unification fails, do nothing
}
}
)
}
}
}
}

View file

@ -4,7 +4,7 @@ import io.Logger
import io.Terminal
import parser.ReplParser
import prolog.Answers
import prolog.Program
import prolog.ast.Database.Program
import prolog.Substitutions
import prolog.ast.logic.Satisfiable
import prolog.ast.terms.Atom
@ -26,6 +26,8 @@ class Write(private val term: Term) : Operator(Atom("write"), null, term), Satis
return sequenceOf(Result.success(emptyMap()))
}
override fun toString(): String = "write($term)"
}
/**

View file

@ -8,6 +8,7 @@ import prolog.ast.logic.LogicOperator
class Initialization(val goal: LogicOperand) : LogicOperator(Atom(":-"), null, goal) {
override fun satisfy(subs: Substitutions): Answers = goal.satisfy(subs).take(1)
override fun toString(): String = goal.toString()
}
class Query(val query: LogicOperand) : LogicOperator(Atom("?-"), null, query) {