;;; -*- Mode: LISP; Syntax: Common-lisp; Package: Meta-aqua; Base: 10 -*- (in-package :metaaqua) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; The Meta-AQUA Introspective Multistrategy Learning System ;;;; Version 6 ;;;; ;;;; Copyright (C) 1996 Michael T. Cox (mcox25@covad.net) ;;;; ;;;; ;;;; File: solver.lisp ;;;; ;;;; ;;;; ******************************************************* ;;; ;;; This program is free software; you can redistribute it and/or modify it ;;; under the terms of the GNU General Public License as published by the Free ;;; Software Foundation; either version 1, or (at your option) any later ;;; version. ;;; ;;; This program is distributed in the hope that it will be useful, but WITHOUT ;;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ;;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ;;; more details. ;;; ;;; You should have received a copy of the GNU General Public License along ;;; with this program; if not, write to the Free Software Foundation, Inc., 675 ;;; Mass Ave, Cambridge, MA 02139, USA. In emacs type C-h C-w to view license. ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; RIPSAU (Robust Integrated Problem-Solving and Understanding) ;;;; ;;;; VERSION 3 - Handles the Dog barks at an inanimate object anomaly. ;;;; - Also Cops & Robbers as well as the LISP Programming ;;; domain. ;;;; ;;;; RIPSAU3 is not just a shell around McAQUA. It also redefines two of the ;;;; functions in file mcaqua4.lisp. These function are make-new-instance ;;;; instantiate-next. ;;; This has since been revised. Function make-new-instance has long been ;;; redesigned and put in frame.lisp as f.make-new-instance. Instantiate-next ;;; is now only defined in this file. See old-fragments.lisp for the old versions ;;; of the code. The old aqua4 is no longer intact. The system has merged and there ;;; is no current code to run the story that had viewing one concept as another, etc. ;;; [17Dec91] ;;;; ;;;; ;;;; PROGRAM VARIABLES ;;;; ;;; ;;; ||||| These really should not be dot-zero instances? ;;; These are usually attribute values. But we want them to be ;;; constant so that when the program is run multiple times ;;; memories of a reasoner reasoning about a story refer to the ;;; same self. ;;; (defconstant *criminal-actor* 'smuggler.0 "The token for the terrorist smuggler.") (defconstant *police-actor* 'authority.0 "The token for the counter-terrorist authority.") (defvar *current-character* nil "May be either the constants cop or robber.") ;;; ;;; The reasoning model for the cop. ;;; See comment for *Reasoning-Model* in file constants.lisp. ;;; (defvar *Cop-Reasoning* nil) ;;; ;;; The reasoning model for the robber. ;;; See comment for *Reasoning-Model* in file constants.lisp. ;;; (defvar *Robber-Reasoning* nil) ;;; ;;; The following queue is for police goals. Is copied into *Goal-Queue* when ;;; it is the officer's turn. ;;; (defvar *Cop-Queue* nil "Queue of goals for the airport authorities.") ;;; ;;; The following queue is for crook goals. Is copied into *Goal-Queue* when ;;; it is the robber's turn. ;;; (defvar *Robber-Queue* nil "Queue of goals for the terrorist smuggler.") ;;; Example of an item that could be in this list is rain. (defvar *World-Events* nil "List of events independent of the major characters.") ;;;; ;;;; SWITCHING BETWEEN COPS & ROBBERS ;;;; (defun toggle-current-agent-window () (current-window (if (equal *aqua-window* *window1*) *window2* *window1*)) ) ;;; ;;; Function swap-perspective performs a kind of context switching ;;; between the cop and robber perspectives. If one of the queues is ;;; empty, then the swap is not executed. ;;; (defun swap-perspective (&optional over-ride) (cond ((equal *current-character* *criminal-actor*) (set-model *Robber-Reasoning* (get-model *Reasoning-Model*)) (set-queue *Robber-Queue* (list-queue *Goal-Queue*)) (cond ((or over-ride (list-queue *Cop-Queue*)) (set-model *Reasoning-Model* (get-model *Cop-Reasoning*)) (set-queue *Goal-Queue* (list-queue *Cop-Queue*)) (setf *current-character* *police-actor*))) ) ((equal *current-character* *police-actor*) (set-model *Cop-Reasoning* (get-model *Reasoning-Model*)) (set-queue *Cop-Queue* (list-queue *Goal-Queue*)) (cond ((or over-ride (list-queue *Robber-Queue*)) (set-model *Reasoning-Model* (get-model *Robber-Reasoning*)) (set-queue *Goal-Queue* (list-queue *Robber-Queue*)) (setf *current-character* *criminal-actor*))) ) (t (format *aqua-window* "ERROR: swap-perspective."))) (toggle-current-agent-window) ;;; (send *aqua-window* ;;; :set-reverse-video-p t) ) ;;;; ;;;; INITIALIZATION FUNCTIONS ;;;; ;;; ;;; Initialize the authority's goals. ;;; (defun init-police () (f.put! *nil* (spawn-new-goal *police-actor* (make-goal-state 'wants *police-actor* (f.instantiate-frame `(controls (,*domain-slot* (,*value-facet* ,*police-actor*)) (,*co-domain-slot* (,*value-facet* ,*criminal-actor*))) *predefined-instance*)) 'achievement-goal.0 'six.0) 'mxp) ) ;;; ;;; Initialize the smuggler's goals. ;;; (defun init-smuggler () (f.put! *nil* (spawn-new-goal *criminal-actor* (make-goal-state 'wants *criminal-actor* (f.instantiate-frame `(at-location (,*domain-slot* (,*value-facet* (explosives))) (,*co-domain-slot* (,*value-facet* (nation)))) *predefined-instance*)) 'achievement-goal.0 'six.0) 'mxp) ) ;;; Initialize the previous smuggling plan. ;;; Called by init-aqua. ;;; ;;; |||||Note that by calling f.make-new-instance the frame ;;; is NOT marked as being a predefined instance as would ;;; f.instantiate-instance. ;;; (defun init-smuggling-plan (mode) (let ((old-plan (f.make-new-instance 'smuggling-plan t *predefined-instance*))) (f.unify (f.get old-plan *actor-slot*) (if (action-mode-p mode) *criminal-actor* *reasoner*)) (f.unify (f.get old-plan 'object) (f.instantiate-instance explosives)) ; (f.put! 'true.0 ; old-plan ; 'success) old-plan)) (defun init-bust-plan (mode) (let ((old-plan (f.make-new-instance 'bust-plan t *predefined-instance*))) (f.unify (f.get old-plan *actor-slot*) (if (action-mode-p mode) *police-actor* *reasoner*)) (f.unify (f.get old-plan 'object) (f.instantiate-instance smuggler)) ; (f.put! 'true.0 ; old-plan ; 'success) old-plan)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; FOUR PHASES OF PLANNING ;;; (will become three, right?) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; ;;;; Problem Identification Phase ;;;; ;;; ;;; Function to notice opportunities to carry out a previously ;;; suspended plan or action because favorable conditions have ;;; arisen, or the goal has already been satisfied. This function ;;; also notices when implicit goals to understand an event in the ;;; world (perception-goals) and explicit goals to understand whether ;;; actions meet one's expectations (feedback-goals) are the same. If ;;; so, unify the two. It also needs to be able to recognize the ;;; conditions under which background or adjunct plans apply. Thus ;;; when anonymity is in danger of being lost (in the cops & robber ;;; domain), the noticer (smuggler) must trigger a response (by ;;; raising the priority of the goal?). ;;; ;;; ||||| Maybe this should be called by a potential-solution-p predicate. ;;; See function do-plan. ;;; (defun notice (concept current-goal world-model) ;; Dumb kludge of unification mentioned in above comments. (cond ((equal (*FRAME* (f.get current-goal 'goal-object)) (*FRAME* (f.get (second (list-queue *Goal-Queue*)) 'goal-object))) (remove-item *Goal-Queue*) ; The first item IS current-goal (remove-item *Goal-Queue*) ; Remove the equivalent goal. (add-item current-goal *Goal-Queue*)) ; Put current-goal back on as first. (t nil)) ) (defun go-thru-motion (concept id-node w-goal) ) (defun formulate-problem (concept w-goal) ;; Post goal to generate a solution. (spawn-sub-goal *current-character* (make-goal-state 'generate *current-character* concept) ;; ||||| NOTE that this is not really an achievement-goal ;; but it is in the service of one. If we make it a knowledge- ;; acquisition-goal the control passes to do-understand. Fix later. 'achievement-goal 'seven.0 w-goal) ) (defun exists-primitive-p (concept) nil) ;;; If the goal-state can be accomplished by a trivial (primitive) ;;; action, then perform the action without much "thought". ;;; Otherwise pose a problem by forming the goal to solve it. ;;; ;;; NOTE that the logic is backwards compared to the strategy- ;;; decision for question-identification. If there is a primitive the ;;; system lightly processes the concept, whereas in the question- ;;; identification if there does not exist a reason the system skims. ;;; (defun pr.strategy-decision (decision-basis concept) (let ((primitive (exists-primitive-p concept)) (k-state (f.instantiate-frame knowledge-state))) (f.put-all! ; Note that believed-item slot is bound to co-domain. (or primitive (list 'noprimitive nil)) k-state 'believed-item) (f.put! (list k-state) (f.get decision-basis 'knowledge) 'members) (if primitive 'gtm.0 'formulation.0) )) (defun pr.runstrategy (id-node choice concept w-goal) (f.unify (f.get id-node 'main-result) (f.instantiate-frame outcome)) (case choice (formulation.0 (f.put! (list (formulate-problem concept w-goal)) (f.get id-node 'main-result) 'members) 'formulate-problem.0) (gtm.0 (go-thru-motion concept id-node w-goal) 'go-thru-motion.0) ( t (format *aqua-window* "ERROR: unknown pr-strategy - ~s." choice))) ) (defun identify-problem (w-goal id-node) (f.unify (pr.runstrategy id-node (f.unify (f.get id-node 'strategy-choice) (pr.strategy-decision (return-decision-basis id-node) (goal-state w-goal))) (goal-state w-goal) w-goal) (f.get id-node 'strategy-execution)) ) ;;;; ;;;; Plan Generation Phase ;;;; ;;; ;;; Function get-plan-from-node retrieves the plan using the index ;;; stored in the decision-basis. It unifies it with the item wanted ;;; in the trace-meta-xp. (REWRITE). ;;; (defun get-plan-from-node (problem plan-node w-goal) (let* ((first-belief (car (return-decision-basis plan-node))) (new-plan (f.make-new-instance (*FRAME* (first (retrieve-memory (f.chase-path first-belief 'believed-item 'type) (f.chase-path first-belief 'believed-item 'relation))))))) (f.unify (f.get new-plan 'main-result) problem) (f.unify (f.chase-path (processing-trace w-goal) 'main-goal 'backptr) new-plan)) ) ;;; ;;; Function remember-plan is akin to memory-based planning. Since the ;;; system has already decided on this strategy, the plan is assumed to ;;; be located on the d-c-node passed to the function. Function ;;; get-plan-from-node is called to retrieve it. Support goals are ;;; added to the goal queu if there exist any in the gen-goals slot of ;;; the plan. Then the individual plan steps are marked as HVQs as if ;;; the plan represents an answer to the question 'What is the solution ;;; to the problem?' Finally a goal is spawned to evaluate the plan. ;;; ;;; ||||| Problem will always be a goal-object? ;;; (defun remember-plan (problem plan-node w-goal) (let ((new-plan (get-plan-from-node problem plan-node w-goal))) ;; When we set these additional goals, ;; we need to establish the backpointers ;; to the new-plan. ; (with-character-style (*Style*) (format *aqua-window* "~%~%Retrieving plan for concept ~s~%" problem) (format *aqua-window* "~%Produced plan: ~s.~%" new-plan) ; ) ; ;; For each scene in the list, post a plan to want it accomplished. ; (dolist (each-scene (f.get new-plan 'scenes)) ; (spawn-goal *current-character* ; (make-goal-state 'wants ; *current-character* ; each-scene) ; 'achievement-goal ; 'seven.0)) (dolist (each-goal (f.get new-plan 'gen-goals)) (add-item each-goal *Goal-Queue*)) ;; Make each step of the plan a HVQ on the proposed anwser to the problem. (let ((plan-steps (f.get new-plan 'scenes))) (dolist (each-step plan-steps) (add-hvq each-step new-plan) (f.put plan-steps new-plan *hvqs-slot*))) (mark-as-question new-plan *hypothesized-in*) ;; Post goal to verify plan/solution. (spawn-sub-goal (goal-actor w-goal) (make-goal-state 'test (goal-actor w-goal) new-plan) 'achievement-goal 'seven.0 w-goal) new-plan) ) (defun plan-from-scratch (problem w-goal) (format *aqua-window* "~%Dummy execute of function plan-from-scratch.~%") ) (defun p.strategy-decision (decision-basis problems) (do-break p.strategy-decision) (let ((new-plan (first (retrieve-memory 'plan-type.0 problems))) ) (cond (new-plan (let ((k-state (f.instantiate-frame knowledge-state))) (f.unify (f.instantiate-frame `(index ;|||||| Need to add memory-item etc.? (type (,*value-facet* plan-type.0)) (domain (,*value-facet* ,problems)) (co-domain (,*value-facet* ,new-plan)) (relation (,*value-facet* ,problems)) (memory-item (,*value-facet* ,new-plan)))) (f.get k-state 'believed-item)) (f.put! (list k-state) (f.get decision-basis 'knowledge) 'members)) 'MBR.0) (t 'MEA.0))) ) (defun p.runstrategy (plan-node choice problem w-goal) (f.unify (f.get plan-node 'main-result) (f.instantiate-frame outcome)) (case choice (MEA.0 (f.put! (list (plan-from-scratch problem w-goal)) (f.get plan-node 'main-result) 'members) 'do-MEA.0) (MBR.0 (f.put! (list (remember-plan problem plan-node w-goal)) (f.get plan-node 'main-result) 'members) 'do-MBR.0) (suspension.0 (suspend-task problem w-goal) 'suspend-task.0) ( t (print "ERROR: unknown p-strategy." ))) ) (defun generate-plan (w-goal plan-node) ;; ||||| The following code is currently dependent on the order of parameters. (f.unify (p.runstrategy plan-node (f.unify (f.get plan-node 'strategy-choice) (p.strategy-decision (return-decision-basis plan-node) (goal-state w-goal))) (goal-state w-goal) w-goal) (f.get plan-node 'strategy-execution)) ;; ||||| The following comes from generate-hypothesis. Will we need something similar? ;; Do we need a main-plan slot in a Trace-Meta-XP? (f.put-all! (car (return-result plan-node)) (processing-trace w-goal) 'main-xp) ) ;;;; ;;;; Evaluation Phase ;;;; ;;; ;;; To evaluate a plan, Meta-AQUA currently (12 Jul 93) tries to run it. ;;; To run it the system calls do-action on the plan. This function ;;; calls function perform-next-scene on each plan step, spawning a new ;;; goal to understand the resultant action at each step's execution. ;;; ;;; ;;; Function execute-in-world simulates the world independently of the ;;; agents expectations, knowledge (agents know only subset of the ;;; world, and some of that is perhaps incorrect), or desires (goals). ;;; Note that the results of the event may not all be apparent to the ;;; agent, even after the event. ;;; ;;; |||||Very hacked right now. [29 may 93] ;;; ;;; The world itself gives the agent the goal of comprehending changes ;;; and actions that occur. Careful though since this is a situated ;;; point of view. ;;; ;;; ||||| But how to notice when the world produces a different result ;;; than expected??? The goal the world spawns will be simply to ;;; understand the next input, and the input will be different. ;;; (defun execute-in-world (event) (f.put! *nil* (spawn-new-goal (goal-actor w-goal) (make-goal-state 'understands (goal-actor w-goal) event) 'knowledge-acquisition-goal 'seven.0 ;;; w-goal ) 'mxp) ; (if (f.get scene 'main-result) ; (set-model ; *World-Model* ; (cons (f.get scene 'main-result) ; (get-model *World-Model*)))) (cond ((equal (frame-type event) 'write-body) (let ((alternative-solution (f.instantiate-frame recursive-add1nums-defun))) ; (with-character-style (*Style*) (format *aqua-window* "~%LISP simulator provides alternative solution ~s~%" alternative-solution) ; ) (set-model *World-Model* (cons alternative-solution (get-model *World-Model*))))) ) ; (case mode ; (act-out-story ; ) ; (read-story ; ) ; (LISP-programming ; (case (frame-type event) ; (run-program ; ))) ; ) ) ;;; ;;; Kludge for the moment. ;;; (defun do-scene (scene w-goal) (do-break do-scene) (let ((goal-agent (goal-actor w-goal))) ; (with-character-style (*Style*) (format *aqua-window* "~%Actor ~s performs act ~s~%" goal-agent scene) (format *aqua-window* "~%and expects result ~s~%" (f.get scene 'main-result)) ; ) (execute-in-world scene) ) scene ) ;;; ;;; Any scene already performed will have its success slot ;;; marked true or false by the understanding task. Of ;;; course this depends on their being no value when the ;;; scene is initially instantiated. ;;; (defun has-performed-scene-p (scene) (let ((success-val (f.get scene 'success))) (or (equal success-val 'true.0) (equal success-val 'false.0))) ) ;;; ;;; To perform the next scene we find the first scene in ;;; the scene-list which has not already been executed and ;;; then call do-scene. ;;; (defun get-next-unexecuted-scene (scene-list) (do-break get-next-unexecuted-scene) (cond ((null scene-list) nil) ((has-performed-scene-p (first scene-list)) (get-next-unexecuted-scene (rest scene-list)))) ) ;;; ;;; Perform each scene with their preconditions met until reaching ;;; one not met. For each scene performed, post a goal to understand ;;; the outcome of the action. Finally it does it. Check that it ;;; meets the actions expectations, i.e, it produces the main-result ;;; if the action is a mop. ;;; ;;; ||||| What should the function be returning? Whatever it is will ;;; be placed in the main-result slot of the verify d-c-node. ;;; However, we will not know if the plan was successful until we ;;; know whether or not the main plan goal was successful. There will ;;; be lots of baggage to do this, but it will be somewhat like was ;;; done with the main-results slot of the generate d-c-node after ;;; the suspended goal was resumed during understanding. Do not ;;; forget that the main-result slot will have to be made *nil* ;;; before the f.unify is called ;;; (defun do-action (plan w-goal) (do-break do-action) (let* ((current-step (get-next-unexecuted-scene (f.get plan 'scenes)))) (cond (current-step ;; |||||The following is a temporary kludge. 24 May 93 ;; Should do this later when sure that step was successful. (f.put! 'true.0 current-step 'success) (do-scene current-step w-goal) ;; Need to include the larger context. (f.put! *nil* (spawn-new-goal (goal-actor w-goal) (make-goal-state 'understands (goal-actor w-goal) current-scene) 'knowledge-acquisition-goal 'seven.0 ;;; w-goal ) 'mxp) (f.put! plan new-goal 'backptr)) (t ;; Here is where the system should verify that the expected main-result of the ;; plan was indeen the actual result in the world. ;; |||||Mark action as successful or not? Clean-up rituals anyhow. (f.get plan 'main-result)))) ) ;;; ;;; No replanning yet. ;;; (defun replan (plan w-goal) ) (defun preconditions-met (plan) t) ;;; ;;; At the current time (12 Jul 93) all plans will be enabled for ;;; execution; no preconditions will not be met since the predicate ;;; will always return true. ;;; (defun e.strategy-decision (decision-basis plan) (if (preconditions-met plan) 'execution.0 'replanning.0) ) (defun e.runstrategy (eval-node choice plan w-goal) (f.unify (f.get eval-node 'main-result) (f.instantiate-frame outcome)) (case choice (execution.0 (f.put! (list (do-action plan w-goal)) (f.get eval-node 'main-result) 'members) 'execute.0) (replanning.0 (f.put! (list (replan plan w-goal)) (f.get eval-node 'main-result) 'members) 'replan.0) (suspension.0 (suspend-task plan w-goal) 'suspend-task.0) (t (print "ERROR: unknown e-strategy." )))) (defun evaluate (w-goal eval-node) ;; ||||| The following code is currently dependent on the order of parameters. (f.unify (e.runstrategy eval-node (f.unify (f.get eval-node 'strategy-choice) (e.strategy-decision (return-decision-basis eval-node) (goal-state w-goal))) (goal-state w-goal) w-goal) (f.get eval-node 'strategy-execution)) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; MAIN CONTROL FUNCTIONS ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; ||||| Check to see whether the spawning of goals are done right. ;;; ;;; On input the calling function, dispatch-world-goal, assures that ;;; the w-goal is for the system to want some state. ;;; ;;; Function boot-wanting is the routine to handle world goals in the ;;; dispatch call of function plan-about. It spawns a goal to ;;; identify any problems concerning the desired goal-state of the ;;; w-goal if there is no plan yet, otherwise it spawns a goal to ;;; test the plan. ;;; (defun boot-wanting (w-goal) (let ((current-actor (goal-actor w-goal))) (if (or (equal (frame-type (f.get w-goal 'backptr)) *nil*) (equal (frame-type (f.get w-goal 'backptr)) 'plan)) ; then this plan is not instantiated yet. ;; Post goal to identify the problem. (spawn-sub-goal current-actor (make-goal-state 'id current-actor (goal-state w-goal)) ;; ||||| NOTE that this is not really an achievement-goal but it is in the ;; service of one. If we make it a knowledge-acquisition-goal the control ;; passes to do-understand. Fix later. 'achievement-goal 'seven.0 w-goal) ;; Otherwise post goal to test the instantiated plan. (spawn-sub-goal current-actor (make-goal-state 'test current-actor (first (return-result (return-d-c-node (processing-trace w-goal) 'generation)))) ;; (goal-state w-goal)) ;; ||||| NOTE that this is not really an achievement-goal either. 'achievement-goal 'seven.0 w-goal)) )) ;;; ;;; Function dispatch-world-goal calls particular reasoning functions ;;; depending on the type of goal-object in the knowledge goal. It ;;; returns a phase identifier that corresponds to the goal-object ;;; type. The counterpart function in the understanding process is ;;; dispatch-knowledge-goal. ;;; (defun dispatch-world-goal (w-goal d-c-node) (case (frame-type (goal-object w-goal)) (wants (boot-wanting w-goal) 'wants) (id (identify-problem w-goal d-c-node) 'identification) (generate (generate-plan w-goal d-c-node) 'generation) (test (evaluate w-goal d-c-node) 'examination) (review/learn ;; A f.unify is performed on goal-target internally to function review. ;; Thus we need to make sure that it remains bound to the proper frame. (learn w-goal d-c-node) 'review) ( t (print "ERROR: unknown goal type in function dispatch-world-goal.") nil)) ) ;;; ;;; Old Control: ;;; ;;; (defun plan-about (concept) ;;; (p.learn-about ;;; (evaluate ;;; (generate-plan ;;; (identify-problem concept))))) ;;; (defun plan-about (w-goal) (let* ((d-c-node (gen-d-c-node w-goal)) (phase (dispatch-world-goal w-goal d-c-node))) (if (and phase (not (equal phase 'wants))) (let ((which-tmxp (if (equal phase 'review) (goal-state w-goal) (processing-trace w-goal)))) (f.unify d-c-node (f.get which-tmxp phase)) (f.put! (f.make-relation which-tmxp phase) which-tmxp 'current-phase))) )) ;;; ;;; Function solve-old-problems is the parallel of function ;;; answer-old-questions. The new input has signalled an object which may ;;; potentially aid in the achievement of an old suspended world-goal. ;;; ;;; |||||| This remains to be worked on. ;;; (defun solve-old-problems (solution problems) (format *aqua-window* "~%Entering solve-old-problems with nothing in it.~%") ) ;;; ;;; Look for opportunities to resume previously suspended planning ;;; tasks. If the opportunity does not exist then we call plan-about. ;;; This parallels the function do-understand. Or, on the other ;;; hand, do we call the Noticer here? ;;; (defun do-plan (w-goal) (let* ((goal-target (goal-state w-goal)) (old-problems (and (is-goal-object-p 'wants w-goal) ;; ||||| Should have potential-solution-p predicate calling notice instead? (notice goal-target w-goal (get-model *World-Model*))))) (cond (old-problems ; (with-character-style (*Style*) (format *aqua-window* "~%~%Input triggers reminding of old problem:~% ~s~%" old-problems) ; ) (solve-old-problems goal-target old-problems)) (t (plan-about w-goal) ))) )