use of de.monticore.featurediagram._visitor.FeatureDiagramTraverser in project feature-diagram by MontiCore.
the class OptionalFeatureCollector method getOptionalFeatures.
public static List<String> getOptionalFeatures(ASTFeatureDiagram fd) {
FeatureDiagramTraverser traverser = FeatureDiagramMill.traverser();
OptionalFeatureCollector visitor = new OptionalFeatureCollector();
traverser.add4FeatureDiagram(visitor);
fd.accept(traverser);
return visitor.getOptionalFeatures();
}
use of de.monticore.featurediagram._visitor.FeatureDiagramTraverser in project feature-diagram by MontiCore.
the class FDTrafo method apply.
public void apply(ASTFeatureDiagram fd, FlatZincModel result) {
this.flatZincModel = result;
FeatureDiagramTraverser traverser = FeatureDiagramMill.traverser();
traverser.add4FeatureDiagram(this);
fd.accept(traverser);
// add contraint for selecting the root feature
Constraint rootFeature = new Constraint("bool_eq", "true", fd.getRootFeature());
flatZincModel.add(rootFeature);
// add cross tree constraints
CrossTreeConstraintTrafo.apply(fd, result);
}
use of de.monticore.featurediagram._visitor.FeatureDiagramTraverser in project feature-diagram by MontiCore.
the class FeatureDiagramPrettyPrinter method print.
public static String print(ASTFeatureDiagramNode node) {
IndentPrinter printer = new IndentPrinter();
FeatureDiagramTraverser t = FeatureDiagramMill.traverser();
t.add4MCBasics(new MCBasicsPrettyPrinter(printer));
CardinalityPrettyPrinter cardinality = new CardinalityPrettyPrinter(printer);
t.setCardinalityHandler(cardinality);
t.add4Cardinality(cardinality);
CommonExpressionsPrettyPrinter commonExpressions = new CommonExpressionsPrettyPrinter(printer);
t.setCommonExpressionsHandler(commonExpressions);
t.add4CommonExpressions(commonExpressions);
ExpressionsBasisPrettyPrinter expressionsBasis = new ExpressionsBasisPrettyPrinter(printer);
t.setExpressionsBasisHandler(expressionsBasis);
t.add4ExpressionsBasis(expressionsBasis);
MCBasicTypesPrettyPrinter mCBasicTypes = new MCBasicTypesPrettyPrinter(printer);
t.setMCBasicTypesHandler(mCBasicTypes);
t.add4MCBasicTypes(mCBasicTypes);
MCCommonLiteralsPrettyPrinter mCCommonLiterals = new MCCommonLiteralsPrettyPrinter(printer);
t.setMCCommonLiteralsHandler(mCCommonLiterals);
t.add4MCCommonLiterals(mCCommonLiterals);
t.add4FeatureDiagram(new FeatureDiagramPrinter(printer));
t.setFeatureDiagramHandler(new FeatureDiagramPrettyPrinter());
node.accept(t);
return printer.getContent();
}
use of de.monticore.featurediagram._visitor.FeatureDiagramTraverser in project feature-diagram by MontiCore.
the class ValidConstraintExpression method check.
@Override
public void check(ASTFeatureConstraint node) {
ASTExpression expression = node.getConstraint();
Checker checker = new Checker(expression);
FeatureDiagramTraverser traverser = FeatureDiagramMill.traverser();
traverser.add4CommonExpressions(checker);
expression.accept(traverser);
}
use of de.monticore.featurediagram._visitor.FeatureDiagramTraverser in project feature-diagram by MontiCore.
the class FDSemDiff method semDiff.
/**
* Calculates the semantic difference witness between two feature diagrams.
*
* Either uses open-world or close-world semantics of FDs as presented here:
* https://se-rwth.de/publications/Semantic-Evolution-Analysis-of-Feature-Models.pdf
*
* @param fd1 The first feature diagram
* @param fd2 The second feature diagram
* @param closedWorld if true, then closed-world semantics is used, otherwise open-world semantics is used
* @return The (optional) semantic diff witness
*/
private Optional<ASTFeatureConfiguration> semDiff(ASTFeatureDiagram fd1, ASTFeatureDiagram fd2, boolean closedWorld) {
final FormulaFactory ff = new FormulaFactory();
final Set<String> features = Sets.union(Sets.newHashSet(fd1.getAllFeatures()), Sets.newHashSet(fd2.getAllFeatures()));
final Map<Variable, String> vars = features.stream().collect(Collectors.toMap(ff::variable, Function.identity()));
FeatureDiagramTraverser traverser = FeatureDiagramMill.traverser();
FD2Formula trafo = new FD2Formula(ff);
traverser.add4FeatureDiagram(trafo);
// traverser.setFeatureDiagramHandler(trafo);
// trafo.setTraverser(traverser);
fd1.accept(traverser);
Formula phi_1 = trafo.getFormula();
fd2.accept(traverser);
Formula phi_2 = trafo.getFormula();
if (closedWorld) {
// features of FD1 that are not features of FD2 must not be selected in FD2
Set<String> featuresInFD1NotInFD2 = new HashSet<>(fd1.getAllFeatures());
featuresInFD1NotInFD2.removeAll(fd2.getAllFeatures());
for (String feature : featuresInFD1NotInFD2) {
// This feature must not be chosen for FD2
Formula notFeature = ff.literal(feature, false);
phi_2 = ff.and(phi_2, notFeature);
}
// features of FD2 that are not features of FD1 must not be selected in FD1
Set<String> featuresInFD2NotInFD1 = new HashSet<>(fd2.getAllFeatures());
featuresInFD2NotInFD1.removeAll(fd1.getAllFeatures());
for (String feature : featuresInFD2NotInFD1) {
// This feature must not be chosen for fd1
Formula notFeature = ff.literal(feature, false);
phi_1 = ff.and(phi_1, notFeature);
}
}
Formula phi = ff.and(phi_1, ff.not(phi_2));
final SATSolver miniSat = MiniSat.miniSat(ff);
miniSat.add(phi);
miniSat.sat();
final Assignment assignment = miniSat.model();
Optional<ASTFeatureConfiguration> result = Optional.empty();
if (assignment != null) {
Set<String> selectedFeatures = assignment.positiveLiterals().stream().map(vars::get).filter(Objects::nonNull).collect(Collectors.toSet());
return Optional.of(calculateConfiguration(selectedFeatures, new HashSet<>(fd1.getAllFeatures()), fd1.getName()));
}
return result;
}
Aggregations