2016-04-17 76 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

謝謝!你的回答非常有幫助! –