2016-03-09 75 views
1

我正在学习Prolog和我,后面跟着 this tutorial for graphs。 这里是我的代码:编写一个Prolog谓词来为另一个谓词提供默认参数

path(X, Y, Length, [X,Y], _) :- 
    connect(X, Y, Length). 
path(X, Y, Length, [X|P], V) :- 
    \+ member(X, V), 
    connect(X, Z, Length1), 
    path(Z, Y, Length2, P, [X|V]), 
    Length is Length1 + Length2. 

要使用此,我呼吁

?- path(a, f, Length, Path, []). 

不过,我想缩短到:

?- path(a, f, Length, Path). 

但我不能得到默认参数工作。

+0

请参阅['this definition'](http://stackoverflow.com/q/30328433)。 – false

+0

@false我最初确实链接了这个问题;但是,如果边缘具有与它们相关的值,则它只是答案的一半。我想利用这个机会问:有没有一个地方可以找到你写的所有优秀代码(以及一些优秀的答案)?目前它分散在Prolog标签周围,即使我知道它在某个地方也经常遇到问题... –

+0

@Boris:查看我的个人资料和[this place](http://www.complang.tuwien .ac.at /乌尔里希/ Prolog的-inedit /)。我打算把它们放到一个更全面的表格中,但它比我想要在所有可能的方面符合标准看起来要多得多。 – false

回答

6

相当直接的:只要定义与调用谓词做的工作相同名称的谓词:

path(X, Y, Length, Path) :- 
    path(X, Y, Length, Path, []). 

在Prolog,谓词总是提到与Name/Arity因为同名但不同元维使得他们两个单独的谓词。所以,现在你的程序将同时定义path/4path/5。关于命名:如果两个谓词都是你的接口的一部分,它们应该有相同的名字。 Prolog标准库中的很多示例,例如format/1, format/2, format/3

但是,如果工作谓词仅用作助手谓词,通常会给它一个后缀。要使用一些简单的list_max/2

list_max([X|Xs], Max) :- 
    list_max_SUFFIX(Xs, X, Max). 

我所看到的代码,其中SUFFIX只是一个底线:list_max_/3(和你继续添加下划线更多的帮手谓词上下一致谓语血统);或者,下划线+号码:list_max_1/3(并增加数字);或者,_aux +可选号码,如果您有更多:list_max_aux/3。使用下划线+数字:

list_max_1([], Max, Max). 
list_max_1([X|Xs], Max0, Max) :- 
    compare(Order, X, Max0), 
    list_max_2(Order, X, Max0, Xs, Max). 

list_max_2(<, _, Max0, Xs, Max) :- list_max_1(Xs, Max0, Max). 
list_max_2(=, _, Max0, Xs, Max) :- list_max_1(Xs, Max0, Max). 
list_max_2(>, X, _, Xs, Max) :- list_max_1(Xs, X, Max). 

但是等等,还有更多。如果您对名称代表参数的谓词使用命名方案,则会获得例如setup_call_cleanup/3call_cleanup/2,定义为setup_call_cleanup(true, Goal, Cleanup)。有了这个命名方案,你可以称之为“路径”谓词,可能是from_to_length_path/4from_to_length_path_acc/5。我觉得这个命名方案很好,因为它是自我记录的,但正如这个例子所显示的,如果你的谓词有太多的参数,它可能会变得过度。

+3

s(X)为您的详尽答案! – repeat

+1

@repeat显然,我没有什么比这更好的了,无处可去。 –

+1

有**是**没有更好的做和无处可去:) – repeat