用于构建序言规则的提取算法

extracting algorithm for building prolog rules

我必须在序言中创建一些 "list of predicates"。 但我不完全理解思维方式 如果我想创建一些工作谓词,我必须学习。

我看过一些流行的教程(也许我搜索得不够精确),但我找不到任何教程来教授如何使用真正的基本步骤来规划算法。

例如...

任务:

Write a concat(X,Y,Z). predicate that is taking elements from the lists X and Y and concatenates them in the list Z.

我的分析算法:

Firstly I define a domain of the number of elements I'll be concatenating (the lengths of the lists X and Y) as non-negative integers (XCount >= 0 and YCount >= 0). Then I create a predicate for the first case, which is XCount = 0 and YCount = 0:

concat([],[],[]).

... then test it and find that it is working for the first case.

Then, I create a predicate for the second case, where XCount = 1 and YCount = 0, as:

concat(X,[],X).

... and again test it and find that it is working with some unexpected positive result.

结果:

I can see that this algorithm is working not only for XCount = 1 but also for XCount = 0. So I can delete concat([],[],[]). and have only concat(X,[],X)., because X = [] inside predicate concat(X,[],X). is the same as concat([],[],[])..

The second unexpected result is that the algorithm is working not only for XCount in 0,1 but for all XCount >= 0.

Then I analyse the domain and search for elements that weren't handled yet, and find that the simplest way is to create a second predicate for YCount > 0.

Remembering that using just X as the first argument can cover all XCount >= 0, I create a case for YCount = 1 and all Xes, which is:

concat(X,[Y|_],[Y|X]).

And this is the place where my algorithm gets a brain-buffer overflow.

尊重 Whosebug 规则,我问的很准确。

问题:

  1. 有什么办法自己找答案吗?我的意思是 - 不是问题的答案,而是我展示的解决问题的算法。 也就是说,我算法的算法。

  2. 如果你能回答问题1,我以后如何找到这种类型的提示?我的问题有具体名称吗?

  3. 我必须有多精确 - 我可以尝试在多少情况下用什么语言来实现我的算法,这不仅是 "doing" 的东西,而且是 "thinking"如何规划和创建其他算法。

列表未定义为其中元素的计数。列表被递归定义为空,或者一对元素和其余元素:

list([]).
list([_A|B]) :- list(B).

列表可以相同:

same_lists([], []).
same_lists([A|B], [A|C]) :- same_lists(B, C).

或者一个可以比另一个短,即它的前缀:

list_prefix([], L):- list(L).
list_prefix([A|B], [A|C]):- list_prefix(B, C).

前缀结束的地方,后缀开始的地方:

list_split([], L, L):- list(L).
list_split([A|B], Sfx, [A|C]):- list_split(B, Sfx, C).

所以,一般的建议是:遵循类型,它们是如何构造的,并根据所有可能的情况分析情况。对于列表,它要么是空的,要么是 non-empty 个列表。