home *** CD-ROM | disk | FTP | other *** search
- ;;;; This file contains the forward-chaining, rule-based,
- ;;;; expert-system program.
-
- ;;; This section contains the key stream-processing procedures.
-
- (DEFUN FILTER-ASSERTIONS (PATTERN INITIAL-A-LIST)
- (DO ((ASSERTIONS ASSERTIONS (REST ASSERTIONS))
- (A-LIST-STREAM (MAKE-EMPTY-STREAM)))
- ((NULL ASSERTIONS) A-LIST-STREAM)
- (LET ((NEW-A-LIST (MATCH PATTERN (FIRST ASSERTIONS) INITIAL-A-LIST)))
- (COND (NEW-A-LIST (SETQ A-LIST-STREAM
- (ADD-TO-STREAM NEW-A-LIST A-LIST-STREAM)))))))
-
- (DEFUN FILTER-A-LIST-STREAM (PATTERN A-LIST-STREAM)
- (COND ((EMPTY-STREAM-P A-LIST-STREAM) (MAKE-EMPTY-STREAM))
- (T (COMBINE-STREAMS
- (FILTER-ASSERTIONS PATTERN (FIRST-OF-STREAM A-LIST-STREAM))
- (FILTER-A-LIST-STREAM PATTERN (REST-OF-STREAM A-LIST-STREAM))))))
-
- (DEFUN CASCADE-THROUGH-PATTERNS (PATTERNS A-LIST-STREAM)
- (COND ((NULL PATTERNS) A-LIST-STREAM)
- (T (FILTER-A-LIST-STREAM (FIRST PATTERNS)
- (CASCADE-THROUGH-PATTERNS (REST PATTERNS)
- A-LIST-STREAM)))))
- (DEFUN SPREAD-THROUGH-THENS (RULE-NAME IFS THENS A-LIST)
- (DO ((THENS THENS (REST THENS))
- (ACTION-STREAM (MAKE-EMPTY-STREAM)))
- ((NULL THENS) ACTION-STREAM)
- (LET ((IFS (REPLACE-VARIABLES IFS A-LIST))
- (THENS (REPLACE-VARIABLES THENS A-LIST)))
- (COND ((REMEMBER-THENS THENS)
- (REPORT-ACTION RULE-NAME IFS THENS)
- (SETQ ACTION-STREAM (COMBINE-STREAMS THENS ACTION-STREAM)))))))
-
- (DEFUN REMEMBER-THENS (THENS)
- (DO ((THENS THENS (REST THENS))
- (SWITCH NIL))
- ((NULL THENS) SWITCH)
- (WHEN (REMEMBER (FIRST THENS)) (SETF SWITCH T))))
-
- (DEFUN REPORT-ACTION (RULE-NAME IFS THENS)
- (FORMAT T "~%Rule ~a asserts: ~a" RULE-NAME (FIRST THENS))
- (MAPCAR #'(LAMBDA (E) (FORMAT T "~% ~a" E)) (REST THENS))
- (FORMAT T "~% because: ~a" (FIRST IFS))
- (MAPCAR #'(LAMBDA (E) (FORMAT T "~% ~a" E)) (REST IFS)))
-
- (DEFUN REPLACE-VARIABLES (S A-LIST)
- (COND ((ATOM S) S)
- ((MEMBER (FIRST S) '(< >))
- (SECOND (ASSOC (PATTERN-VARIABLE S) A-LIST)))
- (T (CONS (REPLACE-VARIABLES (FIRST S) A-LIST)
- (REPLACE-VARIABLES (REST S) A-LIST)))))
-
- (DEFUN FEED-TO-THENS (RULE-NAME IFS THENS A-LIST-STREAM)
- (COND ((EMPTY-STREAM-P A-LIST-STREAM) (MAKE-EMPTY-STREAM))
- (T (COMBINE-STREAMS
- (SPREAD-THROUGH-THENS RULE-NAME
- IFS THENS
- (FIRST-OF-STREAM A-LIST-STREAM))
- (FEED-TO-THENS RULE-NAME
- IFS THENS
- (REST-OF-STREAM A-LIST-STREAM))))))
-
- (DEFUN USE-RULE (RULE)
- (LET* ((RULE-NAME (SECOND RULE))
- (IFS (REVERSE (REST (THIRD RULE))))
- (THENS (REST (THIRD (REST RULE)))) ;GCLISP does not have FOURTH.
- (A-LIST-STREAM (CASCADE-THROUGH-PATTERNS
- IFS
- (ADD-TO-STREAM NIL (MAKE-EMPTY-STREAM))))
- (ACTION-STREAM (FEED-TO-THENS RULE-NAME IFS THENS A-LIST-STREAM)))
- (NOT (EMPTY-STREAM-P ACTION-STREAM))))
-
- (DEFUN FORWARD-CHAIN ()
- (DO ((RULES-TO-TRY RULES (REST RULES-TO-TRY))
- (NO-PROGRESS T))
- ((AND (NULL RULES-TO-TRY) NO-PROGRESS)
- (FORMAT T "~%Nothing more can be done."))
- (WHEN (NULL RULES-TO-TRY)
- (SETQ RULES-TO-TRY RULES NO-PROGRESS T)
- (FORMAT T "~%Making another pass through the rules..."))
- (WHEN (USE-RULE (FIRST RULES-TO-TRY)) (SETQ NO-PROGRESS NIL))))
-
- ;;; These section containts the access procedures.
-
- (DEFUN COMBINE-STREAMS (S1 S2) (APPEND S1 S2))
-
- (DEFUN ADD-TO-STREAM (E S) (CONS E S))
-
- (DEFUN FIRST-OF-STREAM (S) (FIRST S))
-
- (DEFUN REST-OF-STREAM (S) (REST S))
-
- (DEFUN EMPTY-STREAM-P (S) (NULL S))
-
- (DEFUN MAKE-EMPTY-STREAM () NIL)
-
- ;;; This procedure puts new assertions on the assertion list.
-
- (DEFUN REMEMBER (NEW)
- (COND ((MEMBER NEW ASSERTIONS :TEST 'EQUAL) NIL)
- (T (SETQ ASSERTIONS (CONS NEW ASSERTIONS)) NEW)))
-