2010-12-03 36 views
1

警告,我对Prolog很新。一次又一次给出相同的答案,比听者崩溃 - Prolog

我在Prolog中编写了一个分裂谓词。它将一个列表分成两个新列表。一个包含大于Key的项目,另一个包含小于或等于Key的项目。它只应该返回一组答案。问题是如果我输入;为了检查更多的答案,它一直给我我已经得到的答案,然后最终听者崩溃。我想知道你能否帮我解决这个问题?

代码:

split([],_,[],[]). 
split([H|T],Key,Small,Big):- 
    H=<Key, 
    removeFirst(Small,H,NewSmall), 
    split(T,Key,NewSmall,Big). 
split([H|T],Key,Small,Big):- 
    H>Key, 
    removeFirst(Big,H,NewBig), 
    split(T,Key,Small,NewBig). 

removeFirst([H|T],H,T). 
removeFirst(L,Key,Result):- 
    divide(L,Key,F,E), 
    X = F, 
    Y = E, 
    append(X,Y,Z), 
    Result = Z. 

输出:

?- split([1,2,3,4,5],3,S,B).

S = [1, 2, 3]
B = [4, 5] ;

S = [1, 2, 3]
B = [4, 5] ;

S = [1, 2, 3]
B = [4, 5] ;
监听器崩溃4日尝试。

回答

2

我建议你解决这个算法以另一种方式:

  • 定义一个递归谓词(分/ 4)为你做了,检查输入列表中的每个项目,而是建立在返回结果列表递归(即,将当前项目添加为子句头部的适当列表的头部)。

这将是这样的:

split([], _, [], []). % Base case 
split([Item|Tail], Key, [Item|Small], Big):- 
    Item =< Key, 
    !, % Optimization, the cut here is to avoid the comparison in the next clause 
    split(Tail, Key, Small, Big). 
split([Item|Tail], Key, Small, [Item|Big]):- 
    split(Tail, Key, Small, Big). 
+1

+1;这也是我如何写这样一个谓词。如果你不想使用cut(`!`)来获得纯度,就像OP最初一样,将测试`Item> Key`作为split/4的最后一个子句的第一个子目标就足够了。 – sharky 2010-12-03 22:52:03

相关问题