Prolog - 为查询变量赋值(列表递归)

时间:2016-10-23 14:20:22

标签: list recursion prolog

我需要创建一个具有输入列表的规则,然后一次从中获取2个值,比较它们并创建一个具有更大值的新列表。

它需要像这样工作:

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

输出: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 个答案:

答案 0 :(得分:1)

有些事情你需要改变。例如,条款:

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

调用更大的([],L3),它与条款bigger([],_).匹配但'_'与任何内容匹配,因此这会为您提供未知元素。使用append并不是一个好主意,但使用模式匹配会更好:

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.