use of org.kie.dmn.feel.lang.ast.UnaryTestNode in project drools by kiegroup.
the class DMNDTAnalyser method compileTableInputClauses.
private void compileTableInputClauses(DMNModel model, DecisionTable dt, DDTATable ddtaTable) {
for (int jColIdx = 0; jColIdx < dt.getInput().size(); jColIdx++) {
InputClause ie = dt.getInput().get(jColIdx);
Interval infDomain = new Interval(RangeBoundary.CLOSED, Interval.NEG_INF, Interval.POS_INF, RangeBoundary.CLOSED, 0, jColIdx + 1);
String allowedValues;
if (ie.getInputValues() != null) {
allowedValues = ie.getInputValues().getText();
} else {
QName typeRef = DMNCompilerImpl.getNamespaceAndName(dt, ((DMNModelImpl) model).getImportAliasesForNS(), ie.getInputExpression().getTypeRef(), model.getNamespace());
allowedValues = findAllowedValues(model, typeRef);
}
if (allowedValues != null) {
ProcessedUnaryTest compileUnaryTests = (ProcessedUnaryTest) FEEL.compileUnaryTests(allowedValues, FEEL.newCompilerContext());
UnaryTestInterpretedExecutableExpression interpreted = compileUnaryTests.getInterpreted();
UnaryTestListNode utln = (UnaryTestListNode) interpreted.getASTNode();
if (utln.getElements().size() != 1) {
verifyUnaryTestsAllEQ(utln, dt);
List<Comparable<?>> discreteValues = getDiscreteValues(utln);
Collections.sort((List) discreteValues);
Interval discreteDomainMinMax = new Interval(RangeBoundary.CLOSED, discreteValues.get(0), discreteValues.get(discreteValues.size() - 1), RangeBoundary.CLOSED, 0, jColIdx + 1);
DDTAInputClause ic = new DDTAInputClause(discreteDomainMinMax, discreteValues, getDiscreteValues(utln));
ddtaTable.getInputs().add(ic);
} else if (utln.getElements().size() == 1) {
UnaryTestNode utn0 = (UnaryTestNode) utln.getElements().get(0);
Interval interval = utnToInterval(utn0, infDomain, null, 0, jColIdx + 1);
DDTAInputClause ic = new DDTAInputClause(interval);
ddtaTable.getInputs().add(ic);
} else {
throw new IllegalStateException("inputValues not null but utln: " + utln);
}
} else {
DDTAInputClause ic = new DDTAInputClause(infDomain);
ddtaTable.getInputs().add(ic);
}
}
}
use of org.kie.dmn.feel.lang.ast.UnaryTestNode in project drools by kiegroup.
the class DMNDTAnalyser method compileTableOutputClauses.
private void compileTableOutputClauses(DMNModel model, DecisionTable dt, DDTATable ddtaTable) {
for (int jColIdx = 0; jColIdx < dt.getOutput().size(); jColIdx++) {
OutputClause oe = dt.getOutput().get(jColIdx);
Interval infDomain = new Interval(RangeBoundary.CLOSED, Interval.NEG_INF, Interval.POS_INF, RangeBoundary.CLOSED, 0, jColIdx + 1);
String allowedValues = null;
if (oe.getOutputValues() != null) {
allowedValues = oe.getOutputValues().getText();
} else {
QName outputTypeRef = (oe.getTypeRef() == null && dt.getOutput().size() == 1) ? dt.getTypeRef() : oe.getTypeRef();
if (outputTypeRef != null) {
QName typeRef = DMNCompilerImpl.getNamespaceAndName(dt, ((DMNModelImpl) model).getImportAliasesForNS(), outputTypeRef, model.getNamespace());
allowedValues = findAllowedValues(model, typeRef);
}
}
if (allowedValues != null) {
ProcessedUnaryTest compileUnaryTests = (ProcessedUnaryTest) FEEL.compileUnaryTests(allowedValues, FEEL.newCompilerContext());
UnaryTestInterpretedExecutableExpression interpreted = compileUnaryTests.getInterpreted();
UnaryTestListNode utln = (UnaryTestListNode) interpreted.getASTNode();
if (utln.getElements().size() != 1) {
verifyUnaryTestsAllEQ(utln, dt);
List<Comparable<?>> discreteValues = getDiscreteValues(utln);
List<Comparable<?>> outputOrder = new ArrayList<>(discreteValues);
Collections.sort((List) discreteValues);
Interval discreteDomainMinMax = new Interval(RangeBoundary.CLOSED, discreteValues.get(0), discreteValues.get(discreteValues.size() - 1), RangeBoundary.CLOSED, 0, jColIdx + 1);
DDTAOutputClause ic = new DDTAOutputClause(discreteDomainMinMax, discreteValues, outputOrder);
ddtaTable.getOutputs().add(ic);
} else if (utln.getElements().size() == 1) {
UnaryTestNode utn0 = (UnaryTestNode) utln.getElements().get(0);
Interval interval = utnToInterval(utn0, infDomain, null, 0, jColIdx + 1);
DDTAOutputClause ic = new DDTAOutputClause(interval);
ddtaTable.getOutputs().add(ic);
} else {
throw new IllegalStateException("inputValues not null but utln: " + utln);
}
} else {
DDTAOutputClause ic = new DDTAOutputClause(infDomain);
ddtaTable.getOutputs().add(ic);
}
}
}
use of org.kie.dmn.feel.lang.ast.UnaryTestNode in project drools by kiegroup.
the class DMNDTAnalyser method getDiscreteValues.
/**
* Transform a UnaryTestListNode into a List of discrete values for input/output clause enumeration
*/
private List<Comparable<?>> getDiscreteValues(UnaryTestListNode utln) {
List<Comparable<?>> discreteValues = new ArrayList<>();
for (BaseNode e : utln.getElements()) {
BaseNode value = ((UnaryTestNode) e).getValue();
if (!(value instanceof NullNode)) {
// to retrieve value from input/output clause enumeration, null is ignored.
Comparable<?> v = valueFromNode(value);
discreteValues.add(v);
}
}
return discreteValues;
}
use of org.kie.dmn.feel.lang.ast.UnaryTestNode in project drools by kiegroup.
the class FEELImpl method evaluateUnaryTests.
@Override
public List<UnaryTest> evaluateUnaryTests(String expression, Map<String, Type> variableTypes) {
// DMN defines a special case where, unless the expressions are unary tests
// or ranges, they need to be converted into an equality test unary expression.
// This way, we have to compile and check the low level AST nodes to properly
// deal with this case
CompilerContext ctx = newCompilerContext();
for (Map.Entry<String, Type> e : variableTypes.entrySet()) {
ctx.addInputVariableType(e.getKey(), e.getValue());
}
CompiledExpressionImpl compiledExpression = (CompiledExpressionImpl) compileExpressionList(expression, ctx);
if (compiledExpression != null) {
ListNode listNode = (ListNode) compiledExpression.getExpression();
List<BaseNode> tests = new ArrayList<>();
for (BaseNode o : listNode.getElements()) {
if (o == null) {
// not much we can do, so just skip it. Error was reported somewhere else
continue;
} else if (o instanceof UnaryTestNode || o instanceof DashNode) {
tests.add(o);
} else if (o instanceof RangeNode || o instanceof ListNode) {
tests.add(new UnaryTestNode("in", o));
} else {
tests.add(new UnaryTestNode("=", o));
}
}
listNode.setElements(tests);
compiledExpression.setExpression(listNode);
// now we can evaluate the expression to build the list of unary tests
List<UnaryTest> uts = (List<UnaryTest>) evaluate(compiledExpression, FEELImpl.EMPTY_INPUT);
return uts;
}
return Collections.emptyList();
}
use of org.kie.dmn.feel.lang.ast.UnaryTestNode in project drools by kiegroup.
the class DMNDTAnalyser method toIntervals.
private List<Interval> toIntervals(List<BaseNode> elements, boolean isNegated, Interval minMax, List discreteValues, int rule, int col) {
List<Interval> results = new ArrayList<>();
if (elements.size() == 1 && elements.get(0) instanceof UnaryTestNode && ((UnaryTestNode) elements.get(0)).getValue() instanceof NullNode) {
return Collections.emptyList();
}
if (discreteValues != null && !discreteValues.isEmpty() && areAllEQUnaryTest(elements) && elements.size() > 1) {
// JDK BitSet size will always be larger.
int bitsetLogicalSize = discreteValues.size();
BitSet hitValues = new BitSet(bitsetLogicalSize);
for (BaseNode n : elements) {
Comparable<?> thisValue = valueFromNode(((UnaryTestNode) n).getValue());
int indexOf = discreteValues.indexOf(thisValue);
if (indexOf < 0) {
throw new IllegalStateException("Unable to determine discreteValue index for: " + n);
}
hitValues.set(indexOf);
}
if (isNegated) {
hitValues.flip(0, bitsetLogicalSize);
}
int lowerBoundIdx = -1;
int upperBoundIdx = -1;
for (int i = 0; i < hitValues.length(); i++) {
boolean curValue = hitValues.get(i);
if (curValue) {
if (lowerBoundIdx < 0) {
lowerBoundIdx = i;
upperBoundIdx = i;
} else {
upperBoundIdx = i;
}
} else {
if (lowerBoundIdx >= 0 && upperBoundIdx >= 0) {
results.add(createIntervalOfRule(discreteValues, rule, col, lowerBoundIdx, upperBoundIdx));
lowerBoundIdx = -1;
upperBoundIdx = -1;
}
}
}
if (lowerBoundIdx >= 0 && upperBoundIdx >= 0) {
results.add(createIntervalOfRule(discreteValues, rule, col, lowerBoundIdx, upperBoundIdx));
}
} else {
for (BaseNode n : elements) {
if (n instanceof DashNode) {
results.add(new Interval(minMax.getLowerBound().getBoundaryType(), minMax.getLowerBound().getValue(), minMax.getUpperBound().getValue(), minMax.getUpperBound().getBoundaryType(), rule, col));
continue;
}
UnaryTestNode ut = (UnaryTestNode) n;
Interval interval = utnToInterval(ut, minMax, discreteValues, rule, col);
if (isNegated) {
results.addAll(Interval.invertOverDomain(interval, minMax));
} else {
results.add(interval);
}
}
}
return results;
}
Aggregations