Механизм логического вывода для вычисления набора соответствия в соответствии с внутренними правилами
У меня есть набор объектов с атрибутами и набор правил, которые при применении к набору объектов предоставляют подмножество этих объектов. Чтобы это было легче понять, я приведу конкретный пример.
Мои объекты - это люди, и у каждого есть три атрибута: страна происхождения, пол и возрастная группа (все атрибуты являются дискретными). У меня есть несколько правил, таких как "все мужчины из США", которые соответствуют подмножествам этого большего набора объектов.
Я ищу либо существующий "механизм логического вывода" Java, либо что-то подобное, которое сможет сопоставить правила с подмножеством людей, или советы о том, как создать свое собственное. Я ознакомился с механизмами правил, но этот термин, по-видимому, используется исключительно для экспертных систем, которые экстернализуют бизнес-правила и, как правило, не включают каких-либо сложных форм вывода. Вот несколько примеров более сложных сценариев, с которыми мне приходится иметь дело:
Мне нужно сочетание правил. Поэтому, когда представлены оба слова "включают всех мужчин" и "исключают всех лиц США в возрасте 10–20 лет", "меня интересуют только мужчины за пределами США и мужчины в США, которые находятся за пределами 10 - 20 возрастная группа.
Правила могут иметь разные приоритеты (четко определенные). Таким образом, правило, гласящее "исключить всех мужчин", переопределит правило, гласящее "включают всех мужчин США".
Правила могут быть противоречивыми. Таким образом, у меня может быть как "включить всех мужчин", так и "исключить всех мужчин", и в этом случае приоритеты должны будут решить проблему.
Правила симметричны. Таким образом, "включить всех мужчин" эквивалентно "исключить всех женщин".
Правила (или, вернее, подмножества) могут иметь мета-правила (явно определенные), связанные с ними. Эти мета-правила должны будут применяться в любом случае, когда применяется исходное правило, или если подмножество достигается с помощью логического вывода. Таким образом, если к правилу "включай всех мужчин" прикреплено мета-правило "исключить США", и я предоставлю движку правило "исключить всех женщин", то оно должно быть в состоянии сделать вывод, что подмножество "исключить всех женщин" эквивалентно подмножеству "включить всех мужчин" и в качестве такового дополнительно применять правило "исключить США".
Я могу, по всей вероятности, жить без пункта 5, но мне нужны все остальные упомянутые свойства. Мои правила и объекты хранятся в базе данных и могут быть обновлены на любом этапе, поэтому мне нужно будет создать экземпляр "механизма вывода", когда это потребуется, и уничтожить его позже.
6 ответов
Существует множество встроенных Prolog-подобных решений для SLD для Java; Мой любимый подход - использовать мини-Kanren для Scala, так как это чисто и позволяет вам использовать Scala для ленивой обработки результатов запросов, но я не использовал его подробно. Посмотрите Embedded Prolog Interpreter/Compiler for Java для других опций, а также ответ Росса.
Решатели SLD отвечают всем вашим критериям при условии, что у них есть некоторые дополнительные функции, которыми обладает Prolog:
- Соединение правил: Базовая обработка цели SLD;
- Правила могут иметь разные приоритеты: правило сокращения Пролога позволяет представлять отрицание при условии, что запросы разрешимы;
- Правила могут быть противоречивыми: Опять же, с сокращением вы можете гарантировать, что пункты с более низким приоритетом не будут применены, если цели с более высоким приоритетом будут выполнены. Есть несколько способов сделать это.
- Правила симметричны: с помощью cut это легко обеспечивается для разрешимых предикатов.
- Правила (или, вернее, подмножества) могут иметь мета-правила (явно определенные), связанные с ними: ваш пример, кажется, предполагает, что это эквивалентно 4, поэтому я не уверен, что получу то, что вы ищете, здесь.
Преимущества и недостатки решателей SLD по сравнению с инструментами на основе логики описания:
- Программная мощь, гибкость: обычно вы можете найти программные решения для трудностей моделирования, где логика описания может потребовать от вас переосмысления ваших моделей. Но, конечно, отсутствие клейкой ленты означает, что логические решения описания заставят вас быть чистым, что может быть хорошей дисциплиной.
- Надежность: решатели SLD - это очень хорошо понимаемая технология, в то время как инструменты логики описания часто находятся не так далеко от своего рождения в диссертации.
- Отсутствие семантических инструментов: логика описания имеет хорошие связи с логикой первого порядка и логикой модели и дает вам очень богатый набор техник, чтобы рассуждать о них. Гибкость Пролога обычно делает это очень трудно.
Если у вас нет специальных знаний в области логики описания, я бы порекомендовал решатель SLD.
Для случая, который вы описываете, я думаю, что вы захотите использовать обратную цепочку, а не прямую (системы RETE, такие как Drools, имеют прямую цепочку в их поведении по умолчанию).
Проверьте tuProlog. Легко связывается с Java, 100% чистой Java, и может определенно сделать вывод, который вы хотите. Вам нужно понять достаточно о Прологе, чтобы охарактеризовать ваш набор правил.
Prova может также делать выводы и обрабатывать сложные системы правил.
Для меня это звучит как логика описания и базы знаний. У вас есть концепции, роли и индивидуумы.
Если вы хотите развернуть свою проблему в качестве логического обоснования описания, вам следует хорошо смоделировать свою проблему и выполнить ее решение.
Есть несколько бесплатных рассуждений, список можно найти здесь.
Обратите внимание, что это довольно сложный, но мощный подход.
Возможно, вы захотите обратить особое внимание на KAON2 и DIG при использовании Java.
Я считаю, что вы могли бы использовать своего рода алгоритм ID3 для извлечения набора правил из начального состояния ваших объектов. Я не знаю какой-либо конкретной реализации Java, хотя Википедия указывает на различные реализации от Ruby до C (я не могу опубликовать более одной гиперссылки:-)), но это не сложный алгоритм для изучения.
Как только оно построит дерево решений, которое может быть выражено в формате правила, вы можете использовать его, чтобы увидеть, к какому классу принадлежат ваши объекты: всем мужчинам из США, всем женщинам в возрасте от 10 до 20 лет... и когда кто-то обновляет ваши объекты в базе данных, вы можете перестроить дерево решений.
Хорошо, это может быть глупый ответ. Но я все равно попробую.... Вы можете использовать BeanShell, чтобы сделать такие вещи:
Создайте простую команду селектора (что-то вроде select(inicialSet, paramName, paramValue)), которая возвращает набор элементов, который находится в inicialSet и соответствует вашим параметрам.
Создайте несколько констант, которые могут помочь вам написать хорошие сценарии BeanShell.
Таким образом, вы можете написать свои правила в виде простых сценариев и вложенных правил.
Итак, это
Мне нужно сочетание правил. Поэтому, когда представлены оба слова "включают всех мужчин" и "исключают всех лиц США в возрасте 10–20 лет", "меня интересуют только мужчины за пределами США и мужчины в США, которые находятся за пределами 10 - 20 возрастная группа.
Уилл стал такой сценарий:
originalSet = getOriginalSet(); //Get all from DB
//elements in originalSet that have gender=male
males = select(originalSet, PARAM.GENDER, GENDER.MALE);
//elements in males that have age in [10,20]
youngMaleGuys = select(males, PARAM.AGE, AGE.10_20);
//Exclude from
males.removeAll(youngMaleGuys);
notYoungUSMaleGuys = select(males, PARAM.COUNTRY, COUNTRY.US);
males.removeAll(notYoungUSMaleGuys);
return resp;
Конечно, это отстой. Я сделал это сейчас. Но вы можете написать очень хорошие команды и найти способ сделать это более читабельным.
Не так быстро, но легко поддерживать и читать (я думаю). И вам не нужно беспокоиться о заказе
Это оно. Я старался.:)
JBoss DROOLS - один из самых мощных механизмов правил производства на основе Java (механизм логического вывода).
Я буду честен, хотя, если ваше приложение не станет намного сложнее, использование движка правил будет СЛИШКОМ излишним. С другой стороны, если ваше приложение становится слишком большим и имеет слишком много конфликтующих правил, то оно не сможет обеспечить результат.
Если вы сможете лучше контролировать своего клиента или проблемную область, лучше было бы вообще избежать механизмов вывода.