1 /*********************************************************************
2 Copyright 2012, Ralph Ronnquist.
4 This file is part of GORITE.
6 GORITE is free software: you can redistribute it and/or modify it
7 under the terms of the Lesser GNU General Public License as published
8 by the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 GORITE is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the Lesser GNU General Public
17 License along with GORITE. If not, see <http://www.gnu.org/licenses/>.
18 **********************************************************************/
20 package com.intendico.gorite;
22 import com.intendico.gorite.Goal.States;
23 import com.intendico.data.*;
24 import java.util.Vector;
27 * This is a utility class used by BDIGoal execution, to inject a plan
28 * choice goal for choosing the plan instance to pursue. It is not
29 * intended for explicit use within goal hierarchies.
31 * <p> The {@link BDIGoal} uses the {@link
32 * Performer#getPlanChoice(String)} method to determine whether or not
33 * a goal is asoicated with a plan choice goal. If this is the case,
34 * then it will create a PlanChoiceGoal instance for handling the
35 * choice of which of the applicable plan options to pursue next, and
36 * the subsequent execution of that option.
38 * <p> The choice is performed by triggering a (freschly created)
39 * {@link BDIGoal} for the plan choice goal, with a separate Data
40 * object that is initialised with "options", "failed" and "data". As
41 * the plan choice goal succeeds, the resulting "choice" data is used
42 * as being the choice of plan option, and then that plan option is
43 * executed as an attempt of achieving the original goal. If that
44 * succeeds, the original goal succeeds without further ado, and if it
45 * fails, then the BDIGoal forms a new, possibly empty collection of
46 * applicable (non-failed) plan options, and trigger a new
47 * PlanChoiceGoal for that collection.
49 * <p> If the plan choice goal fails, then all applicable options at
50 * this point are added to the failed set, the {@link BDIGoal}
51 * continues by forming a new, possibly empty collection of applicable
52 * (non-failed) plan options, and triggering a new PlanChoiceGoal for
55 * <p> If the plan choice goal fails for the final triggering, i.e,
56 * with an empty collection of applicable (non-failed) plan options,
57 * then the original goal fails. In fact, the orginal goal fails also
58 * if the final plan choice goal succeeds, except if this is also the
59 * first triggering and thus, there are no failed plan options
60 * either. In that case, the original goal will succeed if the plan
61 * choice goal succeeds.
63 * @see Performer#getPlanChoice(String)
64 * @see Performer#setPlanChoice(String,Object)
66 public class PlanChoiceGoal extends Goal {
69 * The invocation data.
71 public Data choice_data;
74 * Status flag for plan choice processing.
76 public States done = States.STOPPED;
79 * The initial first option.
84 * The choice goal. This is set by the plan choice processing.
89 * The currently executing goal instance.
91 public Instance instance = null;
94 * Sub goal head, which is set when this goal is instantiated
99 * Constructor for a given plan choice goal and collection of plan
102 public PlanChoiceGoal(
103 Performer p,String pg,Vector/*<Goal>*/ plans,Vector/*<Goal>*/ failed) {
105 choice_data = new Data();
106 choice_data.setValue( Goal.PERFORMER, p );
107 choice_data.setValue( "options", plans );
108 choice_data.setValue( "failed", failed );
109 if ( plans.size() > 0 )
110 first = (Goal) plans.get( 0 );
114 * Instantiating this goal for execution.
116 public Goal.Instance instantiate(String h,Data d) {
118 choice_data.setValue( "data", d );
119 instance = new BDIGoal(
120 getGoalName() ).instantiate( h + "?", choice_data );
121 return super.instantiate( h, d );
125 * Control callback whereby the goal gets notified that an (its)
126 * intention is cancelled. This will forward the cancellation to
127 * the currently progressing instance, if any.
129 public void cancelled(Instance which) {
130 if ( instance != null )
135 * Excution of this goal. If choice is null, then the execution is
136 * like a BDIGoal of the plan choice goal, with its data holding
137 * the "options", for setting the "choice". If that execution is
138 * successful, then the choice is taken, otherwise the original
139 * first choice is taken. If choice is set, then the execution
140 * executes that goal.
142 public States execute(Data data)
143 throws ParallelEndException {
145 States s = States.FAILED;
147 s = instance.perform( choice == null? choice_data: data );
148 } catch (LoopEndException e) {
150 } catch (ParallelEndException e) {
152 if ( done != States.STOPPED )
155 if ( done != States.STOPPED )
157 if ( s != States.PASSED && s != States.FAILED )
160 if ( s == States.FAILED ) {
161 Vector/*<Goal>*/ options = (Vector/*<Goal>*/)
162 choice_data.getValue( "options" );
163 Vector/*<Goal>*/ failed = (Vector/*<Goal>*/)
164 choice_data.getValue( "failed" );
165 failed.addAll( options );
167 return States.FAILED;
169 choice = (Goal) instance.getValue( "choice" );
170 if ( choice == null )
172 if ( choice == null ) {
173 Vector/*<Goal>*/ failed = (Vector/*<Goal>*/)
174 choice_data.getValue( "failed" );
175 return failed.size() == 0? States.PASSED : States.FAILED;
177 instance = choice.instantiate( head + "!", data );