CLIPS: Finding the most common of facts based on the number of occurences

守給你的承諾、 提交于 2019-12-12 00:36:49

问题


I am new to CLIPS and I am having difficulties understanding the language. I am aware of the rather confusing title so I will try to be as clear and precise as I can.

I have a base of facts represented by student entries and I want to find out which city is the most common (appears most frequent) among the enlisted students.

This is my base of facts:

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

I have been searching for the answer for a couple of days, but CLIPS is not a very popular programming language, so I cannot find questions or answers regarding this matter and the documentation I find is often vague.

I appreciate any answer I get. Cheers!


回答1:


Some languages provide aggregation operators that allow you to collect all facts matching a pattern. That functionality makes it easier to solve this type of problem. CLIPS does not support this functionality, so you must use alternate approaches. Here are two:

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> 


来源:https://stackoverflow.com/questions/36679051/clips-finding-the-most-common-of-facts-based-on-the-number-of-occurences

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!