我想寫 change_state( L1, L2, -L3).
L1 包含狀態,例如:[milled,burned] L2 包含謂詞,例如:[del(milled), add(shifted)] 而 L3 是回傳串列。
例子:
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].
所以它確實有效,但由于遞回,它回到了第一個狀態。
知道如何解決這個問題嗎?
uj5u.com熱心網友回復:
盡管您的代碼已經通過注釋中指出的修改正常作業,但我認為更清晰的實作如下:
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).
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/383323.html
