SE/LS/L5

From WikiZMSI

< SE | LS

Spis treści

Otwarcie i zamknięcie programu

CLIPS zgłasza się znakiem zachęty CLIPS> i oczekuje na komendy. Kilka użytecznych poleceń:

  1. (exit) zamyka CLIPSa.
  2. (clear) usuwa wszystkie programy i dane z pamięci (podobne do procedury restart).
  3. (reset) usuwa dynamiczne dane z pamięci
  4. (run) uruchamia program
  5. CTRL+C kończy pętlę

Fakty

1. W CLIPS można tworzyć bazę wiedzy, która zawiera fakty i reguły. Fakty można wprowadzać poleceniem (assert) np.

CLIPS>(assert (kolor zielony))
<Fact-1>

Polecenie (assert), jak równiez inne polecenia, instrukcje lub fakty sa objete nawiasami.

2. Aby sprawdzić listę wprowadzonych faktów należy podać komendę (facts).

3. Fakty można usuwać poleceniem (retract nr_faktu). Zawsze trzeba podać numer faktu. Numer faktu usuniętego nie jest ponownie wykorzystywany.

CLIPS> (assert (kolor czerwony)) ; Komentarz
<Fact-2>
CLIPS> (facts)
f-0     (initial-fact)
f-1     (kolor zielony)
f-2     (kolor czerwony)
For a total of 3 facts.
CLIPS> (retract 1)
CLIPS> (facts)
f-0     (initial-fact)
f-2     (kolor czerwony)
For a total of 2 facts.

4. Komentarz rozpoczyna się średnikiem i trwa do końca linijki.

5. Polecenie (clear) kasuje wszystko, przywraca stan początkowy.

6. W celu unikniecia koniecznosci wielokrotnego wpisywania pojedynczych faktów mozna zdefiniowac blok faktów, uzywajac polecenia (deffacts), np.

(deffacts skrzyzowanie
(status stoj)
(status idz))

Po słowie kluczowym deffacts podaje sie nazwe definiowanego bloku, a nastepnie fakty (w nawiasach). Cała instrukcja jest ujeta w nawiasy. Fakty zdefiniowane w ten sposób sa wprowadzane na liste faktów przez polecenie (reset).

7. Polecenie (reset) usuwa wszystkie fakty z listy, a nastepnie wprowadza fakty zdefiniowane przez (deffacts) oraz fakt (initial-fact) z indeksem f-0.

8. Fakty zdefiniowane przez (deffacts) i wprowadzone na liste faktów, przez (reset) moga byc w prosty sposób usuniete z tej listy przez uzycie słowa kluczowego (undeffacts) wraz z nazwa bloku faktów np.

(undeffacts skrzyzowanie)

9. Definiowanie struktury faktów przy użyciu konstrukcji (deftemplate). Podaje się strukturę, która opisuje pewien obiekt i jakie jego cechy mogą być podane.

(deftemplate <relation-name> [<optional comment>] <slot-definition>*)
(deftemplate osoba
(slot imie)
(slot wiek)
(slot kolor-wlosow)
(multislot bracia)
(multislot siostry))

10. Na podstawie wzorca można wprowadzać fakty wykorzystując polecenie assert. Zaleta deftemplate: nie ma potrzeby wypełniania wszystkich slotów a ich kolejność nie jest obowiązkowa.

(assert (osoba (imie greg)))
(assert  (osoba (imie joe)(wiek 32)(kolor-wlosow brazowy)(bracia mat mik)(siostry jane)))
(assert (osoba (wiek 44)(imie ken)))

11. Wprowadzanie faktów ze wzorca może też być wykonane przez polecenie (deffacts):

deffacts <deffacts name> [<optional comment>] <facts>)
(deffacts znajomi
(osoba (imie greg))
(osoba (wiek 44)(imie ken))
(osoba (siostry mary)))

12. Polecenie musi być poprzedzone deftemplate (o ile korzystamy ze wzorców). Po wykonaniu polecenia (reset) CLIPS umieści fakty w liście faktów.

Reguły

W Clipsie reguły maja konstrukcje zblizona do instrukcji (IF ... THEN ...), używanych w powszechnie stosowanych jezykach programowania. Słowo IF dla uproszczenia jest pomijane, słowo THEN jest zastepowane symbolem =>:

(defrule <rule-name>
    <facts>+
  =>
    <actions>*)

Przykład:

(defrule kaczka 
  (zwierze kaczka)
   =>
  (assert (dzwiek kwacze)))

Jeżeli w bazie jest fakt, że istnieje zwierzę kaczka, to dodaj kolejny fakt do bazy, że kaczka kwacze.

Kontrola w programie

Clips umożliwia kontrolę wykonywania programu dzięki zastosowaniu polecenia

(watch).

  • (watch facts) - wprowadzenia faktów i usuwania faktów,
  • (watch rules) - wykonywania reguł,
  • (watch activations) - uaktywniania reguł.

Reguły z komunikatem

W celu lepszej komunikacji z użytkownikiem można stosować komunikaty na ekranie:

(defrule kaczka 
  (zwierze kaczka)
   =>
  (assert (dzwiek kwacze))
  (printout t "To jest kaczka" crlf))

Wprowadzić regułę i doprowadzić do jej odpalenia (run).

Zmienne

Reguły ze zmiennymi używają ?symbol do reprezentowania pewnej grupy obiektów, na których reguła działa.

(defrule drapieznik 
 (ma-pazury ?x)
  =>  
 (assert (jest-drapieznik ?x)))

Dodaj fakt, że pantera ma pazury, odpal reguły poleceniem (run) i zobacz jaki fakt powstanie.

Zmienna anonimowa

Zadeklaruj bazę wiedzy:

(deffacts start
(zwierz pies) (zwierz kaczka) (zwierz zolw)
(cieplokrwisty pies) (cieplokrwisty  kon)  (cieplokrwisty  kaczka)
(sklada-jaja kaczka) (sklada-jaja zolw)
(dziecko  kon kuc) (dziecko  zolw zolwik))

W regule można stosować zmienne anonimowe ?.

(defrule zwierz
 (zwierz ?)
 =>
 (printout t "zwierzak znalezniony" crlf))

Odpalenie reguł daje wynik, który wskazuje iż reguła dopasowała część if czterokrotnie. Zmienna anonimowa może być używana w jednej regule wielokrotnie w zależności od potrzeby. Zatem dozwolone jest (dziecko ? ?), acz niedozwolona jest składnia (? ? dziecko)

Reguła usuwająca fakty

Aby usunąć fakt należy znać jego numer, gdyż CLIPS nie usuwa faktów po kontekście.

(defrule usun-ssaki
 ?fakt <- (ssak ?)
 =>
 (printout t "usuwanie " ?fakt crlf)
 (retract ?fakt))

Jeżeli spełniony jest fakt (ssak ?), to indeks tego faktu jest przechowywany w zmiennej ?fakt. (odpowiada za to przypisanie symbol <-).

Regułę można usunąć poleceniem undefrule podając nazwę reguły jako argument np. (undefrule usun-ssaki).


Zadanie 1:

  1. Zadaniem jest stworzenie systemu wnioskującego o tym, co można ugotować na podstawie zawartości lodówki (kuchni).
  2. Zdefiniuj fakty o tym co jest w lodówce (kuchni) np. fakt, że mamy mąkę można zapisać jako (assert (maka)).
  3. Zdefiniuj reguły na przepisy np. Aby zrobić jajecznicę potrzebujemy jaja i masło.
  4. Reguły mają się kończyć wypisaniem na ekranie jakie dania jesteśmy w stanie przygotować mając do dyspozycji pewną liczbę produktów).
  5. Kod zapisać w pliku.

Zadanie 2:

1. Pobierz schemat przedstawiający drzewo decyzyjne o usterce w samochodzie Schemat

2. Zapisz reguły zgodnie z tym co sugeruje drzewo. Każdy liść, to zalecenie, wniosek, prawdopodobnie wypisany na ekranie np. BUY PETROL! Każdy blok kwadratowy to jest dowód, reprezentowany przez fakt, który wskazuje na daną usterkę np. (starter_turning yes) i (petrol no). Te fakty mogłyby być podane przez użytkownika w sesji pytań i odpowiedzi lub po prostu z konsoli CLIPSa.

CLIPS> (assert (petrol no) (starter_turning yes))

Każda ścieżka do liścia reprezentuje jedną regułę, np. IF starter is turning AND there is no petrol THEN buy some petrol.

3. Sprawdź działanie przez załadowanie reguł i podanie faktów, które są wiadome użytkownikowi samochodu, a które mogą wskazywać na daną usterkę.

Operacje logiczne i arytmetyczne

W część IF reguł połączenie przesłanek jest automatycznie wykonywane przez funkcję AND. Użycie funkcji OR ilustruje przykład:

(defrule wez-parasol
 (or (pogoda deszcz)
     (pogoda snieg))
 =>
 (assert (parasol tak)))

OR jak wszystkie operatory w CLIPSie stoi przed argumentami (notacja prefiksowa). Np. dodawanie zapisuje się w CLIPS (+ 5 7). Wpisz bezpośrenio w linii komend:

(+ 5 7)
(- 5 7)
(* 5 7)
(/ 5 7)

Test służy do sprawdzenia dowolnego testu logicznego:

(defrule niepotrzebna
(test (> 6 5)) 
=>
(printout t "Sześć jest większe od pięciu" crlf)
)


Zadanie 3:

  1. Zapisz następujące wyrażenie używając notacji prefiksowej: 10+4*19-35/12 (wynik 83.0833)

Zadanie 4:

  1. Dopisz do systemu wnioskującego co możemy ugotować na podstawie zawartości lodówki, jakie ilości każdego produktu są niebędne do wykonania potrawy. Np. jeżeli na omlet porzebne są dwa jajka a w lodówce mamy 5 jajek, to możemy zrobić omlet, gdyby jaj było mniej, to potrawa omlet, nie powinna się znaleźć na liście potraw do wykonania.

Pobieranie danych od użytkownika

Polecenie (read) pobiera dane od użytkownika.

(assert (od-uzytkownika (read)))

Przetestuj działanie reguły:

(defrule co-jest-dzieckiem
       (zwierz ?nazwa)
       (not (dziecko ?nazwa ?))
=>
       (printout t "Jak nazywa się dziecko " ?nazwa "?")
       (assert (dziecko ?nazwa (read))))

W przykładzie z diagnostyką samochodu można użyć reguły:

(defrule swiatlo-dziala
       (not (swiatlo-dziala ?))
=>
       (printout t "Czy w twoim samochodzie działają światła (tak lub nie)?")
       (assert (swiatlo-dziala (read))))

Zadanie 5:


  1. Stosując dotychczasową wiedzę zmodyfikuj plik z diagnostyką samochodu, by odpytywać użytkownika o niezbędne do diagnozy informacje i podpowiadać mu jak ma postępować. Gdy tylko system wyświetli podpowiedź, powinien wyczyścić wszystkie dane podane od użytkownika i sam wystartować się od nowa. (Usuwanie bez użycia reset).

auto.clp