Coverage Summary for Class: Catch (it.unibo.tuprolog.argumentation.core.engine.stdlib.rule)
| Class |
Class, %
|
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
| Catch |
100%
(1/1)
|
80%
(4/5)
|
|
80%
(4/5)
|
97.3%
(36/37)
|
// Forked from 2p-kt's solve-prolog 3.0.2 (Apache License 2.0): see README.md in this package
package it.unibo.tuprolog.argumentation.core.engine.stdlib.rule
import it.unibo.tuprolog.argumentation.core.engine.PrologExecutionContext
import it.unibo.tuprolog.core.Scope
import it.unibo.tuprolog.core.Term
import it.unibo.tuprolog.solve.rule.RuleWrapper
import kotlin.collections.List as KtList
/**
* ISO `catch/3`: `catch(Goal, Catcher, Recovery) :- Goal.` -- the body just proves `Goal`; the actual
* catch/recovery behaviour is not implemented here but in `StateException`, which climbs the execution-context
* stack looking for a currently-executing goal shaped like this one whose `Catcher` unifies with a raised
* exception, and if so proves `Recovery` instead.
*/
object Catch : RuleWrapper<PrologExecutionContext>("catch", 3) {
override val help: String =
"""
`catch(+Goal, ?Catcher, +Recovery)`
Calls `Goal`, behaving exactly like `call/1` (including backtracking into `Goal`) as long as no exception is raised. If proving `Goal` raises an exception, via `throw/1` or a built-in error, whose ball unifies with `Catcher`, the bindings and choice points created by `Goal` are discarded and `Recovery` is called instead; otherwise the exception propagates to the outer `catch/3` calls.
**Examples**
```prolog
?- catch(X is 1 / 0, error(E, _), true).
E = evaluation_error(zero_divisor).
?- catch(throw(oops), oops, X = recovered).
X = recovered.
?- catch(member(X, [1, 2]), _, true).
X = 1 ; X = 2.
?- catch(catch(throw(oops), other, true), E, true).
E = oops.
```
""".trimIndent()
override val Scope.head: KtList<Term>
get() = listOf(varOf("G"), varOf("E"), varOf("C"))
override val Scope.body: Term
get() = varOf("G")
}