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")
 }