Могу ли я реализовать if else в LHS правила для следующего правила типа?

У меня есть такие факты как

(claim (name Employee) (field 'EmpName' 'Company') (value 'Bob' 'ABC'))
(claim (name Event) (field 'EventName' 'Company') (value 'Conference' 'ABC'))
(drule (id gen1)(name1 'Employee') (field1 'EmpName' 'Company') (value1 'Bob' 'ABC') (name2 'Event')
    (field2 'EventName') (value2 'Conference'))

Я пробовал следующее правило. Но это не работает должным образом.

(defrule drule-rule
    (drule 
        (id ?id))
    (forall
        (drule 
                (id ?id)
                        (name1 ?name1)
                (field1 $?f11 ?field1 $?)
                (value1 $?v11&:(= (length$ ?f11) (length$ ?v11)) ?value1 $?))
                    (name2 ?name2)
                (field2 $?f22 ?field2 $?)
                (value2 $?v22&:(= (length$ ?f22) (length$ ?v22)) ?value2 $?))
        (claim 
            (name ?name1)
                (field $?f1 ?field1 $?)
                (value $?v1&:(= (length$ ?f1) (length$ ?v1)) ?value1 $?))
                (claim (name ?name2)
                (field $?f2 ?field2 $?)
                (value $?v2&:(= (length$ ?f2) (length$ ?v2)) ?value2 $?)))
         (forall
                 (claim 
            (field $?f3 ?field3 $?)
                    (value $?v4&:(= (length$ ?f3) (length$ ?v3)) ?value3 $?))
                 (claim 
            (field $?f4 ?field4 $?)
                    (value $?v4&:(= (length$ ?f4) (length$ ?v4)) ?value3 $?)))

 =>
        (assert (Action allowed)))

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

Для приведенных выше фактов утверждение должно работать. В приведенном ниже утверждении утверждение должно быть неудачным, поскольку поле Company не соответствует другому утверждению.

(claim (name Employee) (field 'EmpName' 'Company') (value 'Bob' 'xyz'))
(claim (name Event) (field 'EventName' 'Company') (value 'Conference' 'ABC'))
(drule (id gen1)(name1 'Employee') (field1 'EmpName' 'Company') (value1 'Bob' 'ABC') (name2 'Event')
    (field2 'EventName') (value2 'Conference'))

Возможно ли это с одним правилом? Или любые другие альтернативы?

Спасибо.


person Vintux    schedule 21.06.2019    source источник


Ответы (1)


Помимо преобразования второго условного элемента forall в два отдельных условных элемента not, было несколько проблем с вашими данными (несогласованное использование одинарных кавычек вокруг имен и размещение непоследовательных компания "xyz" в заявлении "Сотрудник", которое уже проверено фактом drule, а не заявлением "Событие", если это не так).

         CLIPS (6.31 4/1/19)
CLIPS> 
(deftemplate drule
   (slot id)
   (slot name1)
   (multislot field1)
   (multislot value1)
   (slot name2)
   (multislot field2)
   (multislot value2))
CLIPS>    
(deftemplate claim
   (slot name)
   (multislot field)
   (multislot value))
CLIPS>     
(defrule drule-rule
   (drule (id ?id))
   (forall
      (drule (id ?id)
             (name1 ?name1)
             (field1 $?f11 ?field1 $?)
             (value1 $?v11&:(= (length$ ?f11) (length$ ?v11)) ?value1 $?)
             (name2 ?name2)
             (field2 $?f22 ?field2 $?)
             (value2 $?v22&:(= (length$ ?f22) (length$ ?v22)) ?value2 $?))
      (claim (name ?name1)
             (field $?f1 ?field1 $?)
             (value $?v1&:(= (length$ ?f1) (length$ ?v1)) ?value1 $?))
      (claim (name ?name2)
             (field $?f2 ?field2 $?)
             (value $?v2&:(= (length$ ?f2) (length$ ?v2)) ?value2 $?))
      (not (claim (field $?f3 ?field1 $?)
                  (value $?v3&:(= (length$ ?f3) (length$ ?v3)) ~?value1 $?)))
      (not (claim (field $?f4 ?field2 $?)
                  (value $?v4&:(= (length$ ?f4) (length$ ?v4)) ~?value2 $?))))


   =>
   (assert (Action allowed)))
CLIPS>    
(assert
   (claim (name 'Employee') 
          (field 'EmpName' 'Company')
          (value 'Bob' 'ABC'))
   (claim (name 'Event')
          (field 'EventName' 'Company')
          (value 'Conference' 'ABC'))
   (drule (id gen1)
          (name1 'Employee')
          (field1 'EmpName' 'Company')
          (value1 'Bob' 'ABC')
          (name2 'Event')
          (field2 'EventName')
          (value2 'Conference')))
<Fact-3>
CLIPS> (agenda)
0      drule-rule: f-3,*
For a total of 1 activation.
CLIPS> (reset)
CLIPS>           
(assert
   (claim (name 'Employee')
          (field 'EmpName' 'Company')
          (value 'Bob' 'ABC'))
   (claim (name 'Event')
          (field 'EventName' 'Company')
          (value 'Conference' 'xyz'))
   (drule (id gen1)
          (name1 'Employee')
          (field1 'EmpName' 'Company')
          (value1 'Bob' 'ABC')
          (name2 'Event')
          (field2 'EventName')
          (value2 'Conference')))
<Fact-3>
CLIPS> (agenda)
CLIPS> 
person Gary Riley    schedule 21.06.2019