2016-10-23 42 views
1

我需要创建一个规则,该规则具有输入列表,然后一次从中获取值2,并比较它们并创建一个具有较大值的新列表。Prolog - 为查询变量赋值(列表递归)

它需要像这样的工作:

输入:bigger([1,2,6,8,5], X).

OUTPUT:X = [2,6,8,8,5].

这里是我的代码:

%stop 
bigger([],_). 

%last element 
bigger([H1|[]],L2):- 
    append(L2, [H1], L3), 
    bigger([],L3). 

%compare first 2 
bigger([H1,H2|T], L2):- 
    (H1 > H2, 
    append(L2, [H1], L3), 
    bigger([H2|T], L3)) 
    ; 
    (H2 > H1, 
    append(L2, [H2], L3), 
    bigger([H2|T], L3)). 

如果我

更换基本情况
%stop 
bigger([],L):- 
    write(L). 

那么我会得到这样的输出:

[2,6,8,8,5] 
X = [] ; 
[_G3685,2,6,8,8,5] 
X = [_G3685] ; 
[_G3685,_G3691,2,6,8,8,5] 
X = [_G3685, _G3691] ; 
[_G3685,_G3691,_G3697,2,6,8,8,5] 
X = [_G3685, _G3691, _G3697] 
. 

我可以看到,当它达到基本情况技术上的第二个变量具有正确的价值的。但随后它统一为一个空白列表。不仅如此,它还会继续添加未知元素。

我该如何处理?

回答

1

有些事情需要改变。例如,子句:这与第bigger([],_).'_'比赛与任何匹配

bigger([H1|[]],L2):- 
    append(L2, [H1], L3), 
    bigger([],L3). 

调用更大([],L3),所以这给你的未知元素。这不是很好的主意TI采用追加,但它会更好地使用模式匹配,如:

bigger([],[]). 
bigger([H],[H]). 
bigger([H1,H2|T], [X|T1]):- 
    (H1 > H2-> 
     X=H1, 
     bigger([H2|T], T1) 
    ;H2 > H1-> 
     X=H2, 
     bigger([H2|T],T1)). 

这里你实例在每一个递归调用输出列表L3的一个元素,并做休息,直到它同有一个元素。条款bigger([],[]).仅当输入为空列表时才有用。当输入不为空时,当一个元素已经离开列表时,递归停止。 if-else语句最好使用->

结果:

?- bigger([1,2,6,8,5], X). 
X = [2, 6, 8, 8, 5] ; 
false. 
+0

这工作,谢谢。但是有几件事让我感到困惑。 如何做大([H],[H])。完全停止递归?这意味着这两个变量在列表中只有一个元素,对吧?我知道第一个输入列表只剩下一个(因为我们在递归中使它更小),但是不是第二个输入列表(X)变大了吗?它不应该有多个元素? – PadaKatel

+0

我们跟输入一样,注意输出列表也越来越小,当输入中有一个元素时,我们强制它有一个元素。输出列表越来越小,因为它是[X | T1],我们调用更大([H2 | T],T1),因此它在每个递归中都变小了一个元素。 – coder

+0

好吧,我想我已经开始明白了。非常有趣的是,我非常反感地看着它,试图添加到列表中,但是实际上我们需要的工作方式与输入列表相同。谢谢。 – PadaKatel