next up previous contents index
Next: ISO compliant Exception handling Up: Built-in predicates Previous: Control Predicates   Contents   Index


Meta-Call Predicates

Meta call predicates are used to call terms constructed at run time. The basic meta-call mechanism offered by SWI-Prolog is to use variables as a subclause (which should of course be bound to a valid goal at runtime). A meta-call is slower than a normal call as it involves actually searching the database at runtime for the predicate, while for normal calls this search is done at compile time.

call1+Goal Invoke Goal as a goal. Note that clauses may have variables as subclauses, which is identical to call1, except when the argument is bound to the cut. See 0. call2+Goal, +ExtraArg1, ... Append ExtraArg1, ExtraArg2, ... to the argument list of Goal and call the result. For example, call(plus(1), 2, X) will call plus3, binding X to 3.

The call/[2..] construct is handled by the compiler, which implies that redefinition as a predicate has no effect. The predicates call[2-6] are defined as true predicates, so they can be handled by interpreted code. apply2+Term, +List Append the members of List to the arguments of Term and call the resulting term. For example: apply(plus(1), [2, X]) will call plus(1, 2, X). apply2 is incorporated in the virtual machine of SWI-Prolog. This implies that the overhead can be compared to the overhead of call1. New code should use call/[2..] if the length of List is fixed, which is more widely supported and faster because there is no need to build and examine the argument list. not1+Goal Succeeds when Goal cannot be proven. Retained for compatibility only. New code should use 1. once1+Goal Defined as:
\begin{code}
once(Goal) :-
Goal, !.
\end{code}

once1 can in many cases be replaced with 2. The only difference is how the cut behaves (see !/0). The following two clauses are identical:
\begin{code}
1) a :- once((b, c)), d.
2) a :- b, c -> d.
\end{code}

ignore1+Goal Calls Goal as once1, but succeeds, regardless of whether Goal succeeded or not. Defined as:


\begin{code}
ignore(Goal) :-
Goal, !.
ignore(_).
\end{code}

call_with_depth_limit3+Goal, +Limit, -Result If Goal can be proven without recursion deeper than Limit levels, call_with_depth_limit3 succeeds, binding Result to the deepest recursion level used during the proof. Otherwise, Result is unified with depth_limit_exceeded if the limit was exceeded during the proof, or the entire predicate fails if Goal fails without exceeding Limit.

The depth-limit is guarded by the internal machinery. This differ from the depth computed based on a theoretical model. For example, true0 is translated into an inlined virtual machine instruction. Also, repeat0 is not implemented as below, but as a non-deterministic foreign predicate.


\begin{code}
repeat.
repeat :-
repeat.
\end{code}

As a result, call_with_depth_limit3 may still loop inifitly on programs that should theoretically finish in finite time. This problem can be cured by using Prolog equivalents to such built-in predicates.

This predicate may be used for theorem-provers to realise techniques like iterrative deepening. It was implemented after discussion with Steve Moyle .


next up previous contents index
Next: ISO compliant Exception handling Up: Built-in predicates Previous: Control Predicates   Contents   Index
Dr. Richard Botting 2001-12-12