Могу ли я реализовать if if в LHS правила для следующего правила типа? - PullRequest
0 голосов
/ 21 июня 2019

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

(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'))

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

Спасибо.

1 Ответ

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

Помимо преобразования второго условного элемента forall в два отдельных условных элемента , а не , с вашими данными было несколько проблем (непоследовательное использование одинарных кавычек вокруг имен и размещениенесогласованная компания "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> 
...