用于构建序言规则的提取算法
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,我以后如何找到这种类型的提示?我的问题有具体名称吗?
我必须有多精确 - 我可以尝试在多少情况下用什么语言来实现我的算法,这不仅是 "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 个列表。
我必须在序言中创建一些 "list of predicates"。 但我不完全理解思维方式 如果我想创建一些工作谓词,我必须学习。
我看过一些流行的教程(也许我搜索得不够精确),但我找不到任何教程来教授如何使用真正的基本步骤来规划算法。
例如...
任务:
Write a
concat(X,Y,Z).
predicate that is taking elements from the listsX
andY
and concatenates them in the listZ
.
我的分析算法:
Firstly I define a domain of the number of elements I'll be concatenating (the lengths of the lists
X
andY
) 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 onlyconcat(X,[],X).
, becauseX = []
inside predicateconcat(X,[],X).
is the same asconcat([],[],[]).
.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,我以后如何找到这种类型的提示?我的问题有具体名称吗?
我必须有多精确 - 我可以尝试在多少情况下用什么语言来实现我的算法,这不仅是 "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 个列表。