Skip to content

Commit 28d8b97

Browse files
committed
add verifier methods and classes, bump version
1 parent aa164c1 commit 28d8b97

File tree

3 files changed

+200
-1
lines changed

3 files changed

+200
-1
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<modelVersion>4.0.0</modelVersion>
55
<groupId>at.jku.cps</groupId>
66
<artifactId>travart-core</artifactId>
7-
<version>1.0.1</version>
7+
<version>1.1.0</version>
88
<properties>
99
<maven.compiler.source>11</maven.compiler.source>
1010
<maven.compiler.target>11</maven.compiler.target>
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*******************************************************************************
2+
* This Source Code Form is subject to the terms of the Mozilla
3+
* Public License, v. 2.0. If a copy of the MPL was not distributed
4+
* with this file, You can obtain one at
5+
* https://mozilla.org/MPL/2.0/.
6+
*
7+
* Contributors:
8+
* @author Dario Romano
9+
*
10+
* provides constants for use in the UVLVerifier class
11+
*
12+
* Copyright 2024 Johannes Kepler University Linz
13+
* LIT Cyber-Physical Systems Lab
14+
* All rights reserved
15+
*******************************************************************************/
16+
package at.jku.cps.travart.core.verify;
17+
18+
public enum LogicOperator {
19+
AND("&", "&"), OR("|", "|"), EQUALS("<=>", "<=>"), IMPLIES("=>", "=>"), NOT("~", "!");
20+
21+
private String uvl;
22+
private String ng;
23+
24+
LogicOperator(String uvl, String ng) {
25+
this.uvl = uvl;
26+
this.ng = ng;
27+
}
28+
29+
public String uvl() {
30+
return uvl;
31+
32+
}
33+
34+
public String ng() {
35+
return ng;
36+
}
37+
38+
@Override
39+
public String toString() {
40+
return this.uvl;
41+
}
42+
43+
}
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
/*******************************************************************************
2+
* This Source Code Form is subject to the terms of the Mozilla
3+
* Public License, v. 2.0. If a copy of the MPL was not distributed
4+
* with this file, You can obtain one at
5+
* https://mozilla.org/MPL/2.0/.
6+
*
7+
* Contributors:
8+
* @author Dario Romano
9+
*
10+
* Implements various utilities to verify transformation/optimization results
11+
*
12+
* Copyright 2024 Johannes Kepler University Linz
13+
* LIT Cyber-Physical Systems Lab
14+
* All rights reserved
15+
*******************************************************************************/
16+
package at.jku.cps.travart.core.verify;
17+
18+
import static at.jku.cps.travart.core.verify.LogicOperator.*;
19+
import java.util.Collection;
20+
import java.util.List;
21+
import java.util.Objects;
22+
import java.util.Set;
23+
import java.util.stream.Collectors;
24+
25+
import org.apache.logging.log4j.util.Strings;
26+
import org.logicng.formulas.Formula;
27+
import org.logicng.formulas.FormulaFactory;
28+
import org.logicng.io.parsers.FormulaParser;
29+
import org.logicng.io.parsers.ParserException;
30+
import org.logicng.io.parsers.PropositionalParser;
31+
32+
import de.vill.model.Feature;
33+
import de.vill.model.FeatureModel;
34+
import de.vill.model.constraint.Constraint;
35+
36+
public class UVLVerifier {
37+
38+
/**
39+
* forbid public constructor because this is purely a static utility class
40+
*/
41+
private UVLVerifier() {
42+
throw new IllegalStateException("Utility class");
43+
}
44+
45+
/**
46+
* Checks two UVL models for equality. This should guarantee the same
47+
* configuration space. Both models need to have an identical feature-set.
48+
*
49+
* @param fm1 The first UVL model
50+
* @param fm2 The second UVL model to compare it with
51+
* @return true if models have same config space, false if not
52+
*/
53+
public static boolean equals(FeatureModel fm1, FeatureModel fm2) {
54+
FormulaFactory ff = new FormulaFactory();
55+
Formula formulaModel1 = getModelsAsFormula(ff, fm1);
56+
Formula formulaModel2 = getModelsAsFormula(ff, fm2);
57+
58+
// add root <=> True, to make sure root is not an unknown symbol in both
59+
// formulas
60+
61+
return formulaModel1.isEquivalentTo(formulaModel2);
62+
}
63+
64+
/**
65+
* Transforms a number of UVL constraints into a set of logicNG formula objects.
66+
*
67+
* @param ff the formulafactory used to create the formulas (needs to
68+
* be identical for all formulas that need to be compared
69+
* with the result of this method)
70+
* @param constraints the uvl constraint objects to be translated.
71+
* @return a set of formulas to be processed with logicNG
72+
*/
73+
public static Set<Formula> uvlConstraintstoFormulas(FormulaFactory ff, Collection<Constraint> constraints) {
74+
return constraints.stream()
75+
.map(c -> c.toString(false, Strings.EMPTY))
76+
.map(c -> c.replace(NOT.uvl(), NOT.ng()))
77+
.map(c -> UVLVerifier.parseUVL(ff, c))
78+
.filter(Objects::nonNull)
79+
.collect(Collectors.toSet());
80+
}
81+
82+
/**
83+
* Transforms the model into a logic formula to be processes with logicNG
84+
*
85+
* @param ff the formulafactory used to create the formulas (needs to be
86+
* identical for all formulas that need to be compared with the result
87+
* of this method)
88+
* @param fm the uvl model from which to get the constraints
89+
* @return a logic formula that represents the uvl model
90+
*/
91+
public static Formula getModelsAsFormula(FormulaFactory ff, FeatureModel fm) {
92+
Formula formula = ff.and(uvlConstraintstoFormulas(ff, fm.getConstraints()));
93+
return ff.and(formula, getFeaturesBasic(ff, fm));
94+
}
95+
96+
/**
97+
* parses a logicNG formula from an UVL-constraint represented by string s.
98+
* Requires a pre-processing step where all negation signs "!" from uvl have
99+
* been replaces by "~" needed by the parser.
100+
*
101+
* @param ff the formulafactory used to create the formulas (needs to be
102+
* identical for all formulas that need to be compared with the result
103+
* of this method)
104+
* @param s the pre-processes constraint-string
105+
* @return A formula object representing the constraints
106+
*/
107+
private static Formula parseUVL(FormulaFactory ff, String s) {
108+
final FormulaParser parser = new PropositionalParser(ff);
109+
try {
110+
return parser.parse(s);
111+
} catch (ParserException e) {
112+
return null;
113+
}
114+
}
115+
116+
/**
117+
* @deprecated Gets all features within the model and creates a formula like (A
118+
* | !A) and (B | !B) ... this is only used to get all literals
119+
* inside a big formula to check equality of to formal models. Since
120+
* the equality checker needs all literals to be present to generate
121+
* a valid result. This does not actually represent the logic of the
122+
* feature-tree and is to be replaced by a method that actually
123+
* processes that logic.
124+
* @param ff the formulafactory used to create the formulas (needs to be
125+
* identical for all formulas that need to be compared with the result
126+
* of this method)
127+
* @param fm the uvl model from which to get the individual features.
128+
* @return A formula representing all features included in the featuremodel
129+
*/
130+
public static Formula getFeaturesBasic(FormulaFactory ff, FeatureModel fm) {
131+
List<Formula> signs = fm.getFeatureMap()
132+
.values()
133+
.stream()
134+
.map(Feature::getFeatureName)
135+
.map(n -> ff.or(ff.literal(n, true), ff.literal(n, false)))
136+
.collect(Collectors.toList());
137+
return ff.and(signs);
138+
}
139+
140+
/**
141+
* Generates a logic formula that represents the feature-tree of a UVL model
142+
*
143+
* @param ff the formulafactory used to create the formulas (needs to be
144+
* identical for all formulas that need to be compared with the result
145+
* of this method)
146+
* @param fm the uvl model from which to generate the formula
147+
* @return
148+
*/
149+
private static Formula getFormulaFromUVLTree(FormulaFactory ff, FeatureModel fm) {
150+
Feature root = fm.getRootFeature();
151+
// TODO recursively build a formula that represents the feature tree
152+
// mabe some future work I guess
153+
return null;
154+
}
155+
156+
}

0 commit comments

Comments
 (0)