Search in sources :

Example 11 with Interval

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(".");
}
Also used : Bound(org.kie.dmn.validation.dtanalysis.model.Bound) ArrayList(java.util.ArrayList) Hyperrectangle(org.kie.dmn.validation.dtanalysis.model.Hyperrectangle) Overlap(org.kie.dmn.validation.dtanalysis.model.Overlap) Interval(org.kie.dmn.validation.dtanalysis.model.Interval)

Example 12 with Interval

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);
    }
}
Also used : RangeNode(org.kie.dmn.feel.lang.ast.RangeNode) NullNode(org.kie.dmn.feel.lang.ast.NullNode) Interval(org.kie.dmn.validation.dtanalysis.model.Interval)

Example 13 with Interval

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);
            }
        }
    }
}
Also used : QName(javax.xml.namespace.QName) DDTAInputClause(org.kie.dmn.validation.dtanalysis.model.DDTAInputClause) InputClause(org.kie.dmn.model.api.InputClause) Interval(org.kie.dmn.validation.dtanalysis.model.Interval)

Example 14 with Interval

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;
}
Also used : DDTAInputEntry(org.kie.dmn.validation.dtanalysis.model.DDTAInputEntry) Interval(org.kie.dmn.validation.dtanalysis.model.Interval)

Example 15 with Interval

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));
}
Also used : DMNMessage(org.kie.dmn.api.core.DMNMessage) DTAnalysis(org.kie.dmn.validation.dtanalysis.model.DTAnalysis) Contraction(org.kie.dmn.validation.dtanalysis.model.Contraction) BigDecimal(java.math.BigDecimal) Interval(org.kie.dmn.validation.dtanalysis.model.Interval) Test(org.junit.Test)

Aggregations

Interval (org.kie.dmn.validation.dtanalysis.model.Interval)20 Test (org.junit.Test)9 ArrayList (java.util.ArrayList)4 QName (javax.xml.namespace.QName)3 ProcessedUnaryTest (org.kie.dmn.feel.codegen.feel11.ProcessedUnaryTest)3 UnaryTestListNode (org.kie.dmn.feel.lang.ast.UnaryTestListNode)3 UnaryTestNode (org.kie.dmn.feel.lang.ast.UnaryTestNode)3 UnaryTestInterpretedExecutableExpression (org.kie.dmn.feel.lang.impl.UnaryTestInterpretedExecutableExpression)3 DDTAInputClause (org.kie.dmn.validation.dtanalysis.model.DDTAInputClause)3 DDTAInputEntry (org.kie.dmn.validation.dtanalysis.model.DDTAInputEntry)3 BaseNode (org.kie.dmn.feel.lang.ast.BaseNode)2 NullNode (org.kie.dmn.feel.lang.ast.NullNode)2 InputClause (org.kie.dmn.model.api.InputClause)2 Bound (org.kie.dmn.validation.dtanalysis.model.Bound)2 DDTARule (org.kie.dmn.validation.dtanalysis.model.DDTARule)2 Hyperrectangle (org.kie.dmn.validation.dtanalysis.model.Hyperrectangle)2 StaticJavaParser.parseExpression (com.github.javaparser.StaticJavaParser.parseExpression)1 Expression (com.github.javaparser.ast.expr.Expression)1 IntegerLiteralExpr (com.github.javaparser.ast.expr.IntegerLiteralExpr)1 MethodCallExpr (com.github.javaparser.ast.expr.MethodCallExpr)1