【问题标题】:How to force clips to ignore a certain fact for a rule?如何强制剪辑忽略某个规则的某个事实?
【发布时间】:2020-02-13 21:06:59
【问题描述】:

我有以下定义模板

(deftemplate potential
     (multislot values (type INTEGER))
)

如果仅在其中出现整数,我想删除此 deftemplate 的实例。 例子: 事实 1:潜力 1 2 3 事实 2:潜力 2 3 4 事实 3:潜力 2 3 4 5

我想撤回 fact-1 和 fact-3,因为它们包含唯一的 1 和 5。

我正在尝试使用如下规则来实现它:

  1 (defrule remove_if_only_option
  2     ?p<-(potential (values $? ?value $?   ))
  3     (not (exists   (potential (values $? ?value $?)  )))
  4     =>
  5     (retract ?p)
  7 )

显然它不起作用,因为第 3 行可以匹配最初的事实。有什么方法可以让规则不考虑其余部分的 ?p 吗?

谢谢。

【问题讨论】:

    标签: clips


    【解决方案1】:

    规则中的任何模式都不会受到初始事实存在或不存在的影响,因为它们都匹配潜在事实。 exists 条件元素在第二种模式中是多余的,所以你的规则相当于

    (defrule remove_if_only_option
       ?p <- (potential (values $? ?value $?))
       (not (potential (values $? ?value $?)))
       =>
       (retract ?p))
    

    并且由于条件x and not x 永远不会为真,因此永远无法满足此规则。

    您可以通过比较它们的事实地址来判断两个相同类型的事实是否不同,但是由于您无法在非条件元素中绑定事实地址,因此在这种情况下您不能这样做。或者,您可以包含一个槽,其中包含每个事实的唯一值,可用于判断事实是否不同:

             CLIPS (6.31 6/12/19)
    CLIPS> 
    (deftemplate potential
       (slot id (default-dynamic (gensym*)))
       (multislot values (type INTEGER)))
    CLIPS> 
    (defrule remove_if_only_option
       ?p <- (potential (id ?id) (values $? ?value $?))
       (not (potential (id ~?id) (values $? ?value $?)))
       =>
       (retract ?p))
    CLIPS> 
    (assert (potential (values 1 2 3))
            (potential (values 2 3 4))
            (potential (values 2 3 4 5)))
    <Fact-3>
    CLIPS> (agenda)
    0      remove_if_only_option: f-3,*
    0      remove_if_only_option: f-1,*
    For a total of 2 activations.
    CLIPS> 
    

    最初,这似乎可行,但一旦运行,您就会发现存在问题:

    CLIPS> (run 1)
    CLIPS> (agenda)
    0      remove_if_only_option: f-2,*
    0      remove_if_only_option: f-1,*
    For a total of 2 activations.
    CLIPS>
    

    一旦 f-3 被删除,f-2 中的值 4 现在变得唯一,因此这个事实现在也将被这条规则删除。问题是公共值集由潜在事实的集合隐式表示,一旦您开始删除它们,您就改变了公共值集。

    为此,您至少需要两个步骤,因此至少需要两个规则。一种方法是在一个步骤中标记需要删除的事实,然后在另一个步骤中将其删除:

    CLIPS> (clear)
    CLIPS> 
    (deftemplate potential
       (slot id (default-dynamic (gensym*)))
       (multislot values (type INTEGER))
       (slot delete (default no)))
    CLIPS> 
    (defrule remove_if_only_option
       (not (done))
       ?p <- (potential (id ?id) (values $? ?value $?) (delete no))
       (not (potential (id ~?id) (values $? ?value $?)))
       =>
       (modify ?p (delete yes)))
    CLIPS> 
    (defrule remove
       (declare (salience -10))
       ?p <- (potential (delete yes))
       =>
       (assert (done))
       (retract ?p))
    CLIPS>    
    (assert (potential (values 1 2 3))
            (potential (values 2 3 4))
            (potential (values 2 3 4 5)))
    <Fact-3>
    CLIPS> (agenda)
    0      remove_if_only_option: *,f-3,*
    0      remove_if_only_option: *,f-1,*
    For a total of 2 activations.
    CLIPS> (run 1)
    CLIPS> (agenda)
    0      remove_if_only_option: *,f-1,*
    -10    remove: f-4
    For a total of 2 activations.
    CLIPS> (facts)
    f-0     (initial-fact)
    f-1     (potential (id gen4) (values 1 2 3) (delete no))
    f-2     (potential (id gen5) (values 2 3 4) (delete no))
    f-4     (potential (id gen6) (values 2 3 4 5) (delete yes))
    For a total of 4 facts.
    CLIPS> (run 1)
    CLIPS> (agenda)
    -10    remove: f-5
    -10    remove: f-4
    For a total of 2 activations.
    CLIPS> (run)
    CLIPS> (facts)
    f-0     (initial-fact)
    f-2     (potential (id gen5) (values 2 3 4) (delete no))
    f-6     (done)
    For a total of 3 facts.
    CLIPS> 
    

    另一种创建包含唯一值的事实的方法:

    CLIPS> (clear)
    CLIPS> 
    (deftemplate potential
       (slot id (default-dynamic (gensym*)))
       (multislot values (type INTEGER)))
    CLIPS> 
    (defrule add-to-unique
       (not (done))
       ?c <- (unique $?unique)      
       (potential (id ?id) (values $? ?value $?))
       (not (potential (id ~?id) (values $? ?value $?)))
       (test (not (member$ ?value ?unique)))
       =>
       (retract ?c)
       (assert (unique $?unique ?value)))
    CLIPS>  
    (defrule remove_if_only_option
       (declare (salience -10))
       (unique $?unique)
       ?p <- (potential (values $? ?value $?))
       (test (member$ ?value ?unique))
       =>
       (assert (done))
       (retract ?p))
    CLIPS>   
    (assert (potential (values 1 2 3))
            (potential (values 2 3 4))
            (potential (values 2 3 4 5)))
    <Fact-3>
    CLIPS> (assert (unique))
    <Fact-4>
    CLIPS> (run)
    CLIPS> (facts)
    f-0     (initial-fact)
    f-2     (potential (id gen26) (values 2 3 4))
    f-6     (unique 5 1)
    f-7     (done)
    For a total of 4 facts.
    CLIPS> 
    

    【讨论】:

    • 是的,我指的是最初的“潜在”事实,而不是“最初的事实”,但我明白你的意思。一如既往的好解决方案。感谢您的支持!
    猜你喜欢
    • 1970-01-01
    • 2019-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-08
    • 2016-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多