Prolog返回true / false而不是variable

时间:2015-06-01 19:40:06

标签: prolog

我正在研究Prolog中非常简单的反向列表示例。

append(A, [], [A]).
append(A, B, [A|B]).

reverse([], ReversedList).
reverse([A,B], ReversedList) :-
  reverse(B, TemporaryList),
  append(A, TemporaryList, ReversedList).

append正常工作。但是,当我致电reverse时,解释器不会像append这样的变量做出回应,而只是写入真或假。

这是日志:

1 ?- consult('capitolo2'.pl). % file containing the code
2 ?- append(a, [b,c,d], L).
L = [a,b,c,d]. % ok, this works
3 ?- reverse([a,b,c], L).
false. % what? why that's not L = something?

平台是Windows上的SWI-Prolog 7.2

2 个答案:

答案 0 :(得分:3)

<强> append/3

单元测试吗?它运作正常吗?您的append/3实施不正确。第一个条款

第一句:

append( A , [] , [A]   ). 

只需从第一个参数(无论它是什么)创建一个长度为1的列表。鉴于此,如果你说:

append( [1,2,3] , [] , X ) .

你回来了:

X = [ [1,2,3] ]

长度为1的列表,其中包含的唯一项目是原始的第一个参数。第二个条款同样不正确:

append( A , B , [A|B] ).

将第一个参数 - 无论它可能是什么,完整 - 作为该列表的头部。鉴于此,如果你说的话:

append( [1,2,3] , [a,b,c] , X ) .

你回来了:

X = [ [1,2,3] , a , b , c ] .

长度为4的列表,其中第一项是原始的第一个参数。

Prolog是一种描述性语言:您描述解决方案并让引擎解决问题。 append/3断言一个列表(append/3的第三个参数表示第一个参数和第二个参数的串联。

以下是append/3的一种实现,为简洁起见进行了简化:

append( []      , RL , RL ) .  % The concatenation of an empty left-hand list and a right hand list is the right hand list.
append( [LH|LT] , RL , CL ) :- % The concatenation of a non-empty left-hand list and a right-hand list is true IF:
  CL = [LH|CT] ,               % - The left-hand head and the concatenation head are the same, AND
  append( LT , RL , CT )       % - recursively, the concatenated tail represents the conconcatenation of the left-hand tail and the right-hand list.
  .                            % Easy!

当您从左侧列表中弹出项目时,它最终将分解为终止特殊情况。这可以简化为经典实现:

append( []      , RL , RL      ) .
append( [LH|LT] , RL , [LH|CT] ) :- append( LT , RL , CT ) .

<强> reverse/3

同样,您的reverse/3实施不正确。你的第一个条款:

reverse([], ReversedList).

几乎说任何事都与空列表相反。由于您的ReversedList变量从未被引用,因此您的Prolog实现至少应该在此处发出有关单例变量的警告。许多实现都会使它成为错误。

你的第二个条款:

reverse([A,B], ReversedList) :-
  reverse(B, TemporaryList),
  append(A, TemporaryList, ReversedList).

表示通过

获得了2项目列表([A,B])的反向
  • 撤消列表中的第二个项目B)和
  • 将第1项(A)附加到该项目。

不完全正确的解决方案描述。您可以尝试类似

的内容
reverse( []    , [] ) .  % The empty list is already reversed, what with it being atomic and all.
reverse( [H|T] , R  ) :- % a non-empty list can be reversed by decomposing it into its head and tail, and
  reverse(T,T1) ,        % - reversing the tail, and
  append(T1,H,R) .       % - appending the head to the now-reversed tail.

答案 1 :(得分:2)

可能存在其他问题,但

  1. reverse([], ReversedList).
    

    几乎肯定不是你想要的。空列表的反向是空列表,转换为

    reverse([], []).
    
  2. 此外,

    reverse([A,B], ReversedList)
    

    也可能不是你想要的。 是一个包含头部A和尾部B的列表,而是一个包含2个元素列表的列表。