序言程序只以一种方式工作是否可以接受?



我有一个prolog程序:

link(liverpool,preston).
link(liverpool,manchester).
link(preston,lancaster).
link(preston,manchester).
link(lancaster,carlisle).
link(lancaster,leeds).
link(carlisle,leeds).
link(manchester,leeds).
%checks to see if X is in the supplied list
inlist( X, [X|_]).
inlist( X, [_|Ys]) :- inlist( X, Ys).

merge([],L,L).
merge([H|T],BList,CList):-
inlist(H,BList),
merge(T,BList,CList).
merge([H|T],BList,[H|CList]):-
merge(T,BList,CList),
not(inlist(H,BList)).

合并工作,如果我这样调用它:

merge([a,b,c],[d,e,f],Result). --> [a,b,c,d,e,f]

或者更重要的是,它被设计用来解决的问题:

merge([a,b,c],[a,d,e,f],Result). --> [a,b,c,d,e,f]

但是如果我像这样调用merge:

merge(X,[d,e,f],[a,b,c,d,e,f]).

存在堆栈溢出。对于设计为单向工作的函数来说,这种行为通常是可以接受的吗?还是说函数应该以两种方式工作?

如果你像这样调用它,Edit: merge可以工作:

merge([a,b,c],X,[a,b,c,d,e,f]). --> [d,e,f]

首先,不应该调用这些"函数"。"谓词"是正确的术语。

通常希望Prolog谓词"双向"工作。但在特定情况下,这并不总是可能的,也不值得付出努力。

可以使用模式声明来告知谓词的使用方式。这些声明约定因系统而异。这些声明主要作为程序员的文档,很少被编译器使用,但可以被测试框架和其他辅助工具使用。

模式声明约定示例:

  • SWI-Prolog: http://www.swi-prolog.org/pldoc/man?section=modes
  • ECLiPSe CLP: http://eclipseclp.org/doc/applications/tutorial003.html#toc10(滚动到2.7.3模式声明)

还有一个约定(例如,在"The Craft of Prolog"中有描述),谓词的输入参数先出现,输出参数最后出现。

相关内容

  • 没有找到相关文章

最新更新