我有一组按排名排列的公司。我希望我的规则检查指定列表中的公司是否按排名顺序排列,并重复执行该规则,直到检查了列表中的所有公司为止。
我目前有以下内容:
isOrder([]).
isOrder([COM1,COM2|T]) :-
rank(COM1,D), rank(COM2,E),
D<E,
print("in order"),
isOrder([COM2|T]).
但是,这似乎不起作用。有时,递归会永远持续下去,没有结束,有时递归根本不起作用。这是我改变代码以尝试获得正确答案的时候。
有人可以帮助我吗?我刚刚开始使用Prolog,对它的理解非常有限。任何帮助将不胜感激。
I have a set of companies in rank order. I want my rule to check if the companies in a specified list are in rank order, and for the rule to recur until all companies in the list have been checked.
I currently have the following:
isOrder([]).
isOrder([COM1,COM2|T]) :-
rank(COM1,D), rank(COM2,E),
D<E,
print("in order"),
isOrder([COM2|T]).
However, this does not seem to work. Sometimes, the recursion goes on forever without ending, and sometimes the recursion doesn't work at all. This is when I vary the code to try and get the correct answer.
Can anybody help me? I have just started Prolog and my understanding of it is severely limited. Any help would be greatly appreciated.
发布评论
评论(2)
问题是您的程序没有单元素列表的情况:第一种情况处理空列表,而第二种情况仅匹配具有两个或更多元素的列表。
您需要添加一个子句
The problem is that your program has no case for a one-element list: the first case handles the empty list, while the second only matches a list with two or more elements.
You'll need to add a clause
在 Prolog 中,拥有正确的递归“基本”情况以及正确的递归规则非常重要。
在这里,我认为您想要将基本情况从 isOrder([ ]) 更改为 isOrder([_]),或者可能同时拥有这两者。
您现在拥有的第一个子句看起来对于空列表将返回 true,我想这没有什么害处。但第二个子句永远不能将非空列表缩减为空列表。它仅适用于至少具有两个项目(公司)的列表,并将这种情况简化为具有至少一个项目的列表。
因此,添加另一个子句 isOrder([_]),它表示如果列表只有一项,则成功,并让我们知道它是如何工作的!
In Prolog it's important to have the right "base" case for recursion, as well as getting the rule for the recursion itself right.
Here I think you want to change the base case from isOrder([ ]) to isOrder([_]), or maybe to have both of these.
The first clause you have now looks like it will return true for an empty list, which I guess does no harm. But the second clause can never reduce a nonempty list to an empty one. It only applies to a list that has at least two items (companies), and reduces such a case to a list that has at least one item.
So, add another clause isOrder([_]), which says you succeed if the list only has one item, and let us know how it works!