Поиск самой подходящей машины в клипах

Итак, у нас есть проект, в котором нам нужно создать экспертную систему, которая, предоставляя сведения о некоторых автомобилях, выбирает наиболее подходящую для пользователя.

Прежде всего, в классе мы узнали мелочи о клипах, таких как deftemplate, deffacts и defrule. Ничего лишнего (!!!) Так что мой проект, я думаю, не может содержать код вроде модулей или функций.

Во-вторых, согласно приведенным данным, код должен быть таким, который я пишу далее.

Дело в том, что: 1. Другого пути, кроме (отзыва), мы не научились. 2. Если я прав: 2а. Есть ли способ найти в моем коде то, что нужно отозвать, и чтобы эксперт не записывал не относящиеся к делу факты? 2b. что я должен написать, чтобы каждый раз приносил результат? (например, если мы укажем семейство типов и высокую цену, у нас не будет руссельта). 2c. есть ли способ, чтобы после этого "метода вычитания" я, хотя, программа печатала, после вопросов, оставшиеся факты, но не с способом "(факты)" ??

спасибо за преимущество.

код:

(deftemplate car_template
(slot brand_name (type STRING))
(slot type (type STRING)(allowed-symbols family city super))
(slot price (type SYMBOL) (allowed-symbols low mid high))
;;; low = 0-10000 mid = 10001-20000 high = 20001-10000 
(slot performance (type SYMBOL) (allowed-symbols low mid high))
(slot equipment (type SUMBOL) (allowed-symbols low mid high))
)

(deffacts car_facts
(car (brand_name "Opel Astra")(type family)(price mid)(performance low)
(car (brand_name "Peugeot 106a")(type city)(price low)(performance high)
(car (brand_name "Mercedes E200")(type super)(price high)(performance mid)
(car (brand_name "Rover 25")(type family)(price mid)(performance mid)
(car (brand_name "Ferrari F40")(type super)(price high)(performance high)
)


(defrule type_rule
(initial-fact)

=>

(printout t "Give the Type you want (possible options: family city super): "
    (bind ?response (read))
    (if (eq ?response family) then
        ;;;retracting city               
        (retract 2)
        ;;;rectarting super
        (retract 3 5)
    else (if (eq ?response city) then
        ;;;retracting family
        (retract 1 4)
        ;;;rectarting super
        (retract 3 5) 
          else
                ;;;retracting city
        (retract 2)
        ;;;retracting family               
        (retract 1 4)
    ))))

(defrule price_rule
(initial-fact)

=>

(printout t "Give the price you want (possible options: low mid high): "
    (bind ?response (read))
    (if (eq ?response low) then
        ;;;retracting mid               
        (retract 1 4)
        ;;;rectarting high
        (retract 3 5)
    else (if (eq ?response mid) then
        ;;;retracting low
        (retract 2)
        ;;;rectarting high
        (retract 3 5) 
          else
                ;;;retracting mid
        (retract 1 4)
        ;;;retracting low               
        (retract 2)
    ))))

(defrule performance_rule
(initial-fact)

=>

(printout t "Give the performance you want (possible options: low mid high): "
    (bind ?response (read))
    (if (eq ?response low) then
        ;;;retracting mid               
        (retract 3 4)
        ;;;rectarting high
        (retract 2 5)
    else (if (eq ?response mid) then
        ;;;retracting low
        (retract 1)
        ;;;rectarting high
        (retract 2 5) 
          else
                ;;;retracting mid
        (retract 3 4)
        ;;;retracting low               
        (retract 1)
    ))))

(defrule print_facts
(initial-fact)

=>

(printout t "The car that fits you is: "
    (facts)
))

person kman3    schedule 15.05.2017    source источник
comment
Нет необходимости добавлять начальный факт к правилу без других условий; он добавляется автоматически в версиях CLIPS до версии 6.3. Первоначальная функциональность была объявлена ​​устаревшей в версии 6.3; он по-прежнему подтверждается сбросом, но правила без условий больше не полагаются на него. В выпуске 6.4 исходный факт больше не утверждается, поэтому правила, которые явно соответствуют этому факту, больше не будут активироваться.   -  person Gary Riley    schedule 03.01.2019


Ответы (1)


Это лучший способ отказаться от фактов:

(deftemplate car
   (slot brand_name (type STRING))
   (slot type (type SYMBOL)(allowed-symbols family city super))
   (slot price (type SYMBOL) (allowed-symbols low mid high))
   (slot performance (type SYMBOL) (allowed-symbols low mid high))
   (slot equipment (type SYMBOL) (allowed-symbols low mid high)))

(deffacts car_facts
   (car (brand_name "Opel Astra") (type family) (price mid) (performance low))
   (car (brand_name "Peugeot 106a") (type city) (price low) (performance high))
   (car (brand_name "Mercedes E200") (type super) (price high) (performance mid))
   (car (brand_name "Rover 25") (type family) (price mid) (performance mid))
   (car (brand_name "Ferrari F40") (type super) (price high) (performance high)))

(defrule questions
   =>
   (printout t "Give the Type you want (possible options: family city super): ")
   (assert (type (read)))
   (printout t "Give the price you want (possible options: low mid high): ")
   (assert (price (read)))
   (printout t "Give the performance you want (possible options: low mid high): ")
   (assert (performance (read))))

(defrule type_rule
   (type ?type)
   ?c <- (car (type ~?type))
   =>
   (retract ?c))

(defrule price_rule
   (price ?price)
   ?c <- (car (price ~?price))
   =>
   (retract ?c))

(defrule performance_rule
   (performance ?performance)
   ?c <- (car (performance ~?performance))
   =>
   (retract ?c))

(defrule match
   (declare (salience -100))
   (car (brand_name ?name))
   =>
   (printout t "The car that fits you is: " ?name crlf))

Вот как вы можете распечатать список автомобилей по количеству соответствующих критериев:

(deftemplate car
   (slot brand_name (type STRING))
   (slot type (type SYMBOL)(allowed-symbols family city super))
   (slot price (type SYMBOL) (allowed-symbols low mid high))
   (slot performance (type SYMBOL) (allowed-symbols low mid high))
   (slot equipment (type SYMBOL) (allowed-symbols low mid high))
   (multislot matches))

(deffacts car_facts
   (car (brand_name "Opel Astra") (type family) (price mid) (performance low))
   (car (brand_name "Peugeot 106a") (type city) (price low) (performance high))
   (car (brand_name "Mercedes E200") (type super) (price high) (performance mid))
   (car (brand_name "Rover 25") (type family) (price mid) (performance mid))
   (car (brand_name "Ferrari F40") (type super) (price high) (performance high)))

(defrule questions
   =>
   (printout t "Give the Type you want (possible options: family city super): ")
   (assert (type (read)))
   (printout t "Give the price you want (possible options: low mid high): ")
   (assert (price (read)))
   (printout t "Give the performance you want (possible options: low mid high): ")
   (assert (performance (read))))

(defrule type_rule
   (type ?type)
   ?c <- (car (type ?type) (matches $?m))
   (test (not (member$ type ?m)))
   =>
   (modify ?c (matches ?m type)))

(defrule price_rule
   (price ?price)
   ?c <- (car (price ?price) (matches $?m))
   (test (not (member$ price ?m)))
   =>
   (modify ?c (matches ?m price)))

(defrule performance_rule
   (performance ?performance)
   ?c <- (car (performance ?performance) (matches $?m))
   (test (not (member$ performance ?m)))
   =>
   (modify ?c (matches ?m performance)))

(defrule match-header
   (declare (salience -100))
   =>
   (printout t "Cars matching your criteria: " crlf))

(defrule match-3
   (declare (salience -200))
   (car (brand_name ?name) (matches $?m))
   (test (= (length$ ?m) 3))
   =>
   (printout t "   " ?name " : " (implode$ ?m) crlf))

(defrule match-2
   (declare (salience -300))
   (car (brand_name ?name) (matches $?m))
   (test (= (length$ ?m) 2))
   =>
   (printout t "   " ?name " : " (implode$ ?m) crlf))

(defrule match-1
   (declare (salience -400))
   (car (brand_name ?name) (matches $?m))
   (test (= (length$ ?m) 1))
   =>
   (printout t "   " ?name " : " (implode$ ?m) crlf))

(defrule match-none
   (declare (salience -200))
   (not (and (car (brand_name ?name) (matches $?m))
             (test (> (length$ ?m) 0))))
   =>
   (printout t "   None" crlf))

Использование функций сортировки и поиска всех фактов для распечатки результатов:

(deftemplate car
   (slot brand_name (type STRING))
   (slot type (type SYMBOL)(allowed-symbols family city super))
   (slot price (type SYMBOL) (allowed-symbols low mid high))
   (slot performance (type SYMBOL) (allowed-symbols low mid high))
   (slot equipment (type SYMBOL) (allowed-symbols low mid high))
   (multislot matches))

(deffacts car_facts
   (car (brand_name "Opel Astra") (type family) (price mid) (performance low))
   (car (brand_name "Peugeot 106a") (type city) (price low) (performance high))
   (car (brand_name "Mercedes E200") (type super) (price high) (performance mid))
   (car (brand_name "Rover 25") (type family) (price mid) (performance mid))
   (car (brand_name "Ferrari F40") (type super) (price high) (performance high)))

(defrule questions
   =>
   (printout t "Give the Type you want (possible options: family city super): ")
   (assert (type (read)))
   (printout t "Give the price you want (possible options: low mid high): ")
   (assert (price (read)))
   (printout t "Give the performance you want (possible options: low mid high): ")
   (assert (performance (read))))

(defrule type_rule
   (type ?type)
   ?c <- (car (type ?type) (matches $?m))
   (test (not (member$ type ?m)))
   =>
   (modify ?c (matches ?m type)))

(defrule price_rule
   (price ?price)
   ?c <- (car (price ?price) (matches $?m))
   (test (not (member$ price ?m)))
   =>
   (modify ?c (matches ?m price)))

(defrule performance_rule
   (performance ?performance)
   ?c <- (car (performance ?performance) (matches $?m))
   (test (not (member$ performance ?m)))
   =>
   (modify ?c (matches ?m performance)))

(defrule match-header
   (declare (salience -100))
   =>
   (printout t "Cars matching your criteria: " crlf))

(deffunction sort-cars (?f1 ?f2)
   (< (length$ (fact-slot-value ?f1 matches)) 
      (length$ (fact-slot-value ?f2 matches))))

(defrule match-some
   (declare (salience -200))
   (exists (and (car (matches $?m))
                (test (> (length$ ?m) 0))))
   =>
   (bind ?cars (find-all-facts ((?c car)) (> (length$ ?c:matches) 0)))
   (bind ?cars (sort sort-cars ?cars))
   (progn$ (?c ?cars)
      (printout t "   " (fact-slot-value ?c brand_name) " : " (implode$ (fact-slot-value ?c matches)) crlf)))

(defrule match-none
   (declare (salience -200))
   (not (and (car (matches $?m))
             (test (> (length$ ?m) 0))))
   =>
   (printout t "   None" crlf))

Конечные результаты при запуске программы:

CLIPS> (reset)
CLIPS> (run)
Give the Type you want (possible options: family city super): super
Give the price you want (possible options: low mid high): high
Give the performance you want (possible options: low mid high): mid
Cars matching your criteria: 
   Mercedes E200 : performance type price
   Ferrari F40 : price type
   Rover 25 : performance
CLIPS> 
person Gary Riley    schedule 15.05.2017