CLIPS:根据出现的次数查找最常见的事实

时间:2016-04-17 16:21:33

标签: clips

我是CLIPS的新手,我很难理解语言。我知道这个相当混乱的标题,所以我会努力尽可能清晰和准确。

我有一个由学生参赛作品代表的事实基础,我想找出哪些城市是最常见的(最常见的)入伍学生。

这是我的事实基础:

 (deftemplate student
             (slot name)
             (slot city)
             (slot age)
             (multislot subjects)
             (multislot grades)
)

(deffacts students
  (student (name John) (city Florida) (age 20) (subjects RRE SSE DDE SRE) (grades D B F F)
  (student (name Jesse) (city Miami) (age 21) (subjects RRE SSE DDE SRE) (grades C C D D)
  (student (name Sasha) (city Florida) (age 20) (subjects RRE SSE DDE SRE) (grades B A B B)
  (student (name Mark) (city Florida) (age 20) (subjects RRE SSE DDE SRE) (grades C C F F)
)

我一直在寻找答案,但CLIPS不是一种非常流行的编程语言,因此我无法找到有关此事的问题或答案,而且我发现的文档通常含糊不清。

我很感激我得到的任何答案。干杯!

1 个答案:

答案 0 :(得分:0)

某些语言提供聚合运算符,允许您收集与模式匹配的所有事实。该功能可以更轻松地解决此类问题。 CLIPS不支持此功能,因此您必须使用其他方法。这是两个:

CLIPS> 
(deftemplate student
             (slot name)
             (slot city)
             (slot age)
             (multislot subjects)
             (multislot grades))
CLIPS> 
(deffacts students
  (student (name John) (city Florida) (age 20) (subjects RRE SSE DDE SRE) (grades D B F F))
  (student (name Jesse) (city Miami) (age 21) (subjects RRE SSE DDE SRE) (grades C C D D))
  (student (name Sasha) (city Florida) (age 20) (subjects RRE SSE DDE SRE) (grades B A B B))
  (student (name Mark) (city Florida) (age 20) (subjects RRE SSE DDE SRE) (grades C C F F)))
CLIPS>   
(deffunction find_cities_with_most_students_1 ()
   (bind ?cities (create$))
   (bind ?counted_cities (create$))
   (bind ?largest_count 0)
   (do-for-all-facts ((?s student)) TRUE
      (if (not (member$ ?s:city ?counted_cities))
         then
         (bind ?counted_cities (create$ ?s:city ?counted_cities))
         (bind ?count (length$ (find-all-facts ((?s2 student)) (eq ?s2:city ?s:city))))
         (if (= ?count ?largest_count)
            then
            (bind ?cities (create$ ?s:city ?cities))
            else 
            (if (> ?count ?largest_count)
               then
               (bind ?largest_count ?count)
               (bind ?cities (create$ ?s:city))))))      
   (return ?cities))
CLIPS> 
(defrule largest_count_1
   (declare (salience -10))
   =>
   (bind ?cities (find_cities_with_most_students_1))
   (foreach ?c ?cities
      (printout t "1 " ?c " has the most students" crlf)))
CLIPS>    
(deftemplate city_count
   (slot city)
   (multislot facts))
CLIPS>   
(defrule count_cities_2
   (student (city ?city))
   (not (city_count (city ?city)))
   =>
   (assert (city_count (city ?city)
                       (facts (find-all-facts ((?s student)) 
                                              (eq ?s:city ?city))))))
CLIPS> 
(defrule largest_count_2
   (declare (salience -10))
   (city_count (city ?city) (facts $?facts))
   (not (city_count (city ~?city) (facts $?facts2&:(> (length$ ?facts2) (length$ ?facts)))))
   =>
   (printout t "2 " ?city " has the most students" crlf))
CLIPS> (watch rules)
CLIPS> (watch facts)
CLIPS> (reset)
<== f-0     (initial-fact)
==> f-0     (initial-fact)
==> f-1     (student (name John) (city Florida) (age 20) (subjects RRE SSE DDE SRE) (grades D B F F))
==> f-2     (student (name Jesse) (city Miami) (age 21) (subjects RRE SSE DDE SRE) (grades C C D D))
==> f-3     (student (name Sasha) (city Florida) (age 20) (subjects RRE SSE DDE SRE) (grades B A B B))
==> f-4     (student (name Mark) (city Florida) (age 20) (subjects RRE SSE DDE SRE) (grades C C F F))
CLIPS> (run)
FIRE    1 count_cities_2: f-4,*
==> f-5     (city_count (city Florida) (facts <Fact-1> <Fact-3> <Fact-4>))
FIRE    2 count_cities_2: f-2,*
==> f-6     (city_count (city Miami) (facts <Fact-2>))
FIRE    3 largest_count_2: f-5,*
2 Florida has the most students
FIRE    4 largest_count_1: *
1 Florida has the most students
CLIPS> (unwatch all)
CLIPS> (reset)
CLIPS> (run)
2 Florida has the most students
1 Florida has the most students
CLIPS>