首页 > 解决方案 > 我们可以动态绑定多槽值吗?

问题描述

我正在尝试从多槽中获取值并将其动态分配给变量。

假设我们有一个模板如下:

(fact (slot name)
      (multislot field)
      (multislot value))

(fact2 (slot field)
       (slot value))

然后可以有一个规则,例如:

(rule
       (fact (name ?name)
             (field $?field)
             (value $?value))
       ;if length of field and value is greater than 0 
       (fact2 (field ?field1)
              (value ?value1))
       ;if length of field and value is greater than 1 
       (fact2 (field ?field2)
              (value ?value2))
       ;if length of field and value is greater than 2 
       (fact2 (field ?field3)
              (value ?value3))
       ;if length of field and value is greater than 3 
       (fact2 (field ?field4)
              (value ?value4))
=>
       (assert (all field:values found))

这里的事实可以只有一个字段值对或最多 4 个。我想要一个通用的单一规则,可用于动态地从多槽中提取所有可用值。

我猜在上面的规则中,我们不仅需要提取值,还需要实现 a if length > 0else-ifkinda 语句。

所以如果输入是:

(fact (name Employee)
      (field Name Role Department Company)
      (value Bob Admin Security ABC))
(fact2 (field Name)
       (value Bob))
(fact2 (field Role)
       (value Admin))
(fact2 (field Department)
       (value Security))
(fact2 (field Company)
       (value ABC))

那么预期的输出将是:

(all field:value pairs found)

尽管

(fact (name Employee)
      (field Name Role)
      (value Bob Admin))
(fact2 (field Name)
       (value Bob))
(fact2 (field Role)
       (value Admin))

而同样的规则也应该符合上述事实。这可能吗?或者有没有其他解决方案?

先感谢您。

标签: clips

解决方案


您基本上可以使用 forall 条件元素迭代每个字段/值。如果名称槽不包含唯一值并且您有多个事实事实,如果您想在规则的操作中推理事实,则需要添加一个包含唯一值的槽,以便外部的事实模式forall条件元素里面匹配相同的事实

         CLIPS (6.31 4/1/19)
CLIPS> 
(deftemplate fact
    (slot name)
    (slot id (default-dynamic (gensym*)))
    (multislot field)
    (multislot value))
CLIPS> 
(deftemplate fact2
    (slot field)
    (slot value))
CLIPS> 
(deffacts initial
   (fact (name Employee)
         (field Name Role Department Company)
         (value Bob Admin Security ABC))
   (fact (name Employee)
         (field Name Age)
         (value Bob 38))
   (fact2 (field Name)
          (value Bob))
   (fact2 (field Role)
          (value Admin))
   (fact2 (field Department)
          (value Security))
   (fact2 (field Company)
          (value ABC)))       
CLIPS>               
(defrule reasoning
   (fact (id ?id))
   (forall
      (fact (id ?id) 
            (field $?f ?field $?) 
            (value $?v&:(= (length$ ?f) (length$ ?v)) ?value $?))
      (fact2 (field ?field)
             (value ?value)))
   =>
   (assert (all field:values found)))
CLIPS> (reset)
CLIPS> (agenda)
0      reasoning: f-1,*
For a total of 1 activation.
CLIPS> (ppfact 1)
(fact 
   (name Employee) 
   (id gen1) 
   (field Name Role Department Company) 
   (value Bob Admin Security ABC))
CLIPS> 

推荐阅读