如何在prolog中将(0,0)转换为[0,0]?

时间:2014-09-11 15:24:07

标签: string list prolog

我制作一个谓词距离/ 3来计算2d平面上2点之间的距离。例如:

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

仅当(0,0)是列表[0,0]时,我的谓词才有效。有没有办法进行这种转换?

3 个答案:

答案 0 :(得分:2)

您可以使用统一其左侧和右侧的简单规则来执行此操作:

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

Demo.

答案 1 :(得分:2)

虽然其他人已经回答了,但请记住,Prolog中的(a,b)实际上并不是您认为的那样:

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

所以这是术语','/2。如果你正在使用配对,你可以做两件可能“更漂亮”的事情:

将它们保持为“对”,a-b

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

这里的优点是像这样的对可以用一堆事实上的标准谓词来操纵,例如keysort,以及library(pairs)

或者,如果它们实际上是作为程序一部分的数据结构,那么您也可以将其明确化,例如在coor(a, b)中。然后,二维空间中的距离将采用两个coor/2项:

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

如果你不知道你有多少个维度,那么你可以确实将每个点的坐标保持在一个列表中。这里的消息是列表适用于其中可以包含0个或更多元素的事物,而成对或具有arity 2的其他术语,或具有已知arity的任何术语,对于它们具有的元素数量更明确。 / p>

答案 2 :(得分:0)

如果您只有一对简单的对象,则可以使用univ运算符,只需说出以下内容:

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

产生

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

如果X类似于(a,b,c),就会生成

,这不起作用

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

[可能不是你想要的]。

更一般的情况非常简单:

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!