package de.ovgu.cide.typing.guidsl; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import org.sat4j.specs.TimeoutException; import de.ovgu.cide.features.IFeature; import de.ovgu.cide.features.IFeatureModel; import de.ovgu.cide.fm.guidsl.FeatureAdapter; import de.ovgu.cide.fm.guidsl.FeatureModelProxy; import de.ovgu.cide.typing.model.AbstractCachingEvaluationStrategy; import de.ovgu.cide.typing.model.DebugTyping; import featureide.fm.core.Feature; import featureide.fm.core.FeatureModel; /** * evaluation strategy for the typechecker that delegates checks to the guidsl * implementation which then used a SAT solver to check implications on the * background of the feature model * * this strategy must cache results because queries to the SAT solver are * expensive * * @author ckaestne * */ public class SatEvaluationStrategy extends AbstractCachingEvaluationStrategy { @Override public boolean implies(IFeatureModel featureModel, Set<IFeature> source, Set<IFeature> target) { DebugTyping.debug_requests++; // if (source.containall(target)) // return true; if (source.isEmpty() && target.isEmpty()) { DebugTyping.debug_emptycounter++; return true; } if (source.equals(target)) { DebugTyping.debug_equalcounter++; return true; } return super.implies(featureModel, source, target); } @Override protected boolean calcImplies(IFeatureModel featureModel, Set<IFeature> source, Set<IFeature> target) { DebugTyping.debug_cache_miss++; // ignore empty feature models assert featureModel instanceof FeatureModelProxy; DebugTyping.debug_satcounter++; if (source.containsAll(target)) { DebugTyping.debug_subsetcounter++; return true; } long start = System.currentTimeMillis();// debug only FeatureModel guidslModel = ((FeatureModelProxy) featureModel) .getInternalModel(); if (guidslModel == null) return true; Set<Feature> guidslSourceFeatures = convertToGuidslFeatures(source); Set<Feature> guidslTargetFeatures = convertToGuidslFeatures(target); try { boolean result = guidslModel.checkImplies(guidslSourceFeatures, guidslTargetFeatures); long end = System.currentTimeMillis();// debug only DebugTyping.satTime(end - start, source, target); return result; } catch (TimeoutException e) { e.printStackTrace(); // in case of a timeout assume everything is fine and the // implication is true. idea is not to report false positive return true; } } public boolean areMutualExclusive(IFeatureModel featureModel, Set<IFeature> context, List<Set<IFeature>> featureSets) { // ignore empty feature models assert featureModel instanceof FeatureModelProxy; FeatureModel guidslModel = ((FeatureModelProxy) featureModel) .getInternalModel(); if (guidslModel == null) return true; List<Set<Feature>> guidslFeatureSets = new LinkedList<Set<Feature>>(); for (Set<IFeature> features : featureSets) { guidslFeatureSets.add(convertToGuidslFeatures(features)); } try { return guidslModel.areMutualExclusive( convertToGuidslFeatures(context), guidslFeatureSets); } catch (TimeoutException e) { e.printStackTrace(); // in case of a timeout assume everything is fine and the // formula is true. idea is not to report false positive return true; } } public boolean mayBeMissing(IFeatureModel featureModel, Set<IFeature> context, List<Set<IFeature>> featureSets) { // ignore empty feature models assert featureModel instanceof FeatureModelProxy; FeatureModel guidslModel = ((FeatureModelProxy) featureModel) .getInternalModel(); if (guidslModel == null) return true; List<Set<Feature>> guidslFeatureSets = new LinkedList<Set<Feature>>(); for (Set<IFeature> features : featureSets) { guidslFeatureSets.add(convertToGuidslFeatures(features)); } try { return guidslModel.mayBeMissing(convertToGuidslFeatures(context), guidslFeatureSets); } catch (TimeoutException e) { e.printStackTrace(); // in case of a timeout assume everything is fine and the // result is false. idea is not to report false positive return false; } } @Override protected boolean calcExists(IFeatureModel featureModel, Set<IFeature> features) { // ignore empty feature models assert featureModel instanceof FeatureModelProxy; FeatureModel guidslModel = ((FeatureModelProxy) featureModel) .getInternalModel(); if (guidslModel == null) return true; try { return guidslModel.exists(convertToGuidslFeatures(features)); } catch (TimeoutException e) { e.printStackTrace(); // in case of a timeout assume everything is fine and the // formula is true. idea is not to report false positive return true; } } private Set<Feature> convertToGuidslFeatures(Set<IFeature> features) { if (features == null) return null; Set<Feature> guidslFeatures = new HashSet<Feature>(features.size()); for (IFeature f : features) { assert f instanceof FeatureAdapter; guidslFeatures.add(((FeatureAdapter) f).getInternalFeature()); } return guidslFeatures; } }