Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 如何在prolog中将(0,0)转换为[0,0]?_String_List_Prolog - Fatal编程技术网

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

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类似

我正在做一个谓词距离/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
类似于
(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。