Passed
Push — master ( ff18e0...a286a0 )
by Alessandro
05:17
created

clear()   A

Complexity

Conditions 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 6
c 0
b 0
f 0
cc 1
rs 10
1
package it.cnr.istc.pst.platinum.ai.deliberative.solver;
2
3
import java.util.ArrayList;
4
import java.util.List;
5
6
import it.cnr.istc.pst.platinum.ai.deliberative.heuristic.pipeline.PipelineFlawSelectionHeuristic;
7
import it.cnr.istc.pst.platinum.ai.deliberative.strategy.CostDepthSearchStrategy;
8
import it.cnr.istc.pst.platinum.ai.deliberative.strategy.ex.EmptyFringeException;
9
import it.cnr.istc.pst.platinum.ai.framework.domain.component.PlanElementStatus;
10
import it.cnr.istc.pst.platinum.ai.framework.microkernel.annotation.cfg.deliberative.FlawSelectionHeuristicsConfiguration;
11
import it.cnr.istc.pst.platinum.ai.framework.microkernel.annotation.cfg.deliberative.SearchStrategyConfiguration;
12
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.ex.ConsistencyCheckException;
13
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.ex.NoFlawFoundException;
14
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.ex.NoSolutionFoundException;
15
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.ex.PlanRefinementException;
16
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.flaw.Flaw;
17
import it.cnr.istc.pst.platinum.ai.framework.microkernel.resolver.ex.UnsolvableFlawException;
18
19
20
21
/**
22
 * 
23
 * @author anacleto
24
 *
25
 */
26
@FlawSelectionHeuristicsConfiguration(
27
		heuristics = PipelineFlawSelectionHeuristic.class
28
)
29
@SearchStrategyConfiguration(
30
		strategy = CostDepthSearchStrategy.class
31
)
32
public class PseudoControllabilityAwareSolver extends Solver 
33
{
34
	/**
35
	 * 
36
	 * @param timeout
37
	 */
38
	protected PseudoControllabilityAwareSolver(long timeout) {
39
		super("PseudoControllabilityAwareSolver", timeout);
40
	}
41
	
42
	/**
43
	 * 
44
	 */
45
	@Override
46
	public SearchSpaceNode solve() 
47
			throws NoSolutionFoundException 
48
	{
49
		// set solving start time
50
		long start = System.currentTimeMillis();
51
		// set solving step counter
52
		this.stepCounter = 0;
53
		// last extracted node
54
		SearchSpaceNode last = null, node = null;
55
		// search condition
56
		boolean search = true;
57
		// search a solution
58
		while (search) 
59
		{
60
			try 
61
			{
62
				
63
				// update step counter
64
				this.stepCounter++;
65
				// get time passed from the start 
66
				long now = System.currentTimeMillis() - start;
67
				// check timeout
68
				if (this.timeout > 0 && now > this.timeout) 
69
				{
70
					// no solution found stop search
71
					search = false;
72
					// set solving time
73
					this.time = System.currentTimeMillis() - start;
74
					// backtrack from the last propagated node
75
					this.backtrack(last);
76
					// timeout exception
77
					throw new NoSolutionFoundException("Timeout: no solution found after " + this.time + " msecs and " + this.stepCounter + " solving steps");
78
				}
79
				
80
				
81
				// extract a node from the fringe
82
				node = this.fringe.dequeue();
83
84
				// info message
85
				String info = "Extracted node [step = " + this.stepCounter + "]:\n"
86
						+ "node: " + node + "\n";
87
				// check operators 
88
				if (last != null) {
89
					info += "Operators:\n";
0 ignored issues
show
Performance introduced by
String concatenation with + is inefficient. Doing so in a loop may incur a significant performance penalty. Consider using a StringBuilder instead
Loading history...
90
					// print last node operations
91
					for (Operator op : node.getOperators()) {
92
						info += "op: " + op + "\n";
0 ignored issues
show
Performance introduced by
String concatenation with + is inefficient. Doing so in a loop may incur a significant performance penalty. Consider using a StringBuilder instead
Loading history...
93
					}
94
				}
95
				// info log 
96
				info(info);
97
				
98
				// propagate extracted node
99
				this.contextSwitch(last, node);
100
				// updated last propagated node
101
				last = node;
102
				// check consistency of the resulting partial plan
103
				this.pdb.verify();
104
				
105
				// context switch done
106
				info("Context switch successfully done [step = " + this.stepCounter + "]:\n"
107
						+ "Plan: " + last.getPartialPlan() + "\n");
108
				
109
				// print information concerning current partial plan	
110
				debug("Detailed plan after propagation: "  + node.getGenerator() + "\n"
111
							+ "\tplan:\n"
112
							+ "\t\tdecisions= " + this.pdb.getPlan().getDecisions() + "\n"
113
							+ "\t\trelations= " + this.pdb.getPlan().getRelations() + "\n\n"
114
							+ "\tpending plan (agenda):\n"
115
							+ "\t\tdecisions= " + this.pdb.getPlan(PlanElementStatus.PENDING).getDecisions() + "\n"
116
							+ "\t\trelations= " + this.pdb.getPlan(PlanElementStatus.PENDING).getRelations() + "\n\n"
117
							+ "\tsilent plan:\n"
118
							+ "\t\tdecisions= " + this.pdb.getPlan(PlanElementStatus.SILENT).getDecisions() + "\n"
119
							+ "\t\trelations= " + this.pdb.getPlan(PlanElementStatus.SILENT).getRelations() + "\n\n");
120
				
121
 				// choose the best flaws to solve
122
				List<Flaw> flaws = new ArrayList<>(this.heuristic.choose());
123
				// create a branch for each "equivalent" flaw to solve next
124
				for (Flaw flaw : flaws)
125
				{
126
					// expand the search space with the available solutions of the flaw
127
					for (SearchSpaceNode child : this.expand(node, flaw)) {
128
						// add the node to the fringe
129
						this.fringe.enqueue(child);
130
						// expand the search space
131
						info("Search tree expansion:\n"
132
								+ "node: " + child + "\n"
133
								+ "generator: " + child.getGenerator() + "\n");
134
					}
135
				}
136
			}
137
			catch (PlanRefinementException ex) {
138
				// refinement error
139
				warning("Refinement error [step = " + this.stepCounter + "]:\n"
140
						+ "message: " + ex.getMessage() + "\n"
141
						+ "Plan:\n" + last.getPartialPlan() + "\n");
142
			}
143
			catch (UnsolvableFlawException ex) {
144
				// refinement error
145
				warning("Unsolvable flaw found  [step = " + this.stepCounter + "]:\n"
146
						+ "message: " + ex.getMessage() + "\n"
147
						+ "Plan:\n" + last.getPartialPlan() + "\n");
148
			}
149
			catch (ConsistencyCheckException ex) 
150
			{
151
				// context switch failure
152
				warning("Context switch failure [step = " + this.stepCounter + "]:\n"
153
						+ "message: " + ex.getMessage() + "\n"
154
						+ "Plan:\n" + last.getPartialPlan() + "\n");
155
			}
156
			catch (NoFlawFoundException ex)
157
			{
158
				// solution found stop search
159
				search = false;
160
				// set solving time
161
				this.time = System.currentTimeMillis() - start;
162
				// pseudo-controllable solution found
163
				info("Pseudo-controllable solution found after " + (this.time / 1000) + " (secs) and " + this.stepCounter + " solving steps\n");
164
			}
165
			catch (EmptyFringeException ex) 
166
			{
167
				// no solution found stop search
168
				search = false;
169
				// set solving time
170
				this.time = System.currentTimeMillis() - start;
171
				// backtrack from the last propagated node
172
				this.backtrack(last);
173
				// throw exception
174
				throw new NoSolutionFoundException("No pseudo-controllable solution found after " + (this.time / 1000) + " (secs) and " + this.stepCounter + " solving steps\n");
175
			}
176
			// close connection
177
			finally 
178
			{
179
				// check if stop
180
				if (!search)  {
181
					// clear data structures
182
					this.clear();
183
				}
184
			}
185
			
186
		} // end while
187
		
188
		
189
		// get last expanded node
190
		return last;
191
	}
192
	
193
	/**
194
	 * 
195
	 */
196
	@Override
197
	public void clear() {
198
		// clear heuristics
199
		this.heuristic.clear();
200
		// clear the fringe
201
		this.fringe.clear();
202
	}
203
}	
204