it.cnr.istc.pst.platinum.ai.lang.ddl.v3.DDLv3Compiler   F
last analyzed

Complexity

Total Complexity 336

Size/Duplication

Total Lines 2721
Duplicated Lines 42.78 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1245
c 1
b 0
f 0
dl 1164
loc 2721
rs 0.8
wmc 336

22 Methods

Rating   Name   Duplication   Size   Complexity  
A compileDomain() 0 15 2
A compileProblem(PlanDataBase) 0 14 2
A DDLv3Compiler(String,String) 0 2 1
A doCompileDomain() 0 22 1
A doParseDDLFile(String) 0 32 3
A DDLv3Compiler(String) 0 2 1
F doCreateSynchronizationFromGroundDecision(DDLSynchronization,DomainComponent,PlanDataBase) 0 354 42
F doCompileProblem(PlanDataBase) 0 131 20
A addParameterDomains(PlanDataBase) 0 30 4
A addComponents(PlanDataBase) 0 28 5
A addDiscreteResource(PlanDataBase,DDLComponent) 0 17 1
C addSynchronizationRules(PlanDataBase) 0 55 9
F addConstraintToSynchronization(SynchronizationRule,TokenVariable,TokenVariable,DDLTemporalRelationType) 145 145 24
F addStateVariable(PlanDataBase,DDLComponent) 0 191 30
A addReservoirResource(PlanDataBase,DDLComponent) 0 18 1
B addFactToProblem(Problem,ComponentValue,DDLInstantiatedComponentDecision) 34 34 6
F doCreateSynchronizationFromSingletonDecision(DDLSynchronization,DomainComponent,PlanDataBase) 409 409 48
F addBinaryGoal(Problem,ProblemGoal,ProblemGoal,DDLTemporalRelationType) 131 131 24
B addObservationToProblem(Problem,ComponentValue,DDLInstantiatedComponentDecision) 0 45 8
F doCreateSynchronizationFromConsumableResourceValue(DDLSynchronization,ReservoirResource,PlanDataBase) 0 423 50
F doCreateSynchronizationFromRenewableResourceValue(DDLSynchronization,DiscreteResource,PlanDataBase) 408 408 48
B addGoalToProblem(Problem,ComponentValue,DDLInstantiatedComponentDecision) 33 33 6

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.lang.ddl.v3.DDLv3Compiler 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.lang.ddl.v3;
2
3
import java.io.IOException;
4
import java.util.HashMap;
5
import java.util.List;
6
import java.util.Map;
7
8
import org.antlr.runtime.ANTLRFileStream;
9
import org.antlr.runtime.CharStream;
10
import org.antlr.runtime.CommonTokenStream;
11
import org.antlr.runtime.RecognitionException;
12
import org.antlr.runtime.tree.Tree;
13
14
import it.cnr.istc.pst.platinum.ai.framework.domain.PlanDataBaseBuilder;
15
import it.cnr.istc.pst.platinum.ai.framework.domain.component.ComponentValue;
16
import it.cnr.istc.pst.platinum.ai.framework.domain.component.DomainComponent;
17
import it.cnr.istc.pst.platinum.ai.framework.domain.component.DomainComponentType;
18
import it.cnr.istc.pst.platinum.ai.framework.domain.component.PlanDataBase;
19
import it.cnr.istc.pst.platinum.ai.framework.domain.component.pdb.SynchronizationRule;
20
import it.cnr.istc.pst.platinum.ai.framework.domain.component.pdb.TokenVariable;
21
import it.cnr.istc.pst.platinum.ai.framework.domain.component.resource.discrete.DiscreteResource;
22
import it.cnr.istc.pst.platinum.ai.framework.domain.component.resource.discrete.RequirementResourceValue;
23
import it.cnr.istc.pst.platinum.ai.framework.domain.component.resource.reservoir.ReservoirResource;
24
import it.cnr.istc.pst.platinum.ai.framework.domain.component.sv.StateVariable;
25
import it.cnr.istc.pst.platinum.ai.framework.domain.component.sv.StateVariableValue;
26
import it.cnr.istc.pst.platinum.ai.framework.domain.component.sv.Transition;
27
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.ex.DomainComponentNotFoundException;
28
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.ex.SynchronizationCycleException;
29
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.problem.Problem;
30
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.problem.ProblemFact;
31
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.problem.ProblemFluent;
32
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.problem.ProblemGoal;
33
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.RelationType;
34
import it.cnr.istc.pst.platinum.ai.framework.parameter.lang.EnumerationParameterDomain;
35
import it.cnr.istc.pst.platinum.ai.framework.parameter.lang.NumericParameterDomain;
36
import it.cnr.istc.pst.platinum.ai.framework.parameter.lang.ParameterDomain;
37
import it.cnr.istc.pst.platinum.ai.framework.parameter.lang.ParameterDomainType;
38
import it.cnr.istc.pst.platinum.ai.framework.parameter.lang.constraints.ParameterConstraintType;
39
import it.cnr.istc.pst.platinum.ai.lang.ddl.DomainCompiler;
40
import it.cnr.istc.pst.platinum.ai.lang.ddl.DomainCompilerType;
41
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLComponent;
42
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLComponentDecision;
43
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLComponentType;
44
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLConsumableResourceComponentDecision;
45
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLConsumableResourceComponentType;
46
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLDomain;
47
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLEnumerationParameterConstraint;
48
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLEnumerationParameterConstraint.DDLEnumerationParameterConstraintType;
49
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLEnumerationParameterType;
50
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLInstantiatedComponentDecision;
51
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLNumericParameterConstraint;
52
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLNumericParameterConstraint.DDLNumericParameterConstraintType;
53
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLNumericParameterType;
54
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLParameterConstraint;
55
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLParameterType;
56
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLProblem;
57
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLRenewableResourceComponentDecision;
58
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLRenewableResourceComponentType;
59
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLSimpleGroundStateVariableComponentDecision;
60
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLSingletonStateVariableComponentDecision;
61
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLSingletonStateVariableComponentDecisionType;
62
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLSingletonStateVariableComponentType;
63
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLSingletonStateVariableTransitionConstraint;
64
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLSynchronization;
65
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLTemporalRelation;
66
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLTemporalRelationType;
67
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLTimeline;
68
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.DDLTimelineSynchronization;
69
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.ddl3Lexer;
70
import it.cnr.istc.pst.platinum.ai.lang.ddl.v3.parser.ddl3Parser;
71
72
/**
73
 * 
74
 * @author anacleto
75
 *
76
 */
77
public class DDLv3Compiler extends DomainCompiler 
78
{
79
	private long origin;
80
	private long horizon;
81
	
82
	protected DDLDomain ddl_domain;
83
    protected DDLProblem ddl_problem;
84
	
85
	/**
86
	 * 
87
	 * @param ddlFilePath
88
	 * @param pdlFilePath
89
	 */
90
	protected DDLv3Compiler(String ddlFilePath, String pdlFilePath) {
91
		super(DomainCompilerType.DDLv3, ddlFilePath, pdlFilePath);
92
	}
93
	
94
	/**
95
	 * 
96
	 * @param ddlFilePath
97
	 */
98
	protected DDLv3Compiler(String ddlFilePath) {
99
		super(DomainCompilerType.DDLv3, ddlFilePath);
100
	}
101
	
102
	/**
103
     * 
104
     * @return
105
     * @throws SynchronizationCycleException
106
     */
107
	@Override
108
    public PlanDataBase compileDomain() 
109
    		throws SynchronizationCycleException 
110
	{
111
		try 
112
		{
113
    		// parse domain
114
    		this.doParseDDLFile(this.ddlFilePath);
115
    	} 
116
    	catch (IOException | RecognitionException ex) {
117
    		throw new RuntimeException(ex.getMessage());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
118
    	}
119
    	
120
		// actually compile domain
121
    	return this.doCompileDomain();
122
    }
123
	
124
    /**
125
     * 
126
     */
127
	@Override
128
    public Problem compileProblem(PlanDataBase pdb) 
129
	{
130
		try 
131
		{
132
    		// parse problem
133
	    	this.doParseDDLFile(this.pdlFilePath);
134
    	} 
135
    	catch (IOException | RecognitionException ex) {
136
    		throw new RuntimeException(ex.getMessage());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
137
    	}
138
    	
139
    	// actually compile problem
140
    	return this.doCompileProblem(pdb);
141
    }
142
	
143
    /**
144
     * 
145
     * @param ddlFilePath
146
     * @throws IOException
147
     * @throws RecognitionException
148
     */
149
    private void doParseDDLFile(String ddlFilePath) 
150
    		throws IOException, RecognitionException 
151
    {
152
    	// parse domain
153
    	CharStream dcs = new ANTLRFileStream(ddlFilePath);
154
		ddl3Lexer lexer = new ddl3Lexer(dcs);
155
		CommonTokenStream tokens = new CommonTokenStream();
156
		tokens.setTokenSource(lexer);
157
		ddl3Parser parser = new ddl3Parser(tokens);
158
		final ddl3Parser.ddl_return parserResult = parser.ddl();
159
		Tree ddl = (Tree) parserResult.getTree();
160
		if (ddl.getChild(0) instanceof DDLDomain) 
161
		{
162
		    this.ddl_domain = (DDLDomain) ddl.getChild(0);
163
		    this.ddl_domain.parse();
164
		    
165
		    // parse problem specification
166
		    if (ddl.getChild(1) instanceof DDLProblem) 
167
		    {
168
				this.ddl_problem = (DDLProblem) ddl.getChild(1);
169
				this.ddl_problem.parse();
170
		    } 
171
		    else {
172
		    	// error while parsing
173
		    	this.ddl_problem = null;
174
		    }
175
		} 
176
		else 
177
		{
178
		    this.ddl_problem = (DDLProblem) ddl.getChild(0);
179
		    this.ddl_problem.parse();
180
		    this.ddl_domain = null;
181
		}
182
    }
183
184
	/**
185
	 * 
186
	 */
187
	private PlanDataBase doCompileDomain() 
188
			throws SynchronizationCycleException 
189
	{
190
		// get parameter
191
		this.origin = this.ddl_domain.getTemporalModule().getRange().getMin();
192
		this.horizon = this.ddl_domain.getTemporalModule().getRange().getMax();
193
		String name = this.ddl_domain.getName();
194
		
195
		// create plan data-base
196
		PlanDataBase pdb = PlanDataBaseBuilder.createAndSet(name, this.origin, this.horizon);
197
		
198
		// add parameter domain declaration
199
		this.addParameterDomains(pdb);
200
		
201
		// add data
202
		this.addComponents(pdb);
203
		
204
		// add synchronization rules
205
		this.addSynchronizationRules(pdb);
206
		
207
		// get created plan data-base
208
		return pdb;
209
	}
210
	
211
	/**
212
	 * 
213
	 */
214
	private Problem doCompileProblem(PlanDataBase pdb) {
215
		// create problem
216
		Problem problem = new Problem();
217
		
218
		// local cache
219
		Map<String, ProblemGoal> goals = new HashMap<>();
220
		Map<String, ProblemFluent> label2fluent = new HashMap<>();
221
		
222
		
223
		// check problem decisions
224
		for (DDLInstantiatedComponentDecision ddlDec : this.ddl_problem.getComponentDecisions().values()) {
225
			// get related component
226
			DomainComponent comp = pdb.getComponentByName(ddlDec.getComponent());
227
			
228
			// get related value
229
			ComponentValue val = comp.getValueByName(ddlDec.getComponentDecision().getName());
230
231
			// check if component is external
232
			if (comp.isExternal()) {
233
				// add observation
234
				ProblemFact fact = this.addObservationToProblem(problem, val, ddlDec);
235
				for (String label : fact.getParameterLabels()) {
236
					label2fluent.put(label, fact);
237
				}
238
			}
239
			else {
240
				// check type of decision
241
				if (ddlDec.getParameters().contains("fact")) {
242
					// add fact to problem
243
					ProblemFact fact = this.addFactToProblem(problem, val, ddlDec);
244
					for (String label : fact.getParameterLabels()) {
245
						label2fluent.put(label, fact);
246
					}
247
				}
248
				else if (ddlDec.getParameters().contains("goal")) {
249
					// add goal to problem
250
					ProblemGoal goal = this.addGoalToProblem(problem, val, ddlDec);
251
					goals.put(ddlDec.getId(), goal);
252
					for (String label : goal.getParameterLabels()) {
253
						label2fluent.put(label, goal);
254
					}
255
				}
256
				else {
257
					throw new RuntimeException("The decision " + ddlDec + " must be a fact or a goal");
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
258
				}
259
			}
260
		}
261
		
262
		// add constraints between goals
263
		for (DDLTemporalRelation ddlRel : this.ddl_problem.getTemporalRelations()) {
264
			// get related goals
265
			ProblemGoal reference = goals.get(ddlRel.getFrom());
266
			ProblemGoal target = goals.get(ddlRel.getTo());
267
			// add constraint between goals
268
			this.addBinaryGoal(problem, reference, target, ddlRel.getRelationType());
269
		}
270
		
271
		// add parameter constraints
272
		for (DDLParameterConstraint ddlRel : this.ddl_problem.getParameterConstraints()) {
273
			// check type
274
			switch (ddlRel.getConstraintType()) {
275
				// enumeration constraint
276
				case ENUMERATION : {
277
					// get enumeration
278
					DDLEnumerationParameterConstraint ddlpc = (DDLEnumerationParameterConstraint) ddlRel;
279
					// get related fluent
280
					ProblemFluent fluent = label2fluent.get(ddlpc.getLeftTerm());
281
					// check relation type
282
					if (ddlpc.getEnumerationConstraintType().equals(DDLEnumerationParameterConstraintType.NEQ)) {
283
						throw new RuntimeException("Unknown enumeration constraint type " + ddlpc.getEnumerationConstraintType());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
284
					}
285
					
286
					// add binding parameter constraint
287
					problem.addBindingParameterConstraint(fluent, ddlpc.getLeftTerm(), ddlpc.getValue());
288
				}
289
				break;
290
					
291
				// numeric constraint
292
				case NUMERIC : {
293
					// get numeric
294
					DDLNumericParameterConstraint ddlpc = (DDLNumericParameterConstraint) ddlRel;
295
					// get reference
296
					ProblemFluent reference = label2fluent.get(ddlpc.getLeftTerm());
297
					String referenceLabel = ddlpc.getLeftTerm();
298
					
299
					// check if binary constraint
300
					if (ddlpc.getRightVariables() != null && ddlpc.getRightVariables().get(0) != null) {
301
						// get relation type
302
						RelationType relType;
303
						switch (ddlpc.getNumericConstraintType()) {
304
							case EQ : {
305
								// set relation type
306
								relType = RelationType.EQUAL_PARAMETER;
307
							}
308
							break;
309
						
310
							case NEQ : {
311
								// set relation type
312
								relType = RelationType.NOT_EQUAL_PARAMETER;
313
							}
314
							break;
315
							
316
							default : {
317
								throw new RuntimeException("Unknown numeric constraint type " + ddlpc.getNumericConstraintType());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
318
							}
319
						}
320
						
321
						// get targets
322
						for (String targetLabel : ddlpc.getRightVariables()) {
323
							// get target fluent
324
							ProblemFluent target = label2fluent.get(targetLabel);
325
							// create constraint
326
							problem.addParameterConstraint(relType, reference, referenceLabel, target, targetLabel);
327
						}
328
					}
329
					else {
330
						// check relation type
331
						if (ddlpc.getNumericConstraintType().equals(DDLNumericParameterConstraintType.NEQ)) {
332
							throw new RuntimeException("Unknown numeric constraint type " + ddlpc.getNumericConstraintType());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
333
						}
334
						
335
						// add constraint
336
						problem.addBindingParameterConstraint(reference, referenceLabel, Integer.toString(ddlpc.getRightCoefficients().get(0)));
337
					}
338
				}
339
				break;
340
			}
341
		}
342
		
343
		// get created problem
344
		return problem;
345
	}
346
	
347
	/**
348
	 * 
349
	 * @param problem
350
	 * @param val
351
	 * @param ddlDec
352
	 * @return
353
	 */
354 View Code Duplication
	private ProblemGoal addGoalToProblem(Problem problem, ComponentValue val, DDLInstantiatedComponentDecision ddlDec) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
355
		// set start bound
356
		long[] start = new long[] {this.origin, this.horizon};
357
		// check start bounds
358
		if (ddlDec.getStart() != null) {
359
			start = new long[] {
360
				ddlDec.getStart().getMin(),
361
				ddlDec.getStart().getMax() > this.horizon ? 
362
						this.horizon : 
363
						ddlDec.getStart().getMax()
364
			};
365
		}
366
		
367
		// set end bound 
368
		long[] end = new long[] {this.origin, this.horizon};
369
		if (ddlDec.getEnd() != null) {
370
			end = new long[] {
371
					ddlDec.getEnd().getMin(),
372
					ddlDec.getEnd().getMax() > this.horizon ? 
373
							this.horizon : 
374
							ddlDec.getEnd().getMax()
375
				};
376
		}
377
		
378
		// parameter labels
379
		String[] labels = new String[] {};
380
		if (ddlDec.getComponentDecision() instanceof DDLSingletonStateVariableComponentDecision) {
381
			// get decision
382
			DDLSingletonStateVariableComponentDecision ddlSingleton = (DDLSingletonStateVariableComponentDecision) ddlDec.getComponentDecision();
383
			labels = ddlSingleton.getParameterNames().toArray(new String[ddlSingleton.getParameterNames().size()]);
384
		}
385
		// add goal
386
		return problem.addGoal(val, labels, start, end);
387
	}
388
389
	/**
390
	 * 
391
	 * @param problem
392
	 * @param val
393
	 * @param ddlDec
394
	 * @return
395
	 */
396 View Code Duplication
	private ProblemFact addFactToProblem(Problem problem, ComponentValue val, DDLInstantiatedComponentDecision ddlDec) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
397
		// set start bound
398
		long[] start = new long[] {this.origin, this.horizon};
399
		// check start bounds
400
		if (ddlDec.getStart() != null) {
401
			start = new long[] {
402
				ddlDec.getStart().getMin(),
403
				ddlDec.getStart().getMax() > this.horizon ? 
404
						this.horizon : 
405
						ddlDec.getStart().getMax()
406
			};
407
		}
408
		
409
		// set end bound 
410
		long[] end = new long[] {this.origin, this.horizon};
411
		if (ddlDec.getEnd() != null) {
412
			end = new long[] {
413
					ddlDec.getEnd().getMin(),
414
					ddlDec.getEnd().getMax() > this.horizon ? 
415
							this.horizon : 
416
							ddlDec.getEnd().getMax()
417
				};
418
		}
419
		
420
		// parameter labels
421
		String[] labels = new String[] {};
422
		if (ddlDec.getComponentDecision() instanceof DDLSingletonStateVariableComponentDecision) {
423
			// get decision
424
			DDLSingletonStateVariableComponentDecision ddlSingleton = (DDLSingletonStateVariableComponentDecision) ddlDec.getComponentDecision();
425
			labels = ddlSingleton.getParameterNames().toArray(new String[ddlSingleton.getParameterNames().size()]);
426
		}
427
		
428
		// add a fact
429
		return problem.addFact(val, labels, start, end);
430
	}
431
432
	/**
433
	 * 
434
	 * @param problem
435
	 * @param val
436
	 * @param ddlDec
437
	 * @return
438
	 */
439
	private ProblemFact addObservationToProblem(Problem problem, ComponentValue val, DDLInstantiatedComponentDecision ddlDec) 
440
	{
441
		// set start bound
442
		long[] start = new long[] {this.origin, this.horizon};
443
		// check start bounds
444
		if (ddlDec.getStart() != null) {
445
			start = new long[] {
446
				ddlDec.getStart().getMin(),
447
				ddlDec.getStart().getMax() > this.horizon ? 
448
						this.horizon : 
449
						ddlDec.getStart().getMax()
450
			};
451
		}
452
		
453
		// set end bound 
454
		long[] end = new long[] {this.origin, this.horizon};
455
		if (ddlDec.getEnd() != null) {
456
			end = new long[] {
457
					ddlDec.getEnd().getMin(),
458
					ddlDec.getEnd().getMax() > this.horizon ? 
459
							this.horizon : 
460
							ddlDec.getEnd().getMax()
461
				};
462
		}
463
		
464
		// set duration bound
465
		long[] duration = new long[] {1, this.horizon};
466
		if (ddlDec.getDuration() != null) {
467
			duration = new long[] {
468
					ddlDec.getDuration().getMin(),
469
					ddlDec.getDuration().getMax() > this.horizon ? 
470
							this.horizon : 
471
							ddlDec.getDuration().getMax()
472
				};
473
		}
474
		
475
		// parameter labels
476
		String[] labels = new String[] {};
477
		if (ddlDec.getComponentDecision() instanceof DDLSingletonStateVariableComponentDecision) {
478
			// get decision
479
			DDLSingletonStateVariableComponentDecision ddlSingleton = (DDLSingletonStateVariableComponentDecision) ddlDec.getComponentDecision();
480
			labels = ddlSingleton.getParameterNames().toArray(new String[ddlSingleton.getParameterNames().size()]);
481
		}
482
		// add observation
483
		return problem.addObservation(val, labels, start, end, duration);
484
	}
485
486
	/**
487
	 * 
488
	 * @param problem
489
	 * @param reference
490
	 * @param target
491
	 * @param ddlRelType
492
	 */
493 View Code Duplication
	private void addBinaryGoal(Problem problem, ProblemGoal reference, ProblemGoal target, DDLTemporalRelationType ddlRelType) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
494
		// check relation type
495
		if (ddlRelType.getText().equalsIgnoreCase("meets")) {
496
			// create meets constraint
497
			problem.addTemporalConstraint(RelationType.MEETS, reference, target, new long[][] {});
498
		}
499
		else if (ddlRelType.getText().equalsIgnoreCase("met-by")) {
500
			// create met-by constraint
501
			problem.addTemporalConstraint(RelationType.MET_BY, reference, target, new long[][] {});
502
		}
503
		else if (ddlRelType.getText().equalsIgnoreCase("during")) { 
504
			// create during constraint
505
			problem.addTemporalConstraint(RelationType.DURING, reference, target, 
506
				new long[][] {
507
					new long[] {
508
						ddlRelType.getFirstRange().getMin(),
509
						ddlRelType.getFirstRange().getMax() > this.horizon ? 
510
								this.horizon :
511
								ddlRelType.getFirstRange().getMax()
512
					},
513
					new long[] {
514
						ddlRelType.getSecondRange().getMin(),
515
						ddlRelType.getSecondRange().getMax() > this.horizon ? 
516
								this.horizon :
517
								ddlRelType.getSecondRange().getMax()
518
					}
519
				});
520
		}
521
		else if (ddlRelType.getText().equalsIgnoreCase("equals")) {
522
			// create equals constraint
523
			problem.addTemporalConstraint(RelationType.EQUALS, reference, target, new long[][] {});
524
		}
525
		else if (ddlRelType.getText().equalsIgnoreCase("contains")) {
526
			// create contains constraint
527
			problem.addTemporalConstraint(RelationType.CONTAINS, reference, target, 
528
				new long[][] {
529
					new long[] {
530
						ddlRelType.getFirstRange().getMin(),
531
						ddlRelType.getFirstRange().getMax() > this.horizon ? 
532
								this.horizon : 
533
								ddlRelType.getFirstRange().getMax()
534
					},
535
					new long[] {
536
						ddlRelType.getSecondRange().getMin(),
537
						ddlRelType.getSecondRange().getMax() > this.horizon ?
538
								this.horizon : 
539
								ddlRelType.getSecondRange().getMax()
540
					}
541
				});
542
		}
543
		else if (ddlRelType.getText().equalsIgnoreCase("before")) {
544
			problem.addTemporalConstraint(RelationType.BEFORE, reference, target, 
545
				new long[][] {
546
					new long[] {
547
						ddlRelType.getFirstRange().getMin(),
548
						ddlRelType.getFirstRange().getMax() > this.horizon ? 
549
								this.horizon :
550
								ddlRelType.getFirstRange().getMax()
551
					}
552
				});
553
		}
554
		else if (ddlRelType.getText().equalsIgnoreCase("after")) {
555
			problem.addTemporalConstraint(RelationType.AFTER, reference, target, 
556
					new long[][] {
557
						new long[] {
558
							ddlRelType.getFirstRange().getMin(),
559
							ddlRelType.getFirstRange().getMax() > this.horizon ? 
560
									this.horizon :
561
									ddlRelType.getFirstRange().getMax()
562
						}
563
					});
564
		}
565
		else if (ddlRelType.getText().equalsIgnoreCase("start-start")) {
566
			problem.addTemporalConstraint(RelationType.START_START, reference, target, 
567
					new long[][] {
568
						new long[] {
569
								ddlRelType.getFirstRange().getMin(),
570
								ddlRelType.getFirstRange().getMax() > this.horizon ? 
571
										this.horizon : 
572
										ddlRelType.getFirstRange().getMax()
573
						}
574
			});
575
		}
576
		else if (ddlRelType.getText().equalsIgnoreCase("end-end")) {
577
			problem.addTemporalConstraint(RelationType.END_END, reference, target, 
578
					new long[][] {
579
						new long[] {
580
								ddlRelType.getFirstRange().getMin(),
581
								ddlRelType.getFirstRange().getMax() > this.horizon ? 
582
										this.horizon : 
583
										ddlRelType.getFirstRange().getMax()
584
						}
585
			});
586
		}
587
		else if (ddlRelType.getText().equalsIgnoreCase("starts-during")) {
588
			problem.addTemporalConstraint(RelationType.STARTS_DURING, reference, target, 
589
					new long[][] {
590
						new long[] {
591
							ddlRelType.getFirstRange().getMin(),
592
							ddlRelType.getFirstRange().getMax() > this.horizon ? 
593
									this.horizon :
594
									ddlRelType.getFirstRange().getMax()
595
						},
596
						new long[] {
597
							ddlRelType.getSecondRange().getMin(),
598
							ddlRelType.getSecondRange().getMax() > this.horizon ? 
599
									this.horizon : 
600
									ddlRelType.getSecondRange().getMax()
601
						}
602
					});
603
		}
604
		else if (ddlRelType.getText().equalsIgnoreCase("ends-during")) {
605
			problem.addTemporalConstraint(RelationType.ENDS_DURING, reference, target, 
606
					new long[][] {
607
						new long[] {
608
							ddlRelType.getFirstRange().getMin(),
609
							ddlRelType.getFirstRange().getMax() > this.horizon ? 
610
									this.horizon :
611
									ddlRelType.getFirstRange().getMax()
612
						},
613
						new long[] {
614
								ddlRelType.getSecondRange().getMin(),
615
								ddlRelType.getSecondRange().getMax() > this.horizon ? 
616
										this.horizon : 
617
										ddlRelType.getSecondRange().getMax()
618
							}
619
					});
620
		}
621
		else {
622
			
623
			throw new RuntimeException("Unknown temporal relation " + ddlRelType);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
624
		}
625
	}
626
	
627
	/**
628
	 * 
629
	 * @param pdb
630
	 */
631
	private void addParameterDomains(PlanDataBase pdb) {
632
		// add parameter domains 
633
		for (String name : this.ddl_domain.getParameterTypes().keySet()) {
634
			// get parameter declaration
635
			DDLParameterType pDomType = this.ddl_domain.getParameterTypes().get(name);
636
			// check type
637
			switch (pDomType.getDomainType()) 
638
			{
639
				// numeric parameter
640
				case NUMERIC : {
641
					// get numeric domain
642
					DDLNumericParameterType numeric = (DDLNumericParameterType) pDomType;
643
					// create domain parameter
644
					NumericParameterDomain dom  = pdb.createParameterDomain(name, ParameterDomainType.NUMERIC_DOMAIN_PARAMETER_TYPE);
645
					// set bounds
646
					dom.setLowerBound(numeric.getLowerBound());
647
					dom.setUpperBound(numeric.getUpperBound());
648
				}
649
				break;
650
				
651
				// enumeration parameter
652
				case ENUMERATION : {
653
					// get enumeration domain
654
					DDLEnumerationParameterType enumeration = (DDLEnumerationParameterType) pDomType;
655
					// create domain parameter
656
					EnumerationParameterDomain dom = pdb.createParameterDomain(name, ParameterDomainType.ENUMERATION_DOMAIN_PARAMETER_TYPE);
657
					// set values
658
					dom.setValues(enumeration.getEnums().toArray(new String[enumeration.getEnums().size()]));
659
				}
660
				break;
661
			}
662
		}
663
	}
664
	
665
	/**
666
	 * 
667
	 * @param pdb
668
	 */
669
	private void addComponents(PlanDataBase pdb) 
670
	{
671
		// get domain components
672
		for (DDLComponent ddlComponent : this.ddl_domain.getComponents().values()) 
673
		{
674
			// get component type
675
			DDLComponentType ctype = this.ddl_domain.getComponentTypes().get(ddlComponent.getComponentType());
676
			// check component type
677
			if (ctype instanceof DDLSingletonStateVariableComponentType) 
678
			{
679
				// add state variable
680
				this.addStateVariable(pdb, ddlComponent);
681
			}
682
			else if (ctype instanceof DDLRenewableResourceComponentType)
683
			{
684
				// add discrete resource
685
				this.addDiscreteResource(pdb, ddlComponent);
686
			}
687
			else if (ctype instanceof DDLConsumableResourceComponentType)
688
			{
689
				// add reservoir resource
690
				this.addReservoirResource(pdb, ddlComponent);
691
			}
692
			else {
693
				// unknown 
694
				throw new RuntimeException("Unknown/Unrecognized component type\n"
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
695
						+ "- Parsed component " + ddlComponent.getName() + " (" + ddlComponent.getType() + ")\n"
696
						+ "- " + ctype + "\n");
697
			}
698
		}
699
	}
700
	
701
	/**
702
	 * 
703
	 * @param pdb
704
	 * @throws SynchronizationCycleException
705
	 */
706
	private void addSynchronizationRules(PlanDataBase pdb) 
707
			throws SynchronizationCycleException 
708
	{
709
		try 
710
		{
711
			// add synchronization on components
712
			for (DDLTimelineSynchronization ddlComponentSynch : this.ddl_domain.getTimelineSynchronizations()) 
713
			{
714
				// get reference component
715
				DomainComponent comp = pdb.getComponentByName(ddlComponentSynch.getComponent());
716
				
717
				// check component's synchronizations
718
				for (DDLSynchronization ddlSynch : ddlComponentSynch.getSynchronizations()) 
719
				{
720
					// get synchronization's reference
721
					DDLComponentDecision ddlReference = ddlSynch.getReference();
722
					// check type
723
					switch (ddlReference.getDecisionType()) 
724
					{
725
						// singleton decision
726
						case SINGLETON : {
727
							// create synchronization 
728
							this.doCreateSynchronizationFromSingletonDecision(ddlSynch, comp, pdb);
729
						}
730
						break;
731
						
732
						// ground decision
733
						case GROUND : {
734
							// create synchronization
735
							this.doCreateSynchronizationFromGroundDecision(ddlSynch, comp, pdb);
736
						}
737
						break;
738
						
739
						// reservoir resource usage
740
						case CONSUMABLE_RESOURCE_REQUIREMENT : {
741
							// create synchronization
742
							this.doCreateSynchronizationFromConsumableResourceValue(ddlSynch, (ReservoirResource) comp, pdb);
743
						}
744
						break;
745
						
746
						// discrete resource usage
747
						case RENEWABLE_RESOURCE_REQUIREMENT : {
0 ignored issues
show
Comprehensibility introduced by
End this switch case with an unconditional break, return or throw statement.
Loading history...
748
							 // create synchronization
749
							this.doCreateSynchronizationFromRenewableResourceValue(ddlSynch, (DiscreteResource) comp, pdb);
750
						}
751
						
752
						default : {
753
							throw new RuntimeException("Synchronization on unknown type of value " + ddlReference.getDecisionType());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
754
						}
755
					}
756
				}
757
			}
758
		}
759
		catch (DomainComponentNotFoundException ex) {
760
			throw new RuntimeException(ex.getMessage());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
761
		}
762
	}
763
764
	/**
765
	 * 
766
	 * @param ddlSynch
767
	 * @param comp
768
	 * @param pdb
769
	 * @throws DomainComponentNotFoundException
770
	 * @throws SynchronizationCycleException
771
	 */
772 View Code Duplication
	private void doCreateSynchronizationFromRenewableResourceValue(DDLSynchronization ddlSynch, DiscreteResource comp, PlanDataBase pdb) 
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
773
			throws DomainComponentNotFoundException, SynchronizationCycleException
774
	{
775
		// setup auxiliary data structures
776
		Map<String, TokenVariable> label2variable = new HashMap<>();
777
		Map<String, TokenVariable> decId2variable = new HashMap<>();
778
		
779
		// get reference decision
780
		DDLRenewableResourceComponentDecision ddlDec = (DDLRenewableResourceComponentDecision) ddlSynch.getReference();
781
		
782
		// get trigger value
783
		RequirementResourceValue valTrigger = comp.getRequirementValue();
784
		
785
		// create synchronization
786
		SynchronizationRule rule = pdb.createSynchronizationRule(valTrigger, new String[] {ddlDec.getRequirementName()}); 
787
		// add entry to parameter label index
788
		for (String label : rule.getTriggerer().getParameterLabels()) {
789
			label2variable.put(label, rule.getTriggerer());
790
		}
791
		
792
		// check target values
793
		for (DDLInstantiatedComponentDecision ddlTarget : ddlSynch.getTargets().values()) 
794
		{
795
			// get target component
796
			DomainComponent targetComponent = pdb.getComponentByName(ddlTarget.getComponent());
797
			// check target component type
798
			switch (targetComponent.getType())
799
			{
800
				// state variable component
801
				case SV_EXTERNAL : 
802
				case SV_FUNCTIONAL : 
803
				case SV_PRIMITIVE : 
804
				{
805
					// check target decision
806
					DDLComponentDecision ddlTargetDecision = ddlTarget.getComponentDecision();
807
					// check decision type
808
					switch (ddlTargetDecision.getDecisionType())
809
					{
810
						// decision with parameters
811
						case SINGLETON :
812
						{
813
							// cast decision
814
							DDLSingletonStateVariableComponentDecision ddlSingletonTarget = (DDLSingletonStateVariableComponentDecision) ddlTargetDecision;
815
							
816
							// get target value
817
							ComponentValue targetValue = targetComponent.getValueByName(ddlSingletonTarget.getName());
818
							
819
							// add token variable
820
							TokenVariable target = rule.addTokenVariable(targetValue, 
821
									ddlSingletonTarget.getParameterNames().toArray(new String[ddlSingletonTarget.getParameterNames().size()]));
822
							
823
							// check solving knowledge
824
							if (!ddlTarget.getParameters().isEmpty()) {
825
								// check mandatory expansion
826
								if (ddlTarget.getParameters().contains("!")) {
827
									// set knowledge
828
									target.setMandatoryExpansion();
829
								}
830
								
831
								// check mandatory unification
832
								if (ddlTarget.getParameters().contains("?")) {
833
									target.setMandatoryUnification();
834
								}
835
							}
836
							
837
							// add entry to index
838
							for (String label : target.getParameterLabels()) {
839
								// add entry
840
								label2variable.put(label, target);
841
							}
842
							
843
							// get synchronization decision's ID
844
							String id = ddlTarget.getId();
845
							// check if target id already exists 
846
							if (decId2variable.containsKey(id)) {
847
								throw new RuntimeException("Duplicated decision ID <" + id + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
848
							}
849
							
850
							// add entry 
851
							decId2variable.put(id, target);
852
						}
853
						break;
854
						
855
						// ground decision
856
						case GROUND : 
857
						{
858
							// cast decision
859
							DDLSimpleGroundStateVariableComponentDecision ddlGroundTarget = (DDLSimpleGroundStateVariableComponentDecision) ddlTargetDecision;
860
							// get target value
861
							ComponentValue targetValue = targetComponent.getValueByName(ddlGroundTarget.getName());
862
							
863
							// add token variable with no parameter labels
864
							TokenVariable target = rule.addTokenVariable(targetValue, new String[] {}); 
865
							
866
							// check solving knowledge
867
							if (!ddlTarget.getParameters().isEmpty()) {
868
								// check mandatory expansion
869
								if (ddlTarget.getParameters().contains("!")) {
870
									// set knowledge
871
									target.setMandatoryExpansion();
872
								}
873
								
874
								// check mandatory unification
875
								if (ddlTarget.getParameters().contains("?")) {
876
									target.setMandatoryUnification();
877
								}
878
							}
879
							
880
							// get synchronization decision's ID
881
							String id = ddlTarget.getId();
882
							// check if target id already exists 
883
							if (decId2variable.containsKey(id)) {
884
								throw new RuntimeException("Duplicated decision ID <" + id + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
885
							}
886
							
887
							// add entry 
888
							decId2variable.put(id, target);
889
						}
890
						break;
891
						
892
						default : {
893
							throw new RuntimeException("Unknown state variable decision type - " + ddlTargetDecision.getDecisionType());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
894
						}
895
					}
896
					
897
					
898
				}
899
				break;
900
				
901
				// discrete resource component
902
				case RESOURCE_DISCRETE : 
903
				{
904
					// check target decision
905
					DDLComponentDecision ddlTargetDecision = ddlTarget.getComponentDecision();
906
					// cast decision
907
					DDLRenewableResourceComponentDecision ddlRequirementTarget = (DDLRenewableResourceComponentDecision) ddlTargetDecision;
908
					// get target component
909
					DiscreteResource resource = (DiscreteResource) targetComponent;
910
					 
911
					// get target value 
912
					ComponentValue targetValue = resource.getRequirementValue();
913
					// add token variable
914
					TokenVariable target = rule.addTokenVariable(targetValue,
915
							new String[] {ddlRequirementTarget.getRequirementName()});
916
					
917
					// add entry to index
918
					for (String label : target.getParameterLabels()) {
919
						// add entry
920
						label2variable.put(label, target);
921
					}
922
					
923
					// get synchronization decision's ID
924
					String id = ddlTarget.getId();
925
					// check if target id already exists 
926
					if (decId2variable.containsKey(id)) {
927
						throw new RuntimeException("Duplicated decision ID <" + id + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
928
					}
929
					
930
					// add entry 
931
					decId2variable.put(id, target);
932
				}
933
				break;
934
				
935
				// reservoir resource component
936
				case RESOURCE_RESERVOIR : 
937
				{
938
					// get target component
939
					ReservoirResource resource = (ReservoirResource) targetComponent;
940
941
					// check target decision
942
					DDLComponentDecision ddlTargetDecision = ddlTarget.getComponentDecision();
943
					// cast decision
944
					DDLConsumableResourceComponentDecision ddlConsumableTarget = (DDLConsumableResourceComponentDecision) ddlTargetDecision;
945
					// check decision type
946
					switch (ddlConsumableTarget.getComponentDecisionType())
947
					{
948
						// resource consumption
949
						case Consumption : 
950
						{
951
							// get target value 
952
							ComponentValue consumption = resource.getConsumptionValue();
953
							// add token variable
954
							TokenVariable target = rule.addTokenVariable(consumption,
955
									new String[] {ddlConsumableTarget.getParameterName()});
956
							
957
							// add entry to index
958
							for (String label : target.getParameterLabels()) {
959
								// add entry
960
								label2variable.put(label, target);
961
							}
962
							
963
							// get synchronization decision's ID
964
							String id = ddlTarget.getId();
965
							// check if target id already exists 
966
							if (decId2variable.containsKey(id)) {
967
								throw new RuntimeException("Duplicated decision ID <" + id + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
968
							}
969
							
970
							// add entry 
971
							decId2variable.put(id, target);
972
						}
973
						break;
974
						
975
						// resource production 
976
						case Production : 
977
						{
978
							// get target value 
979
							ComponentValue production = resource.getProductionValue();
980
							// add token variable
981
							TokenVariable target = rule.addTokenVariable(production,
982
									new String[] {ddlConsumableTarget.getParameterName()});
983
							
984
							// add entry to index
985
							for (String label : target.getParameterLabels()) {
986
								// add entry
987
								label2variable.put(label, target);
988
							}
989
							
990
							// get synchronization decision's ID
991
							String id = ddlTarget.getId();
992
							// check if target id already exists 
993
							if (decId2variable.containsKey(id)) {
994
								throw new RuntimeException("Duplicated decision ID <" + id + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
995
							}
996
							
997
							// add entry 
998
							decId2variable.put(id, target);
999
						}
1000
						break;
1001
					}
1002
					
1003
					
1004
				}
1005
				break;
1006
				
1007
				default : {
1008
					// unknown target component type
1009
					throw new RuntimeException("Unknownw target component found into synchronization constraint" + ddlTarget);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1010
				}
1011
			}
1012
		}
1013
		
1014
		// set temporal relations
1015
		for (DDLTemporalRelation ddlRel : ddlSynch.getTemporalRelations()) 
1016
		{
1017
			// check relation type
1018
			DDLTemporalRelationType ddlRelType = ddlRel.getRelationType();
1019
			
1020
			// get constraint reference
1021
			TokenVariable cref;
1022
			// check reference's ID
1023
			if (ddlRel.getFrom() == null) {
1024
				cref = rule.getTriggerer();
1025
			}
1026
			else {
1027
				// check if reference exists
1028
				if (!decId2variable.containsKey(ddlRel.getFrom())) {
1029
					throw new RuntimeException("Unknown decision ID found <" + ddlRel.getFrom() + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1030
				}
1031
				
1032
				// get reference decision
1033
				cref = decId2variable.get(ddlRel.getFrom());
1034
			}
1035
			
1036
			// check if target exists
1037
			if (!decId2variable.containsKey(ddlRel.getTo())) {
1038
				throw new RuntimeException("Unknown decision ID found <" + ddlRel.getTo() + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1039
			}
1040
			
1041
			// get constraint target
1042
			TokenVariable ctarget = decId2variable.get(ddlRel.getTo());
1043
			
1044
			// create constraint
1045
			this.addConstraintToSynchronization(rule, cref, ctarget, ddlRelType);
1046
		}
1047
		
1048
		// set parameter relations
1049
		List<DDLParameterConstraint> ddlParameterConstraints = ddlSynch.getParameterConstraints();
1050
		for (DDLParameterConstraint ddlpc : ddlParameterConstraints) 
1051
		{
1052
			// check constraint type
1053
			switch (ddlpc.getConstraintType()) 
1054
			{
1055
				// enumeration parameter constraint
1056
				case ENUMERATION : 
1057
				{
1058
					// get enumeration constraint
1059
					DDLEnumerationParameterConstraint ddlEnumerationConstraint = (DDLEnumerationParameterConstraint) ddlpc;
1060
					// get reference variable
1061
					String leftTerm = ddlEnumerationConstraint.getLeftTerm();
1062
					
1063
					// check if parameter exists
1064
					if (!label2variable.containsKey(leftTerm)) {
1065
						throw new RuntimeException("Unknown reference parameter found <" + leftTerm + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1066
					}
1067
					
1068
					// get reference
1069
					TokenVariable pcReference = label2variable.get(leftTerm);
1070
					
1071
					// get value
1072
					String value = ddlEnumerationConstraint.getValue();
1073
					// get relation type
1074
					RelationType relType;
1075
					switch (ddlEnumerationConstraint.getEnumerationConstraintType()) {
1076
						// equal constraint
1077
						case EQ : {
1078
							// set relation type
1079
							relType = RelationType.BIND_PARAMETER;
1080
						}
1081
						break;
1082
						
1083
						default : {
1084
1085
							throw new RuntimeException("Unknownw enumeration constraint type " + ddlEnumerationConstraint.getEnumerationConstraintType());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1086
						}
1087
					}
1088
					
1089
					// create binding constraint
1090
					rule.addBindingConstraint(pcReference, relType, leftTerm, value);
1091
				}
1092
				break;
1093
				
1094
				// binary parameter constraint
1095
				case NUMERIC : 
1096
				{
1097
					// get numeric constraint
1098
					DDLNumericParameterConstraint ddlNumericConstraint = (DDLNumericParameterConstraint) ddlpc;
1099
					// get reference variable
1100
					String leftTerm = ddlNumericConstraint.getLeftTerm();
1101
					
1102
					// check if parameter exists
1103
					if (!label2variable.containsKey(leftTerm)) {
1104
						throw new RuntimeException("Unknown reference parameter found <" + leftTerm + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1105
					}
1106
					
1107
					// get reference
1108
					TokenVariable pcReference = label2variable.get(leftTerm);
1109
					
1110
					// check if binary
1111
					if (ddlNumericConstraint.isBinary()) 
1112
					{
1113
						// get relation type
1114
						RelationType relType;
1115
						switch (ddlNumericConstraint.getNumericConstraintType()) {
1116
							// equal constraint
1117
							case EQ : {
1118
								// set relation type
1119
								relType = RelationType.EQUAL_PARAMETER;
1120
							}
1121
							break;
1122
							
1123
							// not equal constraint
1124
							case NEQ : {
1125
								// set relation type
1126
								relType = RelationType.NOT_EQUAL_PARAMETER;
1127
							}
1128
							break;
1129
							
1130
							default : {
1131
1132
								throw new RuntimeException("Unknownw numeric constraint type " + ddlNumericConstraint.getNumericConstraintType());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1133
							}
1134
						}
1135
						
1136
						// check targets
1137
						for (String rightTerm : ddlNumericConstraint.getRightVariables()) {
1138
							// check if parameter exists
1139
							if (!label2variable.containsKey(rightTerm)) {
1140
								throw new RuntimeException("Unknown target found <" + rightTerm + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1141
							}
1142
							
1143
							// get target variable
1144
							TokenVariable pcTarget = label2variable.get(rightTerm);
1145
							
1146
							// create constraint
1147
							rule.addParameterConstraint(pcReference, pcTarget, relType, leftTerm, rightTerm);
1148
						}
1149
					}
1150
					else {
1151
						// not binary constraint, set bind constraint
1152
						int value = ddlNumericConstraint.getRightCoefficients().get(0);
1153
						// get relation type
1154
						RelationType relType;
1155
						switch (ddlNumericConstraint.getNumericConstraintType()) 
1156
						{
1157
							// equal constraint
1158
							case EQ : 
1159
							{
1160
								// set relation type
1161
								relType = RelationType.BIND_PARAMETER;
1162
							}
1163
							break;
1164
							
1165
							default : {
1166
1167
								throw new RuntimeException("Unknownw numeric constraint type " + ddlNumericConstraint.getNumericConstraintType());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1168
							}
1169
						}
1170
						
1171
						// create constraint
1172
						rule.addBindingConstraint(pcReference, relType, leftTerm, Integer.toString(value));
1173
					}
1174
				}
1175
			}
1176
		}
1177
		
1178
		// add synchronization rule
1179
		pdb.addSynchronizationRule(rule);
1180
	}
1181
	
1182
	/**
1183
	 * 
1184
	 * @param ddlSynch
1185
	 * @param comp
1186
	 * @param pdb
1187
	 * @throws DomainComponentNotFoundException
1188
	 * @throws SynchronizationCycleException
1189
	 */
1190
	private void doCreateSynchronizationFromConsumableResourceValue(DDLSynchronization ddlSynch, ReservoirResource comp, PlanDataBase pdb) 
1191
			throws DomainComponentNotFoundException, SynchronizationCycleException
1192
	{
1193
		// setup auxiliary data structures
1194
		Map<String, TokenVariable> label2variable = new HashMap<>();
1195
		Map<String, TokenVariable> decId2variable = new HashMap<>();
1196
		
1197
		// get reference decision
1198
		DDLConsumableResourceComponentDecision ddlDec = (DDLConsumableResourceComponentDecision) ddlSynch.getReference();
1199
		
1200
		// get trigger value
1201
		ComponentValue valTrigger = null;
1202
		// check decision type 
1203
		switch (ddlDec.getComponentDecisionType())
1204
		{
1205
			case Consumption : {
1206
				// set trigger value to consumption
1207
				valTrigger = comp.getConsumptionValue();
1208
			}
1209
			break;
1210
			
1211
			case Production : {
1212
				// set trigger value to production
1213
				valTrigger = comp.getProductionValue();
1214
			}
1215
			break;
1216
		}
1217
		
1218
		// create synchronization
1219
		SynchronizationRule rule = pdb.createSynchronizationRule(valTrigger, new String[] {ddlDec.getParameterName()}); 
1220
		// add entry to parameter label index
1221
		for (String label : rule.getTriggerer().getParameterLabels()) {
1222
			label2variable.put(label, rule.getTriggerer());
1223
		}
1224
		
1225
		// check target values
1226
		for (DDLInstantiatedComponentDecision ddlTarget : ddlSynch.getTargets().values()) 
1227
		{
1228
			// get target component
1229
			DomainComponent targetComponent = pdb.getComponentByName(ddlTarget.getComponent());
1230
			// check target component type
1231
			switch (targetComponent.getType())
1232
			{
1233
				// state variable component
1234
				case SV_EXTERNAL : 
1235
				case SV_FUNCTIONAL : 
1236
				case SV_PRIMITIVE : 
1237
				{
1238
					// check target decision
1239
					DDLComponentDecision ddlTargetDecision = ddlTarget.getComponentDecision();
1240
					// check decision type
1241
					switch (ddlTargetDecision.getDecisionType())
1242
					{
1243
						// decision with parameters
1244
						case SINGLETON :
1245
						{
1246
							// cast decision
1247
							DDLSingletonStateVariableComponentDecision ddlSingletonTarget = (DDLSingletonStateVariableComponentDecision) ddlTargetDecision;
1248
							
1249
							// get target value
1250
							ComponentValue targetValue = targetComponent.getValueByName(ddlSingletonTarget.getName());
1251
							
1252
							// add token variable
1253
							TokenVariable target = rule.addTokenVariable(targetValue, 
1254
									ddlSingletonTarget.getParameterNames().toArray(new String[ddlSingletonTarget.getParameterNames().size()]));
1255
							
1256
							// check solving knowledge
1257
							if (!ddlTarget.getParameters().isEmpty()) {
1258
								// check mandatory expansion
1259
								if (ddlTarget.getParameters().contains("!")) {
1260
									// set knowledge
1261
									target.setMandatoryExpansion();
1262
								}
1263
								
1264
								// check mandatory unification
1265
								if (ddlTarget.getParameters().contains("?")) {
1266
									target.setMandatoryUnification();
1267
								}
1268
							}
1269
							
1270
							// add entry to index
1271
							for (String label : target.getParameterLabels()) {
1272
								// add entry
1273
								label2variable.put(label, target);
1274
							}
1275
							
1276
							// get synchronization decision's ID
1277
							String id = ddlTarget.getId();
1278
							// check if target id already exists 
1279
							if (decId2variable.containsKey(id)) {
1280
								throw new RuntimeException("Duplicated decision ID <" + id + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1281
							}
1282
							
1283
							// add entry 
1284
							decId2variable.put(id, target);
1285
						}
1286
						break;
1287
						
1288
						// ground decision
1289
						case GROUND : 
1290
						{
1291
							// cast decision
1292
							DDLSimpleGroundStateVariableComponentDecision ddlGroundTarget = (DDLSimpleGroundStateVariableComponentDecision) ddlTargetDecision;
1293
							// get target value
1294
							ComponentValue targetValue = targetComponent.getValueByName(ddlGroundTarget.getName());
1295
							
1296
							// add token variable with no parameter labels
1297
							TokenVariable target = rule.addTokenVariable(targetValue, new String[] {}); 
1298
							
1299
							// check solving knowledge
1300
							if (!ddlTarget.getParameters().isEmpty()) {
1301
								// check mandatory expansion
1302
								if (ddlTarget.getParameters().contains("!")) {
1303
									// set knowledge
1304
									target.setMandatoryExpansion();
1305
								}
1306
								
1307
								// check mandatory unification
1308
								if (ddlTarget.getParameters().contains("?")) {
1309
									target.setMandatoryUnification();
1310
								}
1311
							}
1312
							
1313
							// get synchronization decision's ID
1314
							String id = ddlTarget.getId();
1315
							// check if target id already exists 
1316
							if (decId2variable.containsKey(id)) {
1317
								throw new RuntimeException("Duplicated decision ID <" + id + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1318
							}
1319
							
1320
							// add entry 
1321
							decId2variable.put(id, target);
1322
						}
1323
						break;
1324
						
1325
						default : {
1326
							throw new RuntimeException("Unknown state variable decision type - " + ddlTargetDecision.getDecisionType());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1327
						}
1328
					}
1329
					
1330
					
1331
				}
1332
				break;
1333
				
1334
				// discrete resource component
1335
				case RESOURCE_DISCRETE : 
1336
				{
1337
					// check target decision
1338
					DDLComponentDecision ddlTargetDecision = ddlTarget.getComponentDecision();
1339
					// cast decision
1340
					DDLRenewableResourceComponentDecision ddlRequirementTarget = (DDLRenewableResourceComponentDecision) ddlTargetDecision;
1341
					// get target component
1342
					DiscreteResource resource = (DiscreteResource) targetComponent;
1343
					 
1344
					// get target value 
1345
					ComponentValue targetValue = resource.getRequirementValue();
1346
					// add token variable
1347
					TokenVariable target = rule.addTokenVariable(targetValue,
1348
							new String[] {ddlRequirementTarget.getRequirementName()});
1349
					
1350
					// add entry to index
1351
					for (String label : target.getParameterLabels()) {
1352
						// add entry
1353
						label2variable.put(label, target);
1354
					}
1355
					
1356
					// get synchronization decision's ID
1357
					String id = ddlTarget.getId();
1358
					// check if target id already exists 
1359
					if (decId2variable.containsKey(id)) {
1360
						throw new RuntimeException("Duplicated decision ID <" + id + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1361
					}
1362
					
1363
					// add entry 
1364
					decId2variable.put(id, target);
1365
				}
1366
				break;
1367
				
1368
				// reservoir resource component
1369
				case RESOURCE_RESERVOIR : 
1370
				{
1371
					// get target component
1372
					ReservoirResource resource = (ReservoirResource) targetComponent;
1373
1374
					// check target decision
1375
					DDLComponentDecision ddlTargetDecision = ddlTarget.getComponentDecision();
1376
					// cast decision
1377
					DDLConsumableResourceComponentDecision ddlConsumableTarget = (DDLConsumableResourceComponentDecision) ddlTargetDecision;
1378
					// check decision type
1379
					switch (ddlConsumableTarget.getComponentDecisionType())
1380
					{
1381
						// resource consumption
1382
						case Consumption : 
1383
						{
1384
							// get target value 
1385
							ComponentValue consumption = resource.getConsumptionValue();
1386
							// add token variable
1387
							TokenVariable target = rule.addTokenVariable(consumption,
1388
									new String[] {ddlConsumableTarget.getParameterName()});
1389
							
1390
							// add entry to index
1391
							for (String label : target.getParameterLabels()) {
1392
								// add entry
1393
								label2variable.put(label, target);
1394
							}
1395
							
1396
							// get synchronization decision's ID
1397
							String id = ddlTarget.getId();
1398
							// check if target id already exists 
1399
							if (decId2variable.containsKey(id)) {
1400
								throw new RuntimeException("Duplicated decision ID <" + id + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1401
							}
1402
							
1403
							// add entry 
1404
							decId2variable.put(id, target);
1405
						}
1406
						break;
1407
						
1408
						// resource production 
1409
						case Production : 
1410
						{
1411
							// get target value 
1412
							ComponentValue production = resource.getProductionValue();
1413
							// add token variable
1414
							TokenVariable target = rule.addTokenVariable(production,
1415
									new String[] {ddlConsumableTarget.getParameterName()});
1416
							
1417
							// add entry to index
1418
							for (String label : target.getParameterLabels()) {
1419
								// add entry
1420
								label2variable.put(label, target);
1421
							}
1422
							
1423
							// get synchronization decision's ID
1424
							String id = ddlTarget.getId();
1425
							// check if target id already exists 
1426
							if (decId2variable.containsKey(id)) {
1427
								throw new RuntimeException("Duplicated decision ID <" + id + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1428
							}
1429
							
1430
							// add entry 
1431
							decId2variable.put(id, target);
1432
						}
1433
						break;
1434
					}
1435
					
1436
					
1437
				}
1438
				break;
1439
				
1440
				default : {
1441
					// unknown target component type
1442
					throw new RuntimeException("Unknownw target component found into synchronization constraint" + ddlTarget);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1443
				}
1444
			}
1445
		}
1446
		
1447
		// set temporal relations
1448
		for (DDLTemporalRelation ddlRel : ddlSynch.getTemporalRelations()) 
1449
		{
1450
			// check relation type
1451
			DDLTemporalRelationType ddlRelType = ddlRel.getRelationType();
1452
			
1453
			// get constraint reference
1454
			TokenVariable cref;
1455
			// check reference's ID
1456
			if (ddlRel.getFrom() == null) {
1457
				cref = rule.getTriggerer();
1458
			}
1459
			else {
1460
				// check if reference exists
1461
				if (!decId2variable.containsKey(ddlRel.getFrom())) {
1462
					throw new RuntimeException("Unknown decision ID found <" + ddlRel.getFrom() + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1463
				}
1464
				
1465
				// get reference decision
1466
				cref = decId2variable.get(ddlRel.getFrom());
1467
			}
1468
			
1469
			// check if target exists
1470
			if (!decId2variable.containsKey(ddlRel.getTo())) {
1471
				throw new RuntimeException("Unknown decision ID found <" + ddlRel.getTo() + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1472
			}
1473
			
1474
			// get constraint target
1475
			TokenVariable ctarget = decId2variable.get(ddlRel.getTo());
1476
			
1477
			// create constraint
1478
			this.addConstraintToSynchronization(rule, cref, ctarget, ddlRelType);
1479
		}
1480
		
1481
		// set parameter relations
1482
		List<DDLParameterConstraint> ddlParameterConstraints = ddlSynch.getParameterConstraints();
1483
		for (DDLParameterConstraint ddlpc : ddlParameterConstraints) 
1484
		{
1485
			// check constraint type
1486
			switch (ddlpc.getConstraintType()) 
1487
			{
1488
				// enumeration parameter constraint
1489
				case ENUMERATION : 
1490
				{
1491
					// get enumeration constraint
1492
					DDLEnumerationParameterConstraint ddlEnumerationConstraint = (DDLEnumerationParameterConstraint) ddlpc;
1493
					// get reference variable
1494
					String leftTerm = ddlEnumerationConstraint.getLeftTerm();
1495
					
1496
					// check if parameter exists
1497
					if (!label2variable.containsKey(leftTerm)) {
1498
						throw new RuntimeException("Unknown reference parameter found <" + leftTerm + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1499
					}
1500
					
1501
					// get reference
1502
					TokenVariable pcReference = label2variable.get(leftTerm);
1503
					
1504
					// get value
1505
					String value = ddlEnumerationConstraint.getValue();
1506
					// get relation type
1507
					RelationType relType;
1508
					switch (ddlEnumerationConstraint.getEnumerationConstraintType()) {
1509
						// equal constraint
1510
						case EQ : {
1511
							// set relation type
1512
							relType = RelationType.BIND_PARAMETER;
1513
						}
1514
						break;
1515
						
1516
						default : {
1517
1518
							throw new RuntimeException("Unknownw enumeration constraint type " + ddlEnumerationConstraint.getEnumerationConstraintType());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1519
						}
1520
					}
1521
					
1522
					// create binding constraint
1523
					rule.addBindingConstraint(pcReference, relType, leftTerm, value);
1524
				}
1525
				break;
1526
				
1527
				// binary parameter constraint
1528
				case NUMERIC : 
1529
				{
1530
					// get numeric constraint
1531
					DDLNumericParameterConstraint ddlNumericConstraint = (DDLNumericParameterConstraint) ddlpc;
1532
					// get reference variable
1533
					String leftTerm = ddlNumericConstraint.getLeftTerm();
1534
					
1535
					// check if parameter exists
1536
					if (!label2variable.containsKey(leftTerm)) {
1537
						throw new RuntimeException("Unknown reference parameter found <" + leftTerm + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1538
					}
1539
					
1540
					// get reference
1541
					TokenVariable pcReference = label2variable.get(leftTerm);
1542
					
1543
					// check if binary
1544
					if (ddlNumericConstraint.isBinary()) 
1545
					{
1546
						// get relation type
1547
						RelationType relType;
1548
						switch (ddlNumericConstraint.getNumericConstraintType()) {
1549
							// equal constraint
1550
							case EQ : {
1551
								// set relation type
1552
								relType = RelationType.EQUAL_PARAMETER;
1553
							}
1554
							break;
1555
							
1556
							// not equal constraint
1557
							case NEQ : {
1558
								// set relation type
1559
								relType = RelationType.NOT_EQUAL_PARAMETER;
1560
							}
1561
							break;
1562
							
1563
							default : {
1564
1565
								throw new RuntimeException("Unknownw numeric constraint type " + ddlNumericConstraint.getNumericConstraintType());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1566
							}
1567
						}
1568
						
1569
						// check targets
1570
						for (String rightTerm : ddlNumericConstraint.getRightVariables()) {
1571
							// check if parameter exists
1572
							if (!label2variable.containsKey(rightTerm)) {
1573
								throw new RuntimeException("Unknown target found <" + rightTerm + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1574
							}
1575
							
1576
							// get target variable
1577
							TokenVariable pcTarget = label2variable.get(rightTerm);
1578
							
1579
							// create constraint
1580
							rule.addParameterConstraint(pcReference, pcTarget, relType, leftTerm, rightTerm);
1581
						}
1582
					}
1583
					else {
1584
						// not binary constraint, set bind constraint
1585
						int value = ddlNumericConstraint.getRightCoefficients().get(0);
1586
						// get relation type
1587
						RelationType relType;
1588
						switch (ddlNumericConstraint.getNumericConstraintType()) 
1589
						{
1590
							// equal constraint
1591
							case EQ : 
1592
							{
1593
								// set relation type
1594
								relType = RelationType.BIND_PARAMETER;
1595
							}
1596
							break;
1597
							
1598
							default : {
1599
1600
								throw new RuntimeException("Unknownw numeric constraint type " + ddlNumericConstraint.getNumericConstraintType());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1601
							}
1602
						}
1603
						
1604
						// create constraint
1605
						rule.addBindingConstraint(pcReference, relType, leftTerm, Integer.toString(value));
1606
					}
1607
				}
1608
			}
1609
		}
1610
		
1611
		// add synchronization rule
1612
		pdb.addSynchronizationRule(rule);
1613
	}
1614
	
1615
	/**
1616
	 * 
1617
	 * @param ddlSynch
1618
	 * @param comp
1619
	 * @param pdb
1620
	 * @throws DomainComponentNotFoundException
1621
	 * @throws SynchronizationCycleException
1622
	 */
1623
	private void doCreateSynchronizationFromGroundDecision(DDLSynchronization ddlSynch, DomainComponent comp, PlanDataBase pdb) 
1624
			throws DomainComponentNotFoundException, SynchronizationCycleException
1625
	{ 
1626
		// setup auxiliary data structures
1627
		Map<String, TokenVariable> label2variable = new HashMap<>();
1628
		Map<String, TokenVariable> decId2variable = new HashMap<>();
1629
		
1630
		// get reference decision
1631
		DDLSimpleGroundStateVariableComponentDecision ddlDec = (DDLSimpleGroundStateVariableComponentDecision) ddlSynch.getReference();
1632
		
1633
		// get trigger value
1634
		ComponentValue valTrigger = comp.getValueByName(ddlDec.getName());
1635
		
1636
		// create synchronization
1637
		SynchronizationRule rule = pdb.createSynchronizationRule(valTrigger, new String[] {});
1638
		// add entry to parameter label index
1639
		for (String label : rule.getTriggerer().getParameterLabels()) {
1640
			label2variable.put(label, rule.getTriggerer());
1641
		}
1642
		
1643
		// check target values
1644
		for (DDLInstantiatedComponentDecision ddlTarget : ddlSynch.getTargets().values()) 
1645
		{
1646
			// get target component
1647
			DomainComponent targetComponent = pdb.getComponentByName(ddlTarget.getComponent());
1648
			// check target decision
1649
			DDLComponentDecision ddlTargetDecision = ddlTarget.getComponentDecision();
1650
			// check type
1651
			switch (ddlTargetDecision.getDecisionType()) 
1652
			{
1653
				// consumable resource
1654
				case CONSUMABLE_RESOURCE_REQUIREMENT :
1655
				{
1656
					// get target value
1657
					ReservoirResource resource = (ReservoirResource) targetComponent;
1658
					// cast decision
1659
					DDLConsumableResourceComponentDecision ddlDecisionTarget = (DDLConsumableResourceComponentDecision) ddlTargetDecision;
1660
					// target token variable
1661
					TokenVariable target = null;
1662
					// check decision type
1663
					switch (ddlDecisionTarget.getComponentDecisionType())
1664
					{
1665
						case Consumption : {
1666
							// add consumption token variable
1667
							target = rule.addTokenVariable(resource.getConsumptionValue(), new String[] {
1668
								ddlDecisionTarget.getParameterName()	
1669
							});
1670
						}
1671
						break;
1672
						
1673
						case Production : {
1674
							// add production token variable
1675
							target = rule.addTokenVariable(resource.getProductionValue(), new String[] {
1676
								ddlDecisionTarget.getParameterName()
1677
							});
1678
						}
1679
						break;
1680
					}
1681
					
1682
					// set as mandatory expansion
1683
					target.setMandatoryExpansion();
0 ignored issues
show
Security Bug introduced by
A "NullPointerException" could be thrown; "target" is nullable here.
Loading history...
1684
					// add entry to index
1685
					for (String label : target.getParameterLabels()) {
1686
						// add entry
1687
						label2variable.put(label, target);
1688
					}
1689
					
1690
					// get synchronization decision's ID
1691
					String id = ddlTarget.getId();
1692
					// check if target id already exists 
1693
					if (decId2variable.containsKey(id)) {
1694
						throw new RuntimeException("Duplicated decision ID <" + id + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1695
					}
1696
					
1697
					// add entry 
1698
					decId2variable.put(id, target);
1699
				}
1700
				break;
1701
			
1702
				// discrete resource target
1703
				case RENEWABLE_RESOURCE_REQUIREMENT :
1704
				{
1705
					// get target value
1706
					ComponentValue targetValue = ((DiscreteResource) targetComponent).getRequirementValue();
1707
					// cast decision
1708
					DDLRenewableResourceComponentDecision ddlRequirementTarget = (DDLRenewableResourceComponentDecision) ddlTargetDecision;
1709
					// add token variable
1710
					TokenVariable target = rule.addTokenVariable(targetValue, new String[] {
1711
							ddlRequirementTarget.getRequirementName()
1712
					});
1713
					
1714
					// set as mandatory expansion
1715
					target.setMandatoryExpansion();
1716
					// add entry to index
1717
					for (String label : target.getParameterLabels()) {
1718
						// add entry
1719
						label2variable.put(label, target);
1720
					}
1721
					
1722
					// get synchronization decision's ID
1723
					String id = ddlTarget.getId();
1724
					// check if target id already exists 
1725
					if (decId2variable.containsKey(id)) {
1726
						throw new RuntimeException("Duplicated decision ID <" + id + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1727
					}
1728
					
1729
					// add entry 
1730
					decId2variable.put(id, target);
1731
				}
1732
				break;
1733
			
1734
				// singleton target decision
1735
				case SINGLETON : 
1736
				{
1737
					// get target value
1738
					ComponentValue targetValue = targetComponent.getValueByName(ddlTarget.getComponentDecision().getName());
1739
					// cast decision
1740
					DDLSingletonStateVariableComponentDecision ddlSingletonTarget = (DDLSingletonStateVariableComponentDecision) ddlTargetDecision;
1741
					// add token variable
1742
					TokenVariable target = rule.addTokenVariable(targetValue, 
1743
							ddlSingletonTarget.getParameterNames().toArray(new String[ddlSingletonTarget.getParameterNames().size()]));
1744
					
1745
					// check solving knowledge
1746
					if (!ddlTarget.getParameters().isEmpty()) {
1747
						// check mandatory expansion
1748
						if (ddlTarget.getParameters().contains("!")) {
1749
							// set knowledge
1750
							target.setMandatoryExpansion();
1751
						}
1752
						
1753
						// check mandatory unification
1754
						if (ddlTarget.getParameters().contains("?")) {
1755
							target.setMandatoryUnification();
1756
						}
1757
					}
1758
					
1759
					// add entry to index
1760
					for (String label : target.getParameterLabels()) {
1761
						// add entry
1762
						label2variable.put(label, target);
1763
					}
1764
					
1765
					// get synchronization decision's ID
1766
					String id = ddlTarget.getId();
1767
					// check if target id already exists 
1768
					if (decId2variable.containsKey(id)) {
1769
						throw new RuntimeException("Duplicated decision ID <" + id + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1770
					}
1771
					
1772
					// add entry 
1773
					decId2variable.put(id, target);
1774
				}
1775
				break;
1776
				
1777
				// ground target decision
1778
				case GROUND : 
1779
				{
1780
					// get target value
1781
					ComponentValue targetValue = targetComponent.getValueByName(ddlTarget.getComponentDecision().getName());
1782
					// add token variable
1783
					TokenVariable target = rule.addTokenVariable(targetValue, new String[] {});
1784
					
1785
					// check solving knowledge
1786
					if (!ddlTarget.getParameters().isEmpty()) {
1787
						// check mandatory expansion
1788
						if (ddlTarget.getParameters().contains("!")) {
1789
							// set knowledge
1790
							target.setMandatoryExpansion();
1791
						}
1792
						
1793
						// check mandatory unification
1794
						if (ddlTarget.getParameters().contains("?")) {
1795
							target.setMandatoryUnification();
1796
						}
1797
					}
1798
					
1799
					// get synchronization decision's ID
1800
					String id = ddlTarget.getId();
1801
					// check if target id already exists 
1802
					if (decId2variable.containsKey(id)) {
1803
						throw new RuntimeException("Duplicated decision ID <" + id + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1804
					}
1805
					
1806
					// add entry 
1807
					decId2variable.put(id, target);
1808
				}
1809
				break;
1810
				
1811
				default : {
1812
					throw new RuntimeException("Unknownw target decision found into synchronization " + ddlTarget);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1813
				}
1814
			}
1815
		}
1816
		
1817
		// set temporal relations
1818
		for (DDLTemporalRelation ddlRel : ddlSynch.getTemporalRelations()) {
1819
			// check relation type
1820
			DDLTemporalRelationType ddlRelType = ddlRel.getRelationType();
1821
			
1822
			// get constraint reference
1823
			TokenVariable cref;
1824
			// check reference's ID
1825
			if (ddlRel.getFrom() == null) {
1826
				cref = rule.getTriggerer();
1827
			}
1828
			else {
1829
				// check if reference exists
1830
				if (!decId2variable.containsKey(ddlRel.getFrom())) {
1831
					throw new RuntimeException("Unknown decision ID found <" + ddlRel.getFrom() + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1832
				}
1833
				
1834
				// set reference
1835
				cref = decId2variable.get(ddlRel.getFrom());
1836
			}
1837
			
1838
			// check if target exists
1839
			if (!decId2variable.containsKey(ddlRel.getTo())) {
1840
				throw new RuntimeException("Unknown decision ID found <" + ddlRel.getTo() + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1841
			}
1842
			
1843
			// get constraint target
1844
			TokenVariable ctarget = decId2variable.get(ddlRel.getTo());
1845
			
1846
			// create constraint
1847
			this.addConstraintToSynchronization(rule, cref, ctarget, ddlRelType);
1848
		}
1849
		
1850
		// set parameter relations
1851
		List<DDLParameterConstraint> ddlParameterConstraints = ddlSynch.getParameterConstraints();
1852
		for (DDLParameterConstraint ddlpc : ddlParameterConstraints) 
1853
		{
1854
			// check constraint type
1855
			switch (ddlpc.getConstraintType()) 
1856
			{
1857
				// enumeration parameter constraint
1858
				case ENUMERATION : 
1859
				{
1860
					// get enumeration constraint
1861
					DDLEnumerationParameterConstraint ddlEnumerationConstraint = (DDLEnumerationParameterConstraint) ddlpc;
1862
					// get reference variable
1863
					String leftTerm = ddlEnumerationConstraint.getLeftTerm();
1864
					
1865
					// check if label exists
1866
					if (!label2variable.containsKey(leftTerm)) {
1867
						throw new RuntimeException("Unknown parameter label found <" + leftTerm +"> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1868
					}
1869
					
1870
					TokenVariable pcReference = label2variable.get(leftTerm);
1871
					// get value
1872
					String value = ddlEnumerationConstraint.getValue();
1873
					// get relation type
1874
					RelationType relType;
1875
					switch (ddlEnumerationConstraint.getEnumerationConstraintType()) {
1876
						// equal constraint
1877
						case EQ : {
1878
							// set relation type
1879
							relType = RelationType.BIND_PARAMETER;
1880
						}
1881
						break;
1882
						
1883
						default : {
1884
1885
							throw new RuntimeException("Unknownw enumeration constraint type " + ddlEnumerationConstraint.getEnumerationConstraintType());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1886
						}
1887
					}
1888
					
1889
					// create binding constraint
1890
					rule.addBindingConstraint(pcReference, relType, leftTerm, value);
1891
				}
1892
				break;
1893
				
1894
				// binary parameter constraint
1895
				case NUMERIC : 
1896
				{
1897
					// get numeric constraint
1898
					DDLNumericParameterConstraint ddlNumericConstraint = (DDLNumericParameterConstraint) ddlpc;
1899
					// get reference variable
1900
					String leftTerm = ddlNumericConstraint.getLeftTerm();
1901
					
1902
					// check if label exists
1903
					if (!label2variable.containsKey(leftTerm)) {
1904
						throw new RuntimeException("Unknown parameter label found <" + leftTerm +"> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1905
					}
1906
					
1907
					TokenVariable pcReference = label2variable.get(leftTerm);
1908
					
1909
					// check if binary
1910
					if (ddlNumericConstraint.isBinary()) 
1911
					{
1912
						// get relation type
1913
						RelationType relType;
1914
						switch (ddlNumericConstraint.getNumericConstraintType()) {
1915
							// equal constraint
1916
							case EQ : {
1917
								// set relation type
1918
								relType = RelationType.EQUAL_PARAMETER;
1919
							}
1920
							break;
1921
							
1922
							// not equal constraint
1923
							case NEQ : {
1924
								// set relation type
1925
								relType = RelationType.NOT_EQUAL_PARAMETER;
1926
							}
1927
							break;
1928
							
1929
							default : {
1930
1931
								throw new RuntimeException("Unknownw numeric constraint type " + ddlNumericConstraint.getNumericConstraintType());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1932
							}
1933
						}
1934
						
1935
						// check targets
1936
						for (String rightTerm : ddlNumericConstraint.getRightVariables()) {
1937
							// check if label exists
1938
							if (!label2variable.containsKey(rightTerm)) {
1939
								throw new RuntimeException("Unknown parameter label found <" + rightTerm +"> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1940
							}
1941
							
1942
							// get target variable
1943
							TokenVariable pcTarget = label2variable.get(rightTerm);
1944
							
1945
							// create constraint
1946
							rule.addParameterConstraint(pcReference, pcTarget, relType, leftTerm, rightTerm);
1947
						}
1948
					}
1949
					else {
1950
						// not binary constraint, set bind constraint
1951
						int value = ddlNumericConstraint.getRightCoefficients().get(0);
1952
						// get relation type
1953
						RelationType relType;
1954
						switch (ddlNumericConstraint.getNumericConstraintType()) {
1955
							// equal constraint
1956
							case EQ : {
1957
								// set relation type
1958
								relType = RelationType.BIND_PARAMETER;
1959
							}
1960
							break;
1961
							
1962
							default : {
1963
1964
								throw new RuntimeException("Unknownw numeric constraint type " + ddlNumericConstraint.getNumericConstraintType());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
1965
							}
1966
						}
1967
						
1968
						// create constraint
1969
						rule.addBindingConstraint(pcReference, relType, leftTerm, Integer.toString(value));
1970
					}
1971
				}
1972
			}
1973
		}
1974
		
1975
		// add synchronization rule
1976
		pdb.addSynchronizationRule(rule);
1977
	}
1978
	
1979
	/**
1980
	 * 
1981
	 * @param ddlSynch
1982
	 * @param comp
1983
	 * @param pdb
1984
	 * @throws DomainComponentNotFoundException
1985
	 * @throws SynchronizationCycleException
1986
	 */
1987 View Code Duplication
	private void doCreateSynchronizationFromSingletonDecision(DDLSynchronization ddlSynch, DomainComponent comp, PlanDataBase pdb) 
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1988
			throws DomainComponentNotFoundException, SynchronizationCycleException
1989
	{ 
1990
		// setup auxiliary data structures
1991
		Map<String, TokenVariable> label2variable = new HashMap<>();
1992
		Map<String, TokenVariable> decId2variable = new HashMap<>();
1993
		
1994
		// get reference decision
1995
		DDLSingletonStateVariableComponentDecision ddlDec = (DDLSingletonStateVariableComponentDecision) ddlSynch.getReference();
1996
		
1997
		// get trigger value
1998
		ComponentValue valTrigger = comp.getValueByName(ddlDec.getName());
1999
		
2000
		// create synchronization
2001
		SynchronizationRule rule = pdb.createSynchronizationRule(valTrigger, 
2002
				ddlDec.getParameterNames().toArray(new String[ddlDec.getParameterNames().size()]));
2003
		// add entry to parameter label index
2004
		for (String label : rule.getTriggerer().getParameterLabels()) {
2005
			label2variable.put(label, rule.getTriggerer());
2006
		}
2007
		
2008
		// check target values
2009
		for (DDLInstantiatedComponentDecision ddlTarget : ddlSynch.getTargets().values()) 
2010
		{
2011
			// get target component
2012
			DomainComponent targetComponent = pdb.getComponentByName(ddlTarget.getComponent());
2013
			// check target component type
2014
			switch (targetComponent.getType())
2015
			{
2016
				// state variable component
2017
				case SV_EXTERNAL : 
2018
				case SV_FUNCTIONAL : 
2019
				case SV_PRIMITIVE : 
2020
				{
2021
					// check target decision
2022
					DDLComponentDecision ddlTargetDecision = ddlTarget.getComponentDecision();
2023
					// check decision type
2024
					switch (ddlTargetDecision.getDecisionType())
2025
					{
2026
						// decision with parameters
2027
						case SINGLETON :
2028
						{
2029
							// cast decision
2030
							DDLSingletonStateVariableComponentDecision ddlSingletonTarget = (DDLSingletonStateVariableComponentDecision) ddlTargetDecision;
2031
							
2032
							// get target value
2033
							ComponentValue targetValue = targetComponent.getValueByName(ddlSingletonTarget.getName());
2034
							
2035
							// add token variable
2036
							TokenVariable target = rule.addTokenVariable(targetValue, 
2037
									ddlSingletonTarget.getParameterNames().toArray(new String[ddlSingletonTarget.getParameterNames().size()]));
2038
							
2039
							// check solving knowledge
2040
							if (!ddlTarget.getParameters().isEmpty()) {
2041
								// check mandatory expansion
2042
								if (ddlTarget.getParameters().contains("!")) {
2043
									// set knowledge
2044
									target.setMandatoryExpansion();
2045
								}
2046
								
2047
								// check mandatory unification
2048
								if (ddlTarget.getParameters().contains("?")) {
2049
									target.setMandatoryUnification();
2050
								}
2051
							}
2052
							
2053
							// add entry to index
2054
							for (String label : target.getParameterLabels()) {
2055
								// add entry
2056
								label2variable.put(label, target);
2057
							}
2058
							
2059
							// get synchronization decision's ID
2060
							String id = ddlTarget.getId();
2061
							// check if target id already exists 
2062
							if (decId2variable.containsKey(id)) {
2063
								throw new RuntimeException("Duplicated decision ID <" + id + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
2064
							}
2065
							
2066
							// add entry 
2067
							decId2variable.put(id, target);
2068
						}
2069
						break;
2070
						
2071
						// ground decision
2072
						case GROUND : 
2073
						{
2074
							// cast decision
2075
							DDLSimpleGroundStateVariableComponentDecision ddlGroundTarget = (DDLSimpleGroundStateVariableComponentDecision) ddlTargetDecision;
2076
							// get target value
2077
							ComponentValue targetValue = targetComponent.getValueByName(ddlGroundTarget.getName());
2078
							
2079
							// add token variable with no parameter labels
2080
							TokenVariable target = rule.addTokenVariable(targetValue, new String[] {}); 
2081
							
2082
							// check solving knowledge
2083
							if (!ddlTarget.getParameters().isEmpty()) {
2084
								// check mandatory expansion
2085
								if (ddlTarget.getParameters().contains("!")) {
2086
									// set knowledge
2087
									target.setMandatoryExpansion();
2088
								}
2089
								
2090
								// check mandatory unification
2091
								if (ddlTarget.getParameters().contains("?")) {
2092
									target.setMandatoryUnification();
2093
								}
2094
							}
2095
							
2096
							// get synchronization decision's ID
2097
							String id = ddlTarget.getId();
2098
							// check if target id already exists 
2099
							if (decId2variable.containsKey(id)) {
2100
								throw new RuntimeException("Duplicated decision ID <" + id + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
2101
							}
2102
							
2103
							// add entry 
2104
							decId2variable.put(id, target);
2105
						}
2106
						break;
2107
						
2108
						default : {
2109
							throw new RuntimeException("Unknown state variable decision type - " + ddlTargetDecision.getDecisionType());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
2110
						}
2111
					}
2112
					
2113
					
2114
				}
2115
				break;
2116
				
2117
				// discrete resource component
2118
				case RESOURCE_DISCRETE : 
2119
				{
2120
					// check target decision
2121
					DDLComponentDecision ddlTargetDecision = ddlTarget.getComponentDecision();
2122
					// cast decision
2123
					DDLRenewableResourceComponentDecision ddlRequirementTarget = (DDLRenewableResourceComponentDecision) ddlTargetDecision;
2124
					// get target component
2125
					DiscreteResource resource = (DiscreteResource) targetComponent;
2126
					 
2127
					// get target value 
2128
					ComponentValue targetValue = resource.getRequirementValue();
2129
					// add token variable
2130
					TokenVariable target = rule.addTokenVariable(targetValue,
2131
							new String[] {ddlRequirementTarget.getRequirementName()});
2132
					
2133
					// add entry to index
2134
					for (String label : target.getParameterLabels()) {
2135
						// add entry
2136
						label2variable.put(label, target);
2137
					}
2138
					
2139
					// get synchronization decision's ID
2140
					String id = ddlTarget.getId();
2141
					// check if target id already exists 
2142
					if (decId2variable.containsKey(id)) {
2143
						throw new RuntimeException("Duplicated decision ID <" + id + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
2144
					}
2145
					
2146
					// add entry 
2147
					decId2variable.put(id, target);
2148
				}
2149
				break;
2150
				
2151
				// reservoir resource component
2152
				case RESOURCE_RESERVOIR : 
2153
				{
2154
					// get target component
2155
					ReservoirResource resource = (ReservoirResource) targetComponent;
2156
2157
					// check target decision
2158
					DDLComponentDecision ddlTargetDecision = ddlTarget.getComponentDecision();
2159
					// cast decision
2160
					DDLConsumableResourceComponentDecision ddlConsumableTarget = (DDLConsumableResourceComponentDecision) ddlTargetDecision;
2161
					// check decision type
2162
					switch (ddlConsumableTarget.getComponentDecisionType())
2163
					{
2164
						// resource consumption
2165
						case Consumption : 
2166
						{
2167
							// get target value 
2168
							ComponentValue consumption = resource.getConsumptionValue();
2169
							// add token variable
2170
							TokenVariable target = rule.addTokenVariable(consumption,
2171
									new String[] {ddlConsumableTarget.getParameterName()});
2172
							
2173
							// add entry to index
2174
							for (String label : target.getParameterLabels()) {
2175
								// add entry
2176
								label2variable.put(label, target);
2177
							}
2178
							
2179
							// get synchronization decision's ID
2180
							String id = ddlTarget.getId();
2181
							// check if target id already exists 
2182
							if (decId2variable.containsKey(id)) {
2183
								throw new RuntimeException("Duplicated decision ID <" + id + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
2184
							}
2185
							
2186
							// add entry 
2187
							decId2variable.put(id, target);
2188
						}
2189
						break;
2190
						
2191
						// resource production 
2192
						case Production : 
2193
						{
2194
							// get target value 
2195
							ComponentValue production = resource.getProductionValue();
2196
							// add token variable
2197
							TokenVariable target = rule.addTokenVariable(production,
2198
									new String[] {ddlConsumableTarget.getParameterName()});
2199
							
2200
							// add entry to index
2201
							for (String label : target.getParameterLabels()) {
2202
								// add entry
2203
								label2variable.put(label, target);
2204
							}
2205
							
2206
							// get synchronization decision's ID
2207
							String id = ddlTarget.getId();
2208
							// check if target id already exists 
2209
							if (decId2variable.containsKey(id)) {
2210
								throw new RuntimeException("Duplicated decision ID <" + id + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
2211
							}
2212
							
2213
							// add entry 
2214
							decId2variable.put(id, target);
2215
						}
2216
						break;
2217
					}
2218
					
2219
					
2220
				}
2221
				break;
2222
				
2223
				default : {
2224
					// unknown target component type
2225
					throw new RuntimeException("Unknownw target component found into synchronization constraint" + ddlTarget);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
2226
				}
2227
			}
2228
		}
2229
		
2230
		// set temporal relations
2231
		for (DDLTemporalRelation ddlRel : ddlSynch.getTemporalRelations()) 
2232
		{
2233
			// check relation type
2234
			DDLTemporalRelationType ddlRelType = ddlRel.getRelationType();
2235
			
2236
			// get constraint reference
2237
			TokenVariable cref;
2238
			// check reference's ID
2239
			if (ddlRel.getFrom() == null) {
2240
				cref = rule.getTriggerer();
2241
			}
2242
			else {
2243
				// check if reference exists
2244
				if (!decId2variable.containsKey(ddlRel.getFrom())) {
2245
					throw new RuntimeException("Unknown decision ID found <" + ddlRel.getFrom() + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
2246
				}
2247
				
2248
				// get reference decision
2249
				cref = decId2variable.get(ddlRel.getFrom());
2250
			}
2251
			
2252
			// check if target exists
2253
			if (!decId2variable.containsKey(ddlRel.getTo())) {
2254
				throw new RuntimeException("Unknown decision ID found <" + ddlRel.getTo() + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
2255
			}
2256
			
2257
			// get constraint target
2258
			TokenVariable ctarget = decId2variable.get(ddlRel.getTo());
2259
			
2260
			// create constraint
2261
			this.addConstraintToSynchronization(rule, cref, ctarget, ddlRelType);
2262
		}
2263
		
2264
		// set parameter relations
2265
		List<DDLParameterConstraint> ddlParameterConstraints = ddlSynch.getParameterConstraints();
2266
		for (DDLParameterConstraint ddlpc : ddlParameterConstraints) 
2267
		{
2268
			// check constraint type
2269
			switch (ddlpc.getConstraintType()) 
2270
			{
2271
				// enumeration parameter constraint
2272
				case ENUMERATION : 
2273
				{
2274
					// get enumeration constraint
2275
					DDLEnumerationParameterConstraint ddlEnumerationConstraint = (DDLEnumerationParameterConstraint) ddlpc;
2276
					// get reference variable
2277
					String leftTerm = ddlEnumerationConstraint.getLeftTerm();
2278
					
2279
					// check if parameter exists
2280
					if (!label2variable.containsKey(leftTerm)) {
2281
						throw new RuntimeException("Unknown reference parameter found <" + leftTerm + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
2282
					}
2283
					
2284
					// get reference
2285
					TokenVariable pcReference = label2variable.get(leftTerm);
2286
					
2287
					// get value
2288
					String value = ddlEnumerationConstraint.getValue();
2289
					// get relation type
2290
					RelationType relType;
2291
					switch (ddlEnumerationConstraint.getEnumerationConstraintType()) {
2292
						// equal constraint
2293
						case EQ : {
2294
							// set relation type
2295
							relType = RelationType.BIND_PARAMETER;
2296
						}
2297
						break;
2298
						
2299
						default : {
2300
2301
							throw new RuntimeException("Unknownw enumeration constraint type " + ddlEnumerationConstraint.getEnumerationConstraintType());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
2302
						}
2303
					}
2304
					
2305
					// create binding constraint
2306
					rule.addBindingConstraint(pcReference, relType, leftTerm, value);
2307
				}
2308
				break;
2309
				
2310
				// binary parameter constraint
2311
				case NUMERIC : 
2312
				{
2313
					// get numeric constraint
2314
					DDLNumericParameterConstraint ddlNumericConstraint = (DDLNumericParameterConstraint) ddlpc;
2315
					// get reference variable
2316
					String leftTerm = ddlNumericConstraint.getLeftTerm();
2317
					
2318
					// check if parameter exists
2319
					if (!label2variable.containsKey(leftTerm)) {
2320
						throw new RuntimeException("Unknown reference parameter found <" + leftTerm + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
2321
					}
2322
					
2323
					// get reference
2324
					TokenVariable pcReference = label2variable.get(leftTerm);
2325
					
2326
					// check if binary
2327
					if (ddlNumericConstraint.isBinary()) 
2328
					{
2329
						// get relation type
2330
						RelationType relType;
2331
						switch (ddlNumericConstraint.getNumericConstraintType()) {
2332
							// equal constraint
2333
							case EQ : {
2334
								// set relation type
2335
								relType = RelationType.EQUAL_PARAMETER;
2336
							}
2337
							break;
2338
							
2339
							// not equal constraint
2340
							case NEQ : {
2341
								// set relation type
2342
								relType = RelationType.NOT_EQUAL_PARAMETER;
2343
							}
2344
							break;
2345
							
2346
							default : {
2347
2348
								throw new RuntimeException("Unknownw numeric constraint type " + ddlNumericConstraint.getNumericConstraintType());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
2349
							}
2350
						}
2351
						
2352
						// check targets
2353
						for (String rightTerm : ddlNumericConstraint.getRightVariables()) {
2354
							// check if parameter exists
2355
							if (!label2variable.containsKey(rightTerm)) {
2356
								throw new RuntimeException("Unknown target found <" + rightTerm + "> on synchronization " + rule);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
2357
							}
2358
							
2359
							// get target variable
2360
							TokenVariable pcTarget = label2variable.get(rightTerm);
2361
							
2362
							// create constraint
2363
							rule.addParameterConstraint(pcReference, pcTarget, relType, leftTerm, rightTerm);
2364
						}
2365
					}
2366
					else {
2367
						// not binary constraint, set bind constraint
2368
						int value = ddlNumericConstraint.getRightCoefficients().get(0);
2369
						// get relation type
2370
						RelationType relType;
2371
						switch (ddlNumericConstraint.getNumericConstraintType()) 
2372
						{
2373
							// equal constraint
2374
							case EQ : 
2375
							{
2376
								// set relation type
2377
								relType = RelationType.BIND_PARAMETER;
2378
							}
2379
							break;
2380
							
2381
							default : {
2382
2383
								throw new RuntimeException("Unknownw numeric constraint type " + ddlNumericConstraint.getNumericConstraintType());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
2384
							}
2385
						}
2386
						
2387
						// create constraint
2388
						rule.addBindingConstraint(pcReference, relType, leftTerm, Integer.toString(value));
2389
					}
2390
				}
2391
			}
2392
		}
2393
		
2394
		// add synchronization rule
2395
		pdb.addSynchronizationRule(rule);
2396
	}
2397
	
2398
	/**
2399
	 * 
2400
	 * @param rule
2401
	 * @param cref
2402
	 * @param ctarget
2403
	 * @param ddlRelType
2404
	 */
2405 View Code Duplication
	private void addConstraintToSynchronization(SynchronizationRule rule, TokenVariable reference, TokenVariable target, DDLTemporalRelationType ddlRelType) 
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2406
	{
2407
		// check relation type
2408
		if (ddlRelType.getText().equalsIgnoreCase("meets")) {
2409
			// create meets constraint
2410
			rule.addTemporalConstraint(reference, target, RelationType.MEETS, new long[][] {});
2411
		}
2412
		else if (ddlRelType.getText().equalsIgnoreCase("met-by")) {
2413
			// create met-by constraint
2414
			rule.addTemporalConstraint(reference, target, RelationType.MET_BY, new long[][] {});
2415
		}
2416
		else if (ddlRelType.getText().equalsIgnoreCase("during")) { 
2417
			// create during constraint
2418
			rule.addTemporalConstraint(reference, target, 
2419
					RelationType.DURING, 
2420
					new long[][] {
2421
						new long[] {
2422
							ddlRelType.getFirstRange().getMin(), 
2423
							ddlRelType.getFirstRange().getMax() > this.horizon ? 
2424
									this.horizon : 
2425
									ddlRelType.getFirstRange().getMax()
2426
						},
2427
						new long[] {
2428
							ddlRelType.getSecondRange().getMin(),
2429
							ddlRelType.getSecondRange().getMax() > this.horizon ? 
2430
									this.horizon :
2431
									ddlRelType.getSecondRange().getMax()
2432
						}
2433
				});
2434
		}
2435
		else if (ddlRelType.getText().equalsIgnoreCase("equals")) {
2436
			// create equals constraint
2437
			rule.addTemporalConstraint(reference, target, RelationType.EQUALS, new long[][] {});
2438
		}
2439
		else if (ddlRelType.getText().equalsIgnoreCase("contains")) {
2440
			// create contains constraint
2441
			rule.addTemporalConstraint(reference, target, 
2442
					RelationType.CONTAINS, 
2443
					new long[][] {
2444
						new long[] {
2445
							ddlRelType.getFirstRange().getMin(),
2446
							ddlRelType.getFirstRange().getMax() > this.horizon ?
2447
									this.horizon :
2448
									ddlRelType.getFirstRange().getMax()
2449
						},
2450
						new long[] {
2451
							ddlRelType.getSecondRange().getMin(),
2452
							ddlRelType.getSecondRange().getMax() > this.horizon ?
2453
									this.horizon :
2454
									ddlRelType.getSecondRange().getMax()
2455
						}
2456
				});
2457
		}
2458
		else if (ddlRelType.getText().equalsIgnoreCase("before")) {
2459
			// create before constraint
2460
			rule.addTemporalConstraint(reference, target, 
2461
					RelationType.BEFORE, 
2462
					new long[][] {
2463
						new long[] {
2464
							ddlRelType.getFirstRange().getMin(),
2465
							ddlRelType.getFirstRange().getMax() > this.horizon ?
2466
									this.horizon : 
2467
									ddlRelType.getFirstRange().getMax()
2468
						}
2469
				});
2470
		}
2471
		else if (ddlRelType.getText().equalsIgnoreCase("after")) {
2472
			// create before constraint
2473
			rule.addTemporalConstraint(reference, target, 
2474
					RelationType.AFTER, 
2475
					new long[][] {
2476
						new long[] {
2477
							ddlRelType.getFirstRange().getMin(),
2478
							ddlRelType.getFirstRange().getMax() > this.horizon ?
2479
									this.horizon : 
2480
									ddlRelType.getFirstRange().getMax()
2481
						}
2482
				});
2483
		}
2484
		else if (ddlRelType.getText().equalsIgnoreCase("start-start")) {
2485
			// create start-start constraint
2486
			rule.addTemporalConstraint(reference, target, 
2487
					RelationType.START_START, 
2488
					new long[][] {
2489
						new long[] {
2490
								ddlRelType.getFirstRange().getMin(),
2491
								ddlRelType.getFirstRange().getMax() > this.horizon ? 
2492
										this.horizon : 
2493
										ddlRelType.getFirstRange().getMax()
2494
						}
2495
			});
2496
			
2497
		}
2498
		else if (ddlRelType.getText().equalsIgnoreCase("end-end")) {
2499
			// create end-end constraint
2500
			rule.addTemporalConstraint(reference, target, 
2501
					RelationType.END_END, 
2502
					new long[][] {
2503
						new long[] {
2504
								ddlRelType.getFirstRange().getMin(),
2505
								ddlRelType.getFirstRange().getMax() > this.horizon ? 
2506
										this.horizon : 
2507
										ddlRelType.getFirstRange().getMax()
2508
						}
2509
			});
2510
		}
2511
		else if (ddlRelType.getText().equalsIgnoreCase("starts-during")) {
2512
			rule.addTemporalConstraint(reference, target,
2513
					RelationType.STARTS_DURING, 
2514
					new long[][] {
2515
						new long[] {
2516
							ddlRelType.getFirstRange().getMin(),
2517
							ddlRelType.getFirstRange().getMax() > this.horizon ? 
2518
									this.horizon :
2519
									ddlRelType.getFirstRange().getMax()
2520
						},
2521
						new long[] {
2522
							ddlRelType.getSecondRange().getMin(),
2523
							ddlRelType.getSecondRange().getMax() > this.horizon ? 
2524
									this.horizon : 
2525
									ddlRelType.getSecondRange().getMax()
2526
						}
2527
					});
2528
		}
2529
		else if (ddlRelType.getText().equalsIgnoreCase("ends-during")) {
2530
			rule.addTemporalConstraint(reference, target,
2531
					RelationType.ENDS_DURING, 
2532
					new long[][] {
2533
						new long[] {
2534
							ddlRelType.getFirstRange().getMin(),
2535
							ddlRelType.getFirstRange().getMax() > this.horizon ? 
2536
									this.horizon :
2537
									ddlRelType.getFirstRange().getMax()
2538
						},
2539
						new long[] {
2540
								ddlRelType.getSecondRange().getMin(),
2541
								ddlRelType.getSecondRange().getMax() > this.horizon ? 
2542
										this.horizon : 
2543
										ddlRelType.getSecondRange().getMax()
2544
							}
2545
					});
2546
		}
2547
		else {
2548
			
2549
			throw new RuntimeException("Unknown temporal relation " + ddlRelType);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
2550
		}
2551
	}
2552
	
2553
	/**
2554
	 * 
2555
	 * @param pdb
2556
	 * @param ddlComponent
2557
	 */
2558
	private void addDiscreteResource(PlanDataBase pdb, DDLComponent ddlComponent)
2559
	{
2560
		// get component name
2561
		String name = ddlComponent.getName();
2562
		// cast component
2563
		DDLRenewableResourceComponentType renewable = (DDLRenewableResourceComponentType) this.ddl_domain.getComponentTypes().get(ddlComponent.getComponentType());
2564
		// get resource capacity
2565
		int capacity = renewable.getCapacity();
2566
		
2567
		// create discrete resource
2568
		DiscreteResource resource = pdb.createDomainComponent(name, DomainComponentType.RESOURCE_DISCRETE);
2569
		// set capacity bounds
2570
		resource.setMinCapacity(0);
2571
		resource.setMaxCapacity(capacity);
2572
		resource.setInitialCapacity(capacity);
2573
		// add component 
2574
		pdb.addDomainComponent(resource);
2575
	}
2576
	
2577
	/**
2578
	 * 
2579
	 * @param pdb
2580
	 * @param ddlComponent
2581
	 */
2582
	private void addReservoirResource(PlanDataBase pdb, DDLComponent ddlComponent)
2583
	{
2584
		// get component name 
2585
		String name = ddlComponent.getName();
2586
		// cast component
2587
		DDLConsumableResourceComponentType consumable = (DDLConsumableResourceComponentType) this.ddl_domain.getComponentTypes().get(ddlComponent.getComponentType());
2588
		// get minimum capacity
2589
		int min = consumable.getMinCapacity();
2590
		int max = consumable.getCapacity();
2591
		int init = consumable.getInitCapacity();
2592
		// create reservoir resource
2593
		ReservoirResource resource = pdb.createDomainComponent(name, DomainComponentType.RESOURCE_RESERVOIR);
2594
		// set capacity bounds
2595
		resource.setMinCapacity(min);
2596
		resource.setMaxCapacity(max);
2597
		resource.setInitialCapacity(init);
2598
		// add component
2599
		pdb.addDomainComponent(resource);
2600
	}
2601
2602
	/**
2603
	 * 
2604
	 * @param pdb
2605
	 * @param ddlComponent
2606
	 */
2607
	private void addStateVariable(PlanDataBase pdb, DDLComponent ddlComponent) 
2608
	{
2609
		// get instances
2610
		for (DDLTimeline ddlTimeline : ddlComponent.getTimelines()) 
2611
		{
2612
			// component's name
2613
			String name = ddlComponent.getName();
2614
			// set state variable 
2615
			StateVariable sv;
2616
			// check state variable type
2617
			if (ddlTimeline.getParameters().contains("uncontrollable")) {
2618
				// external variable
2619
				sv = pdb.createDomainComponent(name, DomainComponentType.SV_EXTERNAL);
2620
			}
2621
			else if (ddlTimeline.getParameters().contains("functional")) {
2622
				// functional variable
2623
				sv = pdb.createDomainComponent(name, DomainComponentType.SV_FUNCTIONAL);
2624
			}
2625
			else {
2626
				// primitive variable
2627
				sv = pdb.createDomainComponent(name, DomainComponentType.SV_PRIMITIVE);
2628
			}
2629
2630
			// get component type
2631
			DDLSingletonStateVariableComponentType ddlComponentType = (DDLSingletonStateVariableComponentType) this.ddl_domain.getComponentTypes().get(ddlComponent.getComponentType());
2632
			
2633
			// value index
2634
			Map<String, StateVariableValue> vindex = new HashMap<>();
2635
			// creating allowed values
2636
			for (DDLSingletonStateVariableComponentDecisionType ddlValueType : ddlComponentType.getAllowedValues().values()) 
2637
			{
2638
				// add value
2639
				String vname = ddlValueType.getName();
2640
				// check controllability property of the value
2641
				boolean controllable = !vname.startsWith("_");
2642
				
2643
				// set duration constraints
2644
				for (DDLSingletonStateVariableTransitionConstraint ddlTransition : ddlComponentType.getTransitionConstraints()) 
2645
				{
2646
					// check transition on current value
2647
					if (ddlTransition.getFrom().getName().equals(vname)) {
2648
						// get duration bounds
2649
						long dmin = ddlTransition.getRange().getMin();
2650
						long dmax = ddlTransition.getRange().getMax() > pdb.getHorizon() ? 
2651
								pdb.getHorizon() : 
2652
								ddlTransition.getRange().getMax();
2653
								
2654
						
2655
						// add value to the variable
2656
						StateVariableValue val = sv.addStateVariableValue(vname, new long[] {dmin, dmax}, controllable);
2657
						
2658
						// add parameter place-holders to the value
2659
						for (String pname : ddlValueType.getParameterTypes()) {
2660
							// get domain
2661
							ParameterDomain dom = pdb.getParameterDomainByName(pname);
2662
							// add parameter place holder
2663
							val.addParameterPlaceHolder(dom);
2664
						}
2665
						
2666
						// add to local index
2667
						vindex.put(vname, val);
2668
						break;
2669
					}
2670
				}
2671
			}
2672
			
2673
			// set transition constraints
2674
			for (DDLSingletonStateVariableTransitionConstraint ddlTransition : ddlComponentType.getTransitionConstraints()) 
2675
			{
2676
				// transition's parameter index
2677
				Map<String, Map<String, DDLNumericParameterConstraintType>> labels2constraint = new HashMap<>();
2678
				// get transition parameter constraints
2679
				List<DDLParameterConstraint> paramConstraints = ddlTransition.getConstraints();
2680
				for (DDLParameterConstraint cons : paramConstraints) 
2681
				{
2682
					// check constraint type
2683
					switch (cons.getConstraintType()) 
2684
					{
2685
						// enumeration parameter constraint
2686
						case ENUMERATION : 
2687
						{
2688
							// not binary constraint
2689
							throw new RuntimeException("Only binary parameter constraints can be specifeid for variables' transitions");
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
2690
						}
2691
						
2692
						// numeric parameter constraint
2693
						case NUMERIC : 
2694
						{
2695
							// get numeric parameter constraint
2696
							DDLNumericParameterConstraint numConstraint = (DDLNumericParameterConstraint) cons;
2697
							// check if binary
2698
							if (numConstraint.isBinary()) {
2699
								// get labels
2700
								String referenceLabel = numConstraint.getLeftTerm();
2701
								// initialize structure
2702
								if (!labels2constraint.containsKey(referenceLabel)) {
2703
									labels2constraint.put(referenceLabel, new HashMap<String, DDLNumericParameterConstraintType>());
2704
								}
2705
								
2706
								// check targets
2707
								for (String targetLabel : numConstraint.getRightVariables()) {
2708
									// add entry 
2709
									labels2constraint.get(referenceLabel).put(targetLabel, numConstraint.getNumericConstraintType());
2710
									// add also "reverse" entry
2711
									if (!labels2constraint.containsKey(targetLabel)) {
2712
										labels2constraint.put(targetLabel, new HashMap<String, DDLNumericParameterConstraintType>());
2713
									}
2714
									labels2constraint.get(targetLabel).put(referenceLabel, numConstraint.getNumericConstraintType());
2715
								}
2716
							}
2717
							else {
2718
								// not binary constraint
2719
								throw new RuntimeException("Only binary parameter constraints can be specified for variables' transitions");
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
2720
							}
2721
						}
2722
						break;
2723
							
2724
						default : {
2725
							// unknown parameter type
2726
							throw new RuntimeException("Unknown parameter constraint type on transition " + cons.getConstraintType());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
2727
						}
2728
					}
2729
				}
2730
				
2731
				
2732
				// get related values
2733
				DDLSingletonStateVariableComponentDecision source = ddlTransition.getFrom();
2734
				StateVariableValue from = vindex.get(source.getName());
2735
				for (DDLSingletonStateVariableComponentDecision target : ddlTransition.getTo()) 
2736
				{
2737
					// get target value
2738
					StateVariableValue to = vindex.get(target.getName());
2739
					// add transition constraint
2740
					Transition t = sv.addValueTransition(from, to);
2741
					
2742
					// add parameter constraints
2743
					for (String referenceParName : source.getParameterNames()) 
2744
					{
2745
						// check target parameters
2746
						for (String targetParName : target.getParameterNames()) 
2747
						{
2748
							// check if constraints exists
2749
							if (labels2constraint.containsKey(referenceParName) && labels2constraint.get(referenceParName).containsKey(targetParName)) 
2750
							{
2751
								// get parameter
2752
								DDLNumericParameterConstraintType ddlConsType = labels2constraint.get(referenceParName).get(targetParName);
2753
								// get parameters's indexes
2754
								int referenceIndex = source.getParameterIndex(referenceParName);
2755
								int targetIndex = target.getParameterIndex(targetParName);
2756
								
2757
								// get type of constraint
2758
								ParameterConstraintType consType;
2759
								// check constraint type
2760
								switch (ddlConsType) 
2761
								{
2762
									case EQ : {
2763
										// equals constraint
2764
										consType = ParameterConstraintType.EQUAL;
2765
									}
2766
									break;
2767
									
2768
									case NEQ : {
2769
										// not equal constraint
2770
										consType = ParameterConstraintType.NOT_EQUAL;
2771
									}
2772
									break;
2773
									
2774
									case GE : 
2775
									case GT : 
2776
									case LE : 
2777
									case LT : {
2778
										
2779
										throw new RuntimeException("Manage GE|GT|LE|LT parameter constraint");
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
2780
									}
2781
									
2782
									default : {
2783
										// unknown parameter constraint type
2784
										throw new RuntimeException("Unknown parameter constraint type into transition " + ddlConsType);
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
2785
									}
2786
								}
2787
								
2788
								// add parameter constraint
2789
								t.addParameterConstraint(referenceIndex, targetIndex, consType);
2790
							}
2791
						}
2792
					}
2793
				}
2794
			}
2795
			
2796
			// add state variable to plan data-base
2797
			pdb.addDomainComponent(sv);
2798
		}
2799
	}
2800
}
2801