Skip to content

Commit f36357f

Browse files
committed
bugfix: exporting true and false as 1 and 0 when converting formulas to strings
1 parent 147b924 commit f36357f

3 files changed

Lines changed: 52 additions & 8 deletions

File tree

src/main/java/org/variantsync/vevos/simulation/util/fide/FormulaUtils.java

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import java.util.ArrayList;
77
import java.util.Arrays;
88
import java.util.List;
9+
import java.util.function.Function;
10+
import java.util.function.Predicate;
911

1012
public class FormulaUtils {
1113
public static Node negate(final Node node) {
@@ -60,7 +62,41 @@ public static void flatten(final And and) {
6062
} while (!redundantChildren.isEmpty());
6163
}
6264

63-
public static String toString(final Node formula, final String[] symbols) {
65+
/**
66+
* Replaces all nodes within the given formula's tree that match the given predicate.
67+
* Matching nodes (i.e., nodes for which the predicate who returns true) will be replaced by the value returned
68+
* by the replacement function, invoked on the matching node.
69+
* @param root The root of the formula in which occurences of formulas should be replaced. The object remains unaltered.
70+
* @param who A replacement is made whenever this predicate evaluates to true on a given node.
71+
* @param replacement Whenever a node should be replaced, this function is invoked with that node as argument.
72+
* The node will be replaced with the node returned.
73+
* @return A new formula in which all nodes matching the given predicate are replaced.
74+
*/
75+
public static Node replaceAll(final Node root, final Predicate<Node> who, final Function<Node, Node> replacement) {
76+
return replaceAllInplace(root.clone(), who, replacement);
77+
}
78+
79+
/**
80+
* Inplace variant of the {@link #replaceAll(Node, Predicate, Function)} function.
81+
* This means the given formula (root parameter) will be altered.
82+
*/
83+
public static Node replaceAllInplace(final Node root, final Predicate<Node> who, final Function<Node, Node> replacement) {
84+
if (who.test(root)) {
85+
return replacement.apply(root);
86+
} else {
87+
final Node[] children = root.getChildren();
88+
for (int i = 0; i < children.length; ++i) {
89+
children[i] = replaceAllInplace(children[i], who, replacement);
90+
}
91+
root.setChildren(children);
92+
return root;
93+
}
94+
}
95+
96+
public static String toString(Node formula, final String[] symbols) {
97+
formula = replaceAll(formula, FixTrueFalse::isTrue, n -> FixTrueFalse.TrueAs1);
98+
formula = replaceAllInplace(formula, FixTrueFalse::isFalse, n -> FixTrueFalse.FalseAs0);
99+
64100
final NodeWriter writer = new NodeWriter(formula);
65101
writer.setNotation(NodeWriter.Notation.INFIX);
66102
writer.setEnquoteWhitespace(false);

src/main/java/org/variantsync/vevos/simulation/util/fide/bugfix/FixTrueFalse.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,23 @@
1717
* as well as a conversion method for parsing certain feature names to true and false, respectively.
1818
*/
1919
public class FixTrueFalse {
20-
/// Names of variables that we want to interpret as atomic values true or false, respectively.
21-
public final static List<String> TrueNames = Arrays.asList("true", "1");
22-
public final static List<String> FalseNames = Arrays.asList("false", "0");
23-
2420
/*
2521
Constant literals representing the true and false value
2622
*/
2723
public final static Literal True = new org.prop4j.True();
2824
public final static Literal False = new org.prop4j.False();
2925

26+
/*
27+
Constant literals representing the true and false values only for serialization.
28+
True and False are represented by the numeric values 0 and 1.
29+
*/
30+
public final static Literal TrueAs1 = new Literal("1");
31+
public final static Literal FalseAs0 = new Literal("0");
32+
33+
/// Names of variables that we want to interpret as atomic values true or false, respectively.
34+
public final static List<String> TrueNames = Arrays.asList("true", (String) TrueAs1.var);
35+
public final static List<String> FalseNames = Arrays.asList("false", (String) FalseAs0.var);
36+
3037
/**
3138
* @return True iff the given formula is a true literal.
3239
* @see FixTrueFalse::isTrueLiteral
@@ -47,14 +54,14 @@ public static boolean isFalse(final Node n) {
4754
* @return True iff the given name represents the atomic value true w.r.t. the constant TrueNames.
4855
*/
4956
public static boolean isTrueLiteral(final Literal l) {
50-
return TrueNames.stream().anyMatch(t -> t.equals(l.var.toString().toLowerCase()));
57+
return TrueNames.stream().anyMatch(t -> t.equalsIgnoreCase(l.var.toString()));
5158
}
5259

5360
/**
5461
* @return True iff the given name represents the atomic value false w.r.t. the constant FalseNames.
5562
*/
5663
public static boolean isFalseLiteral(final Literal l) {
57-
return FalseNames.stream().anyMatch(f -> f.equals(l.var.toString().toLowerCase()));
64+
return FalseNames.stream().anyMatch(f -> f.equalsIgnoreCase(l.var.toString()));
5865
}
5966

6067
private static Node[] filterMatches(final Node[] nodes, Predicate<Node> filter) {

src/main/java/org/variantsync/vevos/simulation/variability/pc/variantlines/VariantAnnotation.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import org.prop4j.Node;
44
import org.prop4j.NodeWriter;
5+
import org.variantsync.vevos.simulation.util.fide.FormulaUtils;
56
import org.variantsync.vevos.simulation.variability.pc.options.VariantGenerationOptions;
67

78
import java.util.ArrayList;
@@ -16,7 +17,7 @@ public List<String> project(final VariantGenerationOptions projectionOptions, fi
1617
final List<String> result = new ArrayList<>();
1718

1819
if (projectionOptions.withMacros()) {
19-
result.add("#if " + condition.toString(NodeWriter.javaSymbols));
20+
result.add("#if " + FormulaUtils.toString(condition, NodeWriter.javaSymbols));
2021
}
2122

2223
for (final VariantLineChunk child : lines) {

0 commit comments

Comments
 (0)