Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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 @@ -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.Dependency;
import de.featjar.base.computation.IComputation;
Expand All @@ -41,6 +42,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.ArrayList;
import java.util.HashSet;
Expand Down Expand Up @@ -74,9 +77,21 @@ public Result<IFormula> compute(List<Object> dependencyList, Progress progress)
Variable variable = new Variable(featureName, feature.getType());
variables.add(variable);

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<IFeatureTree> potentialParentTree = node.getParent();
Literal featureLiteral = Expressions.literal(featureName);

if (potentialParentTree.isEmpty()) {
handleRoot(constraints, featureLiteral, node);
} else {
Expand All @@ -89,20 +104,20 @@ public Result<IFormula> compute(List<Object> dependencyList, Progress progress)
return Result.of(reference);
}

private void handleParent(ArrayList<IFormula> constraints, Literal featureLiteral, IFeatureTree node) {
private void handleParent(ArrayList<IFormula> constraints, IFormula featureLiteral, IFeatureTree node) {
constraints.add(new Implies(
featureLiteral,
Expressions.literal(
node.getParent().get().getFeature().getName().orElse(""))));
}

private void handleRoot(ArrayList<IFormula> constraints, Literal featureLiteral, IFeatureTree node) {
private void handleRoot(ArrayList<IFormula> constraints, IFormula featureLiteral, IFeatureTree node) {
if (node.isMandatory()) {
constraints.add(featureLiteral);
}
}

private void handleGroups(ArrayList<IFormula> constraints, Literal featureLiteral, IFeatureTree node) {
private void handleGroups(ArrayList<IFormula> constraints, IFormula featureLiteral, IFeatureTree node) {
List<Group> childrenGroups = node.getChildrenGroups();
int groupCount = childrenGroups.size();
ArrayList<List<IFormula>> groupLiterals = new ArrayList<>(groupCount);
Expand Down
113 changes: 113 additions & 0 deletions src/test/java/de/featjar/feature/model/TranslateFormulaTest.java
Original file line number Diff line number Diff line change
@@ -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"))
));
}
}