1 package cz.cuni.amis.pogamut.sposh.engine;
2
3 import cz.cuni.amis.pogamut.sposh.elements.Arguments;
4 import cz.cuni.amis.pogamut.sposh.elements.LapPath;
5 import cz.cuni.amis.pogamut.sposh.elements.PrimitiveCall;
6 import cz.cuni.amis.pogamut.sposh.elements.Result;
7 import cz.cuni.amis.pogamut.sposh.elements.Sense;
8 import cz.cuni.amis.pogamut.sposh.elements.Sense.Predicate;
9 import cz.cuni.amis.pogamut.sposh.executor.IWorkExecutor;
10
11
12
13
14
15
16
17
18
19 class SenseResult {
20
21
22 public final String name;
23
24 private final boolean success;
25
26
27
28
29
30
31 SenseResult(String name, boolean success) {
32 this.name = name;
33 this.success = success;
34 }
35
36
37
38
39
40
41 public boolean wasSuccessful() {
42 return success;
43 }
44 }
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 final class SenseExecutor extends AbstractExecutor {
62
63 private PrimitiveCall senseCall;
64 private Predicate predicate;
65
66
67
68
69 private final boolean compare = true;
70 private Object operand;
71
72
73
74
75
76
77
78 SenseExecutor(Sense sense, LapPath sensePath, VariableContext ctx, EngineLog log) {
79 super(sensePath, ctx, log);
80
81 assert sensePath.traversePath(sense.getRootNode()) == sense;
82
83 senseCall = sense.getSenseCall();
84 predicate = sense.getPredicate();
85 operand = sense.getOperand();
86 }
87
88
89
90
91
92 public SenseResult fire(IWorkExecutor workExecuter) {
93 engineLog.fine("Fire: " + toString());
94 engineLog.pathReached(path);
95
96 String senseName = senseCall.getName();
97
98 Object primitiveResult = workExecuter.executeSense(senseName, new VariableContext(ctx, senseCall.getParameters()));
99
100 boolean res;
101
102 if (!compare) {
103 res = Result.isTrue(primitiveResult);
104 } else {
105 res = evaluateComparison(primitiveResult, predicate, operand);
106 }
107 return new SenseResult(senseName, res);
108 }
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126 static boolean evaluateComparison(Object operand1, Predicate predicate, Object operand2) {
127 String comparison = operand1 + " " + predicate + " " + operand2;
128 switch (predicate) {
129 case DEFAULT:
130 case EQUAL:
131 return Result.equal(operand1, operand2);
132 case NOT_EQUAL:
133 return !Result.equal(operand1, operand2);
134 case LOWER:
135 return Result.compare(operand1, operand2) < 0;
136 case GREATER:
137 return Result.compare(operand1, operand2) > 0;
138 case LOWER_OR_EQUAL:
139 return Result.equal(operand1, operand2) || Result.compare(operand1, operand2) < 0;
140 case GREATER_OR_EQUAL:
141 return Result.equal(operand1, operand2) || Result.compare(operand1, operand2) > 0;
142 default:
143 throw new IllegalArgumentException("Predicate operation \"" + predicate + "\" is implemented.");
144 }
145 }
146
147 @Override
148 public String toString() {
149 StringBuilder sb = new StringBuilder("SenseExecutor[(");
150
151 sb.append(senseCall.getName());
152 sb.append('(');
153 boolean first = true;
154 for (Arguments.Argument parameter : senseCall.getParameters()) {
155 if (!first) {
156 sb.append(", ");
157 }
158 sb.append(parameter.getParameterName());
159 first = false;
160 }
161 sb.append(')');
162
163 if (compare) {
164 sb.append(' ');
165 sb.append(predicate);
166
167 sb.append(' ');
168 sb.append(operand);
169 }
170
171 sb.append(')');
172 sb.append(']');
173 return sb.toString();
174 }
175 }