cdc.applic.mountability.core.ComputeMountability 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.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import cdc.applic.dictionaries.AssertionStrategy;
import cdc.applic.dictionaries.Dictionary;
import cdc.applic.dictionaries.NamingConvention;
import cdc.applic.dictionaries.ReserveStrategy;
import cdc.applic.dictionaries.handles.DictionaryHandle;
import cdc.applic.dictionaries.impl.RepositoryImpl;
import cdc.applic.dictionaries.impl.io.RepositoryIo;
import cdc.applic.expressions.Expression;
import cdc.applic.expressions.Formatting;
import cdc.applic.expressions.Spacing;
import cdc.applic.expressions.SymbolType;
import cdc.applic.expressions.checks.ApplicIssue;
import cdc.applic.mountability.MountabilityComputer;
import cdc.applic.mountability.MountabilityComputerFeatures;
import cdc.applic.mountability.MountabilityDataChecker;
import cdc.applic.mountability.handlers.MountabilityHandler;
import cdc.applic.mountability.impl.Data;
import cdc.applic.mountability.impl.UsePoint;
import cdc.applic.mountability.impl.Variant;
import cdc.applic.mountability.impl.io.DataXml;
import cdc.applic.proofs.ProverFeatures;
import cdc.applic.publication.ExpressionFormatter;
import cdc.applic.publication.core.formatters.FormattersCatalog;
import cdc.applic.publication.core.formatters.InfixFormatter;
import cdc.applic.publication.core.formatters.io.FormattersCatalogXml;
import cdc.applic.simplification.SimplifierFeatures;
import cdc.applic.simplification.SimplifierFeatures.Hint;
import cdc.io.xml.XmlWriter;
import cdc.issues.IssuesCollector;
import cdc.issues.io.IssuesIoFactoryFeatures;
import cdc.issues.io.IssuesWriter;
import cdc.issues.io.OutSettings;
import cdc.util.cli.AbstractMainSupport;
import cdc.util.cli.FeatureMask;
import cdc.util.cli.MainResult;
import cdc.util.cli.OptionEnum;
import cdc.util.events.ProgressController;
import cdc.util.events.ProgressEvent;
import cdc.util.lang.FailureReaction;
import cdc.util.time.Chronometer;
/**
* Main program used to load mountability data and compute mountability.
*/
public final class ComputeMountability {
private static final Logger LOGGER = LogManager.getLogger(ComputeMountability.class);
private final MainArgs margs;
private final ProgressController controller = new ProgressController() {
@Override
public void onProgress(ProgressEvent event) {
LOGGER.info(event);
}
@Override
public boolean isCancelled() {
return false;
}
};
public static class MainArgs {
public enum Feature implements OptionEnum {
SIMPLIFY("simplify", "Simplifies mountability expressions (default)."),
NO_SIMPLIFY("no-simplify", "Does not simplify mountability expressions."),
KEEP_GOING("keep-going", "Keep going even if an error is detected."),
NO_KEEP_GOING("no-keep-going", "Interrupt processing when an error is detected (default)."),
INCLUDE_ASSERTION("include-assertions", "Includes assertions in simplification of expressions."),
EXCLUDE_ASSERTION("exclude-assertions", "Excludes assertions in simplification of expressions (default)."),
NO_RESERVES("no-reserves", "Ignores reserves in simplification of expressions (default)."),
ALL_POSSIBLE_RESERVES("all-possible-reserves",
"Takes into account all possible reserves in simplification of expressions."),
USER_DEFINED_RESERVES("user-defined-reserves",
"Takes into account user defined reserves in simplifications of expressions."),
SHORT_SYMBOLS("short-symbols", "Generates mountability using short symbols (&, |, <:, ...)."),
LONG_SYMBOLS("long-symbols", "Generates mountability expressions using long symbols (and, or, in, ...) (default)."),
MATH_SYMBOLS("math-symbols", "Generates mountability expressions using math symbols (\u2227, \u2228, \u2208, ...)."),
PRETTY("pretty", "Pretty prints generated file (default)."),
NO_PRETTY("no-pretty", "Does not pretty print generated file.");
private final String name;
private final String description;
private Feature(String name,
String description) {
this.name = name;
this.description = description;
}
@Override
public final String getName() {
return name;
}
@Override
public final String getDescription() {
return description;
}
}
public File repositoryFile;
public File formattersCatalogFile;
public File mountabilityInputFile;
public File mountabilityOutputFile;
public String dictionaryPath;
public String namingConvention;
public File issuesFile;
protected final FeatureMask features = new FeatureMask<>();
public void setEnabled(Feature feature,
boolean enabled) {
features.setEnabled(feature, enabled);
}
public boolean isEnabled(Feature feature) {
return features.isEnabled(feature);
}
public AssertionStrategy getAssertionStrategy() {
if (isEnabled(MainArgs.Feature.INCLUDE_ASSERTION)) {
return AssertionStrategy.INCLUDE_ASSERTIONS;
} else {
return AssertionStrategy.EXCLUDE_ASSERTIONS;
}
}
public ReserveStrategy getReserveStrategy() {
if (isEnabled(MainArgs.Feature.ALL_POSSIBLE_RESERVES)) {
return ReserveStrategy.ALL_POSSIBLE_RESERVES;
} else if (isEnabled(MainArgs.Feature.USER_DEFINED_RESERVES)) {
return ReserveStrategy.USER_DEFINED_RESERVES;
} else {
return ReserveStrategy.NO_RESERVES;
}
}
public MountabilityComputerFeatures.Hint[] getHints() {
final List hints = new ArrayList<>();
if (!isEnabled(Feature.NO_SIMPLIFY)) {
hints.add(MountabilityComputerFeatures.Hint.SIMPLIFY);
}
if (isEnabled(Feature.KEEP_GOING)) {
hints.add(MountabilityComputerFeatures.Hint.KEEP_GOING);
}
return hints.toArray(new MountabilityComputerFeatures.Hint[hints.size()]);
}
public boolean prettyPrints() {
return !isEnabled(Feature.NO_PRETTY);
}
public SymbolType getSymbolType() {
if (isEnabled(Feature.MATH_SYMBOLS)) {
return SymbolType.MATH;
} else if (isEnabled(Feature.SHORT_SYMBOLS)) {
return SymbolType.SHORT;
} else {
return SymbolType.LONG;
}
}
public Spacing getSpacing() {
if (getSymbolType() == SymbolType.LONG) {
return Spacing.WIDE;
} else {
return Spacing.NARROW;
}
}
public Formatting getFormatting() {
return Formatting.builder()
.symbolType(getSymbolType())
.spacing(getSpacing())
.build();
}
}
private ComputeMountability(MainArgs margs) {
this.margs = margs;
}
private void execute() throws IOException {
final Chronometer chrono = new Chronometer();
// Load Repository
LOGGER.info("Load repository from {}", margs.repositoryFile);
chrono.start();
final RepositoryImpl repository = RepositoryIo.load(margs.repositoryFile, FailureReaction.FAIL);
chrono.suspend();
LOGGER.info("Done ({})", chrono);
final Dictionary dictionary;
if (margs.dictionaryPath == null) {
dictionary = repository.getRegistries().get(0);
} else {
dictionary = repository.getDictionary(margs.dictionaryPath);
}
final DictionaryHandle handle = new DictionaryHandle(dictionary);
final FormattersCatalog catalog;
// Load formatters catalog
if (margs.formattersCatalogFile != null) {
LOGGER.info("Load formatters catalog from {}", margs.formattersCatalogFile);
chrono.start();
final FormattersCatalogXml.StAXLoader catalogLoader = new FormattersCatalogXml.StAXLoader(FailureReaction.WARN);
catalog = catalogLoader.load(margs.formattersCatalogFile);
chrono.suspend();
LOGGER.info("Done ({})", chrono);
} else {
catalog = null;
}
// Load data set
LOGGER.info("Load mountability data from {}", margs.mountabilityInputFile);
chrono.start();
final DataXml.StAXLoader dataLoader = new DataXml.StAXLoader(FailureReaction.WARN, false);
final Data data = dataLoader.load(margs.mountabilityInputFile);
chrono.suspend();
LOGGER.info("Done ({})", chrono);
LOGGER.info("Check mountability data");
chrono.start();
final MountabilityDataChecker checker = new MountabilityDataCheckerImpl<>(handle);
final IssuesCollector collector = new IssuesCollector<>();
checker.check(data, collector);
chrono.suspend();
LOGGER.info("Done ({})", chrono);
if (margs.issuesFile != null) {
LOGGER.info("Save mountability data issues to {}", margs.issuesFile);
chrono.start();
IssuesWriter.save(collector.getIssues(),
OutSettings.builder()
.hint(OutSettings.Hint.NO_ANSWERS)
.hint(OutSettings.Hint.AUTO_LOCATIONS)
.build(),
margs.issuesFile,
ProgressController.VOID,
IssuesIoFactoryFeatures.UTC_FASTEST);
chrono.suspend();
LOGGER.info("Saved mountability data issues to {} ({})", margs.issuesFile, chrono);
} else {
LOGGER.warn("Found {} issues", collector.getIssues().size());
for (final ApplicIssue issue : collector.getIssues()) {
LOGGER.warn(" {}", issue);
}
}
// ProverFeatures
final ProverFeatures proverFeatures =
ProverFeatures.builder()
.assertionStrategy(margs.getAssertionStrategy())
.reserveStrategy(margs.getReserveStrategy())
.build();
// SimpliferFeatures
final SimplifierFeatures simplifierFeatures =
SimplifierFeatures.builder()
.proverFeatures(proverFeatures)
.hints(Hint.CONVERT_TO_DNF,
Hint.NORMALIZE_BOOLEAN_PROPERTIES,
Hint.REMOVE_ALWAYS_TRUE_OR_FALSE,
Hint.REMOVE_NEGATION,
Hint.REMOVE_REDUNDANT_SIBLINGS)
.noLimits()
.namingConvention(dictionary.getRegistry().getNamingConvention(margs.namingConvention))
.build();
final MountabilityComputer computer =
new MountabilityComputerImpl<>(handle, simplifierFeatures);
final Handler handler = new Handler();
final MountabilityComputerFeatures features =
MountabilityComputerFeatures.builder()
.hints(margs.getHints())
.build();
LOGGER.info("Compute mountability");
chrono.start();
computer.compute(data, handler, features, controller);
chrono.suspend();
LOGGER.info("Done ({})", chrono);
// Save computed data set
LOGGER.info("Save data to {}", margs.mountabilityOutputFile);
chrono.start();
try (final XmlWriter writer = new XmlWriter(margs.mountabilityOutputFile)) {
if (margs.prettyPrints()) {
writer.setEnabled(XmlWriter.Feature.PRETTY_PRINT);
}
writer.setIndentString(" ");
final DataXml.Printer dataPrinter = new DataXml.Printer();
dataPrinter.setFormatting(margs.getFormatting());
if (catalog != null) {
final ExpressionFormatter formatter = new InfixFormatter(dictionary.getRegistry(), catalog);
dataPrinter.setFormatter(formatter);
}
dataPrinter.write(writer, handler.data);
}
chrono.suspend();
LOGGER.info("Done ({})", chrono);
}
public static void execute(MainArgs margs) throws IOException {
final ComputeMountability instance = new ComputeMountability(margs);
instance.execute();
}
public static MainResult exec(String... args) {
final MainSupport support = new MainSupport();
support.main(args);
return support.getResult();
}
public static void main(String... args) {
final int code = exec(args).getCode();
System.exit(code);
}
private static class Handler implements MountabilityHandler {
public final Data data = new Data();
private UsePoint currentUsePoint;
public Handler() {
super();
}
@Override
public void processBeginUsePoints() {
LOGGER.debug("processBeginUsePoints()");
}
@Override
public void processEndUsePoints() {
LOGGER.debug("processEndUsePoints()");
}
@Override
public void processBeginUsePoint(UsePoint usePoint) {
LOGGER.debug("processBeginUsePoint({})", usePoint);
currentUsePoint = new UsePoint(usePoint.getId());
}
@Override
public void processEndUsePoint(UsePoint usePoint) {
LOGGER.debug("processEndUsePoint({})", usePoint);
data.addUsePoint(currentUsePoint);
}
@Override
public void processVariantMountability(UsePoint usePoint,
Variant variant,
Expression mountability) {
LOGGER.debug("processVariantMountability({}, {}, {})", usePoint, variant, mountability);
currentUsePoint.addVariant(variant.getId(),
variant.getInterchangeability(),
variant.getApplicability(),
mountability);
}
@Override
public void processError(RuntimeException e) {
LOGGER.error("processError({})", e.getMessage());
}
}
private static class MainSupport extends AbstractMainSupport {
private static final String REPOSITORY_FILE = "repository";
private static final String FORMATTERS_CATALOG_FILE = "formatters-catalog";
private static final String MOUNTABILITY_INPUT_FILE = "input";
private static final String MOUNTABILITY_OUTPUT_FILE = "output";
private static final String ISSUES_FILE = "issues";
private static final String DICTIONARY = "dictionary";
private static final String NAMING_CONVENTION = "naming-convention";
public MainSupport() {
super(ComputeMountability.class, LOGGER);
}
@Override
protected String getVersion() {
return "2020-07-04";
}
@Override
protected boolean addArgsFileOption(Options options) {
return true;
}
@Override
protected void addSpecificOptions(Options options) {
options.addOption(Option.builder()
.longOpt(REPOSITORY_FILE)
.desc("Name of the mandatory input XML, XLS or XLSX repository file.")
.hasArg()
.required()
.build());
options.addOption(Option.builder()
.longOpt(FORMATTERS_CATALOG_FILE)
.desc("Name of the optional input XML formatters catalog file.")
.hasArg()
.build());
options.addOption(Option.builder()
.longOpt(MOUNTABILITY_INPUT_FILE)
.desc("Name of the mandatory input XML mountability file.")
.hasArg()
.required()
.build());
options.addOption(Option.builder()
.longOpt(MOUNTABILITY_OUTPUT_FILE)
.desc("Name of the mandatory output XML mountability file.")
.hasArg()
.required()
.build());
options.addOption(Option.builder()
.longOpt(ISSUES_FILE)
.desc("Name of the optional output issues file.")
.hasArg()
.build());
options.addOption(Option.builder()
.longOpt(DICTIONARY)
.desc("Key of the optional dictionary to use. If none is passed, the first registry is used.\n"
+ "It has the form 'name(/name)*'.")
.hasArg()
.build());
options.addOption(Option.builder()
.longOpt(NAMING_CONVENTION)
.desc("Optional naming convention (Defaults to default naming convention).")
.hasArg()
.build());
addNoArgOptions(options, MainArgs.Feature.class);
createGroup(options,
MainArgs.Feature.PRETTY,
MainArgs.Feature.NO_PRETTY);
createGroup(options,
MainArgs.Feature.EXCLUDE_ASSERTION,
MainArgs.Feature.INCLUDE_ASSERTION);
createGroup(options,
MainArgs.Feature.NO_RESERVES,
MainArgs.Feature.ALL_POSSIBLE_RESERVES,
MainArgs.Feature.USER_DEFINED_RESERVES);
createGroup(options,
MainArgs.Feature.SIMPLIFY,
MainArgs.Feature.NO_SIMPLIFY);
createGroup(options,
MainArgs.Feature.KEEP_GOING,
MainArgs.Feature.NO_KEEP_GOING);
createGroup(options,
MainArgs.Feature.SHORT_SYMBOLS,
MainArgs.Feature.LONG_SYMBOLS,
MainArgs.Feature.MATH_SYMBOLS);
}
@Override
protected MainArgs analyze(CommandLine cl) throws ParseException {
final MainArgs margs = new MainArgs();
margs.repositoryFile = getValueAsResolvedFile(cl, REPOSITORY_FILE, IS_FILE);
margs.formattersCatalogFile = getValueAsResolvedFile(cl, FORMATTERS_CATALOG_FILE, IS_NULL_OR_FILE);
margs.mountabilityInputFile = getValueAsResolvedFile(cl, MOUNTABILITY_INPUT_FILE, IS_FILE);
margs.mountabilityOutputFile = getValueAsResolvedFile(cl, MOUNTABILITY_OUTPUT_FILE);
margs.issuesFile = getValueAsResolvedFile(cl, ISSUES_FILE);
margs.dictionaryPath = getValueAsString(cl, DICTIONARY, null);
margs.namingConvention = getValueAsString(cl, NAMING_CONVENTION, NamingConvention.DEFAULT_NAME.getNonEscapedLiteral());
setMask(cl, MainArgs.Feature.class, margs.features::setEnabled);
return margs;
}
@Override
protected Void execute(MainArgs margs) throws Exception {
ComputeMountability.execute(margs);
return null;
}
}
}