Now =.. is pronounced ``univ''. It can be used to map a term onto a list in this way:
Term [ Functor, Arg, Arg, ... Arg]For example, =../2 can be used with mode =..(+,+) and mode =..(+,-):
?- foo(12,fred)=.. [foo,12,fred].The predicate can also be used with mode =..(-,+).yes
?- fact(male(fred),23)=.. X
X= [fact,male(fred),23]
?- X=.. [fact,male(fred),23].Here are some more examples:X = fact(male(fred),23)
?- (a + b) =.. X.We demonstrate a real application where we have a predicate triple_one/2 which takes as input an integer (first argument) and outputs (second argument) its triple. We are going to use =../2 to triple each element of an input list. This will mimic the behaviour of a predicate triple/2 previously used as an example. We define a predicate map/3 which takes a predicate name as its first argument, the input list as the second argument and returns the output list as the third argument as in:X = [+, a, b]
?- [a,b,c] =.. X.
X = ['.',a,[b,c]]
?- map(triple,[1,2,3],X).We give the special case with the first argument as triple and then generalise it.X=[3,6,9]
map(triple,[],[]).The main trick is to assemble a term looking like triple(H1,H2) using =../2 and then use call/1 to execute the goal.map(triple,[H1T1],H2T2]):-
X=.. [triple,H1,H2],
call(X),
map(triple,T1,T2).
Now we replace the specific reference to triple and provide a more general version that can handle the task for arbitrary predicates of arity 2 ---provided that they are defined to work with mode predname(+,-).
map(Functor,[],[]).The next task is to allow for an even more general version that can do the same sort of thing for predicates with an arity of more than two!map(Functor,[H1T1],H2T2]):-
X=.. [Functor,H1,H2],
call(X),
map(Functor,T1,T2).
For example, define a predicate npl/3 that takes a positive integer as first argument and a number as its second argument, returning the third argument as the second argument `npled' as in:
?- nple(7,5,X).We define nple/3:X=35
nple(Multiplier,In,Out):- Out is Multiplier*In. [-5pt]Now to look at the code. Now, we need to give the new version of map/3 a first argument which contains the necessary info --- viz the name of the predicate and the constant multiplier.
We can do this as the term nple(N) where N is the multiplier. We transform the term nple(N) into a list [nple,N] and then append the two arguments H1 and H2 using the standard append/3. This list is then rebuilt as the term nple(N,H1,H2) and then executed via call/1.
map(nple(N),[],[]).Nowhere does this really depend on the arity of nple(N) ---so we just replace the term nple(N) by Term.map(nple(N),[H1T1],[H2T2]):-
nple(N)=.. List,
append(List,[H1,H2],NewList),
X=.. NewList,
call(X),
map(nple(N),T1,T2).
map(Term,[],[]).map(Term,[H1T1],[H2T2]):-
Term=.. List,
append(List,[H1,H2],NewList),
X=.. NewList,
call(X),
map(Term,T1,T2).