Пролог Пропустить некоторые ответные ветви - PullRequest
0 голосов
/ 11 июня 2018

Я пытаюсь сгенерировать несколько Kakuros, сгенерировать, а не решить.

У меня есть все правила для его генерации, но первые результаты бессмысленны, это как квадраты.

Теперь яЯ хочу пропустить некоторые ветви, например, 15000, чтобы увидеть, какое kakuro сгенерировано в этой точке.

Я пробовал использовать вспомогательную переменную, но когда она не работает, генератор Kakuro запускается снова.

Kakuro Example

1 Ответ

0 голосов
/ 11 июня 2018

В базе знаний можно хранить динамический встречный предикат, который увеличивается при каждом выполнении основного предиката.Значение счетчика изменяется с assert и retract, т. Е. Это не переменная в вашем основном предикате, а глобально сохраненное значение.

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

В качестве примера рассмотрим встроенный предикат permutation/2, который вычисляет перестановки списка(примечание: протестировано с использованием SWI-Prolog, другие интерпретаторы имеют разные встроенные предикаты).Пример вывода:

?- permutation([1,2,3,4,5],L).
L = [1, 2, 3, 4, 5] ;
L = [1, 2, 3, 5, 4] ;
L = [1, 2, 4, 3, 5] ;
L = [1, 2, 4, 5, 3] ;
L = [1, 2, 5, 3, 4] ;
L = [1, 2, 5, 4, 3] ;

Если вы хотите пропустить первые 5 итераций в своем запросе, вы можете использовать следующий код:

:- dynamic iteration_nr/1.

iteration_nr(0).

get_permutations(L1,L2,Skip) :-
    permutation(L1,L2),
    iteration_nr(N),
    N2 is N+1,
    retract(iteration_nr(N)),
    asserta(iteration_nr(N2)),
    Skip < N2.     % force backtracking here if counter < Skip

Пример вывода:

?- get_permutations([1,2,3,4,5],L2,5).
L2 = [1, 2, 5, 4, 3] ;
L2 = [1, 3, 2, 4, 5] ;
L2 = [1, 3, 2, 5, 4] 

Обратите внимание, что здесь используется asserta (т. Е. Утверждение в начале) вместо простого assert, которое не рекомендуется.Также обратите внимание, что счетчик сохранит значение, поэтому при повторном запуске этого же сеанса результаты будут другими.Для сброса счетчика вы можете использовать отдельный предикат инициализации, например:

init_and_get_permutations(L1,L2,Skip) :-
    retractall(iteration_nr(_)),
    asserta(iteration_nr(0)),
    get_permutations(L1,L2,Skip).

Примечание: использование assert и retract на самом деле не считается «чистым» прологическим программированием, потому что этопроцедурный и меняет базу знаний.Однако для некоторых приложений это может быть полезно.

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