2014-02-18 48 views
0

你好我想在Prolog中创建一个程序,它给出一个数字和一个数字列表,它将第二个列表中的所有数字位置附加到后面。在序言中生成列表

例如,对于list (5,10,4,5,6,5)number =5新的列表应该

(1,4,6) 

这里是我到目前为止的代码

positions(X, [X|_],1). 
positions(X, [P|T], N) :- positions(X, T, N1), N is N1+1. 

find(X, [H|T] ,Z) :-positions(X,[H|T],N) , append([],N,Z). 

位置返回x的列表中第一个同意,但我不知道如何继续。你可以帮我吗?

回答

5

查询。如果它不是一个任务,那么你可以使用受益内置插件的findall/3和NTH1/3:

?- findall(Nth, nth1(Nth, [5,10,4,5,6,5], 5), Nths). 
Nths = [1, 4, 6]. 

以刚NTH1短语和运行中,你可以看到它是回溯,寻找多种解决方案,那么我们只不过是你找到它们将它们收集到一个列表中。

?- nth1(Nth, [5,10,4,5,6,5], 5). 
Nth = 1 ; 
Nth = 4 ; 
Nth = 6. 

NTH1/3,使用用于所述第一参数的变量时,在说“给我在哪里,其中第三参数在第二参数的列表中找到一个列表索引。

+0

+1,用于使用内置插件的漂亮整洁的解决方案。 – lurker

2

你有一些好的想法,但我会建议有两件事情:

1)在Prolog,它可以是有益的给变量有意义的名称

2)使用蓄能器,你只需要位置和追加

3)使用不同的基本情况

positions([Num|List],Num,[Index|SubResult],Index) :- Index2 is Index+1, 
             positions(List,Num,SubResult,Index2). 

positions([NotNum|List],Num,Result,Index) :- NotNum \= Num, 
              Index2 is Index+1, 
              positions(List,Num,Result,Index2). 

positions([],Num,[],Index). 

在我们的第一个一般的情况下,我们可以看到数字匹配,所以我们去鳍d多少结果是在我们的子表,我们将调用SubResult,然后推到我们SubResult

下一般情况下,数字不统一目前的指数,我们的Result IS的SubResult,让我们呼唤他们同样的事情。

在我们最后的情况下(基本情况),我们可以看到列表是空的,在这种情况下,我们返回一个空列表,因为我们无法匹配空列表。

您可以看到上述规则是与订单无关的,这在Prolog中非常有用。这意味着您可以按任意顺序排列规则,并且Prolog程序的语义保持不变。使用统一来实现这一点将防止调试中未来的痛苦。

我们可以换我们的谓词以下列方式

positions(Num, List, Positions) :- positions(List, Num, Positions, 1). 

这将允许对positions(5,[5,10,4,5,6,5],Positions).

+0

+1因为我喜欢这个解决方案,而且随机,因为你喜欢“Pythonic”这个词。没有Prolog等价词听起来很酷(“prologish”?“prological”?...) – lurker

+0

@mbratch“prologgy”?我会说“prology”是我们的形容词中最好的。序言是亲逻辑? –

+1

同意。在这些选项中,“Prological”尽我所能地脱颖而出。 – lurker