Home Contents Index Summary Previous Next

3.8 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.

Invoke Goal as a goal. Note that clauses may have variables as subclauses, which is identical to call/1, except when the argument is bound to the cut. See !/0.
call(+Goal, +ExtraArg1, ...)
Append ExtraArg1, ExtraArg2, ... to the argument list of Goal and call the result. For example, call(plus(1), 2, X) will call plus/3, 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.

apply(+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). apply/2 is incorporated in the virtual machine of SWI-Prolog. This implies that the overhead can be compared to the overhead of call/1. 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.
Succeeds when Goal cannot be proven. Retained for compatibility only. New code should use \+/1.
Defined as:

once(Goal) :-
        Goal, !.

once/1 can in many cases be replaced with ->/2. The only difference is how the cut behaves (see !/0). The following two clauses are identical:

1) a :- once((b, c)), d.
2) a :- b, c -> d.

Calls Goal as once/1, but succeeds, regardless of whether Goal succeeded or not. Defined as:

ignore(Goal) :-
        Goal, !.

call_with_depth_limit(+Goal, +Limit, -Result)
If Goal can be proven without recursion deeper than Limit levels, call_with_depth_limit/3 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, true/0 is translated into an inlined virtual machine instruction. Also, repeat/0 is not implemented as below, but as a non-deterministic foreign predicate.

repeat :-

As a result, call_with_depth_limit/3 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 smoyle@ermine.ox.ac.uk.