2013-12-16 19 views
7

Mam 10 czujników, które obserwują otoczenie. Czujnik wynosi 1, jeśli jest OK, a 0, jeśli nie. Potrzebuję utworzyć funkcjonalność, która wydrukuje komunikat ostrzegawczy na terminalu, jeśli są co najmniej 3 czujniki, które są na 0, a ostrzeżenie wiadomości zostanie wyświetlone tylko raz. To muszę zrobić w klipach.Klipsy - mały program rutynowy

Dziękuję.

(deffacts listaSenzor 
    (sensor L1 0) 
    (sensor L2 0) 
    (sensor L3 1) 
    (sensor L4 1) 
    (sensor L5 1) 
    (sensor L6 1) 
    (sensor L7 0) 
    (sensor L8 1) 
    (sensor L9 0) 
    ) 
    (defrule rr 
     (sensor ?a 0) 
     (sensor ?b 0) 
     (sensor ?c 0) 
     => 
     printout t ?a ?b ?c "==>WARNING" crlf) 
     ) 
+0

Co dokładnie pan próbował? Udostępnij jakiś kod ... Czy szukałeś przed pytaniem? Nie możesz oczekiwać, że zrobimy dla ciebie program ... Pomożemy tylko w debugowaniu twojego programu ... –

+0

powinieneś edytować pytanie, aby dodać te szczegóły :) –

+0

@AcelasiEu możesz mi pomóc? –

Odpowiedz

2

Są dwa problemy, z którymi trzeba się uporać. Po pierwsze, zdefiniowane wzorce mogą wielokrotnie odpowiadać temu samemu faktowi (np. Czujnik L1 będzie powiązany z a, b i c). Aby obejść ten problem, należy upewnić się, że a, b i c są unikatowe. Jednym ze sposobów, aby to zrobić w następujący sposób (pamiętaj, że ja również dodać brakujące „(” przed swoim oświadczeniu printout):

(deffacts listaSenzor 
    (sensor L1 0) 
    (sensor L2 0) 
    (sensor L3 1) 
    (sensor L4 1) 
    (sensor L5 1) 
    (sensor L6 1) 
    (sensor L7 0) 
    (sensor L8 1) 
    (sensor L9 0)) 
(defrule rr 
    (sensor ?a 0) 
    (sensor ?b 0) 
    (sensor ?c 0) 
    (test (neq ?a ?b)) 
    (test (neq ?a ?c)) 
    (test (neq ?b ?c)) 
=> 
    (printout t ?a ?b ?c "==>WARNING" crlf)) 

Running tę regułę przed swoimi faktów daje:

CLIPS> (reset) 
CLIPS> (run) 
L9L7L2==>WARNING 
L9L7L1==>WARNING 
L9L2L7==>WARNING 
... 
L1L2L7==>WARNING 
L2L1L7==>WARNING 

ostrzeżenie jest teraz generowane tylko wtedy, gdy są trzy lub więcej czujników niepoprawnych, jednak na wyjściu pojawia się drugie zagadnienie, które oznacza, że ​​ostrzeżenie jest generowane wiele razy (raz dla każdej unikalnej kombinacji trzech czujników niepoprawnych). ominąć to, prawdopodobnie chcesz kontrolować, aby reguła nie była uruchamiana wiele razy. Aby to osiągnąć, możesz zmodyfikować regułę e z następujących czynności:

(defrule rr 
    (not (sensor-warning)) 
    (sensor ?a 0) 
    (sensor ?b 0) 
    (sensor ?c 0) 
    (test (neq ?a ?b)) 
    (test (neq ?a ?c)) 
    (test (neq ?b ?c)) 
=> 
    (assert (sensor-warning)) 
    (printout t ?a ?b ?c "==>WARNING" crlf)) 

Gwarantuje to, że reguła zadziała tylko raz (chyba że chowa fakt sensor-warning). Uruchamianie ze zaktualizowaną regułą:

CLIPS> (reset) 
CLIPS> (run) 
L9L7L2==>WARNING 
CLIPS> 

Jest to proste rozwiązanie Twojego problemu. Jeśli prawdopodobnie zmienisz liczbę czujników niezapisanych, które powinny wywołać regułę, prawdopodobnie powinieneś zastąpić porównania nazw czujników "przewodowych" z bardziej ogólną logiką (np. Możesz obliczyć całkowitą liczbę czujników niezapisanych i porównaj to z twoim progiem).

2

Oto kolejny sposób, aby to zrobić:

(deftemplate sensor 
    (slot id) 
    (slot value)) 

(deffacts listaSenzor 
    (sensor (id L1) (value 0)) 
    (sensor (id L2) (value 0)) 
    (sensor (id L3) (value 1)) 
    (sensor (id L4) (value 1)) 
    (sensor (id L5) (value 1)) 
    (sensor (id L6) (value 1)) 
    (sensor (id L7) (value 0)) 
    (sensor (id L8) (value 1)) 
    (sensor (id L9) (value 0))) 

(defrule rr 
    (exists 
     (sensor (id ?id1) (value 0)) 
     (sensor (id ?id2&~?id1) (value 0)) 
     (sensor (id ?id3&~?id2&~?id1) (value 0))) 
    => 
    (bind ?sensors (create$)) 
    (do-for-all-facts ((?f sensor)) (eq ?f:value 0) 
     (bind ?sensors (create$ ?sensors ?f:id))) 
    (printout t (str-implode ?sensors) " ==> WARNING" crlf)) 

To będzie drukować wszystkie czujniki, jeśli istnieje więcej niż 3, które mają wartość 0.

CLIPS> (reset) 
CLIPS> (run) 
L1 L2 L7 L9 ==> WARNING 
CLIPS> 
Powiązane problemy