如何在CLIPS中对事实进行组合和排列

How to make combination and permutation of facts in CLIPS

在我的程序中出现以下情况:

模板:

(deftemplate MAIN::travel-banchmark
    (slot name)
    (slot value)
)

事实:

(travel-banchmark (name location) (value torino))
(travel-banchmark (name location) (value roma))
(travel-banchmark (name location) (value milano))
(travel-banchmark (name location) (value venezia))

我必须(根据规则)创建所有可能的子集,例如 k=3(n.b。,k 是一个变量)位置(k-组合),对于每个子集,我必须排列其中的元素(并且 assert 每个排列)。

示例组合:

torino roma milano
torino roma venezia
roma milano venezia
venezia milano torino

示例排列:

torino roma milano -> roma torino milano -> torino milano roma ...

我想知道是否可以在规则的 LHS 中执行某些操作以避免在 RHS 中编写所有逻辑?

有什么有用的语法建议可以使用吗?

这是使用规则的一种方法:

         CLIPS (6.31 6/12/19)
CLIPS> 
(deftemplate travel-banchmark
   (slot name)
   (slot value))
CLIPS>    
(deftemplate permutation
   (multislot values))
CLIPS>    
(deffacts initial
   (k-combination 3)
   (travel-banchmark (name location) (value torino))
   (travel-banchmark (name location) (value roma))
   (travel-banchmark (name location) (value milano))
   (travel-banchmark (name location) (value venezia)))
CLIPS>    
(defrule first-in-permutation
   (k-combination ~0)
   (travel-banchmark (name location) (value ?city))
   =>
   (assert (permutation (values ?city))))
CLIPS>    
(defrule next-in-permutation
   (k-combination ?k)
   ?p <- (permutation (values $?cities))
   (test (< (length$ ?cities) ?k))
   (travel-banchmark (name location) (value ?city))
   (test (not (member$ ?city ?cities)))
   =>
   (assert (permutation (values ?cities ?city))))
CLIPS>    
(defrule cleanup
   (declare (salience -5))
   (k-combination ?k)
   ?p <- (permutation (values $?cities))
   (test (< (length$ ?cities) ?k))
   =>
   (retract ?p))   
CLIPS> (reset)
CLIPS> (run)
CLIPS> (facts)
f-0     (initial-fact)
f-1     (k-combination 3)
f-2     (travel-banchmark (name location) (value torino))
f-3     (travel-banchmark (name location) (value roma))
f-4     (travel-banchmark (name location) (value milano))
f-5     (travel-banchmark (name location) (value venezia))
f-8     (permutation (values venezia milano roma))
f-9     (permutation (values venezia milano torino))
f-11    (permutation (values venezia roma milano))
f-12    (permutation (values venezia roma torino))
f-14    (permutation (values venezia torino milano))
f-15    (permutation (values venezia torino roma))
f-18    (permutation (values milano venezia roma))
f-19    (permutation (values milano venezia torino))
f-21    (permutation (values milano roma venezia))
f-22    (permutation (values milano roma torino))
f-24    (permutation (values milano torino venezia))
f-25    (permutation (values milano torino roma))
f-28    (permutation (values roma venezia milano))
f-29    (permutation (values roma venezia torino))
f-31    (permutation (values roma milano venezia))
f-32    (permutation (values roma milano torino))
f-34    (permutation (values roma torino venezia))
f-35    (permutation (values roma torino milano))
f-38    (permutation (values torino venezia milano))
f-39    (permutation (values torino venezia roma))
f-41    (permutation (values torino milano venezia))
f-42    (permutation (values torino milano roma))
f-44    (permutation (values torino roma venezia))
f-45    (permutation (values torino roma milano))
For a total of 30 facts.
CLIPS> 

为了比较,使用函数生成排列:

CLIPS> (clear)
CLIPS> 
(deftemplate travel-banchmark
   (slot name)
   (slot value))
CLIPS>    
(deftemplate permutation
   (multislot values))
CLIPS>    
(deffacts initial
   (k-combination 3)
   (travel-banchmark (name location) (value torino))
   (travel-banchmark (name location) (value roma))
   (travel-banchmark (name location) (value milano))
   (travel-banchmark (name location) (value venezia)))
CLIPS> 
(deffunction gen-permutation (?k ?cities $?result)
   (if (= ?k 0)
      then
      (assert (permutation (values ?result)))
      (return))
   (foreach ?c ?cities
      (gen-permutation (- ?k 1) (delete-member$ ?cities ?c) ?result ?c)))
CLIPS>       
(defrule generate
   (k-combination ?k)
   =>
   (bind ?cities (create$))
   (do-for-all-facts ((?tb travel-banchmark)) (eq ?tb:name location)
      (bind ?cities (create$ ?cities ?tb:value)))
   (gen-permutation ?k ?cities))
CLIPS> (reset)
CLIPS> (run)
CLIPS> (facts)
f-0     (initial-fact)
f-1     (k-combination 3)
f-2     (travel-banchmark (name location) (value torino))
f-3     (travel-banchmark (name location) (value roma))
f-4     (travel-banchmark (name location) (value milano))
f-5     (travel-banchmark (name location) (value venezia))
f-6     (permutation (values torino roma milano))
f-7     (permutation (values torino roma venezia))
f-8     (permutation (values torino milano roma))
f-9     (permutation (values torino milano venezia))
f-10    (permutation (values torino venezia roma))
f-11    (permutation (values torino venezia milano))
f-12    (permutation (values roma torino milano))
f-13    (permutation (values roma torino venezia))
f-14    (permutation (values roma milano torino))
f-15    (permutation (values roma milano venezia))
f-16    (permutation (values roma venezia torino))
f-17    (permutation (values roma venezia milano))
f-18    (permutation (values milano torino roma))
f-19    (permutation (values milano torino venezia))
f-20    (permutation (values milano roma torino))
f-21    (permutation (values milano roma venezia))
f-22    (permutation (values milano venezia torino))
f-23    (permutation (values milano venezia roma))
f-24    (permutation (values venezia torino roma))
f-25    (permutation (values venezia torino milano))
f-26    (permutation (values venezia roma torino))
f-27    (permutation (values venezia roma milano))
f-28    (permutation (values venezia milano torino))
f-29    (permutation (values venezia milano roma))
For a total of 30 facts.
CLIPS>