我的序言代码有问题。我需要反转列表的所有原子元素。
示例:[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 函数和递归调用列表......但我被卡住了......你们知道如何写下来?
几乎。考虑这个解决方案:
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
中。
最后一个子句不变地传递所有其他事物(即原子、数字等 - 任何不是列表或变量的事物)。
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).
这里没有附加