Call & Ignore
This commit is contained in:
parent
9b454a9669
commit
5bfeb96176
7 changed files with 118 additions and 28 deletions
39
src/prolog/builtins/metaOperators.kt
Normal file
39
src/prolog/builtins/metaOperators.kt
Normal 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))
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
Reference in a new issue