Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -733,10 +733,14 @@ public static DiffNode<DiffLinesLabel> fromID(int id, String label) {
* Checks that the VariationDiff is in a valid state.
* In particular, this method checks that all edges are well-formed (e.g., edges can be inconsistent because edges are double-linked).
* This method also checks that a node with exactly one parent was edited, and that a node with exactly two parents was not edited.
* To check all children recursively, use {@link VariationDiff#assertConsistency}.
* @see Assert#assertTrue
* @throws AssertionError when an inconsistency is detected.
*/
public void assertConsistency() {
// check that the projections are valid (i.e., node type specific consistency checks)
diffType.forAllTimesOfExistence(time -> this.projection(time).assertConsistency());

// check consistency of children lists and edges
for (final DiffNode<L> c : getAllChildren()) {
Assert.assertTrue(isChild(c), () -> "Child " + c + " of " + this + " is neither a before nor an after child!");
Expand All @@ -760,6 +764,10 @@ public void assertConsistency() {
if (pb != null && pa == null) {
Assert.assertTrue(isRem());
}
// the root was not edited
if (pb == null && pa == null) {
Assert.assertTrue(isNon());
}
// a node with exactly two parents was not edited
if (pb != null && pa != null) {
Assert.assertTrue(isNon());
Expand All @@ -770,22 +778,6 @@ public void assertConsistency() {
Assert.assertTrue(pb.isNon());
}
}

// Else and Elif nodes have an If or Elif as parent.
if (this.isElse() || this.isElif()) {
Time.forAll(time -> {
if (getParent(time) != null) {
Assert.assertTrue(getParent(time).isIf() || getParent(time).isElif(), time + " parent " + getParent(time) + " of " + this + " is neither IF nor ELIF!");
}
});
}

// Only if and elif nodes have a formula
if (this.isIf() || this.isElif()) {
Assert.assertTrue(this.getFormula() != null, "If or elif without feature mapping!");
} else {
Assert.assertTrue(this.getFormula() == null, "Node with type " + getNodeType() + " has a non null feature mapping");
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,9 @@ public Node getFormula() {
public int getID() {
return getBackingNode().getID();
}

@Override
public String toString() {
return String.format("Projection(%s, %s)", time, getBackingNode());
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -487,26 +487,28 @@ public VariationTreeNode<L> toVariationTree(final Map<? super T, VariationTreeNo
}

/**
* Checks that this node satisfies some easy to check invariants.
* In particular, this method checks that
* <ul>
* <li>if-chains are nested correctly,
* <li>the root is an {@link NodeType#IF} with the feature mapping {@code "true"},
* <li>the feature mapping is {@code null} iff {@code isConditionalAnnotation} is {@code false}
* and
* <li>all edges are well-formed (e.g., edges can be inconsistent because edges are
* double-linked).
* </ul>
*
* <p>Some invariants are not checked. These include
* <ul>
* <li>There should be no cycles and
* <li>{@link getID} should be unique in the whole variation tree.
* </ul>
*
* @see Assert#assertTrue
* @throws AssertionError when an inconsistency is detected.
*/
* Checks that this node satisfies some easy to check invariants.
* In particular, this method checks that
* <ul>
* <li>if-chains are nested correctly,
* <li>the root is an {@link NodeType#IF} with the feature mapping {@code "true"},
* <li>the feature mapping is {@code null} iff {@code isConditionalAnnotation} is {@code false}
* and
* <li>all edges are well-formed (e.g., edges can be inconsistent because edges are
* double-linked).
* </ul>
*
* <p>Some invariants are not checked. These include
* <ul>
* <li>There should be no cycles,
* <li>{@link getID} should be unique in the whole variation tree, and
* <li>children are not checked recursively.
* </ul>
* Use {@link VariationTree#assertConsistency} to check all children recursively.
*
* @see Assert#assertTrue
* @throws AssertionError when an inconsistency is detected.
*/
public void assertConsistency() {
// ELSE and ELIF nodes have an IF or ELIF as parent.
if (isElse() || isElif()) {
Expand Down Expand Up @@ -537,6 +539,12 @@ public void assertConsistency() {
"The root has to have the feature mapping 'true'");
}

// check that there is at most one ELIF/ELSE
Assert.assertTrue(
getChildren().stream().filter(c -> c.isElif() || c.isElse()).count() <= 1,
"There is more than one ELIF/ELSE node."
);

// check consistency of children lists and edges
for (var child : getChildren()) {
Assert.assertTrue(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.variantsync.diffdetective.util.Assert;
import org.variantsync.diffdetective.variation.DiffLinesLabel;
import org.variantsync.diffdetective.variation.Label;
import org.variantsync.diffdetective.variation.NodeType; // For Javadoc
import org.variantsync.diffdetective.variation.diff.DiffNode;
import org.variantsync.diffdetective.variation.diff.VariationDiff;
import org.variantsync.diffdetective.variation.diff.Projection;
Expand Down Expand Up @@ -213,6 +214,17 @@ public String unparse() {
return result.toString();
}

/**
* Checks whether this {@link VariationTree} is consistent.
* Throws an error if this {@link VariationTree} is inconsistent (e.g., if there are multiple
* {@link NodeType#ELSE} nodes). Has no side-effects otherwise.
*
* @see VariationNode#assertConsistency
*/
public void assertConsistency() {
forAllPreorder(VariationTreeNode::assertConsistency);
}

@Override
public String toString() {
return "variation tree from " + source;
Expand Down