Once you have created a higher-order predicate term (sometimes known as a closure), the next thing you want to do is to call it. For predicates, you use the builtin goal call/N:
call(Closure)call(Closure1, Arg1)call(Closure2, Arg1, Arg2)For example, the goal
call(Sum123, Result)
would bind ‘Result’ to the sum of ‘[1, 2, 3]’, i.e. to 6.
For functions, you use the builtin expression apply/N:
apply(Closure)apply(Closure1, Arg1)apply(Closure2, Arg1, Arg2)For example, given the definition of ‘Double’ above, the goal
List = apply(Double, [1, 2, 3])
would be equivalent to
List = scalar_product(2, [1, 2, 3])
and so for a suitable implementation of the function ‘scalar_product/2’ this would bind ‘List’ to ‘[2, 4, 6]’.
One extremely useful higher-order predicate in the Mercury standard
library is solutions/2, which has the following declaration:
:- pred solutions(pred(T), list(T)).
:- mode solutions(pred(out) is nondet, out) is det.
The term which you pass to ‘solutions/2’ is a higher-order predicate term. You can pass the name of a one-argument predicate, or you can pass a several-argument predicate with all but one of the arguments supplied (a closure). The declarative semantics of ‘solutions/2’ can be defined as follows:
solutions(Pred, List) is true iff
all [X] (call(Pred, X) <=> list.member(X, List))
and List is sorted.
where ‘call(Pred, X)’ invokes the higher-order predicate term ‘Pred’ with argument ‘X’, and where ‘list.member/2’ is the standard library predicate for list membership. In other words, ‘solutions(Pred, List)’ finds all the values of ‘X’ for which ‘call(Pred, X)’ is true, collects these solutions in a list, sorts the list, and returns that list as its result. Here's an example: the standard library defines a predicate ‘list.perm(List0, List)’
:- pred list.perm(list(T), list(T)).
:- mode list.perm(in, out) is nondet.
which succeeds iff List is a permutation of List0. Hence the following call to solutions
solutions(list.perm([3,1,2]), L)
should return all the possible permutations of the list ‘[3,1,2]’ in sorted order:
L = [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]].
See also ‘unsorted_solutions/2’ and ‘solutions_set/2’, which are defined in the standard library module ‘solutions’ and documented in the Mercury Library Reference Manual.