Правила обработки ограничений в SWI Prolog: в каком порядке накладываются ограничения на хранилище?
Я изучаю правила обработки ограничений (CHR) в swi-prolog.
Я начал с учебного пособия из « Правила обработки ограничений» Тома Шрайверса - Учебное пособие для (Prolog) программистов .
Часть путаницы заключается в том, что в каком порядке помещать ограничение в хранилище ограничений?
На стр. 69 показано, что при срабатывании правила добавьте текст в запрос (перед ним) .
стр.104 - стр.106 показывают, что обычно порядок наложения ограничения в хранилище соответствует порядку запроса. Это второе ограничение (
piggy(1)
) будет помещен справа от первого ограничения (piggy(5)
) в магазине.стр.107, по п.1, добавить в начало запроса и затем положить в магазин.
с.108, странные вещи случаются, почему
piggy(4)
быть поставлен в передней части магазина (слева, чтобыpiggy(6)
)?с.109 - с.110, более странно то, что после срабатывания правила добавляется в магазин а потом
piggy(2)
быть добавлен в конец магазина (право наpiggy(10)
)?
Мой первый вопрос: в каком именно порядке накладываются ограничения в хранилище ограничений?
Например,
:- use_module(library(chr)).
:- chr_constraint philosophers_stone/0, lead1/0, lead2/0, gold1/0, gold2/0.
philosophers_stone \ lead1 <=> gold1.
philosophers_stone \ lead2 <=> gold2.
?- lead1, lead2, philosophers_stone.
Почему результат запроса в swi-prolog:
philosophers_stone,
gold1,
gold2
вместо того
philosophers_stone,
gold2,
gold1
Замедленное движение (в моем понимании):
query: lead1, lead2, philosophers_stone.
store:
query:
store: lead1, lead2, philosophers_stone.
query: gold1
store: lead2, philosophers_stone
query: gold2, gold1 <---- added to (front of) query
store: philosophers_stone
query:
store: philosophers_stone, gold2, gold1
Кажется, что когда срабатывает правило, тело должно быть добавлено в (конец) запроса? Это правильно?
query: lead1, lead2, philosophers_stone.
store:
query:
store: lead1, lead2, philosophers_stone.
query: gold1
store: lead2, philosophers_stone
query: gold1, gold2 <---- added to (end of) query
store: philosophers_stone
query:
store: philosophers_stone, gold1, gold2 <--- then correct
Мой второй вопрос зависит от порядка?
Я имею в виду, что даже если заказы на размещение будут другими, результат в конечном итоге сведется к переупорядочиванию стабильного магазина? Могу ли я игнорировать этот приказ? Я знаю, что порядок правил очень чувствителен в реализации CHR swi-prolog, и их нельзя игнорировать.
Спасибо.
1 ответ
Согласно моей памяти и https://en.wikipedia.org/wiki/Constraint_Handling_Rules , хранилище констант представляет собой мультимножество. Поэтому в нем вообще нет порядка. (Если бы он был упорядоченным, мы бы назвали его списком, а не мультимножеством.)
Что касается вашего примера, я также получаю:
?- lead1, lead2, philosophers_stone.
philosophers_stone,
gold1,
gold2.
Но и:
?- lead2, lead1, philosophers_stone.
philosophers_stone,
gold1,
gold2.
Немного покопавшись в источнике
chr_show_store/1
а оттуда в
'$enumerate_constraints'/2
, похоже, хранилище печатается в том порядке, в котором вы объявили ограничения. Также похоже, что каждое ограничение управляет своими экземплярами независимо, то есть вообще нет центрального «хранилища ограничений». Каждое ограничение связано со своим собственным списком экземпляров.
Существует некоторый порядок выполнения: «Активное ограничение просматривает правила сверху вниз, чтобы найти все, что срабатывает», но некоторые части этого не указаны (стр. 214). Таким образом, вы не должны писать программы, которые очень чувствительны к вопросам заказа.
Что касается примера с поросятами, мне кажется, что размещение поросят оптимизировано для того, чтобы они не слишком часто двигались, когда слайды демонстрируются во время выступления. Я не думаю, что их размещение должно указывать на фактический порядок слева направо.