diff --git a/src/main/java/de/featjar/feature/model/transformer/ComputeFormula.java b/src/main/java/de/featjar/feature/model/transformer/ComputeFormula.java index dd1f9905..36227117 100644 --- a/src/main/java/de/featjar/feature/model/transformer/ComputeFormula.java +++ b/src/main/java/de/featjar/feature/model/transformer/ComputeFormula.java @@ -20,6 +20,7 @@ */ package de.featjar.feature.model.transformer; +import de.featjar.base.FeatJAR; import de.featjar.base.computation.AComputation; import de.featjar.base.computation.Computations; import de.featjar.base.computation.Dependency; @@ -43,6 +44,8 @@ import de.featjar.formula.structure.connective.Or; import de.featjar.formula.structure.connective.Reference; import de.featjar.formula.structure.predicate.Literal; +import de.featjar.formula.structure.predicate.NotEquals; +import de.featjar.formula.structure.term.value.Constant; import de.featjar.formula.structure.term.value.Variable; import java.util.*; @@ -73,6 +76,28 @@ public Result compute(List dependencyList, Progress progress) HashSet variables = new HashSet<>(); Map, Object>> attributes = new LinkedHashMap<>(); +/* IFormula featureLiteral; + if (feature.getType().equals(Boolean.class)) { + featureLiteral = Expressions.literal(featureName); + } else if (feature.getType().equals(Integer.class)) { + featureLiteral = new NotEquals(variable, new Constant(0)); + } else if(feature.getType().equals(Float.class)) { + featureLiteral = new NotEquals(variable, new Constant((float) 0.0)); + } else { + FeatJAR.log().warning("Could not handle type "+ feature.getType()); + return; + } + + // TODO take featureRanges into Account + Result potentialParentTree = node.getParent(); + + if (potentialParentTree.isEmpty()) { + handleRoot(constraints, featureLiteral, node); + } else { + handleParent(constraints, featureLiteral, node); + } + handleGroups(constraints, featureLiteral, node); +*/ if (SIMPLE_TRANSLATION.get(dependencyList)) { IFeatureTree iFeatureTree = featureModel.getRoots().get(0); @@ -98,6 +123,18 @@ public Result compute(List dependencyList, Progress progress) return Result.of(reference); } +/* + private void handleParent(ArrayList constraints, IFormula featureLiteral, IFeatureTree node) { + constraints.add(new Implies( + featureLiteral, + Expressions.literal( + node.getParent().get().getFeature().getName().orElse("")))); + } + + private void handleRoot(ArrayList constraints, IFormula featureLiteral, IFeatureTree node) { + if (node.isMandatory()) { + constraints.add(featureLiteral); +*/ private void traverseFeatureModel( IFeatureModel featureModel, ArrayList constraints, @@ -235,6 +272,7 @@ private boolean isCardinalityFeature(IFeatureTree node) { return false; } + // private void handleGroups(ArrayList constraints, IFormula featureLiteral, IFeatureTree node) { private void handleGroups(Literal featureLiteral, IFeatureTree node, ArrayList constraints) { List childrenGroups = node.getChildrenGroups(); int groupCount = childrenGroups.size(); diff --git a/src/test/java/de/featjar/feature/model/TranslateFormulaTest.java b/src/test/java/de/featjar/feature/model/TranslateFormulaTest.java new file mode 100644 index 00000000..63eeb12b --- /dev/null +++ b/src/test/java/de/featjar/feature/model/TranslateFormulaTest.java @@ -0,0 +1,113 @@ +package de.featjar.feature.model; + +import de.featjar.base.FeatJAR; +import de.featjar.base.computation.Computations; +import de.featjar.base.data.identifier.Identifiers; +import de.featjar.base.tree.Trees; +import de.featjar.feature.model.transformer.ComputeFormula; +import de.featjar.formula.structure.Expressions; +import de.featjar.formula.structure.IFormula; +import de.featjar.formula.structure.connective.And; +import de.featjar.formula.structure.connective.Reference; +import de.featjar.formula.structure.predicate.Literal; +import de.featjar.formula.structure.predicate.NotEquals; +import de.featjar.formula.structure.term.value.Constant; +import de.featjar.formula.structure.term.value.Variable; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +/** + * @author Lara Merza + * @author Felix Behme + * @author Jonas Hanke + */ + +public class TranslateFormulaTest { + + @BeforeAll + public static void insert() { + FeatJAR.testConfiguration().initialize(); + } + + @Test + public void testInteger() { + IFeatureModel featureModel = new FeatureModel(Identifiers.newCounterIdentifier()); + addValues(featureModel, Integer.class); + + IFormula result = Computations.of(featureModel) + .map(ComputeFormula::new) + .compute(); + IFormula formula = buildFormula(Integer.class, 0); + Assertions.assertTrue(Trees.equals(result, formula), result.print() + "\n" + formula.print()); + FeatJAR.log().info("Integer Test expected value: " + formula.print()); + FeatJAR.log().info("Integer Test result output: " + result.print()); + } + + @Test + public void testBoolean() { + IFeatureModel featureModel = new FeatureModel(Identifiers.newCounterIdentifier()); + addValues(featureModel, Boolean.class); + + IFormula result = Computations.of(featureModel) + .map(ComputeFormula::new) + .compute(); + IFormula formula = buildBooleanForumla(); + Assertions.assertTrue(Trees.equals(result, formula), result.print() + "\n" + formula.print()); + FeatJAR.log().info("Boolean Test expected value: " + formula.print()); + FeatJAR.log().info("Boolean Test result output: " + result.print()); + } + + @Test + public void testFloat() { + IFeatureModel featureModel = new FeatureModel(Identifiers.newCounterIdentifier()); + addValues(featureModel, Float.class); + + IFormula result = Computations.of(featureModel) + .map(ComputeFormula::new) + .compute(); + IFormula formula = buildFormula(Float.class, (float) 0.0); + Assertions.assertTrue(Trees.equals(result, formula), result.print() + "\n" + formula.print()); + FeatJAR.log().info("Float Test expected value: " + formula.print()); + FeatJAR.log().info("Float Test result output: " + result.print()); + } + + private void addValues(IFeatureModel featureModel, Class type) { + IFeature root = featureModel.mutate().addFeature("root"); + IFeatureTree rootTree = featureModel.mutate().addFeatureTreeRoot(root); + rootTree.getRoot().mutate().toAndGroup(); + for (short i = 0; i < 5; i++) { + IFeature feature = featureModel.mutate().addFeature(i + "feature"); + feature.mutate().setName("feature" + i); + feature.mutate().setType(type); + rootTree.mutate().addFeatureBelow(feature); + + FeatJAR.log().info("Added Feature " + feature.getName().get() + " with type " + feature.getType()); + } + } + + private IFormula buildFormula(Class type, Object expectedValue) { + return new Reference(new And( + Expressions.implies(new NotEquals(new Variable("feature0", type), + new Constant(expectedValue, type)), new Literal("root")), + Expressions.implies(new NotEquals(new Variable("feature1", type), + new Constant(expectedValue, type)), new Literal("root")), + Expressions.implies(new NotEquals(new Variable("feature2", type), + new Constant(expectedValue, type)), new Literal("root")), + Expressions.implies(new NotEquals(new Variable("feature3", type), + new Constant(expectedValue, type)), new Literal("root")), + Expressions.implies(new NotEquals(new Variable("feature4", type), + new Constant(expectedValue, type)), new Literal("root")) + )); + } + + private IFormula buildBooleanForumla() { + return new Reference(new And( + Expressions.implies(Expressions.literal("feature0"), Expressions.literal("root")), + Expressions.implies(Expressions.literal("feature1"), Expressions.literal("root")), + Expressions.implies(Expressions.literal("feature2"), Expressions.literal("root")), + Expressions.implies(Expressions.literal("feature3"), Expressions.literal("root")), + Expressions.implies(Expressions.literal("feature4"), Expressions.literal("root")) + )); + } +} \ No newline at end of file