2017-11-18 3 views
0

죄송합니다. 이전에 죄송합니다.이 목록에 각 항목을 반복적으로 표시하고, 목록 항목을 방문한 다음 요소가 재귀에 체크인하는지 확인하려고합니다. 상태가 변경 될 목록에 없습니다. 왜 예상대로 작동하지 않는지 알아 내야합니다. 결과가 7,0,0,0, 0,4,7.4 인 것 같고 수표는이 프로그램 실행에서 동일한 4 가지 결과를 나타내는 것으로 보입니다. 무작위로 이들 중 하나를 뱉어내는 것은 행동 순서가 잘못되었습니다. 가장 어려운 조건에서 일치해야한다는 것을 알고 있기 때문에 목표는 solve (state (0,0)) 호출을 사용하여 이것을 채우는 것입니다. 그런 다음 최종 통화에서 용기에서 5를 얻어야하며 사용 된 경로를 보여주는 목록을 인쇄 한 다음 다른 해결책을 찾으십시오. 7L 주전자에 5L이있는 곳이 2 개 밖에 없기 때문입니다.Swi Prolog - 목록으로 물 주전자 프로그램을 구현

action(state(L,R), P, state(7,R)) :- 
    L < 4, 
    not(lists:member(state(7,R),P)), 
    print(state(7,R)). 
action(state(L,R), P, state(L,4)) :- 
    R < 4, 
    not(lists:member(state(L,4),P)), 
    print(state(L,4)). 
action(state(L,R), P, state(0,R)) :- 
    L > 0, 
    not(lists:member(state(0,R),P)), 
    print(state(0,R)). 
action(state(L,R), P, state(L,0)) :- 
    R > 0, 
    not(lists:member(state(L,0),P)), 
    print(state(L,0)). 
action(state(L,R), P, state(7,C)) :- 
    not(lists:member(state(7,C),P)), 
    C is L + R -7, 
    C > 7, 
    print(state(7,C)). 
action(state(L,R), P, state(C,4)) :- 
    not(lists:member(state(C,4),P)), 
    C is L + R -4, 
    C > 4, 
    print(state(C,4)). 
action(state(L,R), P, state(0,C)) :- 
    not(lists:member(state(0,C),P)), 
    C is L + R, 
    C @=< 4, 
    print(state(0,C)). 
action(state(L,R), P, state(C,0)) :- 
    not(lists:member(state(C,0),P)), 
    C is L + R, 
    C @=< 7, 
    print(state(C,0)). 

solve(X) :- 
    reachedgoal(X,[],A). 

reachedgoal(state(5,_),L,L). 
reachedgoal(State1,P,L) :- 
    action(State1,P,State2), 
    not(lists:member(State2,P)), 
    reachedgoal(State2,[State1|P],L). 
+0

이 코드는 위해이 목록의 경로를 기억하지 보인다 예를 다시하고 다시 처음 몇 절 주위에 –

+0

갈 reachedgoal의 정의를 계속/1이 사실이 될 때 이것을 멈추게합니다. 해결책이나 주문이 누락 되었습니까? –

+0

'추적'을 한 다음 조심스럽게 조사 했습니까? – lurker

답변

1

논리적으로 약간의 실수가 있었으며 값을 계산하기 전에 중복 작업이 있는지 확인하는 것은 의미가 없습니다.

solve(X) :- 
    reachedgoal(X,[],_). 

reachedgoal(state(5,_),L,L). 
reachedgoal(State1,P,L) :- 
    action(State1,P,State2), 
    \+ member(State2,P), 
    reachedgoal(State2,[State1|P],L). 

action(state(_L,R),P,state(7,R)) :- % fill left jug (7l) 
    \+ member(state(7,R),P), 
    print(state(7,R)),nl. 
action(state(L,_R),P,state(L,4)) :- % fill right jug (4l) 
    \+ member(state(L,4),P), 
    print(state(L,4)),nl. 

action(state(_L,R),P,state(0,R)) :- % empty left jug 
    \+ member(state(0,R),P), 
    print(state(0,R)),nl. 
action(state(L,_R),P,state(L,0)) :- % empty right jug 
    \+ member(state(L,0),P), 
    print(state(L,0)),nl. 

action(state(L,R),P,state(7,C)) :- % from right jug to left jug until left full 
    C is L + R - 7, 
    C > 0, C =< 4, 
    \+ member(state(7,C),P), 
    print(state(7,C)),nl. 
action(state(L,R),P,state(C,4)) :- % from left jug to right jug until right full 
    C is L + R - 4, 
    C > 0, C =< 7, 
    \+ member(state(C,4),P), 
    print(state(C,4)),nl. 

action(state(L,R),P,state(0,C)) :- % from left jug to right jug until left empty 
    C is L + R, 
    C =< 4, 
    \+ member(state(0,C),P), 
    print(state(0,C)),nl. 
action(state(L,R),P,state(C,0)) :- % from right jug to left jug until right empty 
    C is L + R, 
    C =< 7, 
    \+ member(state(C,0),P), 
    print(state(C,0)),nl. 

이 생성됩니다

| ?- solve(state(0,0)). 
state(7,0) 
state(7,0) 
state(7,4) 
state(7,4) 
state(0,4) 
state(0,4) 
state(4,0) 
state(4,4) 
state(4,4) 
state(7,1) 
state(7,1) 
state(0,1) 
state(0,1) 
state(1,0) 
state(1,4) 
state(1,4) 
state(5,0) 
yes 

중복 때문에 행동에 충분 조건 (아래 참조)의이다.

각 작업의 중복 상태를 확인하는 것은 reachedgoal/3입니다. 마지막에 목록을 인쇄하는 것이 더 좋고 깨끗합니다.

solve :- 
    solve(state(0,0),RevStates), reverse(RevStates,States), 
    write(States), nl. 

solve(X,States) :- 
    reachedgoal(X,[],States). 

reachedgoal(state(5,_),L,L). 
reachedgoal(State1,P,L) :- 
    action(State1,State2), 
    \+ member(State2,P), 
    reachedgoal(State2,[State1|P],L). 

action(state(L,R),state(7,R)) :- % fill left jug (7l) 
    L < 7. 
action(state(L,R),state(L,4)) :- % fill right jug (4l) 
    R < 4. 
action(state(L,R),state(0,R)) :- % empty left jug 
    L > 0. 
action(state(L,R),state(L,0)) :- % empty right jug 
    R > 0. 
action(state(L,R),state(7,C)) :- % from right jug to left jug until left full 
    R > 0, L < 7, 
    C is L + R - 7, C > 0, C =< 4. 
action(state(L,R),state(C,4)) :- % from left jug to right jug until right full 
    L > 0, R < 4, 
    C is L + R - 4, C > 0, C =< 7. 
action(state(L,R),state(0,C)) :- % from left jug to right jug until left empty 
    L > 0, C is L + R, C =< 4. 
action(state(L,R),state(C,0)) :- % from right jug to left jug until right empty 
    R > 0, C is L + R, C =< 7. 

지금에는 중복이없는 :

| ?- solve. 
[state(0,0),state(7,0),state(7,4),state(0,4),state(4,0),state(4,4),state(7,1),state(0,1),state(1,0),state(1,4)] 
yes 
+0

도움을 주셔서 감사합니다. 훌륭하게 작동했습니다. –