编写Prolog谓词以向另一个谓词提供默认参数

编写Prolog谓词以向另一个谓词提供默认参数,prolog,optional-parameters,default-parameters,Prolog,Optional Parameters,Default Parameters,我在学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. 要使用这个,我打电话给 ?- p

我在学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).

但是我无法让默认参数正常工作。

非常直截了当:只需定义一个与调用执行工作的谓词同名的谓词:

path(X, Y, Length, Path) :-
    path(X, Y, Length, Path, []).
在Prolog中,谓词总是用
Name/Arity
来引用,因为相同的名称但不同的Arity使它们成为两个独立的谓词。因此,现在您的程序将同时定义
path/4
path/5

至于命名:如果两个谓词都是接口的一部分,那么它们应该具有相同的名称。例如,Prolog标准库中的许多示例

但是,如果工作谓词仅用于辅助谓词,则通常为其指定一个后缀。要使用一些简单的方法,如
list\u max/2

list_max([X|Xs], Max) :-
    list_max_SUFFIX(Xs, X, Max).
我看到的代码中,
SUFFIX
只是一个下划线:
list\u max\u/3
(并且在同一谓词沿袭中为更多的辅助谓词添加下划线);或者,下划线+数字:
list\u max\u 1/3
(然后递增数字);或者,
\u aux
+可选号码,如果您有更多:
列表\u max\u 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).
list_max_1([],max,max)。
列表_max_1([X | Xs],Max0,max):-
比较(顺序,X,最大值0),
列表_max_2(顺序,X,Max0,Xs,max)。
list_max_2(,X,X,X,max):-list_max_1(X,X,max)。

但是等等,还有更多。如果为谓词使用命名方案,其中名称表示参数,则会得到例如和,定义为
setup\u call\u cleanup(true,Goal,cleanup)
。使用此命名方案,您可以调用“路径”谓词,可能是
从\u到\u长度\u路径/4
从\u到\u长度\u路径\u acc/5
。我觉得这个命名方案很好,因为它是自文档化的,但如本例所示,如果您的谓词有太多的参数,它可能会变得过度。

非常直截了当:只需定义一个具有相同名称的谓词来调用执行工作的谓词:

path(X, Y, Length, Path) :-
    path(X, Y, Length, Path, []).
在Prolog中,谓词总是用
Name/Arity
来引用,因为相同的名称但不同的Arity使它们成为两个独立的谓词。因此,现在您的程序将同时定义
path/4
path/5

至于命名:如果两个谓词都是接口的一部分,那么它们应该具有相同的名称。例如,Prolog标准库中的许多示例

但是,如果工作谓词仅用于辅助谓词,则通常为其指定一个后缀。要使用一些简单的方法,如
list\u max/2

list_max([X|Xs], Max) :-
    list_max_SUFFIX(Xs, X, Max).
我看到的代码中,
SUFFIX
只是一个下划线:
list\u max\u/3
(并且在同一谓词沿袭中为更多的辅助谓词添加下划线);或者,下划线+数字:
list\u max\u 1/3
(然后递增数字);或者,
\u aux
+可选号码,如果您有更多:
列表\u max\u 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).
list_max_1([],max,max)。
列表_max_1([X | Xs],Max0,max):-
比较(顺序,X,最大值0),
列表_max_2(顺序,X,Max0,Xs,max)。
list_max_2(,X,X,X,max):-list_max_1(X,X,max)。

但是等等,还有更多。如果为谓词使用命名方案,其中名称表示参数,则会得到例如和,定义为
setup\u call\u cleanup(true,Goal,cleanup)
。使用此命名方案,您可以调用“路径”谓词,可能是
从\u到\u长度\u路径/4
从\u到\u长度\u路径\u acc/5
。我觉得这个命名方案很好,因为它是自我记录的,但正如这个例子所示,如果谓词有太多的参数,它可能会变得过度。

s(X)为您详细的答案@显然,重复一遍,我没有更好的事情要做,也没有其他地方要做。没有更好的事情要做,也没有其他地方要做:)s(X)谢谢你详尽的回答@显然,重复一遍,我没有更好的事情要做,也没有其他地方要做。没有更好的事情要做,也没有其他地方要做:)看。@false我最初确实把这个问题联系起来了;但是,如果边具有与之关联的值,则这只是答案的一半。我想借此机会问:是否有一个地方可以找到您编写的所有优秀代码(以及一些优秀的答案)?目前,它分散在Prolog标签上,我经常很难找到它,即使我知道它在某处…@Boris:查看我的个人资料和。我计划把它们变成一个更全面的形式,但这比看起来要复杂得多,因为我试图在所有可能的方面都符合要求。@false是的,我通常通过查看您的个人资料来找到它。我意识到这是一项令人望而生畏的工作,但如果你有一个网站,即使只是用一个描述性名称转储每个解决方案的工作版本,也会使浏览和搜索更容易。我想正确地做这件事和写一本教科书差不多。@Boris:理想情况下,SO的答案应该是现成的……见。@false我最初确实把这个问题联系起来了;但是,如果边具有与之关联的值,则这只是答案的一半。我想借此机会问:是否有一个地方可以找到您编写的所有优秀代码(以及一些优秀的答案)?目前,它分散在Prolog标签上,我经常很难找到它,即使我知道它在某处…@Boris:查看我的个人资料和。我计划把它们变成一个更全面的形式,但这比看起来要复杂得多,因为我试图在所有可能的方面都符合要求。@false是的,我通常通过查看您的个人资料来找到它。我意识到这是一项令人望而生畏的工作,但如果你有一个网站,即使只是用一个描述性名称转储每个解决方案的工作版本,也会使浏览和搜索更容易。我猜是d