Пролог Новичок - это плохая идея?

Приложение, над которым я работаю, является "конфигуратором". Это написано на С#, и я даже написал механизм правил, чтобы пойти с ним. Идея состоит в том, что существует куча пропозициональных логических операторов, и пользователь может сделать выбор. Основываясь на том, что они выбрали, некоторые другие предметы становятся обязательными или полностью недоступными.

Пропозициональные логические утверждения обычно имеют следующие формы:

A => ~X 
ABC => ~(X+Y) 
A+B => Q 
A(~(B+C)) => ~Q A <=> B

Символы:

=>  -- Implication
<=> -- Material Equivalence
~   -- Not
+   -- Or
Two letters side-by-side -- And

Я очень новичок в Prolog, но похоже, что он сможет обрабатывать все "правила обработки" для меня, позволяя мне выйти из моего текущего механизма правил (он работает, но это не так быстро или легко поддерживать, как мне хотелось бы).

Кроме того, все доступные опции попадают в иерархию. Например:

Outside
   Color
      Red
      Blue
      Green
   Material
      Wood
      Metal

Если элемент на втором уровне (функция, например Цвет) подразумевается, то должен быть выбран элемент на третьем уровне (опция, например, красный). Аналогично, если мы знаем, что функция ложна, то все параметры под ней также являются ложными.

Уловка состоит в том, что каждый продукт имеет свой собственный набор правил. Является ли разумным подход к созданию базы знаний, содержащей эти операторы, в качестве предикатов, а затем во время запуска запускает все правила для продукта?

Как я могу себе представить, что это может сработать, нужно настроить идею компонентов, функций и опций. Затем установите отношения между ними (например, если функция является ложной, то все ее параметры являются ложными). Во время выполнения добавьте специальные правила продукта. Затем передайте все пользовательские настройки функции, получая в качестве вывода, какие элементы являются истинными, а какие - ложными.

Я не знаю всех последствий того, о чем я прошу, поскольку я просто попадал в Пролог, но я стараюсь избегать плохого пути и тратить много времени на этот процесс.

Некоторые вопросы, которые могут помочь настроить то, что я пытаюсь выяснить:

  • Помогает ли этот звук?
  • Я лаяю неправильное дерево?
  • Есть ли недостатки или проблемы при попытке создать все эти правила во время выполнения?
  • Есть ли лучшая система для такого рода вещей, что я мог бы сжать в приложение С# (точнее, Silverlight)?
  • Существуют ли другие конкурирующие системы, которые я должен изучить?
  • Есть ли у вас общий совет по поводу такого рода вещей?

Заранее благодарим за ваш совет!

Ответ 1

  • Конечно, но у Prolog есть кривая обучения.
  • Правильный вывод - это игра Prolog, хотя вам, возможно, придется переписать многие правила в предложения Horn. A+B => Q выполнимо (оно становится q :- a. q :- b. или q :- (a;b).), но ваши другие примеры должны быть перезаписаны, включая A => ~X.
  • Зависит от вашего компилятора Prolog, в частности, поддерживает ли он индексирование для динамических предикатов.
  • Поиск вокруг таких терминов, как "проверка вперед", "механизм вывода" и "бизнес-правила". Различные сообщества продолжают придумывать разные термины для этой проблемы.
  • Правила ограничения ограничений (CHR) - это язык логического программирования, реализованный как расширение Prolog, что намного ближе к основанию на основе правил/форвардные цепочки/механизмы бизнес-правил. Если вы хотите использовать его, вам все равно придется изучать базовый Пролог.
  • Имейте в виду, что Prolog - это язык программирования, а не серебряная пуля для логического вывода. Он разрезает несколько углов логики первого порядка, чтобы вещи могли эффективно вычисляться. Вот почему он обрабатывает только предложения Horn: их можно сопоставить один-на-один с помощью процедур/подпрограмм.

Ответ 2

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

Возьмем, например, две пары значений атрибута Цвет в {красный, синий, зеленый} и Материал в {wood, metal}. Они могут указывать дверную ручку, в соответствии с которой возможны не все комбинации:

knob(red,wood)   --> ['100101'].
knob(red,metal)  --> ['100102'].
knob(blue,metal) --> ['100202'].

Затем вы можете определить дверь как:

door ... --> knob ..., panel ...

Интересно, что вы не увидите никакой логической формулы в такой спецификации продукта, только факты и правила, а также множество параметров. Вы можете использовать параметров в компоненте сбора знаний. Просто запустив неисповедимый целей вы можете получить возможные значения для пар значений атрибута. Предикат setof/3 сортирует и удаляет дубликаты для вас:

?- setof(Color,Material^Bill^knob(Color,Material,Bill,[]),Values).
Value = [blue, red] 
?- setof(Material,Color^Bill^knob(Color,Material,Bill,[]),Values).
Material = [metal, wood] 

Теперь вы знаете диапазон атрибутов, и вы можете позволить конечному пользователю последовательно выберите атрибут и значение. Предположим, он берет атрибут "Цвет" и его значение "синий". Диапазон атрибута Материал затем сжимается соответственно:

?- setof(Material,Bill^knob(blue,Material,Bill,[]),Values).
Material = [metal] 

В конце, когда все атрибуты указаны, вы можете прочитать статью числа подпроизведений. Вы можете использовать это для расчета цены, добавив некоторые факты, которые дают вам дополнительную информацию о номерах статей или списки заказов и т.д.:

?- knob(blue,metal,Bill,[]).
Bill = ['100202']

С наилучшими пожеланиями

P.S.: О, похоже, что идея спецификации материалов, используемая в конфигураторе продукта восходит к Clocksin и Mellish. По крайней мере, я нахожу соответствующий комментарий здесь: http://www.amzi.com/manuals/amzi/pro/ref_dcg.htm#DCGBillMaterials