Call & Ignore

This commit is contained in:
Tibo De Peuter 2025-05-09 08:36:11 +02:00
parent 9b454a9669
commit 5bfeb96176
Signed by: tdpeuter
GPG key ID: 38297DE43F75FFE2
7 changed files with 118 additions and 28 deletions

View file

@ -0,0 +1,39 @@
package prolog.builtins
import prolog.Answers
import prolog.Substitutions
import prolog.ast.terms.Atom
import prolog.ast.terms.Goal
import prolog.ast.terms.Operator
import prolog.flags.AppliedCut
class Call(private val goal: Goal) : Operator(Atom("call"), null, goal) {
override fun satisfy(subs: Substitutions): Answers = goal.satisfy(subs)
}
/**
* Calls [Goal] once, but succeeds, regardless of whether Goal succeeded or not.
*/
class Ignore(goal: Goal) : Operator(Atom("ignore"), null, goal) {
private val disjunction = Disjunction(
Conjunction(Call(goal), Cut()),
True
)
override fun satisfy(subs: Substitutions): Answers = sequence {
disjunction.satisfy(subs).forEach { result ->
result.fold(
onSuccess = { newSubs ->
yield(Result.success(newSubs))
},
onFailure = { failure ->
if (failure is AppliedCut && failure.subs != null) {
yield(Result.success(failure.subs))
} else {
yield(Result.failure(failure))
}
}
)
}
}
}