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

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

Другие вопросы по тегам