SWI-Prolog Как Prolog обрабатывает логические сравнения

Я написал следующий код на SWI-Prolog:

:- dynamic state_a/1 .
 :- dynamic state_b/1 .
 :- dynamic state_c/1 .
 state_a([1,2,3,4,5,0]).
 state_b([0]).
 chop(LIST,HEAD,TAIL) :- LIST=[HEAD|TAIL].
 move_ab :- !,state_a(X),
            chop(X,Ha,Ba),
            Ha>0,
            state_b(Y),
            chop(Y,Hb,Bb),!,
            (Ha<Hb ; Hb =:= 0),
            asserta(state_a(Ba)),asserta(state_b([Ha|Y])),
            retract(state_a(X)), retract(state_b(Y));
            write('Wrong Move.Choose Another').

В моем коде есть 2 ИЛИ (;). Когда я впервые спрашиваю move_ab в Прологе, все условия перед вторым ИЛИ верны, поэтому я получаю ответ верно от Пролога. Но второй раз, когда я задаю move_ab в Прологе, я получаю только ответ false. Я не знаю, как это могло случиться. Некоторые из условий перед вторым ИЛИ неверны, поэтому Prolog должен проверить условие после второго ИЛИ и написать мне сообщение Неверный ход. Выберите другое.. Я попытался использовать () для группировки условий, но все равно получаю то же сообщение. Есть идеи о том, что происходит? Кстати, я новичок в Прологе, только 2 дня назад начал :)


person Babilicious    schedule 30.12.2011    source источник


Ответы (1)


Проблема заключается в использовании cut (!/0) до надлежащего тестирования условий. Вырезание удаляет точки выбора. Здесь это означает, что варианты удаляются еще до того, как вы что-либо протестируете. Так что, если тесты терпят неудачу, все терпит неудачу!

Кстати, манипулирование базой данных, возможно, не лучшая идея. Для представления состояний вы можете использовать глобальные переменные следующим образом:

:- nb_setval(state_a, [1,2,3,4,5,0]).
:- nb_setval(state_b, [0]).

move_ab :-
    nb_getval(state_a, [Ha|Ta]),
    Ha > 0,
    nb_getval(state_b, [Hb|Tb]),
    (Ha < Hb ; Hb =:= 0),
    nb_setval(state_a, Ta),
    nb_setval(state_b, [Ha, Hb|Tb]),
    !
    ;
    write('Wrong Move.Choose Another').

Общий совет новичкам в прологе - по возможности держаться подальше от манипуляций с базой данных, так как часто проблемы решаются и без этого. Здесь хоть и может быть оправдано, но глобальными переменными будет быстрее и проще манипулировать.

person m09    schedule 31.12.2011