我正在研究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
答案 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
)和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)
可能存在其他问题,但
reverse([], ReversedList).
几乎肯定不是你想要的。空列表的反向是空列表,转换为
reverse([], []).
此外,
reverse([A,B], ReversedList)
也可能不是你想要的。 不是一个包含头部A和尾部B的列表,而是一个包含2个元素列表的列表。