How to convert (0,0) to [0,0] in prologue?

I am doing a predicate distance / 3 which calculates the distance between two points in the 2d plane. For example:

?- distance((0,0), (3,4), X).
X = 5
Yes

      

My predicate only works if (0,0)

is a list [0,0]

. Is there a way to do this conversion?

+3


source to share


3 answers


You can do this with a simple rule that combines its left and right sides:

convert((A,B), [A,B]).

      



Demo version

+2


source


While the others have answered, keep in mind that (a,b)

Prolog is actually not what you might imagine:

?- write_canonical((a,b)).
','(a,b)
true.

      

So this is the term ','/2

. If you are working with pairs, you can do two things that are probably "prettier":

Keep them as a "couple" a-b

:

?- write_canonical(a-b).
-(a,b)
true.

      



The advantage is that pairs like this can manipulate a bunch of de facto standard predicates, for example keysort

as well as library (pairs) .

Or, if they are a data structure that is part of your program, you can also make it explicit, for example in coor(a, b)

. The distance in two-dimensional space will then take on two terms coor/2

:

distance(coor(X1, Y1), coor(X2, Y2), D) :-
    D is sqrt((X1-X2)^2 + (Y1-Y2)^2).

      

If you don't know how many measurements you have, you can store the coordinates of each point in the list. The message here is that lists are for things that may have 0 or more elements in them, while pairs or other terms with arity 2 or any term with known arity are clearer about the number of elements they have.

+2


source


If you just have a simple pair, you can use an operator univ

and just say something like:

X = (a,b) ,
X =.. [_|Y] .

      

which produces

X = (a,b) .
Y = [a,b] .

      

It doesn't work if X

- it's something like (a,b,c)

creating how it does

X = (a,b,c) .
Y = [a,(b,c)] .

      

[maybe not what you want].

The more general case is pretty simple:

csv2list( X , [X]     ) :- % We have a list of length 1
  var(X) .                 % - if X is UNbound
csv2list( X , [X]     ) :- % We have a list of length 1
  nonvar(X) ,              % - if X is bound, and
  X \= (_,_) .             % - X is not a (_,_) term.
cs22list( Xs , [A|Ys] ) :- % otherwise (the general case) ,
  nonvar(Xs) ,             % - if X is bound, and
  Xs = (A,Bs) ,            % - X is a (_,) term,
  csv2list(Bs,Ys           % - recurse down added the first item to result list.
  .                        % Easy!

      

0


source







All Articles