capture
[rrq/gorite.git] / com / intendico / gorite / EndGoal.java
1 /*********************************************************************
2 Copyright 2012, Ralph Ronnquist.
3
4 This file is part of GORITE.
5
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.
10
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.
15
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 **********************************************************************/
19
20 package com.intendico.gorite;
21
22 import com.intendico.data.Query;
23 import com.intendico.data.Ref;
24
25 import java.util.HashSet;
26 import java.util.Iterator;
27 import java.util.Vector;
28
29 /**
30  * An EndGoal is achieved by means of achieving its sub goals in
31  * sequence, and it will then cause an enclosing {@link LoopGoal} goal
32  * to be achieved. If any sub goal fails, the EndGoal will just
33  * succeed without causing the enclosing {@link LoopGoal} to
34  * succeed. An EndGoal never fails; either it succeeds or it causes
35  * the enclosing {@link LoopGoal} to succeed.
36  *
37  * The usage pattern for {@link LoopGoal} and EndGoal is as follows:
38  *
39  * <pre>
40  * new LoopGoal( "loop", new Goal [] {
41  *     .. // steps in the loop
42  *     .. new EndGoal( "break if", new Goal [] {
43  *            // optional sub goals for ending the loop if they succeed
44  *        } )
45  *     .. // more steps in the loop
46  * } )
47  * </pre>
48  *
49  * <p> There may be any number of {@link EndGoal} to end the loop
50  * although of course only one will take effect. The {@link EndGoal}
51  * may be at any level within the LoopGoal goal hierarchy, except
52  * nested within another LoopGoal.
53  *
54  * <p> The EndLoop effect may be thought of as throwing an {@link
55  * Exception} that the nearest enclosing {@link LoopGoal} catches,
56  * interrupting the progress of any intermediate composite goal,
57  * including {@link ParallelGoal} and {@link RepeatGoal}.  Ongoing
58  * branches of intermediate parallel goals will be cancelled.
59  *
60  * <p> The EndLoop effect does not propagate up through a {@link
61  * BDIGoal} execution of a {@link Plan} with non-null {@link
62  * Context#context(Data)} {@link Query}. I.e., the EndGoal must
63  * typically be explicitely within the sub goal hierarchy of the
64  * {@link LoopGoal} of concern.
65  *
66  * <p> However, the EndGoal effect does propagate up through a {@link
67  * BDIGoal} execution if the {@link Plan} has a null {@link
68  * Context#context(Data)}, or is an implementing {@link Goal}
69  * hierarchy without {@link Context}.
70  * 
71  * @see LoopGoal
72  * @see SequenceGoal
73  * @see ParallelGoal
74  * @see RepeatGoal
75  */
76 public class EndGoal extends SequenceGoal {
77
78     /**
79      * Constructor.
80      */
81     public EndGoal(String n,Goal [] sg) {
82         super( n, sg );
83     }
84
85     /**
86      * Convenience constructor without sub goals.
87      */
88     public EndGoal(String n) {
89         this( n, null );
90     }
91
92     /**
93      * Creates and returns an instance object for achieving
94      * a EndGoal.
95      */
96     public Instance instantiate(String head,Data d) {
97         return new EndInstance( head );
98     }
99
100     /**
101      * Implements a loop-end action ("break")
102      */
103     public class EndInstance extends SequenceInstance {
104
105         /**
106          * Constructor.
107          */
108         public EndInstance(String h) {
109             super( h );
110         }
111
112         /**
113          * Process all subgoals in sequence, then throw a
114          * LoopEndException if success. If subgoals fail, then succeed
115          * without throwing exception.
116          */
117         public States action(String head,Data d)
118             throws LoopEndException, ParallelEndException {
119             States s = super.action( head, d );
120             if ( s == States.PASSED )
121                 throw new LoopEndException( head );
122             if ( s == States.FAILED )
123                 return States.PASSED;
124             return s;
125         }
126     }
127 }