use of org.kie.dmn.validation.dtanalysis.model.Interval in project drools by kiegroup.
the class DMNDTAnalyser method findOverlaps.
private void findOverlaps(DTAnalysis analysis, DDTATable ddtaTable, int jColIdx, Interval[] currentIntervals, Collection<Integer> activeRules) {
LOG.debug("findOverlaps jColIdx {}, currentIntervals {}, activeRules {}", jColIdx, currentIntervals, activeRules);
if (jColIdx < ddtaTable.inputCols()) {
List<Bound> bounds = findBoundsSorted(ddtaTable, jColIdx, activeRules);
List<Interval> activeIntervals = new ArrayList<>();
Bound<?> lastBound = bounds.get(0);
for (Bound<?> currentBound : bounds) {
LOG.debug("lastBound {} currentBound {} activeIntervals {} == rules {}", lastBound, currentBound, activeIntervals, activeIntervalsToRules(activeIntervals));
if (activeIntervals.size() > 1 && canBeNewCurrInterval(lastBound, currentBound)) {
Interval analysisInterval = new Interval(lastBound.isUpperBound() ? Interval.invertBoundary(lastBound.getBoundaryType()) : lastBound.getBoundaryType(), lastBound.getValue(), currentBound.getValue(), currentBound.isLowerBound() ? Interval.invertBoundary(currentBound.getBoundaryType()) : currentBound.getBoundaryType(), 0, 0);
currentIntervals[jColIdx] = analysisInterval;
findOverlaps(analysis, ddtaTable, jColIdx + 1, currentIntervals, activeIntervalsToRules(activeIntervals));
}
if (currentBound.isLowerBound()) {
activeIntervals.add(currentBound.getParent());
} else {
activeIntervals.remove(currentBound.getParent());
}
lastBound = currentBound;
}
// facilitate debugging.
currentIntervals[jColIdx] = null;
} else if (jColIdx == ddtaTable.inputCols()) {
if (activeRules.size() > 1) {
Hyperrectangle overlap = new Hyperrectangle(ddtaTable.inputCols(), Arrays.asList(currentIntervals));
LOG.debug("OVERLAP DETECTED {}", overlap);
analysis.addOverlap(new Overlap(activeRules, overlap));
}
} else {
throw new IllegalStateException();
}
LOG.debug(".");
}
use of org.kie.dmn.validation.dtanalysis.model.Interval in project drools by kiegroup.
the class DMNDTAnalyser method utnToInterval.
private Interval utnToInterval(UnaryTestNode ut, Interval minMax, List discreteValues, int rule, int col) {
if (ut.getOperator() == UnaryOperator.EQ) {
if (discreteValues == null || discreteValues.isEmpty()) {
return new Interval(RangeBoundary.CLOSED, valueFromNode(ut.getValue()), valueFromNode(ut.getValue()), RangeBoundary.CLOSED, rule, col);
} else {
Comparable<?> thisValue = valueFromNode(ut.getValue());
int indexOf = discreteValues.indexOf(thisValue);
if (indexOf < 0) {
throw new IllegalStateException("Unable to determine discreteValue index for: " + ut);
}
if (indexOf + 1 == discreteValues.size()) {
return new Interval(RangeBoundary.CLOSED, thisValue, thisValue, RangeBoundary.CLOSED, rule, col);
}
return new Interval(RangeBoundary.CLOSED, thisValue, (Comparable<?>) discreteValues.get(indexOf + 1), RangeBoundary.OPEN, rule, col);
}
} else if (ut.getOperator() == UnaryOperator.LTE) {
return new Interval(minMax.getLowerBound().getBoundaryType(), minMax.getLowerBound().getValue(), valueFromNode(ut.getValue()), RangeBoundary.CLOSED, rule, col);
} else if (ut.getOperator() == UnaryOperator.LT) {
return new Interval(minMax.getLowerBound().getBoundaryType(), minMax.getLowerBound().getValue(), valueFromNode(ut.getValue()), RangeBoundary.OPEN, rule, col);
} else if (ut.getOperator() == UnaryOperator.GT) {
return new Interval(RangeBoundary.OPEN, valueFromNode(ut.getValue()), minMax.getUpperBound().getValue(), minMax.getUpperBound().getBoundaryType(), rule, col);
} else if (ut.getOperator() == UnaryOperator.GTE) {
return new Interval(RangeBoundary.CLOSED, valueFromNode(ut.getValue()), minMax.getUpperBound().getValue(), minMax.getUpperBound().getBoundaryType(), rule, col);
} else if (ut.getValue() instanceof RangeNode) {
RangeNode rangeNode = (RangeNode) ut.getValue();
if (!(rangeNode.getStart() instanceof NullNode || rangeNode.getEnd() instanceof NullNode)) {
return new Interval(rangeNode.getLowerBound() == IntervalBoundary.OPEN ? RangeBoundary.OPEN : RangeBoundary.CLOSED, valueFromNode(rangeNode.getStart()), valueFromNode(rangeNode.getEnd()), rangeNode.getUpperBound() == IntervalBoundary.OPEN ? RangeBoundary.OPEN : RangeBoundary.CLOSED, rule, col);
} else if (rangeNode.getStart() instanceof NullNode) {
return new Interval(minMax.getLowerBound().getBoundaryType(), minMax.getLowerBound().getValue(), valueFromNode(rangeNode.getEnd()), rangeNode.getUpperBound() == IntervalBoundary.OPEN ? RangeBoundary.OPEN : RangeBoundary.CLOSED, rule, col);
} else {
return new Interval(rangeNode.getLowerBound() == IntervalBoundary.OPEN ? RangeBoundary.OPEN : RangeBoundary.CLOSED, valueFromNode(rangeNode.getStart()), minMax.getUpperBound().getValue(), minMax.getUpperBound().getBoundaryType(), rule, col);
}
} else {
throw new UnsupportedOperationException("UnaryTest type: " + ut);
}
}
use of org.kie.dmn.validation.dtanalysis.model.Interval in project drools by kiegroup.
the class DMNDTAnalyser method compileTableComputeColStringMissingEnum.
private void compileTableComputeColStringMissingEnum(DMNModel model, DecisionTable dt, DDTATable ddtaTable) {
for (int iColIdx = 0; iColIdx < ddtaTable.inputCols(); iColIdx++) {
InputClause ie = dt.getInput().get(iColIdx);
QName typeRef = DMNCompilerImpl.getNamespaceAndName(dt, ((DMNModelImpl) model).getImportAliasesForNS(), ie.getInputExpression().getTypeRef(), model.getNamespace());
if (SimpleType.STRING.equals(typeRef.getLocalPart()) && !ddtaTable.getInputs().get(iColIdx).isDiscreteDomain()) {
Interval infStringDomain = ddtaTable.getInputs().get(iColIdx).getDomainMinMax();
boolean areAllSinglePointOrAll = true;
for (int jRowIdx = 0; jRowIdx < dt.getRule().size() && areAllSinglePointOrAll; jRowIdx++) {
List<Interval> r = ddtaTable.getRule().get(jRowIdx).getInputEntry().get(iColIdx).getIntervals();
for (Interval interval : r) {
areAllSinglePointOrAll = areAllSinglePointOrAll && (infStringDomain.equals(interval) || interval.isSingularity());
}
}
if (areAllSinglePointOrAll) {
ddtaTable.addColIdStringWithoutEnum(iColIdx + 1);
}
}
}
}
use of org.kie.dmn.validation.dtanalysis.model.Interval in project drools by kiegroup.
the class MCDCAnalyser method findValuesForRule.
private Object[] findValuesForRule(int ruleIdx, Object[] knownValues, List<List<?>> allEnumValues) {
Object[] result = Arrays.copyOf(knownValues, knownValues.length);
List<DDTAInputEntry> inputEntry = ddtaTable.getRule().get(ruleIdx).getInputEntry();
for (int i = 0; i < inputEntry.size(); i++) {
if (result[i] == null) {
DDTAInputEntry ddtaInputEntry = inputEntry.get(i);
List<?> enumValues = allEnumValues.get(i);
Interval interval0 = ddtaInputEntry.getIntervals().get(0);
if (interval0.isSingularity()) {
result[i] = interval0.getLowerBound().getValue();
} else if (interval0.getLowerBound().getBoundaryType() == RangeBoundary.CLOSED && interval0.getLowerBound().getValue() != Interval.NEG_INF) {
result[i] = interval0.getLowerBound().getValue();
} else if (interval0.getUpperBound().getBoundaryType() == RangeBoundary.CLOSED && interval0.getUpperBound().getValue() != Interval.POS_INF) {
result[i] = interval0.getUpperBound().getValue();
}
if (!enumValues.contains(result[i])) {
// invalidating if the chosen enum is not part of the plausible ones
result[i] = null;
}
if (result[i] == null) {
for (Object object : enumValues) {
if (ddtaInputEntry.getIntervals().stream().anyMatch(interval -> interval.asRangeIncludes(object))) {
result[i] = object;
break;
}
}
}
}
}
return result;
}
use of org.kie.dmn.validation.dtanalysis.model.Interval in project drools by kiegroup.
the class ContractionRulesTest method testContractionRules.
@Test
public void testContractionRules() {
List<DMNMessage> validate = validator.validate(getReader("Contraction.dmn"), ANALYZE_DECISION_TABLE);
DTAnalysis analysis = getAnalysis(validate, "_01d9abb9-b968-49c0-b6ab-909f3e03d8d3");
assertThat(analysis.getGaps(), hasSize(0));
assertThat(analysis.getOverlaps(), hasSize(0));
// Contraction count.
assertThat(analysis.getContractions(), hasSize(2));
List<Contraction> results = Arrays.asList(new Contraction(4, Arrays.asList(5), 2, Arrays.asList(new Interval(RangeBoundary.CLOSED, new BigDecimal("0.35"), Interval.POS_INF, RangeBoundary.CLOSED, 0, 0))), new Contraction(3, Arrays.asList(6), 1, Arrays.asList(new Interval(RangeBoundary.CLOSED, new BigDecimal("600"), Interval.POS_INF, RangeBoundary.CLOSED, 0, 0))));
assertThat(results, hasSize(2));
assertThat(analysis.getContractions(), contains(results.toArray()));
assertThat("It should contain 2 DMNMessage for the Contraction", validate.stream().filter(p -> p.getMessageType().equals(DMNMessageType.DECISION_TABLE_CONTRACTION_RULE)).collect(Collectors.toList()), hasSize(2));
}
Aggregations