Prolog:递归无法正常工作
Prolog: recursion is not working properly
我要写change_state(+L1, +L2, -L3).
L1 包含状态,例如:[milled, burned]
L2 包含谓词,例如:[del(milled), add(shifted)]
L3 是 return 列表。
示例:
L1 = [milled, burned]
L2 = [del(burned), add(shifted)]
L3 = [milled, shifted]
所以 L1 是我的起始列表,根据 L2 中的谓词,我更改了 L1 的状态。
这是我的递归解决方案:
change_state([], [], []).
change_state(X, [], []).
change_state(State, [H|T], NewState) :-
functor(H, N, 1),
arg(1, H, A),
( N = del
-> remove_from_list(A, State, NewState)
; arg(1, H, A),
add_to_list(A, State, NewState) ),
print(NewState),
change_state(NewState, T, X),
print(NewState).
我也把一些打印放到了函数中进行调试。
现在的问题:
如果我用
调用函数
change_state([milled, burned], [del(burned), add(lol), add(hi)], L).
我得到结果
L = [milled].
所以只有 L2 中的第一个谓词有效。
但指纹显示:
[milled][lol,milled][hi,lol,milled][hi,lol,milled][lol,milled][milled].
所以它确实有效,但由于递归,它回到了第一个状态。
知道如何解决这个问题吗?
虽然您的代码已经在评论中指出的修改后正常工作,但我认为更清晰的实现如下:
change_state(State, Changes, NewState) :-
change_state_loop(Changes, State, NewState).
% Reverse the order of the first two arguments to avoid choice points.
change_state_loop([], State, State).
change_state_loop([Change|Changes], State, NewState) :-
do(Change, State, PartiallyUpdatedState),
change_state_loop(Changes, PartiallyUpdatedState, NewState).
% Use unification to choose the correct operation to perform.
do(del(Fluent), State, NewState) :- subtract(State, [Fluent], NewState).
do(add(Fluent), State, NewState) :- union(State, [Fluent], NewState).
我要写change_state(+L1, +L2, -L3).
L1 包含状态,例如:[milled, burned] L2 包含谓词,例如:[del(milled), add(shifted)] L3 是 return 列表。
示例:
L1 = [milled, burned]
L2 = [del(burned), add(shifted)]
L3 = [milled, shifted]
所以 L1 是我的起始列表,根据 L2 中的谓词,我更改了 L1 的状态。
这是我的递归解决方案:
change_state([], [], []).
change_state(X, [], []).
change_state(State, [H|T], NewState) :-
functor(H, N, 1),
arg(1, H, A),
( N = del
-> remove_from_list(A, State, NewState)
; arg(1, H, A),
add_to_list(A, State, NewState) ),
print(NewState),
change_state(NewState, T, X),
print(NewState).
我也把一些打印放到了函数中进行调试。
现在的问题:
如果我用
调用函数change_state([milled, burned], [del(burned), add(lol), add(hi)], L).
我得到结果
L = [milled].
所以只有 L2 中的第一个谓词有效。
但指纹显示:
[milled][lol,milled][hi,lol,milled][hi,lol,milled][lol,milled][milled].
所以它确实有效,但由于递归,它回到了第一个状态。
知道如何解决这个问题吗?
虽然您的代码已经在评论中指出的修改后正常工作,但我认为更清晰的实现如下:
change_state(State, Changes, NewState) :-
change_state_loop(Changes, State, NewState).
% Reverse the order of the first two arguments to avoid choice points.
change_state_loop([], State, State).
change_state_loop([Change|Changes], State, NewState) :-
do(Change, State, PartiallyUpdatedState),
change_state_loop(Changes, PartiallyUpdatedState, NewState).
% Use unification to choose the correct operation to perform.
do(del(Fluent), State, NewState) :- subtract(State, [Fluent], NewState).
do(add(Fluent), State, NewState) :- union(State, [Fluent], NewState).