Как совместить эти два правила с клипами?

У меня есть два правила в CLIPS, которые я хочу объединить, если они оба верны... хотя я не уверен, как это сделать. У меня есть атрибут, который называется grant-eligible.... я думал, если я установлю его TRUE тогда я мог бы прочитать следующее правило, а затем установить 'grant-eligible' в FALSE.... но кажется, что мой код попадает в бесконечный цикл, когда я делаю это...

Итак, вот мои правила:

    (defrule complete "rule for app completeness"
  ?f <- (application (transcript-received Yes) (app-complete FALSE)
    (gpa
                ?v_gpa&:(
                    > ?v_gpa 0)))

  =>
  (modify ?f (app-complete TRUE)))


    (defrule denied "rule for admission - DENIED"
  ?f <- (application (app-complete TRUE) (app-decision FALSE)
    (gpa
                ?v_gpa&:(
                    < ?v_gpa 3.0))

    (ssat
                ?v_ssat&:(
                    >= ?v_ssat 0.0))



        )


  =>
  (modify ?f (app-decision DENIED))

  )

(defrule accepted "rule for admission - ACCEPTED"
  ?f <- (application (app-complete TRUE) (app-decision FALSE)
    (gpa
                ?v_gpa&:(
                    >= ?v_gpa 3.5))

    (ssat
                ?v_ssat&:(
                    >= ?v_ssat 1500))


        )

  =>
  (modify ?f (app-decision ACCEPTED))

  )

Это те, которые я пытаюсь реализовать сейчас

(defrule female-finaid "rule for finaid applications for female students"
  ?f <- (application (app-decision ACCEPTED) 
    (gender F) (grade-entry Freshman) (country USA)
    (grant-eligible TRUE)
    (grant ?v_grant)
    )

  =>
  (modify ?f
            (grant (+ ?v_grant 5000))
            (grant-eligible TRUE)
        )
    )

    (defrule great-students-finaid "rule for finaid applications for female students"
  ?f <- (application (app-decision ACCEPTED) 
    (country USA)
    (grant-eligible TRUE)
    (grant ?v_grant)
    (gpa
                ?v_gpa&:(
                    >= ?v_gpa 4.0))
    )

  =>
  (modify ?f
            (grant (+ ?v_grant 4500))
            (grant-eligible FALSE)
        )
    )

Если оба эти правила верны, грант должен быть равен 9500, или 5000, или 4500... Есть идеи?

Решение: (где ff-grant-eligible а также es-grant-eligible мои контрольные факты... они означают ff= женский finaid, а es= отличник)

    (defrule female-finaid "rule for finaid applications for female students"
  ?f <- (application (app-decision ACCEPTED) (ff-grant-eligible TRUE)
    (gender F) (grade-entry Freshman) (country USA)

    (grant ?v_grant)
    )

  =>
  (modify ?f
            (grant (+ ?v_grant 5000))
            (ff-grant-eligible FALSE)
        )
    )

    (defrule great-students-finaid "rule for finaid applications for female students"
  ?f <- (application (app-decision ACCEPTED) (es-grant-eligible TRUE)
    (country USA)

    (grant ?v_grant)
    (gpa
                ?v_gpa&:(
                    >= ?v_gpa 4.0))
    )

  =>
  (modify ?f
            (grant (+ ?v_grant 4500))
            (es-grant-eligible FALSE)
        )
    )

1 ответ

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

Рассмотрим следующий факт и правило:

(deffacts application-stages "ordered sequence of stages for an application"
  (stages app-received app-accept-reject app-evaluate-grants
          app-apply-grants app-complete))

(defrule go-to-next-stage "Advances to the next application stage"
  ?stage <- (app-stage ?id ?current-stage)
  (stages $? ?current-stage ?next-stage $?)
  =>
  (retract ?stage)
  (assert (app-stage ?id ?next-stage))
  (printout t "Application " ?id " moved from stage " ?current-stage
              " to " ?next-stage "." crlf))

application-stages deffact определяет последовательность этапов для приложения и go-to-next-stage Правило продвигает этап подачи заявки. Поскольку правило имеет значение ниже значения по умолчанию (0), оно будет выполнено, только если нет других правил, соответствующих текущему этапу. Поэтому, если в вашей программе нет других правил, вы получите следующее:

CLIPS> (reset)
CLIPS> (assert (app-stage app-001 app-received))
<Fact-2>
CLIPS> (run)
Application app-001 moved from stage app-received to app-accept-reject.
Application app-001 moved from stage app-accept-reject to app-evaluate-grants.
Application app-001 moved from stage app-evaluate-grants to app-apply-grants.
Application app-001 moved from stage app-apply-grants to app-complete.
CLIPS> 

Но если у вас есть какие-либо правила, связанные с определенной стадией, они будут выполнены первыми. Таким образом, вы можете добавить правила к app-evaluate-grants этап как это:

(defrule female-finaid "rule for finaid applications for female students"
  (app-stage ?id app-evaluate-grants)
  (application (app-decision ACCEPTED) (id ?id)
    (gender F) (grade-entry Freshman) (country USA)
  =>
  (assert (grant ?id female 5000)))

И вы бы аналогичным образом добавили great-student-finaid править. Тогда есть одно правило для app-apply-grants этап:

(defrule apply-grant "Adds the amount of a grant to an application"
  (app-stage ?id app-apply-grants)
  ?grant <- (grant ?id ? ?amount)
  ?app <- (application (id ?id) (grant ?v_grant))
  =>
  (retract ?grant)
  (modify (?app (grant (+ ?v_grant ?amount))))

Одним из преимуществ такого моделирования является то, что вам не нужно включать контрольные факты (например, grant-eligible) в данных для приложения. То есть ваша логика управления отделена от модели данных. Обратите внимание, что вы можете добиться того же эффекта, что и я, используя модули CLIPS (через defmodule) и это часто предпочтительнее, но для этого потребуется более длинный ответ (а этот уже довольно длинный).

Другие вопросы по тегам