I didn’t mean “specify” in any technical sense; and certainly not in any ISO-Prolog sense.
Anyway, perhaps this example will help:
times(0, 10, 0). % A trivial predicate for this example
times(1, 10, 10).
times(2, 10, 20).
append_arg_and_call(Call, Arg) :-
Call =.. CallList,
append(CallList, [Arg], CallPlusArgList),
CallPlusArg =.. CallPlusArgList,
call(CallPlusArg).
And running it:
?- append_arg_and_call(times(1, 10), Z).
Z = 10.
The call to eval/2
passes in the term times(1,10)
, which gets an additional argument added to it before it’s called. In a functional programming language, you’d create a “closure” or “partial function”, but in Prolog, it’s just a term that is interpreted by the call
predicate to execute a goal (“execute” in the ISO-Prolog sense).
?- trace, append_arg_and_call(times(1, 10), Z).
Call: (10) append_arg_and_call(times(1, 10), _2522) ?
Call: (11) times(1, 10)=.._2844 ?
Exit: (11) times(1, 10)=..[times, 1, 10] ?
Call: (11) lists:append([times, 1, 10], [_2522], _2870) ?
Exit: (11) lists:append([times, 1, 10], [_2522], [times, 1, 10, _2522]) ?
Call: (11) _2884=..[times, 1, 10, _2522] ?
Exit: (11) times(1, 10, _2522)=..[times, 1, 10, _2522] ?
Call: (11) times(1, 10, _2522) ? % <=== executes the *goal*
Exit: (11) times(1, 10, 10) ?
Exit: (10) append_arg_and_call(times(1, 10), 10) ?
Z = 10.
(Normally, you wouldn’t define append_arg_and_call/2
because the builtin call/2
handles appending an arg; I wrote a pure-Prolog implementation to show you that it takes a term, manipulates that term, and finally interprets the manipulated term as a goal.)