ECLiPSe CLP: пауза между подрезультатами, найденными поиском /6 в библиотеке ic
(Этот вопрос касается поиска /6.)
Мне было интересно, есть ли способ, а не ручная трассировка, приостанавливать выполнение поиска /6 каждый раз, когда было найдено новое решение для одной переменной?
Я хотел бы сделать это для дальнейшего изучения того, что происходит во время поиска в моделях с ограничениями.
Например, если вы пытаетесь решить классическую проблему судоку, и вы написали набор ограничений и метод печати для своей доски, может быть полезно распечатать доску после установки ограничений, но перед поиском, чтобы оцените силу своих ограничений. Однако, как только поиск вызван, чтобы решить судоку, у вас не будет обзора отдельных результатов, создаваемых ниже, если вы не сделаете трассировку.
Было бы очень полезно, если бы что-то было возможно в виде:
(это просто абстрактный пример)
% Let's imagine this is a (very poorly) constrained sudoku board
?- problem(Sudoku),constraint(Sudoku),print(Sudoku).
[[1,3,_,2,_,_,7,4,_],
[_,2,5,_,1,_,_,_,_],
[4,8,_,_,6,_,_,5,_],
[_,_,_,7,8,_,2,1,_],
[5,_,_,_,9,_,3,7,_],
[9,_,_,_,3,_,_,_,5],
[_,4,_,_,_,6,8,9,_],
[_,5,3,_,_,1,4,_,_],
[6,_,_,_,_,_,_,_,_]]
Теперь для поиска:
?- problem(Sudoku),constraint(Sudoku),search_pause(Sudoku,BT),print(Sudoku,BT).
[[1,3,6,2,_,_,7,4,_],
[_,2,5,_,1,_,_,_,_],
[4,8,_,_,6,_,_,5,_],
[_,_,_,7,8,_,2,1,_],
[5,_,_,_,9,_,3,7,_],
[9,_,_,_,3,_,_,_,5],
[_,4,_,_,_,6,8,9,_],
[_,5,3,_,_,1,4,_,_],
[6,_,_,_,_,_,_,_,_]]
Board[1,3] = 6
Backtracks = 1
more ;
1 ответ
Использование существующих инструментов визуализации
Ознакомьтесь с Руководством по инструментам визуализации. Вы можете получить желаемый вид отображения матрицы, добавив аннотацию viewable_create/2 к своему коду и запустив клиент визуализации из меню инструментов TkECLiPSe.
Используя свою собственную инструментальную процедуру поиска
Вы можете заменить indomain_xxx
Методы выбора в search/6 с пользовательским, где вы можете печатать информацию до и / или после распространения.
Если этого недостаточно, вы можете заменить весь встроенный search/6
с вашим собственным, что не так уж сложно, см., например, главу Учебное пособие по ECLiPSe о поиске по дереву или мой ответ на этот вопрос.
Трассировка с использованием управляемых данными средств
Используя управляемые данными средства управления ECLiPSe, вы можете довольно легко отображать информацию, когда определенные вещи происходят с вашими переменными. В простейшем случае вы делаете что-то для создания переменной:
?- suspend(printf("X was instantiated to %w%n",[X]), 1, X->inst),
writeln(start), X=3, writeln(end).
start
X was instantiated to 3
end
Основываясь на этой идее, вы можете написать код, который позволит вам выполнять шаги по маркировке и распространению, даже если они происходят внутри подпрограммы поиска черного ящика. Смотрите ссылку для деталей.