我有一个使用4个参数的函数,称为tile
。它旨在以下列方式工作:
tile(?E, ?S, ?W, ?N, ?ID)
我想要一个给定ID的getter函数,它返回前4个参数:E, S, W
和N
。
我尝试过类似的东西:
coordonates(tile(E,S,W,N,L), (E,S,W,N)).
但它不会返回实际值,只会返回true
。
如果我在终端中键入tile(E, S, W, N, #1)
,我会得到所需的结果,但我不知道究竟返回了什么(列表可能?)。
答案 0 :(得分:3)
让我们假设我们描述tile
的事实如下:
tile(p1,p2,p3,p4,id1).
tile(q1,q2,q3,q4,id2).
tile(r1,r2,r3,r4,id3).
在这里,我们有一些有限的事实。可以通过tile
的最常规查询来检查:
?- tile(E,S,W,N,I).
E = p1,
S = p2,
W = p3,
N = p4,
I = id1 ; % <---- user input ; to continue
E = q1,
S = q2,
W = q3,
N = q4,
I = id2 ; % <---- user input ; to continue
E = r1,
S = r2,
W = r3,
N = r4,
I = id3. % <---- toplevel outputs . -- we're done
所以从理论上讲,我们可以按如下方式定义coordonates
:
coordonates(id1, t(p1, p2, p3, p4)).
coordonates(id2, t(q1, q2, q3, q4)).
coordonates(id3, t(r1, r2, r3, r4)).
可以查询id2
,如下所示:
?- coordonates(id2,X).
X = t(q1, q2, q3, q4).
我使用仿函数t
对解决方案进行分组,以明确它不是我们之前定义的谓词tile
。这个定义中还有很多重复,这已经是一个暗示,我们可以做得更好。我们正在寻找的是一条规则,告诉我们如果我们得到tile
的答案,我们可以描述coordonates
。从逻辑上讲,这是作为形式的含义写的:goal1∧...∧目标N→头。这意味着“假设我知道goalN的goal1是真的,那么我也知道头是真的。”在Prolog中,这是向后写的:
head :-
goal1,
% ...
goalN.
让我们回到我们的任务:我们对瓷砖有所了解,我们想要描述投影的样子。这意味着,我们的代码如下所示:
coordonates( ... ) :-
% ...
tile(E,S,W,N,I).
正文tile(E,S,W,N,I)
是我们可以编写的最通用的形式(参见上面的查询),并且可以读作“假设我在坐标E S W N处有任何具有id I的图块”。现在我们只需要填写coordonates
应该是什么样子。我们知道它有两个参数,因为它将id与其他四个元素联系起来。让我们给他们起名字,比如Id
和Coords
:
coordonates(Id, Coords) :-
% ...
tile(E,S,W,N,I).
现在我们只需要找出如何将E,S,E,N和I与Id和Coords联系起来。一个很简单:Id
只是I
。另一个也不太难,我们只需要将坐标分组为一个术语。我们可以选择任意一个,但已经决定采用t
,所以我们会坚持下去:
coordonates(Id, Coords) :-
Id = I,
Coords = t(E,S,W,N),
tile(E,S,W,N,I).
这已经按照我们的预期运作了:
?- coordonates(X,Y).
X = id1,
Y = t(p1, p2, p3, p4) ;
X = id2,
Y = t(q1, q2, q3, q4) ;
X = id3,
Y = t(r1, r2, r3, r4).
现在我们可以做一个观察:如果两个术语相等,我们可以使用一个而不是另一个。因此,我们可以重用Id = I
而不是撰写Id
。 Coords
和t(E,S,W,N)
:
coordonates(I, t(E,S,W,N)) :-
tile(E,S,W,N,I).
它不能短得多: - )
答案 1 :(得分:0)
您必须声明'E,S,W和N',以便prolog可以在您进行查询时将这些参数与输入统一起来。像(在最基本的情况下):
tile(['cordE1','cordS1','cordW1','cordN1'],1).
tile(['cordE2','cordS2','cordW2','cordN2'],2).
tile(['cordE3','cordS3','cordW3','cordN3'],3).
查询:
?- tile(C,2).
C = [cordE2, cordS2, cordW2, cordN2].
?- tile(C,1).
C = [cordE1, cordS1, cordW1, cordN1].
?- tile(C,3).
C = [cordE3, cordS3, cordW3, cordN3].