cdc.applic.mountability.core.Computer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cdc-applic-mountability-core Show documentation
Show all versions of cdc-applic-mountability-core Show documentation
Applicabilities Mountability Core.
The newest version!
package cdc.applic.mountability.core;
import java.io.PrintStream;
import java.util.List;
import java.util.function.UnaryOperator;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.io.IoBuilder;
import cdc.applic.expressions.Expression;
import cdc.applic.mountability.Interchangeability;
import cdc.applic.mountability.handlers.MountabilityHandler;
import cdc.util.events.ProgressSupplier;
/**
* Internal class used to compute mountability at a single Use Point.
*
* @param The use point type.
* @param The variant type.
*/
public class Computer {
private static final Logger LOGGER = LogManager.getLogger(Computer.class);
private static final PrintStream OUT = IoBuilder.forLogger(LOGGER).setLevel(Level.DEBUG).buildPrintStream();
/** The Use point. */
private final U usePoint;
/** The variants wrappers. */
private final List> buckets;
public Computer(U usePoint,
List> buckets) {
LOGGER.debug("init<>({}, ...)", usePoint);
this.usePoint = usePoint;
this.buckets = buckets;
if (LOGGER.isDebugEnabled()) {
print(OUT);
}
}
public void process(MountabilityHandler handler,
UnaryOperator simplify,
ProgressSupplier progress) {
LOGGER.debug("process(...)");
// The number of variants
final int size = buckets.size();
// Iterate on each possible pair of variants
// Iterate on first variant
for (int index1 = 0; index1 < size; index1++) {
LOGGER.debug(" index1: {}", index1);
// Iterate on second variant
for (int index2 = 0; index2 < size; index2++) {
final boolean replaceable = isReplaceable(index2, index1);
LOGGER.debug(" index2: {} replaceable by: {}: {}", index2, index1, replaceable);
if (replaceable) {
buckets.get(index1).p.add(buckets.get(index2).applicability);
} else {
if (index2 > index1) {
buckets.get(index1).n.add(buckets.get(index2).applicability);
}
}
}
progress.incrementValue();
}
for (final Bucket bucket : buckets) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("{} {}", usePoint, bucket.variant);
LOGGER.debug(" {}", bucket.getMountability());
LOGGER.debug(" {}", simplify.apply(bucket.getMountability()));
}
handler.processVariantMountability(usePoint,
bucket.variant,
simplify.apply(bucket.getMountability()));
}
}
/**
* Computes replaceability based on interchangeability.
*
* @param at The index of the reference variant that could be replaced.
* @param by The index of variant that could replace the reference variant.
* @return {@code true} if the reference variant {@code at} can be replaced by the variant {@code by}.
*/
private boolean isReplaceable(int at,
int by) {
if (at < by) {
// The candidate replacer is after the reference variant
// No intermediate interchangeability can be NOT_INTERCHANGEABLE
for (int index = at + 1; index <= by; index++) {
if (buckets.get(index).interchangeability == Interchangeability.NOT_INTERCHANGEABLE) {
return false;
}
}
return true;
} else if (at == by) {
// A variant can be replaced by itself
return true;
} else {
// The candidate replacer is before the reference variant
// All intermediate interchangeability must be TWO_WAYS
for (int index = at; index > by; index--) {
if (buckets.get(index).interchangeability != Interchangeability.TWO_WAYS) {
return false;
}
}
return true;
}
}
public void print(PrintStream out) {
out.println("Use Point: " + usePoint);
for (final Bucket bucket : buckets) {
out.println(" Variant: " + bucket.variant + " " + bucket.interchangeability + " " + bucket.applicability);
}
}
}