Prolog返回true/false而不是变量

Prolog返回true/false而不是变量,prolog,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之类的变量响应,而是只写

我正在用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
之类的变量响应,而是只写true或false

这是日志:

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

可能还有其他问题,但是

  • 这几乎肯定不是你想要的。空列表的反面是空列表,翻译为

    reverse([], []).
    
  • 另外,

    reverse([A,B], ReversedList)
    
    也可能不是你想要的。它不是一个有头a和尾B的列表,而是一个由两个元素组成的列表


  • 可能还有其他问题,但是

  • 这几乎肯定不是你想要的。空列表的反面是空列表,翻译为

    reverse([], []).
    
  • 另外,

    reverse([A,B], ReversedList)
    
    也可能不是你想要的。它不是一个有头a和尾B的列表,而是一个由两个元素组成的列表


  • 追加/3

    你对它进行了单元测试吗?它工作正常吗?您的
    append/3
    实现不正确。第一条

    第一条:

    append( A , [] , [A]   ). 
    
    reverse([], ReversedList).
    
    只需从第一个参数(不管是什么)创建一个长度为1的列表。鉴于此,如果你说:

    append( [1,2,3] , [] , X ) .
    
    你会回来的:

    X = [ [1,2,3] ]
    
    X = [ [1,2,3] , a , b , c ] .
    
    长度为1的列表,其中唯一包含的项是原始的第一个参数。第二条同样不正确:

    append( A , B , [A|B] ).
    
    在第一个参数前面加上前缀-无论它是什么,以及整个作为列表的开头。鉴于此,如果你说:

    append( [1,2,3] , [a,b,c] , X ) .
    
    你会回来的:

    X = [ [1,2,3] ]
    
    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 ) .
    
    反向/3

    同样,您的
    反向/3
    实现是不正确的。您的第一个子句:

    append( A , [] , [A]   ). 
    
    reverse([], ReversedList).
    
    几乎所有内容都是空列表的反面。由于您的
    ReversedList
    变量从未被引用,因此您的Prolog实现至少应该在此处抛出有关单例变量的警告。许多实现都将其视为错误

    你的第二条:

    reverse([A,B], ReversedList) :-
      reverse(B, TemporaryList),
      append(A, TemporaryList, ReversedList).
    
    表示两项列表(
    [a,B]
    )的反面是通过

    • 颠倒列表中的第二项(
      B
      ),以及
    • 将第一项(
      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.
    

    追加/3

    您是否对其进行了单元测试?它是否正常工作?您的
    append/3
    实现不正确。第一个子句

    第一条:

    append( A , [] , [A]   ). 
    
    reverse([], ReversedList).
    
    只需从第一个参数(不管是什么)创建一个长度为1的列表。如果您说:

    append( [1,2,3] , [] , X ) .
    
    你会回来的:

    X = [ [1,2,3] ]
    
    X = [ [1,2,3] , a , b , c ] .
    
    长度为1的列表,其中唯一包含的项是原始的第一个参数。第二个子句同样不正确:

    append( A , B , [A|B] ).
    
    在第一个参数前面加上前缀,无论它是什么,以及整个,作为列表的开头。鉴于此,如果你说:

    append( [1,2,3] , [a,b,c] , X ) .
    
    你会回来的:

    X = [ [1,2,3] ]
    
    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 ) .
    
    反向/3

    同样,您的
    反向/3
    实现是不正确的。您的第一个子句:

    append( A , [] , [A]   ). 
    
    reverse([], ReversedList).
    
    几乎所有内容都是空列表的反面。由于您的
    ReversedList
    变量从未被引用,因此您的Prolog实现至少应该在此处抛出有关单例变量的警告。许多实现都将其视为错误

    你的第二条:

    reverse([A,B], ReversedList) :-
      reverse(B, TemporaryList),
      append(A, TemporaryList, ReversedList).
    
    表示两项列表(
    [a,B]
    )的反面是通过

    • 颠倒列表中的第二项(
      B
      ),以及
    • 将第一项(
      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.
    

    结果是一样的:(这就是问题(nr2)。现在它没有返回正确的结果,但这是我的算法中的一个问题结果是一样的:(这就是问题(nr2).现在它没有返回正确的结果,但这是我的算法中的一个问题,这是一个相当非标准的定义,通常
    append
    被定义用于处理列表,例如
    append([a,b,c],[x,y,z],L)=>L=[a,b,c,x,y,z]
    ,这似乎不是问题所在。如果我将
    append
    重命名为
    my_append
    ,您也需要重新启动Prolog系统。此外,还有
    [A,B]
    ,它可能应该读取
    [A | B]
    等等……只有在第一个参数为空列表的情况下,
    reverse
    规则才会成功(
    []
    )或两元素列表(
    [a,B]
    )。由于其他情况不匹配,因此它将使所有其他情况都失败。为什么要实现像
    append/3
    这样的标准谓词?如果有充分的理由这样做