;;;;;;;;;;Exercice 1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; 1 (gps '(son-at-home car-works) '(son-at-school) *school-ops*) ;; l'appel pour lequel la base d'actions est faite: (gps '(son-at-home car-needs-battery have-money have-phone-book) '(son-at-school) *school-ops*) ;;; 2 ; suffisant: (push newrule list-ops) ; spécialisation: (defun add_schoolops (newrule) (push newrule *school-ops*)) ; ne marche pas (pas d'effet de bord): (defun add_rule (newrule list-ops) (push newrule list-ops)) ; pour comprendre les effets de bords par des ; fonctions, vous pouvez tester: (defun f (l) (setf (cdr l) nil)) (defun add_in_2nd_position (x l) (let ((cdrl (cdr l))) (setf (cdr l) (list x)) (setf (cddr l) cdrl) l)) ; possibilité avec une macro: (defmacro add_rule (newrule list-ops) `(push ,newrule ,list-ops)) ;;;;;;;;;;Exercice 2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Une version simplifiée de la version originale du labyrinte ;;; sans "convert", sans notation en prédicats "(at n)" (cf. version finale de gps) ;;; sans symétrisation des relations (defun mappend (fn list) "Append the results of calling fn on each element of list. Like mapcon, but uses append instead of nconc." (apply #'append (mapcar fn list))) (defun op-simple (action &key preconds add-list del-list) "Make a new operator " (make-op :action action :preconds preconds :add-list add-list :del-list del-list)) (defun make-maze-ops (pair) "Make maze ops in both directions" (list (make-maze-op (first pair) (second pair)))) (defun make-maze-op (here there) "Make an operator to move between two places" (op-simple `(,here ,there) :preconds `(,here) :add-list `(,there) :del-list `(,here))) (defparameter *maze-ops* (mappend #'make-maze-ops '((1 2) (2 3) (3 4) (4 9) (9 14) (9 8) (8 7) (7 12) (12 13) (12 11) (11 6) (11 16) (16 17) (17 22) (21 22) (22 23) (23 18) (23 24) (24 19) (19 20) (20 15) (15 10) (10 5) (20 25)))) ; (gps '(1) '(25) *maze-ops*); marche car pas de boucle dans le labyrinte ; on rajoute une boucle: (defparameter *maze-ops* (mappend #'make-maze-ops '((25 20) (1 2) (2 3) (3 4) (4 9) (9 14) (9 8) (8 7) (7 12) (12 13) (12 11) (11 6) (11 16) (16 17) (17 22) (21 22) (22 23) (23 18) (23 24) (24 19) (19 20) (20 15) (15 10) (10 5) (20 25) ))) ; (gps '(1) '(25) *maze-ops*) ;;boucle ;;;;;;;;;;Exercice 3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; 1 ;; cf. la boucle dans le labyrinthe ci-dessus ;; ou, dans l'exemple de *school-ops*, une règle du genre: (push (make-op :action 'get-money :preconds '(have-money) :add-list '(have-money)) *school-ops*) ;;; 2 ;; un but avec deux sous-buts => ceux-ci ne sont pas réalisés simultanement ;; comme le laisse penser l'appel, mais séquentiellement. En fait, ;; l'argent sera dépensé par l'achieve du but son-at-school, et donc le ;; but ne sera réalisé: (gps '(son-at-home car-needs-battery have-money have-phone-book) '(have-money son-at-school) *school-ops*) (EXECUTING LOOK-UP-NUMBER) (EXECUTING TELEPHONE-SHOP) (EXECUTING TELL-SHOP-PROBLEM) (EXECUTING GIVE-SHOP-MONEY) (EXECUTING SHOP-INSTALLS-BATTERY) (EXECUTING DRIVE-SON-TO-SCHOOL) SOLVED ;;; 3 ;; Et donc, dans le cas où les deux sous-buts sont dans un ordre inversé, ;; cela ne marche pas: (gps '(son-at-home car-needs-battery have-money have-phone-book) '(son-at-school have-money) *school-ops*) (EXECUTING LOOK-UP-NUMBER) (EXECUTING TELEPHONE-SHOP) (EXECUTING TELL-SHOP-PROBLEM) (EXECUTING GIVE-SHOP-MONEY) (EXECUTING SHOP-INSTALLS-BATTERY) (EXECUTING DRIVE-SON-TO-SCHOOL) NIL