您採取錯誤的表示。使用事實對於表示一個不可改變的世界是很好的,但是一旦你開始搜索,你想表示一個可變的世界狀態,這在邏輯變量中最好實現。這樣你就可以利用Prolog非確定性和回溯來找到一系列讓你從開始狀態到最終狀態的動作。因此, 讓我們代表數據庫中的最終狀態,然後規則來獲取變量的開始狀態和最終狀態。我們對一個州的表示是一系列(三個)on(X,Y)
條款。
final(a,b).
final(b,c).
final(c,t).
start(State) :-
findall(on(X,Y), on(X,Y), State).
final(State) :-
findall(on(X,Y), final(X,Y), FinalState),
same_state(State, FinalState).
same_state(State1, State2) :-
sort(State1, State),
sort(State2, State).
現在我們必須定義自由的狀態。這很簡單:最上面的一個和表都是免費的:
free(X, State) :-
box(X),
\+ member(on(_,X), State).
free(t, _).
現在,我們可以定義一個舉動是從初始狀態取出一個on(X,Y)
並添加一個新問題:
move(State0, move(X,New), [on(X,New)|Rest]) :-
select(on(X,_), State0, Rest),
free(X, State0),
free(New, State0),
X \== New.
接下來,我們必須做出多重舉動。我們必須小心,不要進入一個狀態,我們之前已經看到:
moves(State, [], _Visited, State).
moves(State0, [Move|T], Visited, State) :-
move(State0, Move, State1),
\+ (member(V, Visited),
same_state(State1, V)
),
moves(State1, T, [State1|Visited], State).
現在,我們幾乎完成:
solve(Moves) :-
start(State),
moves(State, Moves, [State], Final),
final(Final).
有很多優化。我會把它留給你。最後的兩個謂詞確實顯示了搜索的整體方法:從頭開始,進行移動,避免返回到舊狀態並測試您是否找到了目標狀態。整個東西在一個文件中顯示在https://swish.swi-prolog.org/p/BenchG.pl
這樣一個美麗的解決方案,這就是爲什麼我喜歡Prolog! –