我制作一个谓词距离/ 3来计算2d平面上2点之间的距离。例如:
?- distance((0,0), (3,4), X).
X = 5
Yes
仅当(0,0)
是列表[0,0]
时,我的谓词才有效。有没有办法进行这种转换?
答案 0 :(得分:2)
答案 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!