it.cnr.istc.pst.platinum.ai.framework.microkernel.resolver.plan.TimelineAwarePlanRefinementResolver   F
last analyzed

Complexity

Total Complexity 158

Size/Duplication

Total Lines 1763
Duplicated Lines 76.97 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 745
c 1
b 0
f 0
dl 1357
loc 1763
rs 1.855
wmc 158

16 Methods

Rating   Name   Duplication   Size   Complexity  
F doApplyExpansion(GoalExpansion) 185 271 23
A doComputeUnificationSolutions(Goal) 35 35 5
D isTemporalUnificationFeasible(Decision,Decision) 88 88 12
F doApplyUnification(GoalUnification) 292 292 27
F doComputeExpansionSolutions(Goal) 69 197 11
A load() 0 10 1
A doFindFlaws() 27 27 4
A doApply(FlawSolution) 0 22 3
C doRetractUnification(GoalUnification) 97 97 11
A expansions(Goal) 24 39 3
F doRestoreUnification(GoalUnification) 265 265 27
A TimelineAwarePlanRefinementResolver() 0 6 1
F isPredicateUnificationFeasible(Decision,Decision) 251 251 22
A doComputeFlawSolutions(Flaw) 24 24 4
A doRetract(FlawSolution) 0 13 2
A doRestore(FlawSolution) 0 14 2

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.microkernel.resolver.plan.TimelineAwarePlanRefinementResolver 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.microkernel.resolver.plan;
2
3
import java.util.ArrayList;
4
import java.util.Collections;
5
import java.util.HashMap;
6
import java.util.HashSet;
7
import java.util.List;
8
import java.util.Map;
9
import java.util.Set;
10
11
import it.cnr.istc.pst.platinum.ai.framework.domain.component.Decision;
12
import it.cnr.istc.pst.platinum.ai.framework.domain.component.DomainComponent;
13
import it.cnr.istc.pst.platinum.ai.framework.domain.component.ex.DecisionPropagationException;
14
import it.cnr.istc.pst.platinum.ai.framework.domain.component.ex.FlawSolutionApplicationException;
15
import it.cnr.istc.pst.platinum.ai.framework.domain.component.ex.RelationPropagationException;
16
import it.cnr.istc.pst.platinum.ai.framework.domain.component.pdb.ParameterSynchronizationConstraint;
17
import it.cnr.istc.pst.platinum.ai.framework.domain.component.pdb.SynchronizationConstraint;
18
import it.cnr.istc.pst.platinum.ai.framework.domain.component.pdb.SynchronizationRule;
19
import it.cnr.istc.pst.platinum.ai.framework.domain.component.pdb.TemporalSynchronizationConstraint;
20
import it.cnr.istc.pst.platinum.ai.framework.domain.component.pdb.TokenVariable;
21
import it.cnr.istc.pst.platinum.ai.framework.microkernel.ConstraintCategory;
22
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.ex.ConsistencyCheckException;
23
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.flaw.Flaw;
24
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.flaw.FlawSolution;
25
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.Relation;
26
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.RelationType;
27
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.parameter.BindParameterRelation;
28
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.parameter.EqualParameterRelation;
29
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.parameter.NotEqualParameterRelation;
30
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.parameter.ParameterRelation;
31
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.temporal.BeforeRelation;
32
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.temporal.TemporalRelation;
33
import it.cnr.istc.pst.platinum.ai.framework.microkernel.resolver.Resolver;
34
import it.cnr.istc.pst.platinum.ai.framework.microkernel.resolver.ResolverType;
35
import it.cnr.istc.pst.platinum.ai.framework.microkernel.resolver.ex.UnsolvableFlawException;
36
import it.cnr.istc.pst.platinum.ai.framework.microkernel.resolver.plan.GoalJustification.JustificationType;
37
import it.cnr.istc.pst.platinum.ai.framework.time.ex.TemporalConstraintPropagationException;
38
import it.cnr.istc.pst.platinum.ai.framework.time.lang.TemporalConstraintType;
39
import it.cnr.istc.pst.platinum.ai.framework.time.lang.allen.BeforeIntervalConstraint;
40
import it.cnr.istc.pst.platinum.ai.framework.utils.properties.FilePropertyReader;
41
42
/**
43
 * 
44
 * @author alessandro
45
 *
46
 */
47
public class TimelineAwarePlanRefinementResolver extends Resolver<DomainComponent> {
48
	
49
	private boolean load;
50
	private double expansionCost;
51
	private double unificationCost;
52
	
53
	/**
54
	 * 
55
	 */
56
	protected TimelineAwarePlanRefinementResolver() {
57
		super(ResolverType.TIMELINE_AWARE_PLAN_REFINEMENT.getLabel(),
58
				ResolverType.TIMELINE_AWARE_PLAN_REFINEMENT.getFlawTypes());
59
		
60
		// flag to load parameters when it is necessary
61
		this.load = false;
62
	}
63
	
64
	/**
65
	 * 
66
	 */
67
	private void load() {
68
		// get deliberative property file
69
		FilePropertyReader properties = new FilePropertyReader(
70
				FRAMEWORK_HOME + FilePropertyReader.DEFAULT_DELIBERATIVE_PROPERTY);
71
		
72
		// read weights
73
		this.expansionCost = Double.parseDouble(properties.getProperty("expansion-cost"));
74
		this.unificationCost = Double.parseDouble(properties.getProperty("unification-cost"));
75
		// set load flag
76
		this.load = true;
77
	}
78
	
79
	/**
80
	 * 
81
	 */
82 View Code Duplication
	@Override
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
83
	protected List<Flaw> doFindFlaws() {
84
		
85
		// check load parameters
86
		if (!this.load) {
87
			this.load();
88
		}
89
90
		// list of goals
91
		List<Flaw> flaws = new ArrayList<>();
92
		// check pending decisions
93
		for (Decision decision : this.component.getPendingDecisions()) {
94
			
95
			// add sub-goal
96
			Goal goal = new Goal(FLAW_COUNTER.getAndIncrement(), this.component, decision);
97
			// check if external component
98
			if (decision.getComponent().isExternal()) {
99
				// set mandatory unification
100
				goal.setMandatoryUnification();
101
			}
102
			
103
			// add goal to flaws
104
			flaws.add(goal);
105
		}
106
		
107
		// get flaws
108
		return flaws;
109
	}
110
	
111
	/**
112
	 * 
113
	 */
114 View Code Duplication
	@Override
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
115
	protected void doComputeFlawSolutions(Flaw flaw) 
116
			throws UnsolvableFlawException {
117
		
118
		// get goal
119
		Goal goal = (Goal) flaw;
120
		
121
		// check solving information
122
		if (!goal.isMandatoryExpansion()) {
123
			// compute unification solutions
124
			this.doComputeUnificationSolutions(goal);
125
		}
126
		
127
		// check solving information
128
		if (!goal.isMandatoryUnification()) {
129
			// compute expansion solutions
130
			this.doComputeExpansionSolutions(goal);
131
		}
132
		 
133
		// check if solvable
134
		if (!goal.isSolvable()) {
135
			// simply throw exception
136
			throw new UnsolvableFlawException("Unsolvable flaw found on component " + this.component.getName() + ":"
137
					+ "\n" + flaw + "\n");
138
		}
139
	}
140
	
141
	
142
	/**
143
	 * 
144
	 * @param solution
145
	 * @throws Exception
146
	 */
147
	@Override
148
	protected void doApply(FlawSolution solution) 
149
			throws FlawSolutionApplicationException 
150
	{
151
		// get goal justification
152
		GoalJustification just = (GoalJustification) solution;
153
		// check type 
154
		switch (just.getJustificationType()) 
155
		{
156
			// expansion step
157
			case EXPANSION : {
158
				// apply solution
159
				this.doApplyExpansion((GoalExpansion) just);
160
			}
161
			break;
162
			
163
			// unification step
164
			case UNIFICATION : {
165
				// apply solution
166
				this.doApplyUnification((GoalUnification) just);
167
			}
168
			break;
169
		}
170
	}
171
	
172
	/**
173
	 * 
174
	 */
175
	@Override
176
	protected void doRestore(FlawSolution solution) 
177
			throws DecisionPropagationException, RelationPropagationException 
178
	{
179
		// get goal justification
180
		GoalJustification just = (GoalJustification) solution;
181
		// check if unification 
182
		if (just.getJustificationType().equals(JustificationType.UNIFICATION)) {
183
			// restore unification
184
			this.doRestoreUnification((GoalUnification) just);
185
		}
186
		else {
187
			// "standard" way of restoring a flaw solution
188
			super.doRestore(solution);
189
		}
190
	}
191
	
192
	/**
193
	 * 
194
	 * @param solution
195
	 * @throws RelationPropagationException
196
	 */
197 View Code Duplication
	private void doRestoreUnification(GoalUnification solution) 
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
198
			throws RelationPropagationException {
199
		
200
		// restore relation translation
201
		for (Relation rel : solution.getTranslatedReferenceGoalRelations()) {
202
			
203
			// check relation category
204
			if (rel.getCategory().equals(ConstraintCategory.TEMPORAL_CONSTRAINT)) {
205
				// replace reference
206
				rel.setReference(solution.getUnificationDecision());
207
			}
208
			
209
			if (rel.getCategory().equals(ConstraintCategory.PARAMETER_CONSTRAINT)) {
210
				
211
				// check relation type
212
				switch (rel.getType()) {
213
				
214
					// bind parameter
215
					case BIND_PARAMETER: 
216
					{
217
						// the goal can be only the reference of the relation
218
						ParameterRelation pRel = (ParameterRelation) rel;
219
						
220
						// get relation reference parameter label
221
						String refParamLabel = pRel.getReferenceParameterLabel();
222
						// get label index
223
						int refParameterIndex = pRel.getReference().getParameterIndexByLabel(refParamLabel);
224
						// get unification decision parameter label
225
						String label = solution.getUnificationDecision().getParameterLabelByIndex(refParameterIndex);
226
227
						// update reference decision 
228
						pRel.setReference(solution.getUnificationDecision());
229
						// update reference label of the relation 
230
						pRel.setReferenceParameterLabel(label);
231
					}
232
					break;
233
					
234
					case EQUAL_PARAMETER : 
235
					{
236
						// get parameter relation
237
						EqualParameterRelation eqRel = (EqualParameterRelation) rel;
238
						// get relation reference parameter label
239
						String refParamLabel = eqRel.getReferenceParameterLabel();
240
						// get label index
241
						int refParameterIndex = eqRel.getReference().getParameterIndexByLabel(refParamLabel);
242
						// get unification decision parameter label
243
						String label = solution.getUnificationDecision().getParameterLabelByIndex(refParameterIndex);
244
245
						// update reference decision 
246
						eqRel.setReference(solution.getUnificationDecision());
247
						// update reference label of the relation 
248
						eqRel.setReferenceParameterLabel(label);
249
					}
250
					break;
251
					
252
					case NOT_EQUAL_PARAMETER : 
253
					{
254
						// get parameter relation
255
						NotEqualParameterRelation neqRel = (NotEqualParameterRelation) rel;
256
						// get relation reference parameter label
257
						String refParamLabel = neqRel.getReferenceParameterLabel();
258
						// get label index
259
						int refParameterIndex = neqRel.getReference().getParameterIndexByLabel(refParamLabel);
260
						// get unification decision parameter label
261
						String label = solution.getUnificationDecision().getParameterLabelByIndex(refParameterIndex);
262
263
						// update reference decision 
264
						neqRel.setReference(solution.getUnificationDecision());
265
						// update reference label of the relation 
266
						neqRel.setReferenceParameterLabel(label);
267
					}
268
					break;
269
					
270
					
271
					default:
272
						// unknown parameter relation
273
						throw new RuntimeException("Unknown Parameter relation type : " + rel.getType() + "\n");
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
274
				}
275
			}
276
		}
277
		
278
		
279
		// restore relation translation
280
		for (Relation rel : solution.getTranslatedTargetGoalRelations()) {
281
			
282
			// check relation category
283
			if (rel.getCategory().equals(ConstraintCategory.TEMPORAL_CONSTRAINT)) {
284
				// replace reference
285
				rel.setTarget(solution.getUnificationDecision());
286
			}
287
			
288
			if (rel.getCategory().equals(ConstraintCategory.PARAMETER_CONSTRAINT)) {
289
				
290
				// check relation type
291
				switch (rel.getType()) {
292
				
293
					case EQUAL_PARAMETER : 
294
					{
295
						// get parameter relation
296
						EqualParameterRelation eqRel = (EqualParameterRelation) rel;
297
						// get relation reference parameter label
298
						String refParamLabel = eqRel.getTargetParameterLabel();
299
						// get label index
300
						int refParameterIndex = eqRel.getTarget().getParameterIndexByLabel(refParamLabel);
301
						// get unification decision parameter label
302
						String label = solution.getUnificationDecision().getParameterLabelByIndex(refParameterIndex);
303
304
						// update reference decision 
305
						eqRel.setTarget(solution.getUnificationDecision());
306
						// update reference label of the relation 
307
						eqRel.setTargetParameterLabel(label);
308
					}
309
					break;
310
					
311
					case NOT_EQUAL_PARAMETER : 
312
					{
313
						// get parameter relation
314
						NotEqualParameterRelation neqRel = (NotEqualParameterRelation) rel;
315
						// get relation reference parameter label
316
						String refParamLabel = neqRel.getTargetParameterLabel();
317
						// get label index
318
						int refParameterIndex = neqRel.getTarget().getParameterIndexByLabel(refParamLabel);
319
						// get unification decision parameter label
320
						String label = solution.getUnificationDecision().getParameterLabelByIndex(refParameterIndex);
321
322
						// update reference decision 
323
						neqRel.setTarget(solution.getUnificationDecision());
324
						// update reference label of the relation 
325
						neqRel.setTargetParameterLabel(label);
326
					}
327
					break;
328
					
329
					
330
					default:
331
						// unknown parameter relation
332
						throw new RuntimeException("Unknown Parameter relation type : " + rel.getType() + "\n");
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
333
				}
334
			}
335
		}
336
337
		
338
		
339
		// list of committed parameter constraints
340
		Set<Relation> committed = new HashSet<>();
341
		try	
342
		{
343
			// get goal component
344
			DomainComponent gComp = solution.getGoalDecision().getComponent();
345
			// remove original goal: PENDING -> SILENT
346
			gComp.free(solution.getGoalDecision());
347
			
348
			// activate translated relations
349
			for (Relation rel : solution.getActivatedRelations()) 
350
			{
351
				// check if can be activated
352
				if (rel.getReference().getComponent().activate(rel)) {
353
					// add relation to the committed list
354
					committed.add(rel);
355
				}
356
			}
357
			
358
			// check consistency
359
			this.tdb.verify();
360
			this.pdb.verify();
361
			
362
		} catch (RelationPropagationException | ConsistencyCheckException ex) {
363
			
364
			// get goal component
365
			DomainComponent gComp = solution.getGoalDecision().getComponent();
366
			// restore goal: SILENT -> PENDING
367
			gComp.restore(solution.getGoalDecision());
368
			
369
			// deactivate committed relations
370
			for (Relation rel : committed) {
371
				// get reference component
372
				DomainComponent refComp = rel.getReference().getComponent();
373
				refComp.deactivate(rel);
374
			}
375
			
376
			// translated back relations
377
			for (Relation rel : solution.getTranslatedReferenceGoalRelations()) {
378
				// check category
379
				if (rel.getCategory().equals(ConstraintCategory.PARAMETER_CONSTRAINT)) {
380
					// get parameter relation
381
					ParameterRelation pRel = (ParameterRelation) rel;
382
					
383
					// get relation reference parameter label
384
					String refParamLabel = pRel.getReferenceParameterLabel();
385
					// get label index
386
					int pIndex = pRel.getReference().getParameterIndexByLabel(refParamLabel);
387
					// get goal decision parameter label
388
					String label = solution.getGoalDecision().getParameterLabelByIndex(pIndex);
389
					
390
					// update relation
391
					pRel.setReference(solution.getGoalDecision());
392
					pRel.setReferenceParameterLabel(label);
393
				}
394
				
395
				if (rel.getCategory().equals(ConstraintCategory.TEMPORAL_CONSTRAINT)) {
396
					// update relation
397
					rel.setReference(solution.getGoalDecision());
398
				}
399
			}
400
			
401
			
402
			// translated back parameter relations
403
			for (Relation rel : solution.getTranslatedTargetGoalRelations())
404
			{
405
				// check relation category 
406
				if (rel.getCategory().equals(ConstraintCategory.PARAMETER_CONSTRAINT))
407
				{
408
					// check relation
409
					switch (rel.getType())
410
					{
411
						case EQUAL_PARAMETER : 
412
						{
413
							// get equal relation
414
							EqualParameterRelation eqRel = (EqualParameterRelation) rel;
415
							// get relation reference parameter label
416
							String tarParamLabel = eqRel.getTargetParameterLabel();
417
							// get label index
418
							int pIndex = eqRel.getTarget().getParameterIndexByLabel(tarParamLabel);
419
							// get goal decision parameter label
420
							String label = solution.getGoalDecision().getParameterLabelByIndex(pIndex);
421
							
422
							// update relation
423
							eqRel.setTarget(solution.getGoalDecision());
424
							eqRel.setTargetParameterLabel(label);
425
						}
426
						break;
427
							
428
						case NOT_EQUAL_PARAMETER : 
429
						{
430
							// get equal relation
431
							NotEqualParameterRelation neqRel = (NotEqualParameterRelation) rel;
432
							// get relation reference parameter label
433
							String tarParamLabel = neqRel.getTargetParameterLabel();
434
							// get label index
435
							int pIndex = neqRel.getTarget().getParameterIndexByLabel(tarParamLabel);
436
							// get goal decision parameter label
437
							String label = solution.getGoalDecision().getParameterLabelByIndex(pIndex);
438
							
439
							// update relation
440
							neqRel.setTarget(solution.getGoalDecision());
441
							neqRel.setTargetParameterLabel(label);
442
						}
443
						break;
444
						
445
						default:
446
							// unknown parameter relation
447
							throw new RuntimeException("Unknown Parameter relation type : " + rel.getType() + "\n"); 
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
448
							
449
					}
450
				}
451
				
452
				// check temporal relation
453
				if (rel.getCategory().equals(ConstraintCategory.TEMPORAL_CONSTRAINT))
454
				{
455
					// update relation
456
					rel.setTarget(solution.getGoalDecision());
457
				}
458
			}
459
460
			// not feasible solution
461
			throw new RelationPropagationException(ex.getMessage());
462
		}
463
	}
464
	
465
	/**
466
	 * 
467
	 */
468
	@Override
469
	protected void doRetract(FlawSolution solution) {
470
		
471
		// check solution type
472
		GoalJustification justif = (GoalJustification) solution;
473
		// check if unification solution
474
		if (justif.getJustificationType().equals(JustificationType.UNIFICATION)) {
475
			// special management of unification
476
			this.doRetractUnification((GoalUnification) solution);
477
		}
478
		else {
479
			// "standard" management of flaw solution
480
			super.doRetract(solution);
481
		}
482
	}
483
	
484
	/**
485
	 * 
486
	 * @param goal
487
	 */
488 View Code Duplication
	private void doComputeUnificationSolutions(Goal goal) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
489
		
490
		// get goal component
491
		DomainComponent gComp = goal.getComponent();
492
		// list of goal unifications found
493
		List<GoalUnification> unifications = new ArrayList<>();
494
		
495
		// search active decisions that can be unified with the goal
496
		for (Decision unif : gComp.getActiveDecisions()) {
497
			
498
			// check predicate and temporal unification
499
			if (this.isPredicateUnificationFeasible(goal.getDecision(), unif) && 
500
					this.isTemporalUnificationFeasible(goal.getDecision(), unif)) {
501
				
502
				// possible unification found
503
				GoalUnification unification = new GoalUnification(goal, unif, this.unificationCost);
504
				// add unifications
505
				unifications.add(unification);
506
				info("Feasible unification found:\n"
507
						+ "- planning goal: " + goal + "\n"
508
						+ "- unification decision: " + unification + "\n");
509
			}
510
			else {
511
				
512
				// unification not feasible
513
				debug("No feasible unification:\n"
514
						+ "- planning goal: " + goal + "\n"
515
						+ "- decision : \"" + unif + "\"\n");
516
			}
517
		}
518
		
519
		// add unifications as goal solutions
520
		Collections.shuffle(unifications);
521
		for (GoalUnification unif : unifications) {
522
			goal.addSolution(unif);
523
		}
524
	}
525
526
	/**
527
	 * 
528
	 * @param goal
529
	 * @param decision
530
	 * @return
531
	 */
532 View Code Duplication
	private boolean isPredicateUnificationFeasible(Decision goal, Decision decision) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
533
		
534
		// feasibility flag
535
		boolean feasible = true;
536
		// first check if the decisions refer to the same values
537
		if (!decision.getValue().equals(goal.getValue()) && 
538
				decision.getComponent().equals(goal.getComponent())) {
539
			
540
			// not feasible unification
541
			feasible = false;
542
			debug("Not feasible predicate unification:\n"
543
					+ "- planning goal: " + goal + "\n"
544
					+ "- unification decision: " + decision + "\n"); 
545
		} else {
546
			
547
			// list of committed parameter constraints
548
			Set<Relation> committed = new HashSet<>();
549
			// list of translated parameter relations - reference
550
			Set<ParameterRelation> translatedReferenceGoalRelations = new HashSet<>();
551
			// list of translated parameter relations - target
552
			Set<ParameterRelation> translatedTargetGoalRelations = new HashSet<>();
553
			
554
			// get goal component
555
			DomainComponent goalComp = goal.getComponent();
556
			// get all (pending) relation concerning the goal decision
557
			Set<Relation> pending = goalComp.getRelations(goal);
558
			// check relations
559
			for (Relation rel : pending)
560
			{
561
				// check parameter constraint type
562
				if (rel.getCategory().equals(ConstraintCategory.PARAMETER_CONSTRAINT))
563
				{
564
					// check relation type
565
					switch (rel.getType())
566
					{
567
						// bind parameter
568
						case BIND_PARAMETER: 
569
						{
570
							// the goal can be only the reference of the relation
571
							ParameterRelation pRel = (ParameterRelation) rel;
572
							
573
							// get relation reference parameter label
574
							String refParamLabel = pRel.getReferenceParameterLabel();
575
							// get label index
576
							int refParameterIndex = pRel.getReference().getParameterIndexByLabel(refParamLabel);
577
							// get unification decision parameter label
578
							String label = decision.getParameterLabelByIndex(refParameterIndex);
579
580
							// update reference decision 
581
							pRel.setReference(decision);
582
							
583
							// update reference label of the relation 
584
							pRel.setReferenceParameterLabel(label);
585
							// add relation to the list of translated ones
586
							translatedReferenceGoalRelations.add(pRel);
587
						}
588
						break;
589
						
590
						case EQUAL_PARAMETER : 
591
						{
592
							// get parameter relation
593
							EqualParameterRelation eqRel = (EqualParameterRelation) rel;
594
							// check if the goal is the reference or the parameter constraint 
595
							if (eqRel.getReference().equals(goal))
596
							{
597
								// get relation reference parameter label
598
								String refParamLabel = eqRel.getReferenceParameterLabel();
599
								// get label index
600
								int refParameterIndex = eqRel.getReference().getParameterIndexByLabel(refParamLabel);
601
								// get unification decision parameter label
602
								String label = decision.getParameterLabelByIndex(refParameterIndex);
603
604
								// update reference decision 
605
								eqRel.setReference(decision);
606
								// update reference label of the relation 
607
								eqRel.setReferenceParameterLabel(label);
608
								// add relation to the list of translated ones
609
								translatedReferenceGoalRelations.add(eqRel);
610
							}
611
							else // the goal is the target of the relation 
612
							{
613
								// get relation reference parameter label
614
								String refParamLabel = eqRel.getTargetParameterLabel();
615
								// get label index
616
								int refParameterIndex = eqRel.getTarget().getParameterIndexByLabel(refParamLabel);
617
								// get unification decision parameter label
618
								String label = decision.getParameterLabelByIndex(refParameterIndex);
619
620
								// update reference decision 
621
								eqRel.setTarget(decision);
622
								// update reference label of the relation 
623
								eqRel.setTargetParameterLabel(label);
624
								// add relation to the list of translated ones
625
								translatedTargetGoalRelations.add(eqRel);
626
							}
627
						}
628
						break;
629
						
630
						case NOT_EQUAL_PARAMETER : 
631
						{
632
							// get parameter relation
633
							NotEqualParameterRelation neqRel = (NotEqualParameterRelation) rel;
634
							// check if the goal is the reference or the parameter constraint 
635
							if (neqRel.getReference().equals(goal))
636
							{
637
								// get relation reference parameter label
638
								String refParamLabel = neqRel.getReferenceParameterLabel();
639
								// get label index
640
								int refParameterIndex = neqRel.getReference().getParameterIndexByLabel(refParamLabel);
641
								// get unification decision parameter label
642
								String label = decision.getParameterLabelByIndex(refParameterIndex);
643
644
								// update reference decision 
645
								neqRel.setReference(decision);
646
								// update reference label of the relation 
647
								neqRel.setReferenceParameterLabel(label);
648
								// add relation to the list of translated ones
649
								translatedReferenceGoalRelations.add(neqRel);
650
							}
651
							else // the goal is the target of the relation 
652
							{
653
								// get relation reference parameter label
654
								String refParamLabel = neqRel.getTargetParameterLabel();
655
								// get label index
656
								int refParameterIndex = neqRel.getTarget().getParameterIndexByLabel(refParamLabel);
657
								// get unification decision parameter label
658
								String label = decision.getParameterLabelByIndex(refParameterIndex);
659
660
								// update reference decision 
661
								neqRel.setTarget(decision);
662
								// update reference label of the relation 
663
								neqRel.setTargetParameterLabel(label);
664
								// add relation to the list of translated ones
665
								translatedTargetGoalRelations.add(neqRel);
666
							}
667
						}
668
						break;
669
						
670
						
671
						default:
672
							// unknown parameter relation
673
							throw new RuntimeException("Unknown Parameter relation type : " + rel.getType() + "\n");
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
674
					}
675
				}
676
			}
677
				
678
			try {
679
				
680
				// activate translated relations
681
				for (Relation rel : translatedReferenceGoalRelations) {
682
					// check if can be activated
683
					if (rel.getReference().getComponent().activate(rel)) {
684
						// add relation to the committed list
685
						committed.add(rel);
686
					}
687
				}
688
				
689
				// activate translated relations
690
				for (Relation rel : translatedTargetGoalRelations) {
691
					// check if can be activated
692
					if (rel.getReference().getComponent().activate(rel)) {
693
						// add relation to the committed list
694
						committed.add(rel);
695
					}
696
				}
697
				
698
				// check parameter of the plan
699
				this.pdb.verify();
700
			}
701
			catch (ConsistencyCheckException | RelationPropagationException ex) {
702
				// not feasible 
703
				feasible = false;
704
				// not feasible unification
705
				debug("Not feasible predicate unification:\n"
706
						+ "- planning goal: " + goal + "\n"
707
						+ "- unification decision: " + decision + "\n");
708
			
709
			} finally  {
710
				
711
				// check committed relations
712
				for (Relation rel : committed) {
713
					// deactivate relation
714
					rel.getReference().getComponent().deactivate(rel);
715
				}
716
				
717
				// translated back parameter relations
718
				for (ParameterRelation rel : translatedReferenceGoalRelations) {
719
					
720
					// get relation reference parameter label
721
					String refParamLabel = rel.getReferenceParameterLabel();
722
					// get label index
723
					int pIndex = rel.getReference().getParameterIndexByLabel(refParamLabel);
724
					// get goal decision parameter label
725
					String label = goal.getParameterLabelByIndex(pIndex);
726
					
727
					// update relation
728
					rel.setReference(goal);
729
					rel.setReferenceParameterLabel(label);
730
				}
731
				
732
				// translated back parameter relations
733
				for (ParameterRelation rel : translatedTargetGoalRelations)
734
				{
735
					// check relation
736
					switch (rel.getType())
737
					{
738
						case EQUAL_PARAMETER : 
739
						{
740
							// get equal relation
741
							EqualParameterRelation eqRel = (EqualParameterRelation) rel;
742
							// get relation reference parameter label
743
							String tarParamLabel = eqRel.getTargetParameterLabel();
744
							// get label index
745
							int pIndex = eqRel.getTarget().getParameterIndexByLabel(tarParamLabel);
746
							// get goal decision parameter label
747
							String label = goal.getParameterLabelByIndex(pIndex);
748
							
749
							// update relation
750
							eqRel.setTarget(goal);
751
							eqRel.setTargetParameterLabel(label);
752
						}
753
						break;
754
							
755
						case NOT_EQUAL_PARAMETER : 
756
						{
757
							// get equal relation
758
							NotEqualParameterRelation neqRel = (NotEqualParameterRelation) rel;
759
							// get relation reference parameter label
760
							String tarParamLabel = neqRel.getTargetParameterLabel();
761
							// get label index
762
							int pIndex = neqRel.getTarget().getParameterIndexByLabel(tarParamLabel);
763
							// get goal decision parameter label
764
							String label = goal.getParameterLabelByIndex(pIndex);
765
							
766
							// update relation
767
							neqRel.setTarget(goal);
768
							neqRel.setTargetParameterLabel(label);
769
						}
770
						break;
771
						
772
						default:
773
							// unknown parameter relation
774
							throw new RuntimeException("Unknown Parameter relation type : " + rel.getType() + "\n"); 
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
Bug introduced by
Remove this throw statement from this finally block.
Loading history...
Best Practice introduced by
If you throw an exception in a finally block, the original exception will be hidden. Additionally, the finally block is no longer guaranteed to run to completion. Consider refactoring your code to avoid throwing the exception here.
Loading history...
775
							
776
					}
777
				}
778
			}
779
		}
780
		
781
		// get feasibility flag
782
		return feasible;
783
	}
784
	
785
	/**
786
	 * 
787
	 * @param goal
788
	 * @param decision
789
	 * @return
790
	 */
791 View Code Duplication
	private boolean isTemporalUnificationFeasible(Decision goal,  Decision decision) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
792
		
793
		// feasibility flag
794
		boolean feasible = true;
795
		// list of translated relations
796
		Set<Relation> translated = new HashSet<>();
797
		// list of committed relations
798
		Set<Relation> committed = new HashSet<>();
799
		
800
		// get goal component 
801
		DomainComponent gComp = goal.getComponent();
802
		// get all (pending) relations associated to the goal 
803
		Set<Relation> pRels = gComp.getRelations(goal);
804
		// translate relations
805
		for (Relation pRel : pRels)
806
		{
807
			// focus on temporal relations only 
808
			if (pRel.getCategory().equals(ConstraintCategory.TEMPORAL_CONSTRAINT))
809
			{
810
				// check relation reference
811
				if (pRel.getReference().equals(goal)) {
812
					// replace reference
813
					pRel.setReference(decision);
814
					// add translated relation
815
					translated.add(pRel);
816
				}
817
				
818
				// check relation target
819
				if (pRel.getTarget().equals(goal)) {
820
					// replace target
821
					pRel.setTarget(decision);
822
					// add translated relation
823
					translated.add(pRel);
824
				}
825
			}
826
		}
827
	
828
		try {
829
			
830
			// check translated relation and activate them if possible
831
			for (Relation tRel : translated) {
832
				// activate relation
833
				if (tRel.getReference().getComponent().activate(tRel)) {
834
835
					// add relation to committed list
836
					committed.add(tRel);
837
				}
838
			}
839
			
840
			// check temporal consistency after activated relations
841
			this.tdb.verify();
842
			
843
		} catch (ConsistencyCheckException | RelationPropagationException ex) {
844
			
845
			// not feasible unification 
846
			feasible = false;
847
			// not feasible unification
848
			debug("Not feasible temporal unification:\n"
849
					+ "- planning goal: " + goal + "\n"
850
					+ "- unification decision: " + decision + "\n");
851
			
852
		} finally {
853
			
854
			// deactivate relations
855
			for (Relation rel : committed) {
856
				// deactivate relation
857
				rel.getReference().getComponent().deactivate(rel);
858
			}
859
			
860
			// translate back relations
861
			for (Relation rel : translated) {
862
				
863
				// check reference 
864
				if (rel.getReference().equals(decision)) {
865
					// replace reference
866
					rel.setReference(goal);
867
				}
868
				
869
				// check target
870
				if (rel.getTarget().equals(decision)) {
871
					// replace target
872
					rel.setTarget(goal);
873
				}
874
			}
875
		}
876
		
877
		// get feasibility flag
878
		return feasible;
879
	}
880
	
881
	/**
882
	 * 
883
	 * @param goal
884
	 */
885
	private void doComputeExpansionSolutions(Goal goal) {
886
		
887
		// get component
888
		DomainComponent gComp = goal.getComponent();
889
		// buffer of activated relations
890
		Set<Relation> rels = new HashSet<>();
891
		
892
		try {
893
			
894
			// get the list of current tokens on the timeline
895
			List<Decision> tokens = gComp.getActiveDecisions();
896
			
897
			// activate goal decision and check its feasibility
898
			rels = gComp.activate(goal.getDecision());
899
			// check temporal and parameter consistency
900
			this.tdb.verify();
901
			this.pdb.verify();
902
			info("Goal decision consistent.. check possible schedules and refinements\n-\t " + goal.getDecision());
903
904
			// evaluate possible schedules of the goal w.r.t. existing tokens.
905
			if (!tokens.isEmpty()) {
906
				
907
				// create relation
908
				BeforeIntervalConstraint c0 = this.tdb.createTemporalConstraint(
909
						TemporalConstraintType.BEFORE);
910
				// set constraint data
911
				c0.setReference(goal.getDecision().getToken().getInterval());
912
				c0.setTarget(tokens.get(0).getToken().getInterval());
913
				c0.setLowerBound(0);
914
				c0.setUpperBound(this.tdb.getHorizon());
915
				
916 View Code Duplication
				try {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
917
					
918
					// propagate temporal constraint
919
					this.tdb.propagate(c0);
920
					// check temporal consistency
921
					this.tdb.verify();
922
					
923
					//  consistent so create a possible refinements considering this schedule
924
					for (GoalExpansion exp : this.expansions(goal)) {
925
						
926
						// add goal schedule
927
						exp.addGoalSchedule(new GoalSchedule(
928
								goal.getDecision(),
929
								tokens.get(0),
930
								0,
931
								this.tdb.getHorizon()));
932
						
933
						// add expansion and related relation as feasible refinement of the goal
934
						goal.addSolution(exp);
935
						debug("Add goal expansion solution\n\t- " + exp + "\n");
936
						
937
					}
938
					
939
				} catch (TemporalConstraintPropagationException | ConsistencyCheckException  ix) {
940
					
941
					// infeasible schedule of the decision
942
					debug("Infeasible schedule of goal " + goal.getDecision() + "\n"
943
							+ "\t- goal: " + goal.getDecision() + "\n"
944
							+ "\t- token: " + tokens.get(0) + "\n");
945
				} finally {
946
					
947
					// discard propagated constraints
948
					this.tdb.retract(c0);
949
				}
950
				
951
				
952
				// iterate over tokens to find feasible schedule of the activated one
953
				for (int index = 0; index < tokens.size() - 1; index++) {
954
					
955
					// create temporal constraint
956
					BeforeIntervalConstraint c1 = this.tdb.createTemporalConstraint(
957
							TemporalConstraintType.BEFORE);
958
					// set constraint data
959
					c1.setReference(tokens.get(index).getToken().getInterval());
960
					c1.setTarget(goal.getDecision().getToken().getInterval());
961
					c1.setLowerBound(0);
962
					c1.setUpperBound(this.tdb.getHorizon());
963
					
964
					// create temporal constraint
965
					BeforeIntervalConstraint c2 = this.tdb.createTemporalConstraint(
966
							TemporalConstraintType.BEFORE);
967
					// set constraint data
968
					c2.setReference(goal.getDecision().getToken().getInterval());
969
					c2.setTarget(tokens.get(index + 1).getToken().getInterval());
970
					c2.setLowerBound(0);
971
					c2.setUpperBound(this.tdb.getHorizon());
972
					
973
					try {
974
						
975
						// propagate constraints
976
						this.tdb.propagate(c1);
977
						this.tdb.propagate(c2);
978
						// check temporal consistency
979
						this.tdb.verify();
980
					
981
						//  consistent so create a possible refinements considering this schedule
982
						for (GoalExpansion exp : this.expansions(goal)) {
983
							
984
							// add goal schedules
985
							exp.addGoalSchedule(new GoalSchedule(
986
									tokens.get(index), 
987
									goal.getDecision(),
988
									0,
989
									this.tdb.getHorizon()));
990
							
991
							exp.addGoalSchedule(new GoalSchedule(
992
									goal.getDecision(),
993
									tokens.get(index + 1),
994
									0,
995
									this.tdb.getHorizon()));
996
							
997
							// add expansion and related relation as feasible refinement of the goal
998
							goal.addSolution(exp);
999
							debug("Add goal expansion solution\n\t- " + exp + "\n");
1000
							
1001
						}
1002
						
1003
					} catch (TemporalConstraintPropagationException | ConsistencyCheckException  ix) {
1004
						
1005
						// infeasible schedule of the decision
1006
						debug("Infeasible schedule of goal " + goal.getDecision() + "\n"
1007
								+ "\t- token: " + tokens.get(index) + "\n"
1008
								+ "\t- goal: " + goal.getDecision() + "\n"
1009
								+ "\t- token: " + tokens.get(index + 1) + "\n");
1010
						
1011
					} finally {
1012
1013
						// discard propagated constraints
1014
						this.tdb.retract(c1);
1015
						this.tdb.retract(c2);
1016
					}
1017
				}
1018
				
1019
				// check last token
1020
				
1021
				// create temporal constraint
1022
				BeforeIntervalConstraint c3 = this.tdb.createTemporalConstraint(
1023
						TemporalConstraintType.BEFORE);
1024
				// set constraint data
1025
				c3.setReference(tokens.get(tokens.size() - 1).getToken().getInterval());
1026
				c3.setTarget(goal.getDecision().getToken().getInterval());
1027
				c3.setLowerBound(0);
1028
				c3.setUpperBound(this.tdb.getHorizon());
1029
				
1030 View Code Duplication
				try {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1031
					
1032
					// propagate temporal constraint
1033
					this.tdb.propagate(c3);
1034
					// check temporal consistency
1035
					this.tdb.verify();
1036
					
1037
					//  consistent so create a possible refinements considering this schedule
1038
					for (GoalExpansion exp : this.expansions(goal)) {
1039
						
1040
						// create schedule
1041
						GoalSchedule schedule = new GoalSchedule(
1042
								tokens.get(tokens.size() - 1), 
1043
								goal.getDecision(),
1044
								0,
1045
								this.tdb.getHorizon());
1046
1047
						// add goal schedule
1048
						exp.addGoalSchedule(schedule);
1049
						// add expansion and related relation as feasible refinement of the goal
1050
						goal.addSolution(exp);
1051
						debug("Add goal expansion solution\n\t- " + exp + "\n");
1052
						
1053
					}
1054
					
1055
				} catch (TemporalConstraintPropagationException | ConsistencyCheckException  ix) {
1056
					
1057
					// infeasible schedule of the decision
1058
					debug("Infeasible schedule of goal " + goal.getDecision() + "\n"
1059
							+ "\t- token: " + tokens.get(tokens.size() - 1) + "\n"
1060
							+ "\t- goal: " + goal.getDecision() + "\n");
1061
					
1062
				} finally {
1063
					
1064
					// discard propagated constraints
1065
					this.tdb.retract(c3);
1066
				}
1067
			}
1068
			
1069
		} catch (DecisionPropagationException | ConsistencyCheckException  ex) {
1070
			// not feasible goal expansion
1071
			warning("Infeasible activated goal:\n\t- goal " + goal.getDecision() + "\n\t- msg: " + ex.getMessage() + "\n");
1072
			
1073
		} finally {
1074
			
1075
			// deactivate relations if any
1076
			for (Relation rel : rels) {
1077
				gComp.deactivate(rel);
1078
			}
1079
			
1080
			// deactivate goal decision
1081
			gComp.deactivate(goal.getDecision());
1082
		}
1083
	}
1084
	
1085
	/**
1086
	 * 
1087
	 * @return
1088
	 */
1089
	private List<GoalExpansion> expansions(Goal goal) {
1090
		
1091
		// list of expansions according to synchronization rules
1092
		List<GoalExpansion> exps = new ArrayList<>();
1093
		List<SynchronizationRule> rules = this.component.getSynchronizationRules(goal.getDecision().getValue());
1094
		
1095
		// check rules
1096 View Code Duplication
		if (rules.isEmpty()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1097
			
1098
			// create expansion
1099
			GoalExpansion expansion = new GoalExpansion(goal, this.expansionCost);
1100
			// add expansion 
1101
			exps.add(expansion);
1102
			// print debug message
1103
			debug("Simple goal found no synchronization is triggered after expansion:\n"
1104
					+ "- planning goal: " + goal.getDecision() + "\n");
1105
			
1106
			
1107
		} else {
1108
			
1109
			// create a branch for each rule
1110
			for (SynchronizationRule rule : rules) {
1111
				
1112
				// expansion solution
1113
				GoalExpansion expansion = new GoalExpansion(goal, rule, this.expansionCost);
1114
				// add expansion
1115
				exps.add(expansion);
1116
				// print debug message
1117
				debug("Complex goal found:\n"
1118
						+ "- planning goal: " + goal.getDecision() + "\n"
1119
						+ "- synchronization rule: " + rule + "\n");
1120
			}
1121
			
1122
		}
1123
		
1124
		// randomly order created expansions
1125
		Collections.shuffle(exps);
1126
		// get expansions
1127
		return exps;
1128
	}
1129
	
1130
	/**
1131
	 * 
1132
	 * @param unification
1133
	 * @throws Exception
1134
	 */
1135 View Code Duplication
	private void doApplyUnification(GoalUnification unification) 
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1136
			throws FlawSolutionApplicationException {
1137
		
1138
		// get original goal
1139
		Decision goal = unification.getGoalDecision();
1140
		// get all (pending) relations concerning the planning goal
1141
		DomainComponent goalComp = goal.getComponent();
1142
1143
		// list of committed parameter constraints
1144
		Set<Relation> committed = new HashSet<>();
1145
		// list of translated parameter relations - reference
1146
		Set<Relation> translatedReferenceGoalRelations = new HashSet<>();
1147
		// list of translated parameter relations - target
1148
		Set<Relation> translatedTargetGoalRelations = new HashSet<>();
1149
		
1150
		
1151
		// get pending relations associated to the goal
1152
		Set<Relation> gRels = goalComp.getRelations(goal);
1153
		// translate pending relations by replacing goal's information with unification decision's information
1154
		for (Relation rel : gRels) {
1155
			
1156
			// check relation category
1157
			if (rel.getCategory().equals(ConstraintCategory.TEMPORAL_CONSTRAINT)) {
1158
				
1159
				// check relation reference
1160
				if (rel.getReference().equals(goal)) {
1161
					// replace reference 
1162
					rel.setReference(unification.getUnificationDecision());
1163
					// add relation to the list
1164
					translatedReferenceGoalRelations.add(rel);
1165
				}
1166
1167
				// check relation target
1168
				if (rel.getTarget().equals(goal)) {
1169
					// replace target
1170
					rel.setTarget(unification.getUnificationDecision());
1171
					// add relation to the list
1172
					translatedTargetGoalRelations.add(rel);
1173
				}
1174
				
1175
			}
1176
			
1177
			if (rel.getCategory().equals(ConstraintCategory.PARAMETER_CONSTRAINT))
1178
			{
1179
				// check relation type
1180
				switch (rel.getType())
1181
				{
1182
					// bind parameter
1183
					case BIND_PARAMETER: 
1184
					{
1185
						// the goal can be only the reference of the relation
1186
						ParameterRelation pRel = (ParameterRelation) rel;
1187
						
1188
						// get relation reference parameter label
1189
						String refParamLabel = pRel.getReferenceParameterLabel();
1190
						// get label index
1191
						int refParameterIndex = pRel.getReference().getParameterIndexByLabel(refParamLabel);
1192
						// get unification decision parameter label
1193
						String label = unification.getUnificationDecision().getParameterLabelByIndex(refParameterIndex);
1194
1195
						// update reference decision 
1196
						pRel.setReference(unification.getUnificationDecision());
1197
						// update reference label of the relation 
1198
						pRel.setReferenceParameterLabel(label);
1199
						// add relation to the list of translated ones
1200
						translatedReferenceGoalRelations.add(pRel);
1201
					}
1202
					break;
1203
					
1204
					case EQUAL_PARAMETER : 
1205
					{
1206
						// get parameter relation
1207
						EqualParameterRelation eqRel = (EqualParameterRelation) rel;
1208
						// check if the goal is the reference or the parameter constraint 
1209
						if (eqRel.getReference().equals(goal))
1210
						{
1211
							// get relation reference parameter label
1212
							String refParamLabel = eqRel.getReferenceParameterLabel();
1213
							// get label index
1214
							int refParameterIndex = eqRel.getReference().getParameterIndexByLabel(refParamLabel);
1215
							// get unification decision parameter label
1216
							String label = unification.getUnificationDecision().getParameterLabelByIndex(refParameterIndex);
1217
1218
							// update reference decision 
1219
							eqRel.setReference(unification.getUnificationDecision());
1220
							// update reference label of the relation 
1221
							eqRel.setReferenceParameterLabel(label);
1222
							// add relation to the list of translated ones
1223
							translatedReferenceGoalRelations.add(eqRel);
1224
						}
1225
						else // the goal is the target of the relation 
1226
						{
1227
							// get relation reference parameter label
1228
							String refParamLabel = eqRel.getTargetParameterLabel();
1229
							// get label index
1230
							int refParameterIndex = eqRel.getTarget().getParameterIndexByLabel(refParamLabel);
1231
							// get unification decision parameter label
1232
							String label = unification.getUnificationDecision().getParameterLabelByIndex(refParameterIndex);
1233
1234
							// update reference decision 
1235
							eqRel.setTarget(unification.getUnificationDecision());
1236
							// update reference label of the relation 
1237
							eqRel.setTargetParameterLabel(label);
1238
							// add relation to the list of translated ones
1239
							translatedTargetGoalRelations.add(eqRel);
1240
						}
1241
					}
1242
					break;
1243
					
1244
					case NOT_EQUAL_PARAMETER : 
1245
					{
1246
						// get parameter relation
1247
						NotEqualParameterRelation neqRel = (NotEqualParameterRelation) rel;
1248
						// check if the goal is the reference or the parameter constraint 
1249
						if (neqRel.getReference().equals(goal))
1250
						{
1251
							// get relation reference parameter label
1252
							String refParamLabel = neqRel.getReferenceParameterLabel();
1253
							// get label index
1254
							int refParameterIndex = neqRel.getReference().getParameterIndexByLabel(refParamLabel);
1255
							// get unification decision parameter label
1256
							String label = unification.getUnificationDecision().getParameterLabelByIndex(refParameterIndex);
1257
1258
							// update reference decision 
1259
							neqRel.setReference(unification.getUnificationDecision());
1260
							// update reference label of the relation 
1261
							neqRel.setReferenceParameterLabel(label);
1262
							// add relation to the list of translated ones
1263
							translatedReferenceGoalRelations.add(neqRel);
1264
						}
1265
						else // the goal is the target of the relation 
1266
						{
1267
							// get relation reference parameter label
1268
							String refParamLabel = neqRel.getTargetParameterLabel();
1269
							// get label index
1270
							int refParameterIndex = neqRel.getTarget().getParameterIndexByLabel(refParamLabel);
1271
							// get unification decision parameter label
1272
							String label = unification.getUnificationDecision().getParameterLabelByIndex(refParameterIndex);
1273
1274
							// update reference decision 
1275
							neqRel.setTarget(unification.getUnificationDecision());
1276
							// update reference label of the relation 
1277
							neqRel.setTargetParameterLabel(label);
1278
							// add relation to the list of translated ones
1279
							translatedTargetGoalRelations.add(neqRel);
1280
						}
1281
					}
1282
					break;
1283
					
1284
					
1285
					default:
1286
						// unknown parameter relation
1287
						throw new RuntimeException("Unknown Parameter relation type : " + rel.getType() + "\n");
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1288
				}
1289
			}
1290
		}
1291
		
1292
		
1293
		try	
1294
		{
1295
			// remove original goal: PENDING -> SILENT
1296
			goalComp.free(goal);
1297
			
1298
			// activate translated relations
1299
			for (Relation rel : translatedReferenceGoalRelations) 
1300
			{
1301
				// check if can be activated
1302
				if (rel.getReference().getComponent().activate(rel)) {
1303
					
1304
					// add activated relations
1305
					unification.addActivatedRelation(rel);
1306
					// add relation to the committed list
1307
					committed.add(rel);
1308
				}
1309
			}
1310
			
1311
			// activate translated relations
1312
			for (Relation rel : translatedTargetGoalRelations) 
1313
			{
1314
				// check if can be activated
1315
				if (rel.getReference().getComponent().activate(rel)) {
1316
					
1317
					// add activated relations
1318
					unification.addActivatedRelation(rel);
1319
					// add relation to the committed list
1320
					committed.add(rel);
1321
				}
1322
			}
1323
1324
			// set translated relations
1325
			unification.setTranslatedReferenceGoalRelation(translatedReferenceGoalRelations);
1326
			unification.setTranslatedTargetGoalRealtion(translatedTargetGoalRelations);
1327
			
1328
			// check consistency
1329
			this.tdb.verify();
1330
			this.pdb.verify();
1331
			
1332
		} catch (RelationPropagationException | ConsistencyCheckException ex) {
1333
1334
			// restore goal: SILENT -> PENDING
1335
			goalComp.restore(goal);
1336
			// deactivate committed relations
1337
			for (Relation rel : committed) {
1338
				// get reference component
1339
				DomainComponent refComp = rel.getReference().getComponent();
1340
				refComp.deactivate(rel);
1341
			}
1342
			
1343
			
1344
			// translated back relations
1345
			for (Relation rel : translatedReferenceGoalRelations) {
1346
				// check category
1347
				if (rel.getCategory().equals(ConstraintCategory.PARAMETER_CONSTRAINT)) {
1348
					
1349
					// get parameter relation
1350
					ParameterRelation pRel = (ParameterRelation) rel;
1351
					// get relation reference parameter label
1352
					String refParamLabel = pRel.getReferenceParameterLabel();
1353
					// get label index
1354
					int pIndex = pRel.getReference().getParameterIndexByLabel(refParamLabel);
1355
					// get goal decision parameter label
1356
					String label = goal.getParameterLabelByIndex(pIndex);
1357
					
1358
					// update relation
1359
					pRel.setReference(goal);
1360
					pRel.setReferenceParameterLabel(label);
1361
				}
1362
				
1363
				if (rel.getCategory().equals(ConstraintCategory.TEMPORAL_CONSTRAINT)) {
1364
					// update relation
1365
					rel.setReference(goal);
1366
				}
1367
			}
1368
			
1369
			// translated back parameter relations
1370
			for (Relation rel : translatedTargetGoalRelations) {
1371
				
1372
				// check relation category 
1373
				if (rel.getCategory().equals(ConstraintCategory.PARAMETER_CONSTRAINT)) {
1374
					// check relation
1375
					switch (rel.getType()) {
1376
					
1377
						case EQUAL_PARAMETER : {
1378
							
1379
							// get equal relation
1380
							EqualParameterRelation eqRel = (EqualParameterRelation) rel;
1381
							// get relation reference parameter label
1382
							String tarParamLabel = eqRel.getTargetParameterLabel();
1383
							// get label index
1384
							int pIndex = eqRel.getTarget().getParameterIndexByLabel(tarParamLabel);
1385
							// get goal decision parameter label
1386
							String label = goal.getParameterLabelByIndex(pIndex);
1387
							
1388
							// update relation
1389
							eqRel.setTarget(goal);
1390
							eqRel.setTargetParameterLabel(label);
1391
						}
1392
						break;
1393
							
1394
						case NOT_EQUAL_PARAMETER : {
1395
							
1396
							// get equal relation
1397
							NotEqualParameterRelation neqRel = (NotEqualParameterRelation) rel;
1398
							// get relation reference parameter label
1399
							String tarParamLabel = neqRel.getTargetParameterLabel();
1400
							// get label index
1401
							int pIndex = neqRel.getTarget().getParameterIndexByLabel(tarParamLabel);
1402
							// get goal decision parameter label
1403
							String label = goal.getParameterLabelByIndex(pIndex);
1404
							
1405
							// update relation
1406
							neqRel.setTarget(goal);
1407
							neqRel.setTargetParameterLabel(label);
1408
						}
1409
						break;
1410
						
1411
						default:
1412
							// unknown parameter relation
1413
							throw new RuntimeException("Unknown Parameter relation type : " + rel.getType() + "\n"); 
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1414
							
1415
					}
1416
				}
1417
				
1418
				// check temporal relation
1419
				if (rel.getCategory().equals(ConstraintCategory.TEMPORAL_CONSTRAINT)) {
1420
					// update relation
1421
					rel.setTarget(goal);
1422
				}
1423
			}
1424
1425
			// not feasible solution
1426
			throw new FlawSolutionApplicationException(ex.getMessage());
1427
		}
1428
	}
1429
	
1430
	/**
1431
	 * 
1432
	 * @param expansion
1433
	 * @throws Exception
1434
	 */
1435
	private void doApplyExpansion(GoalExpansion expansion) 
1436
			throws FlawSolutionApplicationException {
1437
		
1438
		// get goal
1439
		Decision goal = expansion.getGoalDecision();
1440
		
1441
		// check subgoals from selected synchronization rule if any
1442 View Code Duplication
		if (expansion.hasSubGoals()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1443
			
1444
			// get the rule to apply
1445
			SynchronizationRule rule = expansion.getSynchronizationRule();
1446
			// create an index of token variable
1447
			Map<TokenVariable, Decision> var2dec = new HashMap<>();
1448
			var2dec.put(rule.getTriggerer(), goal);
1449
			// add pending decisions
1450
			for (TokenVariable var : rule.getTokenVariables()) {
1451
				
1452
				// get target component
1453
				DomainComponent target = var.getValue().getComponent(); 
1454
				// create a pending decision
1455
				Decision pending = target.create(
1456
						var.getValue(),
1457
						var.getParameterLabels());
1458
				
1459
				// set causal link
1460
				pending.setCausalLink(goal);
1461
				// check solving knowledge
1462
				if (var.isMandatoryExpansion()) {
1463
					pending.setMandatoryExpansion();
1464
				}
1465
1466
				// check solving knowledge
1467
				if (var.isMandatoryUnificaiton()) {
1468
					pending.setMandatoryUnification();
1469
				}
1470
				
1471
				// add entry to cache
1472
				var2dec.put(var, pending);
1473
				// add created decision
1474
				expansion.addCreatedDecision(pending);
1475
			}
1476
			
1477
			// add pending relations
1478
			for (SynchronizationConstraint c : rule.getConstraints()) {
1479
				// check category
1480
				switch (c.getCategory()) {
1481
1482
					// temporal category
1483
					case TEMPORAL_CONSTRAINT : {
1484
						
1485
						// temporal constraint
1486
						TemporalSynchronizationConstraint tc = (TemporalSynchronizationConstraint) c;
1487
						// get decisions
1488
						Decision reference = var2dec.get(tc.getReference());
1489
						Decision target = var2dec.get(tc.getTarget());
1490
						// get reference component
1491
						DomainComponent refComp = reference.getComponent();
1492
						// create pending relation
1493
						TemporalRelation rel = refComp.create(tc.getType(), reference, target);
1494
						// set bounds
1495
						rel.setBounds(tc.getBounds());
1496
						// add created relation
1497
						expansion.addCreatedRelation(rel);
1498
					}
1499
					break;
1500
					
1501
					// parameter category
1502
					case PARAMETER_CONSTRAINT: {
1503
						
1504
						// parameter constraint
1505
						ParameterSynchronizationConstraint pc = (ParameterSynchronizationConstraint) c;
1506
						// get decisions
1507
						Decision reference = var2dec.get(pc.getReference());
1508
						Decision target = var2dec.get(pc.getTarget());
1509
						// get reference component
1510
						DomainComponent refComp = reference.getComponent();
1511
						// create pending relation
1512
						ParameterRelation rel = (ParameterRelation) refComp.create(pc.getType(), reference, target);
1513
						
1514
						// check parameter relation type
1515
						switch (rel.getType()) {
1516
						
1517
							// bind parameter relation
1518
							case BIND_PARAMETER : {
1519
								
1520
								// bind constraint
1521
								BindParameterRelation bind = (BindParameterRelation) rel;
1522
								// set binding value
1523
								bind.setValue(pc.getTargetLabel());
1524
								// set reference label
1525
								if (pc.getReference().equals(rule.getTriggerer())) {
1526
									
1527
									// get trigger label index
1528
									int index = rule.getTriggerer().getParameterIndexByLabel(pc.getReferenceLabel());
1529
									// set decision's label
1530
									String label = goal.getParameterLabelByIndex(index);
1531
									// set label
1532
									bind.setReferenceParameterLabel(label);
1533
									
1534
								} else {
1535
									
1536
									bind.setReferenceParameterLabel(pc.getReferenceLabel());
1537
								}
1538
							}
1539
							break;
1540
							
1541
							// equal parameter relation
1542
							case EQUAL_PARAMETER : {
1543
								
1544
								// get relation
1545
								EqualParameterRelation eq = (EqualParameterRelation) rel;
1546
								
1547
								// check if source is the trigger
1548
								if (pc.getReference().equals(rule.getTriggerer())) {
1549
									
1550
									// get trigger label index
1551
									int index = rule.getTriggerer().getParameterIndexByLabel(pc.getReferenceLabel());
1552
									// get decions's label
1553
									String label = goal.getParameterLabelByIndex(index);
1554
									// set label
1555
									eq.setReferenceParameterLabel(label);
1556
									
1557
								} else {
1558
									
1559
									// directly set the label
1560
									eq.setReferenceParameterLabel(pc.getReferenceLabel());
1561
								}
1562
								
1563
								// check if target is the trigger
1564
								if (pc.getTarget().equals(rule.getTriggerer())) {
1565
									
1566
									// get trigger label index
1567
									int index = rule.getTriggerer().getParameterIndexByLabel(pc.getTargetLabel());
1568
									// get decision's label
1569
									String label = goal.getParameterLabelByIndex(index);
1570
									// set label
1571
									eq.setTargetParameterLabel(label);
1572
									
1573
								} else {
1574
									
1575
									// directly set the label
1576
									eq.setTargetParameterLabel(pc.getTargetLabel());
1577
								}
1578
							}
1579
							break;
1580
							
1581
							// not-equal parameter relation
1582
							case NOT_EQUAL_PARAMETER : {
1583
								
1584
								// get relation
1585
								NotEqualParameterRelation neq = (NotEqualParameterRelation) rel;
1586
								
1587
								// check if source is the trigger
1588
								if (pc.getReference().equals(rule.getTriggerer())) {
1589
									
1590
									// get trigger label index
1591
									int index = rule.getTriggerer().getParameterIndexByLabel(pc.getReferenceLabel());
1592
									// get decions's label
1593
									String label = goal.getParameterLabelByIndex(index);
1594
									// set label
1595
									neq.setReferenceParameterLabel(label);
1596
									
1597
								} else {
1598
									
1599
									// directly set the label
1600
									neq.setReferenceParameterLabel(pc.getReferenceLabel());
1601
								}
1602
								
1603
								// check if target is the trigger
1604
								if (pc.getTarget().equals(rule.getTriggerer())) {
1605
									
1606
									// get trigger label index
1607
									int index = rule.getTriggerer().getParameterIndexByLabel(pc.getTargetLabel());
1608
									// get decision's label
1609
									String label = goal.getParameterLabelByIndex(index);
1610
									// set label
1611
									neq.setTargetParameterLabel(label);
1612
									
1613
								} else {
1614
									// directly set the label
1615
									neq.setTargetParameterLabel(pc.getTargetLabel());
1616
								}
1617
							}
1618
							break;
1619
							
1620
							default : {
1621
								throw new RuntimeException("Unknown parameter constraint type - " + rel.getType());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1622
							}
1623
						}
1624
						
1625
						// add created relation
1626
						expansion.addCreatedRelation(rel);
1627
					}
1628
				}
1629
			}
1630
		}
1631
		
1632
		try {
1633
			
1634
			// activate goal decision 
1635
			DomainComponent goalComp = goal.getComponent();
1636
			// get goal-related activated relations
1637
			Set<Relation> list = goalComp.activate(goal);
1638
			// add goal to activated decisions
1639
			expansion.addActivatedDecision(goal);
1640
			// add to activated relations
1641
			expansion.addActivatedRelations(list);
1642
			
1643
			// create goal scheduling relations
1644
			for (GoalSchedule schedule : expansion.getGoalSchedules()) {
1645
				
1646
				Decision left = schedule.getLeft();
1647
				Decision right = schedule.getRight();
1648
				
1649
				// create before relation
1650
				BeforeRelation rel = left.getComponent().create(RelationType.BEFORE, 
1651
						left, 
1652
						right);
1653
				// set bounds
1654
				rel.setBound(new long[] {
1655
						schedule.getLowerBound(),
1656
						schedule.getUpperBound()
1657
				});
1658
				
1659
				// add created relation
1660
				expansion.addCreatedRelation(rel);
1661
				
1662
				// activate relation
1663
				left.getComponent().activate(rel);
1664
				
1665
				// add activated relation
1666
				expansion.addActivatedRelation(rel);
1667
			}
1668
			
1669
			// check consistency 
1670
			this.tdb.verify();
1671
			this.pdb.verify();
1672
			
1673
		} catch (RelationPropagationException | DecisionPropagationException | ConsistencyCheckException ex) {
1674
			
1675
			// deactivate activated relations
1676
			for (Relation rel : expansion.getActivatedRelations()) {
1677
				// get reference component
1678
				DomainComponent refComp = rel.getReference().getComponent();
1679
				refComp.deactivate(rel);
1680
			}
1681
			
1682
			// delete created relations
1683
			for (Relation rel : expansion.getCreatedRelations()) {
1684
				// get reference component
1685
				DomainComponent refComp = rel.getReference().getComponent();
1686
				refComp.delete(rel);
1687
			}
1688
1689
			// deactivate activated decisions
1690
			for (Decision dec : expansion.getActivatedDecisions()) {
1691
				// get component
1692
				DomainComponent refComp = dec.getComponent();
1693
				refComp.deactivate(dec);
1694
			}
1695
			
1696
			
1697
			// delete created decisions 
1698
			for (Decision dec : expansion.getCreatedDecisions()) {
1699
				// get component
1700
				DomainComponent comp = dec.getComponent();
1701
				comp.free(dec);
1702
			}
1703
			
1704
			// throw exception
1705
			throw new FlawSolutionApplicationException(ex.getMessage());
1706
		}
1707
	}
1708
1709
	/**
1710
	 * 
1711
	 * @param unification
1712
	 */
1713 View Code Duplication
	private void doRetractUnification(GoalUnification unification) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1714
		
1715
		// original goal 
1716
		Decision goal = unification.getGoalDecision();
1717
		
1718
		// get goal component
1719
		DomainComponent goalComp = goal.getComponent();
1720
		// restore original planning goal SILENT -> PENDING
1721
		goalComp.restore(goal);
1722
1723
		// deactivate activated relations
1724
		for (Relation rel : unification.getActivatedRelations()) {
1725
			// get reference component
1726
			DomainComponent refComp = rel.getReference().getComponent();
1727
			refComp.deactivate(rel);
1728
		}
1729
		
1730
		// translated back relations
1731
		for (Relation rel : unification.getTranslatedReferenceGoalRelations()){
1732
			// check category
1733
			if (rel.getCategory().equals(ConstraintCategory.PARAMETER_CONSTRAINT)) {
1734
				
1735
				// get parameter relation
1736
				ParameterRelation pRel = (ParameterRelation) rel;
1737
				
1738
				// get relation reference parameter label
1739
				String refParamLabel = pRel.getReferenceParameterLabel();
1740
				// get label index
1741
				int pIndex = pRel.getReference().getParameterIndexByLabel(refParamLabel);
1742
				// get goal decision parameter label
1743
				String label = goal.getParameterLabelByIndex(pIndex);
1744
				
1745
				// update relation
1746
				pRel.setReference(goal);
1747
				pRel.setReferenceParameterLabel(label);
1748
			}
1749
			
1750
			if (rel.getCategory().equals(ConstraintCategory.TEMPORAL_CONSTRAINT)) {
1751
				// update relation
1752
				rel.setReference(goal);
1753
			}
1754
		}
1755
		
1756
		// translated back parameter relations
1757
		for (Relation rel : unification.getTranslatedTargetGoalRelations()) {
1758
			
1759
			// check relation category 
1760
			if (rel.getCategory().equals(ConstraintCategory.PARAMETER_CONSTRAINT)) {
1761
				// check relation
1762
				switch (rel.getType()) {
1763
				
1764
					case EQUAL_PARAMETER : {
1765
						
1766
						// get equal relation
1767
						EqualParameterRelation eqRel = (EqualParameterRelation) rel;
1768
						// get relation reference parameter label
1769
						String tarParamLabel = eqRel.getTargetParameterLabel();
1770
						// get label index
1771
						int pIndex = eqRel.getTarget().getParameterIndexByLabel(tarParamLabel);
1772
						// get goal decision parameter label
1773
						String label = goal.getParameterLabelByIndex(pIndex);
1774
						
1775
						// update relation
1776
						eqRel.setTarget(goal);
1777
						eqRel.setTargetParameterLabel(label);
1778
					}
1779
					break;
1780
						
1781
					case NOT_EQUAL_PARAMETER : {
1782
						
1783
						// get equal relation
1784
						NotEqualParameterRelation neqRel = (NotEqualParameterRelation) rel;
1785
						// get relation reference parameter label
1786
						String tarParamLabel = neqRel.getTargetParameterLabel();
1787
						// get label index
1788
						int pIndex = neqRel.getTarget().getParameterIndexByLabel(tarParamLabel);
1789
						// get goal decision parameter label
1790
						String label = goal.getParameterLabelByIndex(pIndex);
1791
						
1792
						// update relation
1793
						neqRel.setTarget(goal);
1794
						neqRel.setTargetParameterLabel(label);
1795
					}
1796
					break;
1797
					
1798
					default:
1799
						// unknown parameter relation
1800
						throw new RuntimeException("Unknown Parameter relation type : " + rel.getType() + "\n"); 
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1801
						
1802
				}
1803
			}
1804
			
1805
			// check temporal relation
1806
			if (rel.getCategory().equals(ConstraintCategory.TEMPORAL_CONSTRAINT)) {
1807
				
1808
				// update relation
1809
				rel.setTarget(goal);
1810
			}
1811
		}
1812
	}
1813
	
1814
}
1815