,因为你说,添加第二个迭代后/ 3失败,我假设你使用的跟踪/ 0
反正,那就是:
[trace] ?- doStuff([[1,2], [3,4], [5,6], [7,8]], R).
Call: (6) doStuff([[1, 2], [3, 4], [5, 6], [7, 8]], _G405) ? creep
Call: (7) lists:reverse([3, 4], _G496) ? creep
Exit: (7) lists:reverse([3, 4], [4, 3]) ? creep
Call: (7) add([1, 2], [4, 3], _G405) ? creep
Exit: (7) add([1, 2], [4, 3], [[1, 2], [4, 3]]) ? creep
Call: (7) doStuff([[5, 6], [7, 8]], [[1, 2], [4, 3]]) ? creep
Call: (8) lists:reverse([7, 8], _G514) ? creep
Exit: (8) lists:reverse([7, 8], [8, 7]) ? creep
Call: (8) add([5, 6], [8, 7], [[1, 2], [4, 3]]) ? creep
Fail: (8) add([5, 6], [8, 7], [[1, 2], [4, 3]]) ? creep
Redo: (7) doStuff([[5, 6], [7, 8]], [[1, 2], [4, 3]]) ? creep
Fail: (7) doStuff([[5, 6], [7, 8]], [[1, 2], [4, 3]]) ? creep
Redo: (6) doStuff([[1, 2], [3, 4], [5, 6], [7, 8]], _G405) ? creep
Fail: (6) doStuff([[1, 2], [3, 4], [5, 6], [7, 8]], _G405) ? creep
false.
那么它为什么会失败?这是因为prolog的主要特征之一 基本上是一个prolog中的变量,一旦它需要一个值,它永远不会改变 如果你迄今使用了命令式语言,但是认为在数学中发生完全相同的事情,听起来有点奇怪。
例如,考虑下面的等式:
x+3=4
4-x=5
从第一,我们得到的是X = 1
和来自第二我们得到是x = -1
因为x不能是1和-1我们说没有x满足上面的等式;
不使x为-1,因为这是第二个(和最后)式的值
完全相同的事情发生在YOUT程序:
doStuff([X,S|T],R):- reverse(S,Rev), add(X,Rev,R), doStuff(T,R).
所以第一时间R被分配的值,并且doStuff/2的呼叫值为R.
显然,这是不正确的值,所以doStuff/2失败
所以你怎么解决这个问题?看看你写[X,S | T]的方式来分离你想要处理的前两个元素。你只需要做与结果完全一样的结果:
写下来就像[XResult,SResult | Rest] 当然XResult只是X而SResult会是S(Rev)的反向
剩下的就是你从doStuff/2的递归调用中获得/ 2
最后但并非最不重要的是,您应该检查最后调用的子句。
你可以检查有关lists和recursion
你好一些东西。感谢你的回答。过去几天我一直在努力实施它。 所以我的问题是,R函数变量在第二次迭代中已经有一个值,当add函数试图改变它时。所以我需要使用临时变量。这是我根据你的回答写的。它返回但不返回结果列表。 (X,S | T],R): - reverse(S,Rev),add(X,Rev,[XResult,SResult | Rest]),doStuff(T,[XResult,SResult | Rest]) 。 我在做什么错? 再次感谢。 – eidolon 2011-05-16 15:46:37
您不应将XResult,SResult传递给doStuff/2 的递归调用,而只需调用doStuff(T,Rest)。结果列表是R,所以你应该定义R是什么。例如,你可以写R = [X,Rev | Rest]。所以基本上你有这样的结果: - reverse(S,Rev),doStuff(T,Rest),R = [X,Rev | Rest]。因为你不使用任何其他地方你可以简单地写: doStuff([X,S | T],[X,Rev | Rest]): - reverse(S,Rev),doStuff(T,Rest) 。 – 2011-05-16 17:05:36
好吧,现在我明白你的意思了,不需要添加功能。谢谢,我真的很感激。 – eidolon 2011-05-16 18:15:31