我们可以动态绑定多槽值吗?

Can we bind multislot values dynamically?

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

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

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

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

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

所以如果输入是:

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

虽然同样的规则也应该符合上述事实。这可能吗?或者有其他解决问题的方法吗?

提前谢谢你。

您基本上可以使用 forall 条件元素遍历每个 field/value。如果 name 槽不包含唯一值并且您有多个 fact 事实,则需要添加一个包含唯一值的槽,如果您想在规则的操作中对 fact 进行推理,以便 fact 模式在 forall[= 外部和内部19=] 条件元素匹配相同 fact.

         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>