RetractAll

This commit is contained in:
Tibo De Peuter 2025-05-05 22:06:26 +02:00
parent 4d334c1600
commit 1179e6a29b
Signed by: tdpeuter
GPG key ID: 38297DE43F75FFE2
4 changed files with 94 additions and 16 deletions

View file

@ -94,6 +94,7 @@ open class Preprocessor {
// Database
term.functor == "dynamic/1" -> Dynamic((args[0] as Atom).name)
term.functor == "retract/1" -> Retract(args[0])
term.functor == "retractall/1" -> RetractAll(args[0])
term.functor == "assert/1" -> {
if (args[0] is Rule) {
Assert(args[0] as Rule)
@ -138,4 +139,4 @@ open class Preprocessor {
return prepped
}
}
}

View file

@ -1,5 +1,6 @@
package prolog.builtins
import io.Logger
import prolog.Answers
import prolog.Substitutions
import prolog.ast.logic.Clause
@ -86,7 +87,7 @@ open class AssertZ(val clause: Clause) : Operator(Atom("assertz"), null, clause)
*
* @see [SWI-Prolog Predicate retract/1](https://www.swi-prolog.org/pldoc/doc_for?object=retract/1)
*/
class Retract(val term: Term) : Operator(Atom("retract"), null, term) {
open class Retract(val term: Term) : Operator(Atom("retract"), null, term) {
override fun satisfy(subs: Substitutions): Answers = sequence {
// Check that term is a structure or atom
if (term !is Structure && term !is Atom) {
@ -101,6 +102,12 @@ class Retract(val term: Term) : Operator(Atom("retract"), null, term) {
return@sequence
}
// Check if the predicate is dynamic
if (!predicate.dynamic) {
yield(Result.failure(Exception("No permission to modify static procedure '$functorName'")))
return@sequence
}
predicate.clauses.toList().forEach { clause ->
unifyLazy(term, clause.head, subs).forEach { unifyResult ->
unifyResult.fold(
@ -119,3 +126,29 @@ class Retract(val term: Term) : Operator(Atom("retract"), null, term) {
override fun applySubstitution(subs: Substitutions): Retract = Retract(applySubstitution(term, subs))
}
class RetractAll(term: Term) : Retract(term) {
override fun satisfy(subs: Substitutions): Answers {
// Check that term is a structure or atom
if (term !is Structure && term !is Atom) {
return sequenceOf(Result.failure(Exception("Cannot retract a non-structure or non-atom")))
}
// If the predicate does not exist, implicitly create it
val functor = term.functor
val predicate = Program.db.predicates[functor]
if (predicate == null) {
Logger.debug("Predicate $functor not found, creating it")
Program.db.predicates += functor to Predicate(functor, dynamic = true)
}
// Propagate errors from the super class
super.satisfy(subs).forEach {
if (it.isFailure) {
return sequenceOf(it)
}
}
return sequenceOf(Result.success(emptyMap()))
}
}

View file

@ -95,9 +95,7 @@ class Repl {
return subs.entries.joinToString(",\n") { "${it.key} = ${it.value}" }
},
onFailure = {
val text = "Failure: ${it.message}"
Logger.warn(text)
return text
return "ERROR: ${it.message}"
}
)
}