2016-04-17 41 views
0

我是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是不是一个很流行的编程语言,所以我不能找到有关这个问题或答案事情和我发现的文件通常是模糊的。

我很欣赏我得到的任何答案。干杯!

回答

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> 
+0

谢谢!你的回答非常有帮助! –