Skip to content
Snippets Groups Projects
Commit 5a4e5900 authored by Jonas Blatt's avatar Jonas Blatt :ant:
Browse files

Merge branch 'develop' into 'master'

Develop

See merge request fg-bks/br-verification-tool!33
parents e1cfbebe 3431e812
No related branches found
No related tags found
No related merge requests found
......@@ -147,8 +147,8 @@ public class DmnRuleMap {
for (OutputType ot : outputColumns) {
Set<OutputType> equalOuts = new HashSet<>();
for (OutputType otInner : outputColumns) {
if (ot.label != null
&& ot.label.equals(otInner.label)
if (ot.expressionName != null
&& ot.expressionName.equals(otInner.expressionName)
&& ot.dataType.equals(otInner.dataType)) {
equalOuts.add(otInner);
}
......@@ -181,10 +181,14 @@ public class DmnRuleMap {
inputColumns.stream()
.filter(i -> i.getDecisionKey().equals(ot.getDecisionKey()))
.collect(Collectors.toList())) {
// only, if the label didn't exists in previously created input
// only, if the expressionName didn't exists in previously created input
Optional<InputType> existingInputType =
newInputTypes.stream()
.filter(i -> i.label.equals(inputType.label) && i.dataType == inputType.dataType)
.filter(
i ->
i.expressionName != null
&& i.expressionName.equals(inputType.expressionName)
&& i.dataType == inputType.dataType)
.findFirst();
if (existingInputType.isPresent()) {
inputType
......@@ -216,7 +220,10 @@ public class DmnRuleMap {
// try to find existing col
Optional<InputType> orgI =
orgInputTypes.stream()
.filter(i -> i.label.equals(inputType.label) && i.dataType == inputType.dataType)
.filter(
i ->
i.expressionName.equals(inputType.expressionName)
&& i.dataType == inputType.dataType)
.findFirst();
List<Value> vals = inputs.getOrDefault(inputType, new ArrayList<>());
if (orgI.isPresent()) {
......@@ -234,7 +241,10 @@ public class DmnRuleMap {
// try to find existing col
Optional<InputType> orgI =
orgInputTypes.stream()
.filter(i -> i.label.equals(inputType.label) && i.dataType == inputType.dataType)
.filter(
i ->
i.expressionName.equals(inputType.expressionName)
&& i.dataType == inputType.dataType)
.findFirst();
List<Value> vals = inputs.getOrDefault(inputType, new ArrayList<>());
if (!orgI.isPresent()) {
......
package de.unikoblenz.fgbks.dmn.core.dmnhelper;
import java.util.UUID;
import org.camunda.bpm.dmn.engine.DmnDecision;
import org.camunda.bpm.dmn.engine.impl.DmnDecisionTableInputImpl;
......@@ -14,7 +15,9 @@ public class InputType extends Type {
d,
input.getId(),
DataType.getTypeFromString(input.getExpression().getTypeDefinition().getTypeName()),
input.getName());
input.getExpression().getExpression() == null
? UUID.randomUUID().toString().substring(0, 9)
: input.getExpression().getExpression());
}
public InputType(InputType inputType) {
......
......@@ -12,7 +12,7 @@ public abstract class Type {
protected final DmnDecision decision;
protected final String id;
protected final DataType dataType;
protected final String label;
protected final String expressionName;
protected String overwrittenDecisionKey;
protected Set<String> predefinedValues;
......@@ -35,8 +35,8 @@ public abstract class Type {
return dataType;
}
public String getLabel() {
return label;
public String getExpressionName() {
return expressionName;
}
public void setOverwrittenDecisionKey(String overwrittenDecisionKey) {
......@@ -51,11 +51,11 @@ public abstract class Type {
predefinedValues.add(predefinedValue);
}
protected Type(DmnDecision decision, String id, DataType dataType, String label) {
protected Type(DmnDecision decision, String id, DataType dataType, String expressionName) {
this.decision = decision;
this.id = id;
this.dataType = dataType;
this.label = label;
this.expressionName = expressionName;
this.overwrittenDecisionKey = null;
this.predefinedValues = new HashSet<>();
}
......@@ -64,7 +64,7 @@ public abstract class Type {
this.decision = type.decision;
this.id = type.id;
this.dataType = type.dataType;
this.label = type.label;
this.expressionName = type.expressionName;
this.overwrittenDecisionKey = type.overwrittenDecisionKey;
this.predefinedValues = new HashSet<>(type.predefinedValues);
}
......@@ -106,7 +106,7 @@ public abstract class Type {
}
public boolean isEqualExpression(Type type) {
return this.label.equals(type.label);
return this.expressionName.equals(type.expressionName);
}
@Override
......
......@@ -16,53 +16,80 @@ import org.camunda.bpm.dmn.engine.DmnDecision;
import org.slf4j.LoggerFactory;
public enum VerifierType {
/** Detecting rules which have an identical input, i.e. are redundant. */
Identical("Checking for identical rules.", IdenticalVerifier.class, true, true, false),
/**
* Detecting individual rules which are subsumed by other rules, i.e. they are not necessary. For
* example, rules containing wildcards often render more specific rules unnecessary due to
* subsumption.
*/
Subsumption(
"Checking for rules, which subsume other rules.",
SubsumptionVerifier.class,
true,
true,
false),
/**
* Detecting rules which are not identical, but still semantically equivalent. Here, our tool can
* verify if there exist multiple rules which use synonyms as inputs and are therefore equivalent,
* based on synonym relations via Wordnet.
*/
Equivalent(
"Checking for semantically equivalent rules.", EquivalentVerifier.class, true, false, false),
/** Detecting whether there are any overlaps in rule conditions. */
Overlap("Checking for overlapping rules.", OverlappingVerifier.class, true, true, false),
/**
* Detecting whether there are any missing business rules, i.e. if there are rules missing for
* expected inputs.
*/
Missing("Checking for missing rules.", MissingVerifier.class, true, false, false),
/** Checking wether ranges can be combined to simplify decision tables. */
PartialReduction(
"Checking for partial reduction of rules (combination).",
PartialReductionVerifier.class,
true,
false,
false),
/**
* Detecting rules which will always be activated together, but have differing or contradicting
* conclusions. For example, rules which will be activated together must not yield that a customer
* is both credit worthy, and not creditworthy, as this is logically inconsistent.
*/
Interdeterminism(
"Checking for rules that are activated together but have different conclusions.",
InterdeterminismVerifier.class,
false,
false,
false),
/** Same as {@link VerifierType#Identical}, including a multi table view. */
MultiTableIdentical(
"Checking for identical rules in multiple tables (identical outcome column).",
MultiTableIdenticalVerifier.class,
true,
true,
true),
/** Same as {@link VerifierType#Overlap}, including a multi table view. */
MultiTableOverlapping(
"Checking for overlapping rules in multiple tables (identical outcome column).",
MultiTableOverlappingVerifier.class,
true,
true,
true),
/** Same as {@link VerifierType#Subsumption}, including a multi table view. */
MultiTableSubsumption(
"Checking for subsumptions in multiple tables (identical outcome column).",
MultiTableSubsumptionVerifier.class,
true,
true,
true),
/** Same as {@link VerifierType#Equivalent}, including a multi table view. */
MultiTableEquivalent(
"Checking for equivalent rules in multiple tables (identical outcome column).",
MultiTableEquivalentVerifier.class,
true,
false,
true),
/** Same as {@link VerifierType#PartialReduction}, including a multi table view. */
MultiTablePartialReduction(
"Checking for partial reduction of rules in multiple tables (identical outcome column).",
MultiTablePartialReductionVerifier.class,
......@@ -134,7 +161,7 @@ public enum VerifierType {
}
public static VerifierCollectionResult getAllResults(List<DmnDecision> dmnDecisionList) {
return getAllResults(dmnDecisionList, false);
return getAllResults(dmnDecisionList, true);
}
public static VerifierCollectionResult getAllResults(
......
......@@ -30,7 +30,7 @@ public class EquivalentVerifier extends AbstractVerifier {
for (Type t : allTypesFromDecisionKey) {
// only check strings for equvalent rules (input + output)
if (t.getDataType() == DataType.STRING) {
// ensure label is not null and not empty
// ensure expression is not null and not empty
List<Value> values =
dmnRuleMap.getValuesFromType(t).stream()
.filter(
......
......@@ -5,14 +5,14 @@
<biodi:bounds x="311" y="89" width="180" height="80" />
</extensionElements>
<decisionTable id="decisionTable_1">
<input id="input_1" label="a">
<input id="input_1">
<inputExpression id="inputExpression_1" typeRef="integer">
<text></text>
<text>a</text>
</inputExpression>
</input>
<input id="InputClause_0quh9nu" label="b">
<input id="InputClause_0quh9nu">
<inputExpression id="LiteralExpression_0u964y9" typeRef="integer">
<text></text>
<text>b</text>
</inputExpression>
</input>
<output id="output_1" name="outX" typeRef="integer" />
......@@ -56,8 +56,10 @@
<biodi:bounds x="105" y="88" width="180" height="80" />
</extensionElements>
<decisionTable id="DecisionTable_1whu57b">
<input id="InputClause_00l1ge6" label="a">
<inputExpression id="LiteralExpression_0ujv368" typeRef="integer" />
<input id="InputClause_00l1ge6">
<inputExpression id="LiteralExpression_0ujv368" typeRef="integer">
<text>a</text>
</inputExpression>
</input>
<output id="OutputClause_10gzo88" name="outX" typeRef="integer" />
<rule id="DecisionRule_0udq1f7">
......
......@@ -13,7 +13,7 @@
<link rel="stylesheet"
href="https://unpkg.com/dmn-js@6.3.1/dist/assets/dmn-js-decision-table-controls.css"/>
<link rel="stylesheet"
href="https://unpkg.com/dmn-js@6.3.1/dist/assets/dmn-js-literal-label.css"/>
href="https://unpkg.com/dmn-js@6.3.1/dist/assets/dmn-js-literal-expression.css"/>
<link rel="stylesheet"
href="https://unpkg.com/dmn-js@6.3.1/dist/assets/dmn-font/css/dmn.css"/>
<h:panelGroup id="content" layout="block">
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment