Guest User

Untitled

a guest
Jul 8th, 2018
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lisp 4.91 KB | None | 0 0
  1. (defun match (pattern data bindings-list)
  2.     (let ((end-of-pattern (endp pattern))
  3.         (end-of-data (endp data)))
  4.         (if (or end-of-pattern end-of-data)
  5.             (when (and end-of-pattern end-of-data) bindings-list)
  6.             (let ((result (match-elements (first pattern) (first data) bindings-list)))
  7.                 (when result (match (rest pattern) (rest data) result))))))
  8.  
  9. (defun match-elements (pattern-elem data-elem bindings-list)
  10.     (cond ((and (atom pattern-elem) (atom data-elem))
  11.         ; oba elementy sa atomami
  12.         (match-atoms pattern-elem data-elem bindings-list))
  13.         ((and (listp pattern-elem)
  14.             (eq '? (first pattern-elem)))
  15.             ; element wzorca jest wyrażeniem reprezentujacym zmienna
  16.             (match-variable pattern-elem data-elem bindings-list) )
  17.         (t nil) ; tylko dla przejrzystosci zapisu
  18.     ))
  19.  
  20. (defun match-atoms (pattern-elem data-elem bindings-list)
  21.     (when (eql pattern-elem data-elem) bindings-list))
  22.  
  23. (defun match-variable (pattern-elem data-elem bindings-list)
  24.     (let ((binding (find-binding pattern-elem bindings-list))) ; sprawdz czy jest przypisanie dla zmiennej
  25.         (if binding (match-elements (extract-value binding) data-elem bindings-list)
  26.             ; jesli jest przypisanie to dopasuj wartosć zmiennej
  27.             (add-binding pattern-elem data-elem bindings-list )
  28.             ; w przeciwnym razie dołacz przypisanie do listy
  29.         )))
  30.  
  31. (defun find-binding (pattern-variable-expr bindings-list)
  32.     (assoc (extract-variable pattern-variable-expr)
  33.         ; nazwa zmiennej
  34.         bindings-list
  35.         ; szukaj przypisania w liscie przypisań wg klucza
  36.         ; którym jest nazwa zmiennej
  37.     ))
  38.  
  39. (defun extract-variable (pattern-variable-expr)
  40.     (second pattern-variable-expr))
  41.  
  42. (defun extract-value (binding)
  43.     (second binding))
  44.  
  45. (defun add-binding (pattern-variable-expr symbol bindings-list)
  46.     (cons (list (extract-variable pattern-variable-expr) symbol) bindings-list))
  47.  
  48. (defun match-pattern-to-facts (pattern subst)
  49.     (filter-list
  50.         ; usuń pozycje nil z listy podstawień zwróconej przez mapcar
  51.         (mapcar
  52.             #'(lambda (fact) (match pattern fact subst))
  53.             *facts*
  54.             ; dopasuj wzorzec kolejno do każdego faktu
  55.         )))
  56.  
  57. (defun process-one-antecedent (antecedent subst-list)
  58.     (conc-lists
  59.         ; sklej listę list podstawień zwróconš przez mapcar w jedna listę
  60.         (mapcar
  61.             #'(lambda (subst)
  62.             (match-pattern-to-facts antecedent subst))
  63.             subst-list
  64.         ; wykonaj przeglad faktów kolejno dla każdego podstawienia
  65.         ; z listy subst-list. Przeglad faktów dla wybranego podstawienia
  66.         ; zwraca listę podstawień. mapcar zwraca listę list podstawień.
  67.         )))
  68.  
  69. (defun filter-list (list)
  70.     (remove-if
  71.         ; procedura remove-if stosuje test okreslony funkcja do listy
  72.         #'(lambda (element) (eq nil element))
  73.         ; ta funkcja anonimowa sprawdza, czy element jest symbolem nil
  74.         list))
  75.  
  76. (defun conc-lists (lists)
  77.     (if (endp lists)
  78.         nil
  79.         (append
  80.             (first lists)
  81.             (conc-lists (rest lists)))))
  82.  
  83. (defun process-antecedents (antecedents initial-subst-list)
  84.     (if (endp antecedents)
  85.         initial-subst-list
  86.         ; jesli koniec listy poprzedników, to zwróć zbudowana listę podstawień
  87.         (process-antecedents
  88.         ; przetwarzaj resztę listy poprzedników
  89.             (rest antecedents)
  90.             (process-one-antecedent
  91.                 ; podajac listę podstawień otrzymana po
  92.                 ; przetworzeniu pierwszego poprzednika z listy
  93.                 (first antecedents)
  94.                 initial-subst-list))))
  95.  
  96. (defun use-rule (rule)
  97.     (let ((subst-list
  98.         (process-antecedents
  99.             (get-antecedents rule)
  100.             (list nil))))
  101.         (do ((remaining-subst-list subst-list
  102.             (rest remaining-subst-list))
  103.             (success-flag nil))
  104.             ((endp remaining-subst-list) success-flag)
  105.             (let ((result
  106.                 (instantiate-variables
  107.                     (get-consequent rule)
  108.                         (first remaining-subst-list))))
  109.                 (when (assert-fact result)
  110.                     (format t
  111.                         " ~%Nowy fakt: ~a
  112.                         ~%Na podstawie reguły ~a "
  113.                         result
  114.                         (get-name rule))
  115.                     (setf success-flag t))))))
  116.  
  117. (defun get-antecedents (rule)
  118.     (butlast (rest rule)))
  119.  
  120. (defun get-consequent (rule)
  121.     (first (last rule)))
  122.  
  123. (defun get-name (rule)
  124.     (first rule))
  125.  
  126. (defun instantiate-variables (pattern bindings-list)
  127.     (if (endp pattern)
  128.         nil
  129.         (cons (process-pattern-element (first pattern) bindings-list)
  130.             (instantiate-variables (rest pattern) bindings-list))))
  131.  
  132. (defun assert-fact (fact)
  133.     (unless (member fact *facts* :test #'equal)
  134.         (setf *facts* (cons fact *facts*))))
  135.  
  136. (defun process-pattern-element (element bindings-list)
  137.     (cond ((atom element) element)
  138.         ((and (listp element)
  139.             (eq '? (first element)))
  140.             (extract-value (find-binding element bindings-list)))))
  141.  
  142. (defun forward-chain ()
  143.     (do ((remaining-rules *rules*
  144.         (rest remaining-rules))
  145.         (repeat-flag nil))
  146.         ((endp remaining-rules)
  147.             (if repeat-flag
  148.                 (progn
  149.                     (format t " ~% Następny przebieg. ")
  150.                     (forward-chain))
  151.                 (progn
  152.                     (format t
  153.                         " ~% Brak nowych faktów. ")
  154.                     ' koniec-wnioskowania)))
  155.         (when (use-rule (first remaining-rules))
  156.             (setf repeat-flag t))))
Add Comment
Please, Sign In to add comment