2

我的序言代码有问题。我需要反转列表的所有原子元素。

示例:[1,2,[3,4]] -> [[4,3],2,1]

我的解决方案:

myReverse([], []).
myReverse([H|T], X) :- myReverse(T, RT), myAppend(RT, H, X).

但它只给了我: [[3,4],2,1] 我想,如果它不是原子的,我需要使用 is_list 函数和递归调用列表......但我被卡住了......你们知道如何写下来?

4

2 回答 2

3

几乎。考虑这个解决方案:

myReverse([], []) :- !.

myReverse([H|T], X) :-
    !,
    myReverse(H, NewH),
    myReverse(T, NewT),
    append(NewT, [NewH], X).

myReverse(X, X).

第一个子句是基本情况,它包括一个 cut ( !) 以排除由于最后一个子句而留下的选择。

第二个子句颠倒了 head H,它可以是一个原子或一个列表。如果H是一个原子,则切割后的递归子目标使用最后一个子句进行评估,并且原子通过不变。如果H是一个列表,则使用第二个子句对其进行评估,并且所有元素都被反转。下一个子目标对列表的其余部分(尾部,T)执行相同的操作,然后最终使用内置的append/3. 请注意,新的 head 元素NewH是单数的,因此需要根据其对列表进行操作[NewH]的定义添加到单例列表结构append/3中。

最后一个子句不变地传递所有其他事物(即原子、数字等 - 任何不是列表或变量的事物)。

于 2012-04-10T02:37:51.113 回答
2
revall(L, Y) :-
    revall(L, [], Y).
revall([], Y, Y).
revall([H|T], T2, Y) :-
    is_list(H),!,
    revall(H, Hr),
    revall(T, [Hr|T2], Y).
revall([H|T], T2, Y) :-
    revall(T, [H|T2], Y).

这里没有附加

于 2012-04-10T07:27:03.517 回答