首页 > 解决方案 > 如何将同一位置的元素加在一起 ​​CLIPS

问题描述

我是剪辑新手,我不知道如何正确遍历列表并将它们加在一起并将总和放在同一位置。我有两个定义为事实的列表,我想创建一个列表,其中包含同一位置的元素列表的总和。例如: (deffacts lists (list 1 2 3 4) (list 1 2 3 4) ) 结果应该是: (listSum 2 4 6 8)

欢迎任何帮助或建议。谢谢!

标签: listclips

解决方案


这是一个将合并两个列表的函数:

         CLIPS (6.31 6/12/19)
CLIPS> 
(deffunction add-merge (?m1 ?m2)
   ;; Get the lengths of the multifields
   (bind ?l1 (length$ ?m1))
   (bind ?l2 (length$ ?m2))
   ;; Swap values if the first multifield is not the largest
   (if (> ?l2 ?l1)
      then
      (bind ?tmp ?l1)
      (bind ?l1 ?l2)
      (bind ?l2 ?tmp)
      (bind ?tmp ?m1)
      (bind ?m1 ?m2)
      (bind ?m2 ?tmp))
   ;; Merge the values
   (bind ?rv (create$))
   (loop-for-count (?i ?l2)
      (bind ?rv (create$ ?rv (+ (nth$ ?i ?m1) (nth$ ?i ?m2)))))
   (loop-for-count (?i (+ ?l2 1) ?l1)
      (bind ?rv (create$ ?rv (nth$ ?i ?m1))))
   ?rv)
CLIPS> (add-merge (create$ 1 2 3 4) (create$ 5 6 7 8))
(6 8 10 12)
CLIPS>

使用 CLIPS 中的默认设置,您不能有重复的事实,因此如果您想要两个具有相同值的列表,您需要创建一个插槽,其中包含每个列表的唯一值:

CLIPS>    
(deftemplate list
   (slot id (default-dynamic (gensym*)))
   (multislot values))
CLIPS>    
(deffacts lists
   (list (id l1) (values 1 2 3 4))
   (list (id l2) (values 1 2 3 4)))
CLIPS>

然后您可以创建一个将合并两个列表的规则:

CLIPS>
(defrule merge
   (sum-lists ?l1 ?l2)
   (list (id ?l1) (values $?v1))
   (list (id ?l2) (values $?v2))
   =>
   (assert (list (values (add-merge ?v1 ?v2)))))
CLIPS> (reset)
CLIPS> (assert (sum-lists l1 l2))
<Fact-3>
CLIPS> (run)
CLIPS> (facts)
f-0     (initial-fact)
f-1     (list (id l1) (values 1 2 3 4))
f-2     (list (id l2) (values 1 2 3 4))
f-3     (sum-lists l1 l2)
f-4     (list (id gen1) (values 2 4 6 8))
For a total of 5 facts.
CLIPS> 

推荐阅读