it.cnr.istc.pst.platinum.ai.framework.domain.component.pdb.PlanDataBaseComponent   F
last analyzed

Complexity

Total Complexity 134

Size/Duplication

Total Lines 1342
Duplicated Lines 6.71 %

Importance

Changes 0
Metric Value
eloc 551
dl 90
loc 1342
rs 2
c 0
b 0
f 0
wmc 134

60 Methods

Rating   Name   Duplication   Size   Complexity  
A verify() 0 8 1
A create(ComponentValue,String[],long[],long[],long[]) 0 8 1
A createParameterDomain(String,ParameterDomainType) 0 7 1
A getSilentDecisions() 0 7 2
A isActive(Decision) 0 3 1
A getToActivateRelations(Decision) 0 10 1
A activate(Decision) 0 10 1
F doSetupProblem(Problem) 0 174 19
A detectFlaws() 0 14 2
A createDomainComponent(String,DomainComponentType) 0 12 2
A create(RelationType,Decision,Decision) 0 6 1
A propagate(Operator) 0 32 4
A retract(Operator) 0 7 1
A restore(Decision) 0 4 1
A getPendingRelations() 0 18 4
B getValueByName(String) 0 23 6
D addSynchronizationRule(SynchronizationRule) 0 53 12
A getActiveDecisions() 0 10 2
A create(ComponentValue,String[],long[]) 0 8 1
A getDomainKnowledge() 0 3 1
A getSilentRelations() 0 18 4
A deactivate(Relation) 0 6 1
A getParameterDomainByName(String) 0 3 1
A PlanDataBaseComponent(String) 0 12 1
A checkFlaws() 0 12 2
A init() 0 27 1
A getPlan() 0 20 3
A create(ComponentValue,String[]) 0 8 1
A checkFlaws(FlawType[]) 0 12 2
A getValues() 0 8 2
A getBehaviorDuration() 34 34 3
A detectFlaws(FlawType) 0 15 2
A getPendingDecisions() 0 9 2
A restore(FlawSolution) 0 7 1
A rollback(FlawSolution) 0 6 1
B prepareDecisionVariable(Decision) 22 57 6
A getComponents() 0 3 1
A createSynchronizationRule(ComponentValue,String[]) 0 13 2
A free(Decision) 0 6 1
A getActiveRelations() 0 21 4
A isSilent(Decision) 0 4 1
A getPendingRelations(Decision) 0 6 1
A activate(Relation) 0 7 1
A clear() 0 26 3
A deactivate(Decision) 0 5 1
A commit(FlawSolution) 0 7 1
A isPending(Decision) 0 4 1
A restore(Relation) 0 5 1
A getRelations() 0 17 3
A toString() 0 3 1
A getMakespan() 34 34 3
A addDomainComponent(DomainComponent) 0 4 1
A setup(Problem) 0 5 1
A getComponentByName(String) 0 7 2
A getActiveRelations(Decision) 0 10 1
A getSolutionPlan() 0 25 3
A getParameterDoamins() 0 3 1
A create(ComponentValue,String[],long[],long[]) 0 8 1
A delete(Relation) 0 6 1
A getRelations(Decision) 0 10 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like it.cnr.istc.pst.platinum.ai.framework.domain.component.pdb.PlanDataBaseComponent often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
package it.cnr.istc.pst.platinum.ai.framework.domain.component.pdb;
2
3
import java.util.ArrayList;
4
import java.util.HashMap;
5
import java.util.HashSet;
6
import java.util.List;
7
import java.util.Map;
8
import java.util.Set;
9
10
import it.cnr.istc.pst.platinum.ai.deliberative.solver.Operator;
11
import it.cnr.istc.pst.platinum.ai.framework.domain.DomainComponentBuilder;
12
import it.cnr.istc.pst.platinum.ai.framework.domain.component.ComponentValue;
13
import it.cnr.istc.pst.platinum.ai.framework.domain.component.Decision;
14
import it.cnr.istc.pst.platinum.ai.framework.domain.component.DomainComponent;
15
import it.cnr.istc.pst.platinum.ai.framework.domain.component.DomainComponentType;
16
import it.cnr.istc.pst.platinum.ai.framework.domain.component.PlanDataBase;
17
import it.cnr.istc.pst.platinum.ai.framework.domain.component.Predicate;
18
import it.cnr.istc.pst.platinum.ai.framework.domain.component.ex.DecisionPropagationException;
19
import it.cnr.istc.pst.platinum.ai.framework.domain.component.ex.FlawSolutionApplicationException;
20
import it.cnr.istc.pst.platinum.ai.framework.domain.component.ex.RelationPropagationException;
21
import it.cnr.istc.pst.platinum.ai.framework.domain.knowledge.DomainKnowledge;
22
import it.cnr.istc.pst.platinum.ai.framework.domain.knowledge.DomainKnowledgeType;
23
import it.cnr.istc.pst.platinum.ai.framework.microkernel.ConstraintCategory;
24
import it.cnr.istc.pst.platinum.ai.framework.microkernel.annotation.cfg.framework.DomainComponentConfiguration;
25
import it.cnr.istc.pst.platinum.ai.framework.microkernel.annotation.cfg.framework.DomainKnowledgeConfiguration;
26
import it.cnr.istc.pst.platinum.ai.framework.microkernel.annotation.cfg.framework.ParameterFacadeConfiguration;
27
import it.cnr.istc.pst.platinum.ai.framework.microkernel.annotation.cfg.framework.TemporalFacadeConfiguration;
28
import it.cnr.istc.pst.platinum.ai.framework.microkernel.annotation.inject.framework.DomainKnowledgePlaceholder;
29
import it.cnr.istc.pst.platinum.ai.framework.microkernel.annotation.lifecycle.PostConstruct;
30
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.ex.ConsistencyCheckException;
31
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.ex.DomainComponentNotFoundException;
32
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.ex.OperatorPropagationException;
33
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.ex.ProblemInitializationException;
34
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.ex.SynchronizationCycleException;
35
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.flaw.Flaw;
36
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.flaw.FlawSolution;
37
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.flaw.FlawType;
38
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.plan.Plan;
39
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.plan.SolutionPlan;
40
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.problem.ParameterProblemConstraint;
41
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.problem.Problem;
42
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.problem.ProblemConstraint;
43
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.problem.ProblemFact;
44
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.problem.ProblemFluent;
45
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.problem.ProblemGoal;
46
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.problem.TemporalProblemConstraint;
47
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.Relation;
48
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.RelationType;
49
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.parameter.BindParameterRelation;
50
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.parameter.EqualParameterRelation;
51
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.parameter.NotEqualParameterRelation;
52
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.parameter.ParameterRelation;
53
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.temporal.TemporalRelation;
54
import it.cnr.istc.pst.platinum.ai.framework.microkernel.query.ParameterQueryType;
55
import it.cnr.istc.pst.platinum.ai.framework.microkernel.query.TemporalQueryType;
56
import it.cnr.istc.pst.platinum.ai.framework.microkernel.resolver.ex.UnsolvableFlawException;
57
import it.cnr.istc.pst.platinum.ai.framework.parameter.csp.solver.ParameterSolverType;
58
import it.cnr.istc.pst.platinum.ai.framework.parameter.lang.EnumerationParameter;
59
import it.cnr.istc.pst.platinum.ai.framework.parameter.lang.NumericParameter;
60
import it.cnr.istc.pst.platinum.ai.framework.parameter.lang.Parameter;
61
import it.cnr.istc.pst.platinum.ai.framework.parameter.lang.ParameterDomain;
62
import it.cnr.istc.pst.platinum.ai.framework.parameter.lang.ParameterDomainType;
63
import it.cnr.istc.pst.platinum.ai.framework.parameter.lang.query.CheckValuesParameterQuery;
64
import it.cnr.istc.pst.platinum.ai.framework.parameter.lang.query.ComputeSolutionParameterQuery;
65
import it.cnr.istc.pst.platinum.ai.framework.time.TemporalInterval;
66
import it.cnr.istc.pst.platinum.ai.framework.time.lang.query.IntervalScheduleQuery;
67
import it.cnr.istc.pst.platinum.ai.framework.time.solver.TemporalSolverType;
68
import it.cnr.istc.pst.platinum.ai.framework.time.tn.TemporalNetworkType;
69
import it.cnr.istc.pst.platinum.ai.framework.utils.properties.FilePropertyReader;
70
71
/**
72
 * 
73
 * @author anacleto
74
 *
75
 */
76
@DomainKnowledgeConfiguration(
77
		
78
		// set domain knowledge
79
		knowledge = DomainKnowledgeType.STATIC
80
)
81
@TemporalFacadeConfiguration(
82
		
83
		// set temporal network 
84
		network = TemporalNetworkType.STNU, 
85
		
86
		// set planner solver
87
		solver = TemporalSolverType.APSP
88
)
89
@ParameterFacadeConfiguration(
90
		
91
		// set parameter reasoner
92
		solver = ParameterSolverType.CHOCHO_SOLVER
93
)
94
public final class PlanDataBaseComponent extends DomainComponent implements PlanDataBase
0 ignored issues
show
Bug introduced by
Override the "equals" method in this class.
Loading history...
95
{
96
	@DomainKnowledgePlaceholder
97
	protected DomainKnowledge knowledge;
98
	
99
	// see Composite design pattern
100
	private Map<String, DomainComponent> components;
101
	
102
	// the planning problem
103
	protected Problem problem;
104
	
105
	// domain theory
106
	private Map<String, ParameterDomain> parameterDomains;
107
	
108
	private boolean allowRecursiveRules;								// check if recursive rules are allowed
109
		
110
	/**
111
	 * 
112
	 * @param name
113
	 */
114
	
115
	@DomainComponentConfiguration(resolvers = {
116
			// no resolver is needed
117
	})
118
	protected PlanDataBaseComponent(String name) 
119
	{
120
		super(name, DomainComponentType.PLAN_DATABASE);
121
		
122
		// initialize data structures
123
		this.components = new HashMap<>();
124
		this.parameterDomains = new HashMap<>();
125
		this.problem = null;
126
		this.allowRecursiveRules = false;				// default behavior
127
	}
128
	
129
	/**
130
	 * 
131
	 */
132
	@PostConstruct
133
	protected synchronized void init() {
134
		super.init();
135
		
136
		// clear static (global) information
137
		synchronized (rules) {
138
			// clear if needed global synchronization rules
139
			rules.clear();
140
		}
141
		
142
		synchronized(globalRelations) {
143
			// clear if needed global relations
144
			globalRelations.clear();
145
		}
146
	
147
		// reset predicate counter
148
		PREDICATE_COUNTER.set(0);
149
		// reset decision counter
150
		DecisionIdCounter.set(0);
151
		// reset relation counter
152
		RELATION_COUNTER.set(0);
153
		
154
		// check property file
155
		FilePropertyReader properties = new FilePropertyReader(
156
				FRAMEWORK_HOME + FilePropertyReader.DEFAULT_DELIBERATIVE_PROPERTY);
157
		// check property flag
158
		this.allowRecursiveRules = properties.getProperty("allow-recursive-rules").equals("1");
159
		
160
	}
161
	
162
	/**
163
	 * 
164
	 */
165
	@Override
166
	public synchronized void setup(Problem problem) 
167
			throws ProblemInitializationException {
168
		// setup problem
169
		this.doSetupProblem(problem);
170
	}
171
	
172
	/**
173
	 * 
174
	 */
175
	@Override
176
	public synchronized void clear() 
177
	{
178
		// clear components
179
		for (DomainComponent component : this.components.values()) {
180
			// clear component
181
			component.clear();
182
		}
183
184
		// clear local relations
185
		this.localRelations.clear();
186
		// clear global relations
187
		synchronized (globalRelations) {
188
			// clear global active relations
189
			for (Relation rel : globalRelations) {
190
				// delete global relation
191
				this.deactivate(rel);
192
			}
193
			
194
			// clear global relations
195
			globalRelations.clear();
196
		}
197
		// clear problem
198
		this.problem = null;
199
		// clear domain knowledge
200
		this.knowledge = null;
201
	}
202
	
203
	/**
204
	 * 
205
	 */
206
	@Override
207
	public synchronized DomainKnowledge getDomainKnowledge() {
208
		return this.knowledge;
209
	}
210
	
211
	/*
212
	 * 
213
	 */
214
	@Override
215
	public synchronized void addSynchronizationRule(SynchronizationRule rule) 
216
			throws SynchronizationCycleException
217
	{
218
		// get head value
219
		ComponentValue value = rule.getTriggerer().getValue();
220
		// set the trigger as complex
221
		value.setComplex();
222
				
223
		// check data
224
		if (!rules.containsKey(value.getComponent())) {
225
			rules.put(value.getComponent(), new HashMap<ComponentValue, List<SynchronizationRule>>());
226
		}
227
		if (!rules.get(value.getComponent()).containsKey(value)) {
228
			// initialize
229
			rules.get(value.getComponent()).put(value, new ArrayList<SynchronizationRule>());
230
		}
231
		
232
		// look for cycles
233
		for (TokenVariable var : rule.getTokenVariables()) 
234
		{
235
			// get value 
236
			ComponentValue v = var.getValue();
237
			// check if this value is trigger of other synchronizations
238
			if (rules.containsKey(v.getComponent()) && rules.get(v.getComponent()).containsKey(v)) {
239
				// get synchronizations
240
				List<SynchronizationRule> existingRules = rules.get(v.getComponent()).get(v);
241
				for (SynchronizationRule existingRule : existingRules) {
242
					// get rule trigger
243
					TokenVariable existingRuleTrigger = existingRule.getTriggerer();
244
					// check constraint
245
					for (SynchronizationConstraint cons : existingRule.getConstraints()) {
246
						// consider temporal constraint for cycle detection
247
						if (cons.getCategory().equals(ConstraintCategory.TEMPORAL_CONSTRAINT)) {
248
							// get constraint target
249
							TokenVariable target = cons.getTarget();
250
							if (!target.equals(existingRuleTrigger) && target.getValue().equals(value)) { 
251
								// we've got a cycle
252
								warning("A cycle has been detected after the introduction of synchronization rule\n" + rule + "\n");
253
								// check recursive rules flag
254
								if (!this.allowRecursiveRules) {
255
									// stop parsing on detected cycle
256
									throw new SynchronizationCycleException("A cycle has been detected after the introduction of synchronization rule " + rule);
257
								}
258
							}
259
						}
260
					}
261
				}
262
			}
263
		}
264
		
265
		// add rule if no cycle is detected
266
		rules.get(value.getComponent()).get(value).add(rule);
267
	}
268
	
269
	/**
270
	 * 
271
	 * @param value
272
	 * @return
273
	 */
274
	@Override
275
	public synchronized SynchronizationRule createSynchronizationRule(ComponentValue value, String[] labels) 
276
			throws DomainComponentNotFoundException 
277
	{
278
		// check if related component exists
279
		if (!this.getComponents().contains(value.getComponent())) {
280
			throw new DomainComponentNotFoundException("Value's component not found " + value);
281
		}
282
		
283
		// set value as complex
284
		value.setComplex();
285
		// create synchronization rule
286
		return new SynchronizationRule(value, labels);
287
	}
288
	
289
	/**
290
	 * 
291
	 */
292
	@Override
293
	public synchronized SolutionPlan getSolutionPlan() 
294
	{
295
		// create a plan
296
		SolutionPlan plan = new SolutionPlan(this.name, this.getHorizon());
297
		// set components
298
		for (DomainComponent component : this.components.values()) {
299
			// add a component to the plan
300
			plan.add(component);
301
		}
302
		
303
		// add active relations
304
		for (Relation rel : this.getActiveRelations()) {
305
			// add relation
306
			plan.add(rel);
307
		}
308
		
309
		// computer parameter solutions
310
		ComputeSolutionParameterQuery query = this.pdb.
311
				createQuery(ParameterQueryType.COMPUTE_SOLUTION);
312
		
313
		// process query
314
		this.pdb.process(query);
315
		// get current plan
316
		return plan;
317
	}
318
	
319
	/**
320
	 * Compute the duration of a plan as the minimum and maximal average duration of the activities
321
	 * of its components 
322
	 */
323 View Code Duplication
	@Override
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
324
	public synchronized double[] getMakespan() 
325
	{
326
		// set the initial minimal and maximal values
327
		double[] makespan = new double[] {
328
				0,
329
				0
330
			};
331
		
332
		
333
		// get the list of primitive components
334
		Set<DomainComponent> primset = new HashSet<>();
335
		// compute "local" makespan for each component
336
		for (DomainComponent comp : this.components.values()) 
337
		{
338
			// check type 
339
			if (comp.getType().equals(DomainComponentType.SV_PRIMITIVE)) 
340
			{
341
				// get local makespan
342
				double[] local = comp.getMakespan();
343
				// update "global" minimum makespan
344
				makespan[0] += local[0];
345
				// update "global" maximum makespan
346
				makespan[1] += local[1];
347
				// add component to primset
348
				primset.add(comp);
349
			}
350
		}
351
		
352
		// compute average values
353
		makespan[0] = makespan[0] / primset.size();
354
		makespan[1] = makespan[1] / primset.size();
355
		// get the makespan
356
		return makespan;
357
	}
358
	
359
	/**
360
	 * 
361
	 */
362 View Code Duplication
	@Override
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
363
	public synchronized double[] getBehaviorDuration() 
364
	{
365
		// set the initial minimal and maximal values
366
		double[] duration = new double[] {
367
				0,
368
				0
369
			};
370
		
371
		
372
		// get the list of primitive components
373
		Set<DomainComponent> primset = new HashSet<>();
374
		// compute "local" makespan for each component
375
		for (DomainComponent comp : this.components.values()) 
376
		{
377
			// check type 
378
			if (comp.getType().equals(DomainComponentType.SV_PRIMITIVE)) 
379
			{
380
				// get local makespan
381
				double[] local = comp.getBehaviorDuration();
382
				// update "global" minimum makespan
383
				duration[0] += local[0];
384
				// update "global" maximum makespan
385
				duration[1] += local[1];
386
				// add component to primset
387
				primset.add(comp);
388
			}
389
		}
390
		
391
		// compute average values
392
		duration[0] = duration[0] / primset.size();
393
		duration[1] = duration[1] / primset.size();
394
		// get the duration
395
		return duration;
396
	}
397
	
398
	/**
399
	 * 
400
	 * @param decision
401
	 * @return
402
	 */
403
	private DecisionVariable prepareDecisionVariable(Decision decision) 
404
	{
405
		// get predicate
406
		Predicate predicate = decision.getToken().getPredicate();
407
		// prepare ground predicate
408
		String groundPredicate = predicate.getValue().getLabel();
409
		// check parameters
410
		for (Parameter<?> param : predicate.getParameters()) 
411
		{
412
			// query the plan database to retrieve values
413
			CheckValuesParameterQuery query = this.pdb.createQuery(ParameterQueryType.CHECK_PARAMETER_VALUES);
414
			query.setParameter(param);
415
			this.pdb.process(query);
416
			
417
			String val = "";
418
			// check parameter type
419 View Code Duplication
			switch (param.getType()) 
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
420
			{
421
				case ENUMERATION_PARAMETER_TYPE : 
422
				{
423
					EnumerationParameter ep = (EnumerationParameter) param;
424
					// check bounded values
425
					for (int index = 0; index < ep.getValues().length; index++) {
426
						if (index > 0) {
427
							val += "_";
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...
428
						}
429
						
430
						val += ep.getValues()[index];
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...
431
					}
432
				}
433
				break;
434
				
435
				case NUMERIC_PARAMETER_TYPE : 
436
				{
437
					NumericParameter np = (NumericParameter) param;
438
					val += np.getLowerBound() + "_" + np.getUpperBound();
439
				}
440
				break;
441
			}
442
			
443
			// update grounded predicate
444
			groundPredicate += "-" + val;
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...
445
		}
446
		
447
		IntervalScheduleQuery query = this.tdb.createTemporalQuery(TemporalQueryType.INTERVAL_SCHEDULE);
448
		query.setInterval(decision.getToken().getInterval());
449
		this.tdb.process(query);
450
		TemporalInterval i = query.getInterval();
451
		
452
		// add decision variable to plan description
453
		return new DecisionVariable(
454
				decision.getId(), 
455
				decision.getComponent().getName(), 
456
				groundPredicate, 
457
				new long[] {i.getStartTime().getLowerBound(), i.getStartTime().getUpperBound()}, 
458
				new long[] {i.getEndTime().getLowerBound(), i.getEndTime().getUpperBound()}, 
459
				new long[] {i.getDurationLowerBound(), i.getDurationUpperBound()});
460
	}
461
	
462
	/**
463
	 * 
464
	 * @return
465
	 */
466
	@Override
467
	public synchronized Plan getPlan() 
468
	{
469
		// initialize the plan
470
		Plan plan = new Plan();
471
		// set decisions
472
		for (Decision decision : this.getActiveDecisions())  
473
		{
474
			// add decision variable to plan description
475
			plan.add(decision.getComponent(), this.prepareDecisionVariable(decision));
476
//			plan.add(goal);
477
		}
478
		
479
		// set relations
480
		for (Relation rel : this.getActiveRelations()) {
481
			plan.add(rel);
482
		}
483
		
484
		// get the plan
485
		return plan;
486
	}
487
488
	
489
	/**
490
	 * 
491
	 */
492
//	@Override
493
//	public synchronized Plan getPlan(PlanElementStatus status) 
494
//	{
495
//		// prepare the plan
496
//		Plan plan = new Plan();
497
//		// check desired level
498
//		switch (status) 
499
//		{
500
//			// get the plan
501
//			case ACTIVE : {
502
//				// get currently active plan
503
//				plan = this.getPlan();
504
//			}
505
//			break;
506
//			
507
//			// get the pending plan
508
//			case PENDING : {
509
//				// get pending decisions
510
//				for (Decision decision : this.getPendingDecisions()) {
511
//					plan.add(decision);
512
//				}
513
//				// get pending relations
514
//				for (Relation rel : this.getPendingRelations()) {
515
//					plan.add(rel);
516
//				}
517
//			}
518
//			break;
519
//			
520
//			// get silent plan
521
//			case SILENT : {
522
//				// get silent decisions
523
//				for (Decision decision : this.getSilentDecisions()) {
524
//					plan.add(decision);
525
//				}
526
//				// get silent relations
527
//				for (Relation rel : this.getSilentRelations()) {
528
//					plan.add(rel);
529
//				}
530
//			}
531
//			break;
532
//		}
533
//		
534
//		return plan;
535
//	}
536
	
537
	/**
538
	 * 
539
	 */
540
	@Override
541
	public synchronized List<DomainComponent> getComponents() {
542
		return new ArrayList<>(this.components.values());
543
	}
544
	
545
	/**
546
	 * 
547
	 */
548
	@Override
549
	public synchronized DomainComponent getComponentByName(String name) {
550
		if (!this.components.containsKey(name)) {
551
			throw new RuntimeException("Component with name " + name + " does not exist");
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
552
		}
553
		// get component
554
		return this.components.get(name);
555
	}
556
	
557
	/**
558
	 * Verify the temporal consistency of the plan.
559
	 * 
560
	 * If the underlying network is an STNU, then the 
561
	 * procedure checks also the pseudo-controllability
562
	 * of the plan. If the network is not pseudo-controllable
563
	 * the exception reports information concerning the values
564
	 * that have been "squeezed" during the solving process 
565
	 * 
566
	 * @throws ConsistencyCheckException
567
	 */
568
	@Override
569
	public synchronized void verify() 
570
			throws ConsistencyCheckException 
571
	{
572
		// check temporal consistency of the network
573
		this.tdb.verify();
574
		// check parameter consistency
575
		this.pdb.verify();
576
	}
577
578
	/**
579
	 * The method returns the list of all available domain values
580
	 */
581
	@Override
582
	public synchronized List<ComponentValue> getValues() {
583
		List<ComponentValue> values = new ArrayList<>();
584
		for (DomainComponent component : this.components.values()) {
585
			values.addAll(component.getValues());
586
		}
587
		// get all domain values
588
		return values;
589
	}
590
	
591
	/**
592
	 * 
593
	 */
594
	@Override
595
	public synchronized ComponentValue getValueByName(String name) {
596
		ComponentValue value = null;
597
		for (DomainComponent comp : this.components.values()) {
598
			for (ComponentValue v : comp.getValues()) {
599
				if (v.getLabel().equals(name)) {
600
					value = v;
601
					break;
602
				}
603
			}
604
			
605
			if (value != null) {
606
				break;
607
			}
608
		}
609
		
610
		// check if value has been found
611
		if (value == null) {
612
			throw new RuntimeException("Value " + name + " not found");
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
613
		}
614
		
615
		// get value
616
		return value;
617
	}
618
	
619
	/**
620
	 * 
621
	 * @param name
622
	 * @param type
623
	 */
624
	@Override
625
	public synchronized <T extends ParameterDomain> T createParameterDomain(String name, ParameterDomainType type) {
626
		// create parameter domain
627
		T pd = this.pdb.createParameterDomain(name, type);
628
		// add parameter domain
629
		this.parameterDomains.put(name, pd);
630
		return pd;
631
	}
632
	
633
	/**
634
	 * 
635
	 * @return
636
	 */
637
	@Override
638
	public synchronized List<ParameterDomain> getParameterDoamins() {
639
		return new ArrayList<>(this.parameterDomains.values());
640
	}
641
	
642
	/**
643
	 * 
644
	 * @param name
645
	 * @return
646
	 */
647
	@Override
648
	public synchronized ParameterDomain getParameterDomainByName(String name) {
649
		return this.parameterDomains.get(name);
650
	}
651
	
652
	/**
653
	 * 
654
	 * @param name
655
	 * @return
656
	 */
657
	@Override
658
	public synchronized <T extends DomainComponent> T createDomainComponent(String name, DomainComponentType type) 
659
	{
660
		// check if a component already exist
661
		if (this.components.containsKey(name)) {
662
			throw new RuntimeException("A component with name " + name + " already exists");
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
663
		}
664
	
665
		// create domain component
666
		T c = DomainComponentBuilder.createAndSet(name, type, this.tdb, this.pdb);
667
		// get created component
668
		return c;
669
	}
670
	
671
	/**
672
	 * 
673
	 * @param component
674
	 */
675
	@Override
676
	public synchronized void addDomainComponent(DomainComponent component) {
677
		// add component
678
		this.components.put(component.getName(), component);
679
	}
680
	
681
	/**
682
	 * 
683
	 * @return
684
	 */
685
	@Override
686
	public synchronized List<Decision> getActiveDecisions() {
687
		// list of active decisions with schedule information
688
		List<Decision> list = new ArrayList<>();
689
		// get schedule information from components
690
		for (DomainComponent comp : this.components.values()) {
691
			list.addAll(comp.getActiveDecisions());
692
		}
693
		// get list
694
		return list;
695
	}
696
	
697
	/**
698
	 * 
699
	 * @return
700
	 */
701
	@Override
702
	public synchronized List<Decision> getPendingDecisions() {
703
		// list of pending decisions
704
		List<Decision> list = new ArrayList<>();
705
		for (DomainComponent comp : this.components.values()) {
706
			list.addAll(comp.getPendingDecisions());
707
		}
708
		// get list of pending decisions
709
		return list;
710
	}
711
	
712
	/**
713
	 * 
714
	 */
715
	@Override
716
	public synchronized Set<Relation> getPendingRelations(Decision dec) 
717
	{
718
		// get decision component 
719
		DomainComponent comp = dec.getComponent();
720
		return comp.getPendingRelations(dec);
721
	}
722
	
723
	/**
724
	 * 
725
	 */
726
	@Override 
727
	public synchronized void restore(Decision dec) {
728
		// dispatch request to the related component
729
		dec.getComponent().restore(dec);
730
	}
731
	
732
	/**
733
	 * 
734
	 */
735
	@Override
736
	public synchronized void restore(Relation rel) {
737
		// get reference component
738
		DomainComponent comp = rel.getReference().getComponent();
739
		comp.restore(rel);
740
	}
741
	
742
	/**
743
	 * 
744
	 */
745
	@Override
746
	public synchronized Decision create(ComponentValue value, String[] labels) {
747
		// get the component the value belongs to
748
		DomainComponent comp = value.getComponent();
749
		// create decision
750
		Decision dec = comp.create(value, labels);
751
		// get created decision
752
		return dec;
753
	}
754
	
755
	/**
756
	 * 
757
	 */
758
	@Override
759
	public synchronized Decision create(ComponentValue value, String[] labels, long[] duration) {
760
		// get the component the value belongs to
761
		DomainComponent comp = value.getComponent();
762
		// create decision
763
		Decision dec = comp.create(value, labels, duration);
764
		// get created decision
765
		return dec;
766
	}
767
	
768
	/**
769
	 * 
770
	 */
771
	@Override
772
	public synchronized Decision create(ComponentValue value, String[] labels, long[] end, long[] duration) {
773
		// get the component the value belongs to
774
		DomainComponent comp = value.getComponent();
775
		// create decision
776
		Decision dec = comp.create(value, labels, end, duration);
777
		// get created decision
778
		return dec;
779
	}
780
	
781
	/**
782
	 * 
783
	 */
784
	@Override
785
	public synchronized Decision create(ComponentValue value, String[] labels, long[] start, long[] end, long[] duration) {
786
		// get the component the value belongs to
787
		DomainComponent comp = value.getComponent();
788
		// create decision
789
		Decision dec = comp.create(value, labels, start, end, duration);
790
		// get created decision
791
		return dec;
792
	}
793
	
794
	/**
795
	 * 
796
	 */
797
	@Override
798
	public synchronized Set<Relation> activate(Decision dec) 
799
			throws DecisionPropagationException 
800
	{
801
		// get the component the decision belongs to
802
		DomainComponent c = dec.getComponent();
803
		// add decision and get the list of local and global relations propagated
804
		Set<Relation> set = c.activate(dec);
805
		// get global and local relations propagated
806
		return set;
807
	}
808
	
809
	/**
810
	 * 
811
	 */
812
	@Override
813
	public synchronized Set<Relation> getRelations(Decision dec) 
814
	{
815
		// list of relations concerning the decision
816
		Set<Relation> set = new HashSet<>();
817
		// get decision component
818
		DomainComponent comp = dec.getComponent();
819
		set.addAll(comp.getRelations(dec));
820
		// get the set
821
		return set;
822
	}
823
	
824
	/**
825
	 * Get the set of both active and pending local and global relations on components
826
	 */
827
	@Override
828
	public synchronized Set<Relation> getRelations() {
829
		// list of relations
830
		Set<Relation> set = new HashSet<>();
831
		for (DomainComponent comp : this.components.values()) {
832
			set.addAll(comp.getRelations());
833
		}
834
		
835
		// add global relations
836
		synchronized (globalRelations) {
837
			for (Relation rel : globalRelations) {
838
				set.add(rel);
839
			}
840
		}
841
		
842
		// get the set
843
		return set;
844
	}
845
	
846
	/**
847
	 * Get the set of local active relations and local active relations on components 
848
	 *  
849
	 * @param dec
850
	 * @return
851
	 */
852
	@Override
853
	public synchronized Set<Relation> getActiveRelations()
854
	{
855
		// list of active relations
856
		Set<Relation> set = new HashSet<>();
857
		// check local relations
858
		for (DomainComponent component : this.components.values()) {
859
			// add active local relations
860
			set.addAll(component.getActiveRelations());
861
		}
862
		
863
		// add global active relations
864
		synchronized (globalRelations) {
865
			for (Relation rel : globalRelations) {
866
				if (rel.isActive()) {
867
					set.add(rel);
868
				}
869
			}
870
		}
871
		// get the list
872
		return set;
873
	}
874
	
875
	/**
876
	 * Get the set of pending global relations and pending local relations on components
877
	 * 
878
	 * @return
879
	 */
880
	public synchronized Set<Relation> getPendingRelations()
881
	{
882
		// set of relations
883
		Set<Relation> set = new HashSet<>();
884
		for (DomainComponent comp : this.components.values()) {
885
			set.addAll(comp.getPendingRelations());
886
		}
887
		
888
		// add pending global relations
889
		synchronized (globalRelations) {
890
			for (Relation rel : globalRelations) {
891
				if (rel.isPending()) {
892
					set.add(rel);
893
				}
894
			}
895
		}
896
		// get the set
897
		return set;
898
	}
899
	
900
	/**
901
	 * 
902
	 */
903
	@Override
904
	public synchronized Set<Relation> getActiveRelations(Decision dec) 
905
	{
906
		// list of active relations
907
		Set<Relation> set = new HashSet<>();
908
		// get decision component
909
		DomainComponent comp = dec.getComponent();
910
		set.addAll(comp.getActiveRelations(dec));
911
		// get the set
912
		return set;
913
	}
914
	
915
	/**
916
	 * 
917
	 */
918
	@Override
919
	public synchronized Set<Relation> getToActivateRelations(Decision dec) 
920
	{
921
		// list of relations
922
		Set<Relation> set = new HashSet<>();
923
		// get decision component
924
		DomainComponent comp = dec.getComponent();
925
		set.addAll(comp.getToActivateRelations(dec));
926
		// get the set
927
		return set;
928
	}
929
	
930
	/**
931
	 * 
932
	 * @param dec
933
	 * @throws Exception
934
	 */
935
	@Override
936
	public synchronized void free(Decision dec) 
937
	{
938
		// get decision component
939
		DomainComponent comp = dec.getComponent();
940
		comp.free(dec);
941
	}
942
	
943
	/**
944
	 * 
945
	 */
946
	@Override
947
	public synchronized Set<Relation> deactivate(Decision dec) {
948
		// get decision component
949
		DomainComponent comp = dec.getComponent();
950
		return new HashSet<>(comp.deactivate(dec));
951
	}
952
	
953
	/**
954
	 * 
955
	 * @param relation
956
	 */
957
	@Override
958
	public synchronized void delete(Relation relation) 
959
	{
960
		// get reference component
961
		DomainComponent refComp = relation.getReference().getComponent();
962
		refComp.delete(relation);
963
	}
964
	
965
	/**
966
	 * Only for debugging
967
	 */
968
	@Override
969
	public synchronized List<Decision> getSilentDecisions() {
970
		List<Decision> list = new ArrayList<>();
971
		for (DomainComponent component : this.components.values()) {
972
			list.addAll(component.getSilentDecisions());
973
		}
974
		return list;
975
	}
976
	
977
	/**
978
	 * Only for debugging
979
	 */
980
	@Override
981
	public synchronized Set<Relation> getSilentRelations() {
982
		// set of relations
983
		Set<Relation> set = new HashSet<>();
984
		for (DomainComponent component : this.components.values()) {
985
			set.addAll(component.getSilentRelations());
986
		}
987
		
988
		// check global relations
989
		synchronized (globalRelations) {
990
			for (Relation rel : globalRelations) {
991
				if (rel.isSilent()) {
992
					set.add(rel);
993
				}
994
			}
995
		}
996
		// get the set
997
		return set;
998
	}
999
	
1000
	/**
1001
	 * 
1002
	 */
1003
	@Override
1004
	public synchronized boolean isActive(Decision dec) {
1005
		return dec.getComponent().isActive(dec);
1006
	}
1007
	
1008
	/**
1009
	 * 
1010
	 */
1011
	@Override
1012
	public synchronized boolean isPending(Decision dec) {
1013
		// forward to component
1014
		return dec.getComponent().isPending(dec);
1015
	}
1016
	
1017
	/**
1018
	 * 
1019
	 */
1020
	@Override
1021
	public synchronized boolean isSilent(Decision dec) {
1022
		// forward to component
1023
		return dec.getComponent().isSilent(dec);
1024
	}
1025
	
1026
	/**
1027
	 * 
1028
	 */
1029
	@Override
1030
	public synchronized boolean activate(Relation rel) 
1031
			throws RelationPropagationException  {
1032
		
1033
		// get reference component
1034
		DomainComponent refComp = rel.getReference().getComponent();
1035
		return refComp.activate(rel);
1036
	}
1037
	
1038
	/**
1039
	 * 
1040
	 */
1041
	@Override
1042
	public synchronized void deactivate(Relation rel) 
1043
	{
1044
		// get reference component
1045
		DomainComponent refComp = rel.getReference().getComponent();
1046
		refComp.deactivate(rel);
1047
	}
1048
	
1049
	/**
1050
	 * 
1051
	 */
1052
	@Override
1053
	public synchronized List<Flaw> checkFlaws() {
1054
		// list of flaws to solve
1055
		List<Flaw> list = new ArrayList<>();
1056
		// simply query the components
1057
		for (DomainComponent comp : this.components.values()) {
1058
			// query each COMPOSITE component for flaws
1059
			List<Flaw> flaws = comp.checkFlaws();
1060
			list.addAll(flaws);
1061
		}
1062
		// get the list of detected flaws in the domain
1063
		return list;
1064
	}
1065
	
1066
	/**
1067
	 * 
1068
	 */
1069
	@Override
1070
	public synchronized List<Flaw> checkFlaws(FlawType[] types) {
1071
		// list of flaws to solve
1072
		List<Flaw> list = new ArrayList<>();
1073
		// simply query the components
1074
		for (DomainComponent comp : this.components.values()) {
1075
			// query each COMPOSITE component for flaws
1076
			List<Flaw> flaws = comp.checkFlaws(types);
1077
			list.addAll(flaws);
1078
		}
1079
		// get the list of detected flaws in the domain
1080
		return list;
1081
	}
1082
	
1083
	/**
1084
	 * 
1085
	 * @return
1086
	 */
1087
	@Override
1088
	public synchronized List<Flaw> detectFlaws() 
1089
			throws UnsolvableFlawException 
1090
	{
1091
		// list of flaws to solve
1092
		List<Flaw> list = new ArrayList<>();
1093
		// simply query the components
1094
		for (DomainComponent comp : this.components.values()) {
1095
			// query each COMPOSITE component for flaws
1096
			List<Flaw> flaws = comp.detectFlaws();
1097
			list.addAll(flaws);
1098
		}
1099
		// get the list of detected flaws in the domain
1100
		return list;
1101
	}
1102
	
1103
	/**
1104
	 * 
1105
	 * @param type
1106
	 * @return
1107
	 * @throws UnsolvableFlawException
1108
	 */
1109
	@Override
1110
	public synchronized List<Flaw> detectFlaws(FlawType type) 
1111
			throws UnsolvableFlawException {
1112
		
1113
		// list of flaws to solve
1114
		List<Flaw> list = new ArrayList<>();
1115
		// simply query the components
1116
		for (DomainComponent comp : this.components.values()) {
1117
			// get the list of flaws
1118
			List<Flaw> flaws = comp.detectFlaws(type);
1119
			list.addAll(flaws);
1120
		}
1121
		
1122
		// get the list of detected flaws
1123
		return list;
1124
	}
1125
	
1126
	/**
1127
	 * 
1128
	 */
1129
	@Override
1130
	public synchronized void rollback(FlawSolution solution) 
1131
	{ 
1132
		// get component
1133
		DomainComponent comp = solution.getFlaw().getComponent();
1134
		comp.rollback(solution);
1135
	}
1136
	
1137
	/**
1138
	 * Solve a flaw by applying the selected solution. 
1139
	 * 
1140
	 * Commit the effect of a flaw solution to the underlying component
1141
	 * 
1142
	 * @param flaw
1143
	 * @param sol
1144
	 * @throws Exception
1145
	 */
1146
	@Override
1147
	public synchronized void commit(FlawSolution solution) 
1148
			throws FlawSolutionApplicationException 
1149
	{
1150
		// get component
1151
		DomainComponent comp = solution.getFlaw().getComponent();
1152
		comp.commit(solution);
1153
	}
1154
	
1155
	/**
1156
	 * 
1157
	 * @param solution
1158
	 * @throws Exception
1159
	 */
1160
	@Override
1161
	public synchronized void restore(FlawSolution solution) 
1162
			throws Exception
1163
	{
1164
		// get component
1165
		DomainComponent comp = solution.getFlaw().getComponent();
1166
		comp.restore(solution);
1167
	}
1168
	
1169
	/**
1170
	 * 
1171
	 */
1172
	@Override
1173
	public synchronized void propagate(Operator operator) 
1174
			throws OperatorPropagationException 
1175
	{
1176
		// check if operator has been applied already
1177
		if (!operator.isApplied()) {
1178
			
1179
			try {
1180
				
1181
				// commit solution 
1182
				this.commit(operator.getFlawSolution());
1183
				// set applied
1184
				operator.setApplied();
1185
			}
1186
			catch (FlawSolutionApplicationException ex) {
1187
				// throw exception
1188
				throw new OperatorPropagationException("Error while propagating operator:\n"
1189
						+ "- Operator: " + operator + "\n");
1190
			}
1191
		}
1192
		else {
1193
			
1194
			try {
1195
				
1196
				// simply restore flaw solution by leveraging "SILENT" plan
1197
				this.restore(operator.getFlawSolution());
1198
			} 
1199
			catch (Exception ex) {
1200
				
1201
				// error while resetting operator
1202
				throw new OperatorPropagationException("Error while restoring operator status:\n"
1203
						+ "- Operator: " + operator + "\n");
1204
			}
1205
		}
1206
	}
1207
	
1208
	/**
1209
	 * 
1210
	 */
1211
	@Override
1212
	public synchronized void retract(Operator operator) 
1213
	{
1214
		// get flaw solution
1215
		FlawSolution solution = operator.getFlawSolution();
1216
		// retract flaw solution
1217
		this.rollback(solution);
1218
	}
1219
	
1220
	/**
1221
	 * 
1222
	 */
1223
	@Override
1224
	public String toString() {
1225
		return "{ \"components\": " + this.components.values() +" }";
1226
	}
1227
	
1228
	/**
1229
	 * 
1230
	 */
1231
	@Override
1232
	public <T extends Relation> T create(RelationType type, Decision reference, Decision target) {
1233
		// get reference component
1234
		DomainComponent refComp = reference.getComponent();
1235
		// create relation
1236
		return refComp.create(type, reference, target);
1237
	}
1238
	
1239
	/**
1240
	 * 
1241
	 * @param problem
1242
	 * @throws ProblemInitializationException
1243
	 */
1244
	private void doSetupProblem(Problem problem) 
1245
			throws ProblemInitializationException
1246
	{
1247
		// check if a problem has been already set up
1248
		if (this.problem == null) 
1249
		{
1250
			// list of committed decisions
1251
			List<Decision> committedDecisions = new ArrayList<>();
1252
			// list of committed relations
1253
			List<Relation> committedRelations = new ArrayList<>();
1254
			// index fluent to added decisions
1255
			Map<ProblemFluent, Decision> fluent2decisions = new HashMap<>();
1256
			
1257
			try 
1258
			{
1259
				// get facts 
1260
				for (ProblemFact fact : problem.getFacts()) {
1261
					// create decision
1262
					Decision dec = this.create(
1263
							fact.getValue(), 
1264
							fact.getParameterLabels(), 
1265
							fact.getStart(), 
1266
							fact.getEnd(), 
1267
							fact.getDuration());
1268
					
1269
					// add decision
1270
					this.activate(dec);
1271
					// add committed decision
1272
					committedDecisions.add(dec);
1273
					// add entry
1274
					fluent2decisions.put(fact, dec);
1275
				}
1276
			}
1277
			catch (Exception ex) {
1278
				// roll-back committed decisions
1279
				for (Decision dec : committedDecisions) {
1280
					try {
1281
						// retract decision
1282
						this.free(dec);
1283
					} catch (Exception exx) {
1284
						throw new RuntimeException(exx.getMessage());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1285
					}
1286
				}
1287
				// throw exception
1288
				throw new ProblemInitializationException(ex.getMessage());
1289
			}
1290
			
1291
			// create goals
1292
			for (ProblemGoal goal : problem.getGoals()) {
1293
				// create related decisions
1294
				Decision dec = this.create(
1295
						goal.getValue(), 
1296
						goal.getParameterLabels(), 
1297
						goal.getStart(), 
1298
						goal.getEnd(), 
1299
						goal.getDuration());
1300
				
1301
				// set mandatory expansion
1302
				dec.setMandatoryExpansion();
1303
				// add entry
1304
				fluent2decisions.put(goal, dec);
1305
			}
1306
			
1307
			try 
1308
			{
1309
				// check constraints
1310
				for (ProblemConstraint constraint : problem.getConstraints()) 
1311
				{
1312
					// get related decisions
1313
					Decision reference = fluent2decisions.get(constraint.getReference());
1314
					Decision target = fluent2decisions.get(constraint.getTarget());
1315
					
1316
					// check relation type
1317
					switch (constraint.getCategory()) 
1318
					{
1319
						// temporal constraint
1320
						case TEMPORAL_CONSTRAINT : 
1321
						{
1322
							// get temporal constraint
1323
							TemporalProblemConstraint tc = (TemporalProblemConstraint) constraint;
1324
							// create relation
1325
							TemporalRelation rel = this.create(constraint.getType(), reference, target);
1326
							rel.setBounds(tc.getBounds());
1327
							// check if relation can be activated
1328
							if (this.activate(rel)) {
1329
								committedRelations.add(rel);
1330
							}
1331
						}
1332
						break;
1333
						
1334
						// parameter constraint
1335
						case PARAMETER_CONSTRAINT : 
1336
						{
1337
							// get parameter constraint
1338
							ParameterProblemConstraint pc = (ParameterProblemConstraint) constraint;
1339
							// create relation
1340
							ParameterRelation rel = this.create(constraint.getType(), reference, target);
1341
							// set labels
1342
							rel.setReferenceParameterLabel(pc.getReferenceParameterLabel());
1343
							
1344
							// check relation type
1345
							switch (rel.getType())
1346
							{
1347
								// bind parameter relation
1348
								case BIND_PARAMETER :
1349
								{
1350
									// get relation
1351
									BindParameterRelation bind = (BindParameterRelation) rel;
1352
									// set the binding value
1353
									bind.setValue(pc.getTargetParameterLabel());
1354
								}
1355
								break;
1356
								
1357
								// equal parameter relation
1358
								case EQUAL_PARAMETER :  
1359
								{
1360
									// get relation
1361
									EqualParameterRelation eq = (EqualParameterRelation) rel;
1362
									// set target label
1363
									eq.setTargetParameterLabel(pc.getTargetParameterLabel());
1364
								}
1365
								break; 
1366
								
1367
								// not equal parameter relation
1368
								case NOT_EQUAL_PARAMETER : 
1369
								{
1370
									// get relation
1371
									NotEqualParameterRelation neq = (NotEqualParameterRelation) rel;
1372
									// set also the target label
1373
									neq.setTargetParameterLabel(pc.getTargetParameterLabel());
1374
								}
1375
								break;
1376
								
1377
								default : {
1378
									throw new RuntimeException("Unknown parameter relation type - " + rel.getType());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1379
								}
1380
							}
1381
							
1382
							// check if relation can be activated
1383
							if (this.activate(rel)) {
1384
								committedRelations.add(rel);
1385
							}
1386
						}
1387
						break;
1388
					}
1389
				}
1390
			}
1391
			catch (RelationPropagationException ex) {
1392
				// roll-back committed relations
1393
				for (Relation rel : committedRelations) {
1394
					// retract 
1395
					this.deactivate(rel);
1396
				}
1397
				
1398
				// throw exception
1399
				throw new ProblemInitializationException(ex.getMessage());
1400
			}
1401
			
1402
			try {
1403
				
1404
				// check unsolvable flaws
1405
				this.detectFlaws();
1406
			} 
1407
			catch (UnsolvableFlawException ex) {
1408
				// unsolvable flaws found
1409
				throw new ProblemInitializationException("Inconsistent Problem description\n- Unsolvable flaws have been found\n" + ex.getMessage());
1410
			}
1411
			
1412
			// set problem 
1413
			this.problem = problem;
1414
		}
1415
		else {
1416
			// a problem already exists
1417
			throw new ProblemInitializationException("A problem instace has been already set up... try clear() before setting up a new problem instance");
1418
		}
1419
	}
1420
}
1421