String 如何在prolog中将(0,0)转换为[0,0]?
我正在做一个谓词距离/3,它计算二维平面上两个点之间的距离。例如:String 如何在prolog中将(0,0)转换为[0,0]?,string,list,prolog,String,List,Prolog,我正在做一个谓词距离/3,它计算二维平面上两个点之间的距离。例如: ?- distance((0,0), (3,4), X). X = 5 Yes 只有当(0,0)是列表[0,0]时,我的谓词才起作用。有没有办法进行这种转换 您可以使用一个简单的规则来统一其左右两侧: convert((A,B), [A,B]). 如果你只有一对简单的,你可以使用univ操作符,简单地说: X = (a,b) , X =.. [_|Y] . 产生 X = (a,b) . Y = [a,b] . 如果X类似
?- distance((0,0), (3,4), X).
X = 5
Yes
只有当
(0,0)
是列表[0,0]
时,我的谓词才起作用。有没有办法进行这种转换 您可以使用一个简单的规则来统一其左右两侧:
convert((A,B), [A,B]).
如果你只有一对简单的,你可以使用
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!
尽管其他人已经回答了,但请记住,Prolog中的
(a,b)
实际上并不是您可能认为的那样:
?- write_canonical((a,b)).
','(a,b)
true.
这就是术语,'/2
。如果你是结对工作,你可以做两件可能“更漂亮”的事情:
将它们保持为一对,a-b
:
?- write_canonical(a-b).
-(a,b)
true.
这里的优点是,这样的对可以使用一堆事实上的标准谓词进行操作,例如keysort
,以及
或者,如果它们实际上是程序中的一部分数据结构,您也可以将其显式化,例如在coor(a,b)
中。然后,二维空间中的距离将采用两个coor/2
术语:
distance(coor(X1, Y1), coor(X2, Y2), D) :-
D is sqrt((X1-X2)^2 + (Y1-Y2)^2).
如果您不知道有多少个维度,那么您确实可以在列表中保留每个点的坐标。这里要传达的信息是,列表是指可以包含0个或多个元素的事物,而对、或其他具有2个算术数的术语、或任何具有已知算术数的术语,则更明确地说明了它们所包含的元素的数量。谢谢,我现在可以使用它了。虽然我有一种感觉,我可以让我的程序更“漂亮”。我将对此进行研究:)请注意,
(0,0)
是比[0,0]
更紧凑、更高效的表示形式。当您查看这两个术语的规范表示时,这一点(更)明显:,”(0,0)
vs。”(0,[])
。我很好奇为什么你的谓词只能使用列表表示法…因为我使用了一个头尾分割来将毕达哥拉斯定理应用于(0,0)和(3,4)。但是你不需要进行头尾分割。您可以轻松地从(X,Y)
中提取值<代码>距离((X1,Y1),(X2,Y2),D):-D是sqrt((X2-X1)*(X2-X1)+(Y2-Y1)*(Y2-Y1))。如果需要,还可以定义平方(X,S):-S是X*X。
。