如何将这两个规则与CLIPS结合? [英] how to combine these two rules with CLIPS?

查看:98
本文介绍了如何将这两个规则与CLIPS结合?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在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-eligiblees-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)
        )
    )

解决方案

有很多方法可以控制程序的执行(例如,控制事实,显着性,模块).该答案将在应用程序处理的各个阶段中使用控制事实(具有显着性).我还要假设您有与每个应用程序关联的唯一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定义了应用程序的阶段顺序,而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),可以达到与我在这里所做的相同的效果,通常这是更可取的,但它需要更长的答案(并且这个答案已经相当长了). >

I have two rules in CLIPS which I want to combine if they're both true...not sure how to do it though. I have an attribute which is called grant-eligible....I was thinking if I set it to TRUE then I could read the next rule, and then set the 'grant-eligible' to FALSE....but it seems that my code is getting into an infinite loop when I do this...

So here are my rules:

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

  )

This is the ones I am trying to implement now

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

If both of these rules are true, the grant awarded should be 9500, or it could be 5000 or it could be 4500...Any ideas?

The solution: (where ff-grant-eligible and es-grant-eligible are my control facts...they stand for ff=female finaid, and es=excellent student)

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

解决方案

There are numerous ways you can control execution of your program (e.g., control facts, salience, modules). This answer will use control facts (with salience) for the stages of application processing. I am also going to assume that you have a unique id slot associated with each application.

Consider the following fact and rule:

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

The application-stages deffact defines the sequence of stages for an application and the go-to-next-stage rule advances the application stage. Since the rule has salience that is lower than the default (0), it will only be executed if there are no other rules corresponding to the current stage. So with no other rules in your program, you would get the following:

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> 

But if you have any rules associated with a particular stage, they will be executed first. So you can add rules to the app-evaluate-grants stage like this:

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

And you would similarly add a great-student-finaid rule. Then, there is a single rule for the app-apply-grants stage:

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

One of the benefits of modeling it this way is that you don't have to include control facts (e.g., grant-eligible) in the data for an application. That is, your control logic is separate from the data model. Note that you can achieve the same effect as what I've done here by using CLIPS modules (via defmodule) and that is often preferable but it would require a lengthier answer (and this one is already fairly long).

这篇关于如何将这两个规则与CLIPS结合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆