capture
[rrq/gorite.git] / com / intendico / gorite / ParallelGoal.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  * A ParallelGoal is achieved by means of achieving all its sub goals
31  * in parallel. If any sub goal execution fails, then all other sub
32  * goal executions are interrupted by means of throwing an {@link
33  * java.lang.InterruptedException InterruptedException}, and
34  * thereafter the parallel goal execution fails (when all the sub goal
35  * executions have terminated).
36  *
37  * <p> A ParallelGoal execution can also be interrupted to end in
38  * success, by means of throwing a {@link ParallelEndException} within
39  * one of its branches. In this case all other sub goal executions are
40  * interrupted by means of throwing an {@link
41  * java.lang.InterruptedException InterruptedException}, and
42  * thereafter the parallel goal execution succeeds (when all the sub
43  * goal executions have terminated).
44  *
45  * <p> See also {@link ControlGoal}, which throws a {@link
46  * ParallelEndException} if its sub goals succeed. The following is a
47  * code snippet to illustrate the use of an embedded {@link
48  * ControlGoal} for an optional premature interupt of an indefinite
49  * intention.
50  * 
51  * <pre>
52  * new ParallelGoal( ..., new Goal [] {
53  *     new BDIGoal( "do something indefinitely" ),
54  *     new FailGoal( "not interrupting is fine", new Goal [] {
55  *         new ControlGoal( "interrupt if desired", new Goal [] {
56  *             new BDIGoal( "decide if and when to interrupt" )
57  *         }
58  *     }
59  * } )
60  * </pre>
61  */
62 public class ParallelGoal extends BranchingGoal {
63
64     /**
65      * Constructor.
66      */
67     public ParallelGoal(String n,Goal [] sg) {
68         super( n, sg );
69     }
70
71     /**
72      * Convenience constructor without sub goals.
73      */
74     public ParallelGoal(String n) {
75         this( n, null );
76     }
77
78     /**
79      * Creates and returns an instance object for achieving
80      * a ParallelGoal.
81      */
82     public Instance instantiate(String head,Data d) {
83         return new ParallelInstance( head );
84     }
85
86     /**
87      * Implements parallel execution of sub goals.
88      */
89     public class ParallelInstance extends MultiInstance {
90
91         /**
92          * Constructor.
93          */
94         public ParallelInstance(String h) {
95             super( h );
96         }
97
98         /**
99          * There is one branch for each sub goal.
100          */
101         public boolean more(int i,Data d) {
102             return getGoalSubgoals() != null && i < getGoalSubgoals().length;
103         }
104
105         /**
106          * The sub goal branch is obtained by instantiating the sub
107          * goal.
108          */
109         public Instance getBranch(int i,String head,Data d) {
110             return getGoalSubgoals()[ i ].instantiate( head, d );
111         }
112     }
113 }