@pshevnin

Почему программа не работает так, как нужно?

Добрый день, написал на прологе решение задачи миссионеров и людоедов, но оно не работает так как нужно. Я не очень хорошо пишу на прологе, но сейчас не могу найти баг уже пару дней. Вот код:
% Правила для проверки состояния на допустимость
valid_state(state(Location, Missionaries, Cannibals)) :-
    % Условия проверки на допустимость
    % 1. Количество миссионеров и людоедов должно быть неотрицательным

    
    Missionaries >= 0,
    Cannibals >= 0,
    % 2. Количество миссионеров и людоедов не должно превышать 3
    
    Missionaries =< 3,
    Cannibals =< 3,

    % 3. На каждом берегу должно быть либо больше миссионеров, чем людоедов, либо не быть миссионеров вообще

    (Missionaries >= Cannibals ; Missionaries = 0),
    % 4. То же самое для противоположного берега
    (3 - Missionaries >= 3 - Cannibals ; 3 - Missionaries = 0).

    

% Правила для перемещения
move(state(east, M1, C1), state(west, M1_new, C1_new)) :-
    between(0, 2, X), % Количество миссионеров, пересекающих реку (от 0 до 2)
    MaxCannibals is 2 - X, % Максимальное количество каннибалов в лодке, учитывая текущее количество миссионеров
    between(0, MaxCannibals, Y), % Количество людоедов, пересекающих реку (от 0 до максимально допустимого)
    
    writeln('Current state: (in move)'), writeln(state(east, M1, C1)),
    writeln('Moving from east to west'),

    (X + Y > 0),
    M1_new is 3 - (M1 - X),
    C1_new is 3 - (C1 - Y),
    
    valid_state(state(west, M1_new, C1_new)).
    

move(state(west, M2, C2), state(east, M2_new, C2_new)) :-
    between(0, 2, X), % Количество миссионеров, пересекающих реку (от 0 до 2)
    MaxCannibals is 2 - X, % Максимальное количество каннибалов в лодке, учитывая текущее количество миссионеров
    between(0, MaxCannibals, Y), % Количество людоедов, пересекающих реку (от 0 до максимально допустимого)

    writeln('Current state: (in move)'), writeln(state(west, M2, C2)),
    writeln('Moving from west to east'),
    (X + Y > 0),
    M2_new is 3 - (M2 - X),
    C2_new is 3 - (C2 - Y),
    
    valid_state(state(east, M2_new, C2_new)).
    

breadth_first_search([Goal|_], Goal, _, [Goal]) :-
    writeln('Goal state reached!').

breadth_first_search([State|States], Goal, Visited, [State|Path]) :-
    % Выводим информацию о текущем состоянии
    writeln('===> Entering breadth_first_search/4 with state: '), writeln(State),
    % Выводим информацию о состояниях в списке посещенных
    writeln('Visited states so far: '), writeln(Visited),
    % Выводим информацию о состояниях в очереди

    % Проверяем, что состояние еще не посещалось
    \+ member(State, Visited),
    % Вывод текущего состояния
    writeln('Current state: ======='), writeln(State),

    % Переход в новые состояния
    findall(NextState, (move(State, NextState), \+ member(NextState, States)), NextStates),
   
    % Вывод новых состояний
    writeln('Adding new states to the queue...'),
    writeln('Next states: '), writeln(NextStates),

    % Добавление новых состояний в очередь
    append(States, NextStates, NewStates),
    % Добавление текущего состояния в список посещенных
    

    % Вывод обновленной очереди
    writeln('Current states in queue: '), writeln(NewStates),
    append(Visited, [State], UpdatedVisited),
    breadth_first_search(NewStates, Goal, UpdatedVisited, Path).
    
    
% Предикат для нахождения пути от начального состояния до целевого
find_path(Path) :-
    writeln('Starting breadth-first search...'),
    breadth_first_search([state(east, 3, 3)], state(west, 3, 3), [], Path),
    writeln('Path found: '), writeln(Path). % Выводим найденный путь


Вот часть того, что код выводит, путь он найти не может. У меня есть некоторое предположение, что это связано с посещёнными состояниями, потому что если я убираю проверку на посещённые состояния, программа очень долго работает, но находит возможный путь решения.
Moving from west to east
Current state: (in move)
state(west,0,2)
Moving from west to east
Current state: (in move)
state(west,0,2)
Moving from west to east
Adding new states to the queue...
Next states: 
[]
Current states in queue: 
[state(west,1,1),state(east,3,3)]
===> Entering breadth_first_search/4 with state: 
state(west,1,1)
Visited states so far: 
[state(east,3,3),state(west,0,1),state(west,0,2)]
Current state: =======
state(west,1,1)
Current state: (in move)
state(west,1,1)
Moving from west to east
Current state: (in move)
state(west,1,1)
Moving from west to east
Current state: (in move)
state(west,1,1)
Moving from west to east
Current state: (in move)
state(west,1,1)
Moving from west to east
Current state: (in move)
state(west,1,1)
Moving from west to east
Current state: (in move)
state(west,1,1)
Moving from west to east
Adding new states to the queue...
Next states: 
[]
Current states in queue: 
[state(east,3,3)]
===> Entering breadth_first_search/4 with state: 
state(east,3,3)
Visited states so far: 
[state(east,3,3),state(west,0,1),state(west,0,2),state(west,1,1)]
false.
Заранее спасибо за помощь!
  • Вопрос задан
  • 52 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы