Passing the results of a Prolog predicate

How to evaluate the result of a prologue predicate to be passed as an argument? I am trying to write code for the inverse pair of elements in a list:



I want to get the result:



but I get this result:



Here is my code:

swap(L,R) :- swapA(L,[],R).
swapA([H,H2|T],A,R) :-  swapA(T, append(A,[H2,H]), R).




source to share

2 answers

A few things:

  • the variable starts with a capital letter, if you want to distinguish an atom from a variable, wrap it between '


  • you don't need to add for this predicate to succeed. The complexity is worse when using append.
  • because you don't need to add, you also don't need 3 arguments, 2 is enough

Here's a suggestion:

swapA([], []).
swapA([X, Y|T], [Y, X|R]) :- swapA(T, R).


And consider adding another base argument if you want your predicate to hold when you have an odd number of items in your list:

swapA([X], [X]).




You cannot call a Prolog predicate as a function. It returns nothing. When you submit append(A,[H2,H])

to exchange, it interprets it as data, not code.

A Prolog clause creates a link between N boolean variables. This means that in theory there is no concept of "enter" and "output" in Prolog predicates, you can make a query with any combination of instantiated and non-instantiated variables, and the language will find a meaningful relation (relations) for you:

1 ?- append([a],[b,c],[a,b,c]).

2 ?- append([a],[b,c],Z).
Z = [a, b, c].

3 ?- append([a],Y,[a,b,c]).
Y = [b, c].

4 ?- append(X,[b,c],[a,b,c]).
X = [a] ;

5 ?- append([a],Y,Z).
Z = [a|Y].

6 ?- append(X,[b,c],Z).
X = [],
Z = [b, c] ;
X = [_G383],
Z = [_G383, b, c] ;
X = [_G383, _G389],
Z = [_G383, _G389, b, c] . % etc

7 ?- append(X,Y,[a,b,c]).
X = [],
Y = [a, b, c] ;
X = [a],
Y = [b, c] ;
X = [a, b],
Y = [c] ;
X = [a, b, c],
Y = [] ;

8 ?- append(X,Y,Z).
X = [],
Y = Z ;
X = [_G362],
Z = [_G362|Y] ;
X = [_G362, _G368],
Z = [_G362, _G368|Y] . % etc

9 ?- 


In practice, not every predicate can be called with every combination due to restrictions in the expression of the relation so as not to lead to an infinite loop. Another reason could be additional boolean functions such as arithmetic. When you see the predicate documented as:

pred(+Foo, -Bar, ?Baz)


This means that it expects to Foo

be instantiated (i.e. unified for another non-var) Bar

for a free variable and Baz

can be anything. The same predicate can have more than one way to call it.

This is why you cannot think of a Prolog relation as a function in general. If you pass a compound as an argument, sentences are likely to treat it as a compound, unless it's specifically designed to be treated as code. One example is call/1

one that executes its argument as code. is

, =:=

, <

And other arithmetic operators also perform some interpretation, if you pass something like cos(X)




All Articles