Можем ли мы связать мультислот значения динамически? - PullRequest
0 голосов
/ 07 июня 2019

Я пытаюсь извлечь значения из мультислотов и динамически назначить их переменным.

Предположим, у нас есть шаблон следующим образом:

(fact (slot name)
      (multislot field)
      (multislot value))

(fact2 (slot field)
       (slot value))

Тогда может быть правило, такое как:

(rule
       (fact (name ?name)
             (field $?field)
             (value $?value))
       ;if length of field and value is greater than 0 
       (fact2 (field ?field1)
              (value ?value1))
       ;if length of field and value is greater than 1 
       (fact2 (field ?field2)
              (value ?value2))
       ;if length of field and value is greater than 2 
       (fact2 (field ?field3)
              (value ?value3))
       ;if length of field and value is greater than 3 
       (fact2 (field ?field4)
              (value ?value4))
=>
       (assert (all field:values found))

Здесь факт может иметь только одну пару значений поля или максимум 4. Я хочу общее единое правило, которое можно использовать для динамического извлечения всех доступных значений из мультислота.

Полагаю, в вышеприведенном правиле нам нужно не только извлекать значения, но и реализовывать if length > 0, else-if своего рода операторы.

Так что если Input равен:

(fact (name Employee)
      (field Name Role Department Company)
      (value Bob Admin Security ABC))
(fact2 (field Name)
       (value Bob))
(fact2 (field Role)
       (value Admin))
(fact2 (field Department)
       (value Security))
(fact2 (field Company)
       (value ABC))

Тогда ожидаемый результат будет:

(all field:value pairs found)

, а

(fact (name Employee)
      (field Name Role)
      (value Bob Admin))
(fact2 (field Name)
       (value Bob))
(fact2 (field Role)
       (value Admin))

Хотя это же правило также должно соответствовать приведенным выше фактам.Это возможно?Или есть альтернативное решение проблемы?

Заранее спасибо.

1 Ответ

1 голос
/ 07 июня 2019

Вы можете по существу перебирать каждое поле / значение, используя полный условный элемент. Если доза слота name не содержит уникального значения, и у вас есть несколько фактов fact , вам нужно добавить слот, содержащий уникальное значение, если вы хотите рассуждать о fact в действиях правила, так что шаблон fact снаружи и внутри условного элемента forall соответствует одному и тому же fact .

         CLIPS (6.31 4/1/19)
CLIPS> 
(deftemplate fact
    (slot name)
    (slot id (default-dynamic (gensym*)))
    (multislot field)
    (multislot value))
CLIPS> 
(deftemplate fact2
    (slot field)
    (slot value))
CLIPS> 
(deffacts initial
   (fact (name Employee)
         (field Name Role Department Company)
         (value Bob Admin Security ABC))
   (fact (name Employee)
         (field Name Age)
         (value Bob 38))
   (fact2 (field Name)
          (value Bob))
   (fact2 (field Role)
          (value Admin))
   (fact2 (field Department)
          (value Security))
   (fact2 (field Company)
          (value ABC)))       
CLIPS>               
(defrule reasoning
   (fact (id ?id))
   (forall
      (fact (id ?id) 
            (field $?f ?field $?) 
            (value $?v&:(= (length$ ?f) (length$ ?v)) ?value $?))
      (fact2 (field ?field)
             (value ?value)))
   =>
   (assert (all field:values found)))
CLIPS> (reset)
CLIPS> (agenda)
0      reasoning: f-1,*
For a total of 1 activation.
CLIPS> (ppfact 1)
(fact 
   (name Employee) 
   (id gen1) 
   (field Name Role Department Company) 
   (value Bob Admin Security ABC))
CLIPS> 
...