
de.rwth.swc.coffee4j.model.converter.SimpleCartesianProductConstraintConverter Maven / Gradle / Ivy
package de.rwth.swc.coffee4j.model.converter;
import de.rwth.swc.coffee4j.engine.TupleList;
import de.rwth.swc.coffee4j.engine.util.Combinator;
import de.rwth.swc.coffee4j.engine.util.Preconditions;
import de.rwth.swc.coffee4j.model.Parameter;
import de.rwth.swc.coffee4j.model.constraints.Constraint;
import de.rwth.swc.coffee4j.model.constraints.ConstraintFunction;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* Converts {@link Constraint} objects to their {@link TupleList} representation by executing their
* {@link ConstraintFunction} with every possible value combination of its
* parameters. This means the cartesian product of its parameters values is used.
* For example, if a constraint uses parameters "param1" with value "1" and "2" and "param2" with value "5" and "6",
* then the constraint it tested with all these combinations: {"1", "5"}, {"1", "6"}, {"2", "5"} ,{"2", "6"}.
* For all combinations for which the {@link ConstraintFunction}
* returns {@code false}, a corresponding tuple is added to the {@link TupleList} representation.
* Naturally, this is a very expensive conversion process, especially if there are many large parameters involved.
*/
public class SimpleCartesianProductConstraintConverter implements IndexBasedConstraintConverter {
@Override
public List convert(List constraints, List parameters) {
Preconditions.notNull(constraints);
Preconditions.notNull(parameters);
final Int2ObjectMap idToParameterMap = constructIdToParameterMap(parameters);
final Object2IntMap parameterNameIdMap = constructParameterNameMap(parameters);
assertContainsOnlyValidParameters(constraints, parameterNameIdMap.keySet());
final List convertedConstraints = new ArrayList<>();
for (int i = 0; i < constraints.size(); i++) {
convertedConstraints.add(convertedConstraint(constraints.get(i), parameterNameIdMap, idToParameterMap, i + 1));
}
return convertedConstraints;
}
private Int2ObjectMap constructIdToParameterMap(List parameters) {
final Int2ObjectMap idToParameterMap = new Int2ObjectOpenHashMap<>();
for (int i = 0; i < parameters.size(); i++) {
idToParameterMap.put(i, parameters.get(i));
}
return idToParameterMap;
}
private Object2IntMap constructParameterNameMap(List parameters) {
final Object2IntMap parameterNameMap = new Object2IntOpenHashMap<>();
for (int i = 0; i < parameters.size(); i++) {
parameterNameMap.put(parameters.get(i).getName(), i);
}
return parameterNameMap;
}
private void assertContainsOnlyValidParameters(List constraints, Collection parameterNames) {
for (Constraint constraint : constraints) {
Preconditions.check(parameterNames.containsAll(constraint.getParameterNames()));
}
}
private TupleList convertedConstraint(Constraint constraint, Object2IntMap parameterIdMap, Int2ObjectMap idToParameterMap, int id) {
int[] relevantParameters = constraint.getParameterNames().stream().mapToInt(parameterIdMap::getInt).toArray();
final Int2IntMap relevantParameterSizes = computeSizeMap(idToParameterMap, relevantParameters);
final Collection cartesianProduct = Combinator.computeCartesianProduct(relevantParameterSizes, relevantParameters.length);
final List tuples = new ArrayList<>();
for (int[] combination : cartesianProduct) {
final List> arguments = mapToArguments(combination, relevantParameters, idToParameterMap);
if (!constraint.getConstraintFunction().check(arguments)) {
int[] tuple = new int[combination.length];
System.arraycopy(combination, 0, tuple, 0, combination.length);
tuples.add(tuple);
}
}
return new TupleList(id, relevantParameters, tuples);
}
private Int2IntMap computeSizeMap(Int2ObjectMap idToParameterMap, int[] relevantKeys) {
final Int2IntMap subMap = new Int2IntOpenHashMap();
for (int i = 0; i < relevantKeys.length; i++) {
final Parameter relevantParameter = idToParameterMap.get(relevantKeys[i]);
subMap.put(i, relevantParameter.size());
}
return subMap;
}
private List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy