Mentions légales du service

Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • rules/integraal
  • ulliana/integraal
2 results
Select Git revision
Show changes
Commits on Source (89)
Showing
with 1922 additions and 1104 deletions
package fr.boreal.component_builder; package fr.boreal.component_builder;
import java.lang.reflect.Field;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.boreal.component_builder.api.algorithm.IAlgorithmParameters; import fr.boreal.component_builder.api.algorithm.IAlgorithmParameters;
import fr.boreal.component_builder.externalHaltingConditions.ExternalAlgorithmHaltingConditions; import fr.boreal.component_builder.externalHaltingConditions.ExternalAlgorithmHaltingConditions;
import fr.boreal.component_builder.utils.StringUtils; import fr.boreal.component_builder.utils.StringUtils;
import fr.boreal.configuration.keywords.InteGraalKeywords; import fr.boreal.configuration.keywords.InteGraalKeywords;
import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms; import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms;
import fr.boreal.configuration.keywords.InteGraalKeywords.InternalStorageConfiguration;
import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Answers; import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Answers;
import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Images; import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Images;
import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Chase.*;
import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Compilation; import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Compilation;
import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Chase.Applier; import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Explanation.*;
import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Chase.Checker; import fr.boreal.configuration.keywords.InteGraalKeywords.InternalStorageConfiguration;
import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Chase.Computer;
import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Chase.Evaluator;
import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Chase.Scheduler;
import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Chase.Namer;
import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Chase.Transformer;
import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Explanation.ExplainerVerbosity;
import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Explanation.ExplainerSolver;
import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Explanation.ExplainerType;
import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Explanation.ExplanationType;
import fr.boreal.configuration.keywords.InteGraalKeywords.InternalStorageConfiguration.DBMSDriverParameters; import fr.boreal.configuration.keywords.InteGraalKeywords.InternalStorageConfiguration.DBMSDriverParameters;
import fr.boreal.configuration.keywords.InteGraalKeywords.InternalStorageConfiguration.DBType; import fr.boreal.configuration.keywords.InteGraalKeywords.InternalStorageConfiguration.DBType;
import fr.boreal.configuration.keywords.InteGraalKeywords.InternalStorageConfiguration.DriverType; import fr.boreal.configuration.keywords.InteGraalKeywords.InternalStorageConfiguration.DriverType;
import fr.boreal.configuration.keywords.InteGraalKeywords.InternalStorageConfiguration.StorageLayout; import fr.boreal.configuration.keywords.InteGraalKeywords.InternalStorageConfiguration.StorageLayout;
import fr.boreal.configuration.parameters.IGParameter; import fr.boreal.configuration.parameters.IGParameter;
import fr.lirmm.boreal.util.enumerations.EnumUtils; import fr.lirmm.boreal.util.enumerations.EnumUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Field;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
/** /**
* Default implementation for {@link IAlgorithmParameters}. * Default implementation for {@link IAlgorithmParameters}.
...@@ -48,798 +38,892 @@ import fr.lirmm.boreal.util.enumerations.EnumUtils; ...@@ -48,798 +38,892 @@ import fr.lirmm.boreal.util.enumerations.EnumUtils;
*/ */
public class AlgorithmParameters implements IAlgorithmParameters { public class AlgorithmParameters implements IAlgorithmParameters {
/// ////////////////////////////////////// /// //////////////////////////////////////
/// / FIELDS /// / FIELDS
/// ////////////////////////////////////// /// //////////////////////////////////////
static final Logger LOG = LoggerFactory.getLogger(AlgorithmParameters.class); static final Logger LOG = LoggerFactory.getLogger(AlgorithmParameters.class);
private final boolean parametereSetAtConstruction; private final boolean parametereSetAtConstruction;
// Core configuration fields // Core configuration fields
private final Algorithms algorithm; private final Algorithms algorithm;
protected final String name; protected final String name;
// Closed parameters from enumeration // Closed parameters from enumeration
// chase // chase
private Scheduler scheduler; private Scheduler scheduler;
private Checker checker; private Checker checker;
private Computer computer; private Computer computer;
private Applier applier; private Applier applier;
private Namer skolem; private Namer skolem;
private Evaluator evaluator; // added by Michel private Evaluator evaluator; // added by Michel
private Transformer transformer; // added by Michel private Transformer transformer; // added by Michel
// TODO check transfer of IntegralParameters to AlgorithmParameters // TODO check transfer of IntegralParameters to AlgorithmParameters
// storage // storage
private DBType dbtype; private DBType dbtype;
private DriverType driverType; private DriverType driverType;
private StorageLayout storageLayout; private StorageLayout storageLayout;
// query rewriting // query rewriting
private Compilation compilation; private Compilation compilation;
// Open parameters, with names defined from a parent enumeration // Open parameters, with names defined from a parent enumeration
// database // database
private String DBMSDriverParameters_URL; private String DBMSDriverParameters_URL;
private String DBMSDriverParameters_PORT; private String DBMSDriverParameters_PORT;
private String DBMSDriverParameters_DATABASE_NAME; private String DBMSDriverParameters_DATABASE_NAME;
private String DBMSDriverParameters_USER_NAME; private String DBMSDriverParameters_USER_NAME;
private String DBMSDriverParameters_USER_PASSWORD; private String DBMSDriverParameters_USER_PASSWORD;
private String DBMSDriverParameters_CLEAR_DB; private String DBMSDriverParameters_CLEAR_DB;
// Open parameters, with names not defined from a parent enumeration // Open parameters, with names not defined from a parent enumeration
private Integer max; private Integer max;
private Integer rank; private Integer rank;
private Duration timeout; private Duration timeout;
// query answering // query answering
private Answers answers; private Answers answers;
private Images images; private Images images;
// Alternative for setting timeout and rank // Alternative for setting timeout and rank
private ExternalAlgorithmHaltingConditions externalHaltingConditions; private ExternalAlgorithmHaltingConditions externalHaltingConditions;
private Algorithms.Parameters.Explanation.ExplainerVerbosity explainerVerbosity; private ExplainerVerbosity explainerVerbosity;
private Algorithms.Parameters.Explanation.ExplainerSolver explainerSolver; private ExplainerSolver explainerSolver;
private Algorithms.Parameters.Explanation.ExplainerType explainerType; private GraphOfRuleInstancesComputation graphOfRuleInstancesComputation;
private Algorithms.Parameters.Explanation.ExplanationType explanationType; private ExplanationSupportType explanationSupportType;
///////////////////////////////////////// private GraphOfRuleInstancesType graphOfRuleInstancesType;
//// CONSTRUCTORS private Algorithms.Parameters.Explanation explanation;
///////////////////////////////////////// private Integer GSATSolverParameters_SMART_SOLVER_TRESHOLD;
private String GSATSolverParameters_MARCO_PATH_TO_EXECUTABLE;
/** /////////////////////////////////////////
* Constructs a new {@code AlgorithmParameters} instance. //// CONSTRUCTORS
* /////////////////////////////////////////
* @param name the name of the configuration
* @param algorithmType the algorithm type (e.g., KB_CHASE, OMQA_CHASE) /**
*/ * Constructs a new {@code AlgorithmParameters} instance.
public AlgorithmParameters(String name, Algorithms algorithmType) { *
this.name = name; * @param name the name of the configuration
this.algorithm = algorithmType; * @param algorithmType the algorithm type (e.g., KB_CHASE, OMQA_CHASE)
this.parametereSetAtConstruction = false; */
initDefaultValues(); public AlgorithmParameters(String name, Algorithms algorithmType) {
} this.name = name;
this.algorithm = algorithmType;
/** this.parametereSetAtConstruction = false;
* Constructs a new {@code AlgorithmParameters} instance and immediately sets initDefaultValues();
* parameters from the specified {@link IGParameter} object. }
*
* @param name the name of the configuration /**
* @param algorithmType the algorithm type * Constructs a new {@code AlgorithmParameters} instance and immediately sets
* @param params an {@code IGParameter} containing parameter metadata * parameters from the specified {@link IGParameter} object.
*/ *
public AlgorithmParameters(String name, Algorithms algorithmType, IGParameter<InteGraalKeywords, ?>... params) { * @param name the name of the configuration
this.name = name; * @param algorithmType the algorithm type
this.algorithm = algorithmType; * @param params an {@code IGParameter} containing parameter metadata
initDefaultValues(); */
this.parametereSetAtConstruction = setParams(params); public AlgorithmParameters(String name, Algorithms algorithmType, IGParameter<InteGraalKeywords, ?>... params) {
} this.name = name;
this.algorithm = algorithmType;
///////////////////////////////////////// initDefaultValues();
//// OVERRIDDEN / PUBLIC METHODS this.parametereSetAtConstruction = setParams(params);
///////////////////////////////////////// }
/** /////////////////////////////////////////
* Returns the name of the configuration concatenated with the algorithm name. //// OVERRIDDEN / PUBLIC METHODS
* /////////////////////////////////////////
* @return the name of the configuration (e.g., "MyConfig_OMQA_CHASE")
*/ /**
public String getName() { * Returns the name of the configuration concatenated with the algorithm name.
return this.name + "_" + this.algorithm.toString(); *
} * @return the name of the configuration (e.g., "MyConfig_OMQA_CHASE")
*/
/** public String getName() {
* Returns the current algorithm type. return this.name + "_" + this.algorithm.toString();
* }
* @return the current {@link InteGraalKeywords.Algorithms} enum value
*/ /**
public InteGraalKeywords.Algorithms getAlgorithm() { * Returns the current algorithm type.
return algorithm; *
} * @return the current {@link InteGraalKeywords.Algorithms} enum value
*/
@Override public InteGraalKeywords.Algorithms getAlgorithm() {
public boolean usesSaturationAlgorithm() { return algorithm;
return algorithm.equals(InteGraalKeywords.Algorithms.KB_CHASE) }
|| algorithm.equals(InteGraalKeywords.Algorithms.OMQA_CHASE)
|| algorithm.equals(InteGraalKeywords.Algorithms.QUERY_ANSWERING_VIA_HYBRID_STRATEGY); @Override
} public boolean usesSaturationAlgorithm() {
return algorithm.equals(InteGraalKeywords.Algorithms.KB_CHASE)
@Override || algorithm.equals(InteGraalKeywords.Algorithms.OMQA_CHASE)
public boolean usesQueryRewritingAlgorithm() { || algorithm.equals(InteGraalKeywords.Algorithms.QUERY_ANSWERING_VIA_HYBRID_STRATEGY);
return algorithm.equals(InteGraalKeywords.Algorithms.OMQ_REWRITING) }
|| algorithm.equals(InteGraalKeywords.Algorithms.OMQA_REW);
} @Override
public boolean usesQueryRewritingAlgorithm() {
@Override return algorithm.equals(InteGraalKeywords.Algorithms.OMQ_REWRITING)
public boolean usesQueryAnsweringAlgorithm() { || algorithm.equals(InteGraalKeywords.Algorithms.OMQA_REW);
return algorithm.equals(InteGraalKeywords.Algorithms.QUERY_ANSWERING); }
}
@Override
@Override public boolean usesQueryAnsweringAlgorithm() {
public boolean usesRuleCompilationAlgorithm() { return algorithm.equals(InteGraalKeywords.Algorithms.QUERY_ANSWERING);
return algorithm.equals(InteGraalKeywords.Algorithms.RULE_COMPILATION) || usesQueryRewritingAlgorithm(); }
}
@Override
@Override public boolean usesRuleCompilationAlgorithm() {
public boolean usesOMQASaturationAlgorithm() { return algorithm.equals(InteGraalKeywords.Algorithms.RULE_COMPILATION) || usesQueryRewritingAlgorithm();
return algorithm.equals(InteGraalKeywords.Algorithms.OMQA_CHASE); }
}
@Override
@Override public boolean usesOMQASaturationAlgorithm() {
public boolean usesOMQARewritingAlgorithm() { return algorithm.equals(InteGraalKeywords.Algorithms.OMQA_CHASE);
return algorithm.equals(InteGraalKeywords.Algorithms.OMQA_REW); }
}
@Override
@Override public boolean usesOMQARewritingAlgorithm() {
public boolean usesOMQAHybridAlgorithm() { return algorithm.equals(InteGraalKeywords.Algorithms.OMQA_REW);
return algorithm.equals(InteGraalKeywords.Algorithms.QUERY_ANSWERING_VIA_HYBRID_STRATEGY); }
}
@Override
@Override public boolean usesOMQAHybridAlgorithm() {
public boolean usesStorage() { return algorithm.equals(InteGraalKeywords.Algorithms.QUERY_ANSWERING_VIA_HYBRID_STRATEGY);
return usesSaturationAlgorithm() || usesQueryAnsweringAlgorithm() || usesOMQASaturationAlgorithm() }
|| usesOMQARewritingAlgorithm() || usesOMQAHybridAlgorithm();
} @Override
public boolean usesStorage() {
@Override return usesSaturationAlgorithm() || usesQueryAnsweringAlgorithm() || usesOMQASaturationAlgorithm()
public Optional<Applier> getRuleApplier() { || usesOMQARewritingAlgorithm() || usesOMQAHybridAlgorithm();
return Optional.ofNullable(applier); }
}
@Override
@Override public Optional<Applier> getRuleApplier() {
public Optional<Scheduler> getScheduler() { return Optional.ofNullable(applier);
return Optional.ofNullable(scheduler); }
}
@Override
@Override public Optional<Scheduler> getScheduler() {
public Optional<Checker> getCriterion() { return Optional.ofNullable(scheduler);
return Optional.ofNullable(checker); }
}
@Override
@Override public Optional<Checker> getCriterion() {
public Optional<Computer> getComputer() { return Optional.ofNullable(checker);
return Optional.ofNullable(computer); }
}
@Override
@Override public Optional<Computer> getComputer() {
public Optional<Namer> getSkolemization() { return Optional.ofNullable(computer);
return Optional.ofNullable(skolem); }
}
@Override
@Override public Optional<Namer> getSkolemization() {
public Optional<Evaluator> getEvaluator() { return Optional.ofNullable(skolem);
return Optional.ofNullable(evaluator); }
}
@Override
@Override public Optional<Evaluator> getEvaluator() {
public Optional<Transformer> getTransformer() { return Optional.ofNullable(evaluator);
return Optional.ofNullable(transformer); }
}
@Override
@Override public Optional<Transformer> getTransformer() {
public Optional<DBType> getStorageType() { return Optional.ofNullable(transformer);
return Optional.ofNullable(dbtype); }
}
@Override
@Override public Optional<DBType> getStorageType() {
public Optional<DriverType> getDBDriver() { return Optional.ofNullable(dbtype);
return Optional.ofNullable(driverType); }
}
@Override
@Override public Optional<DriverType> getDBDriver() {
public Optional<StorageLayout> getDBStrategy() { return Optional.ofNullable(driverType);
return Optional.ofNullable(storageLayout); }
}
@Override
@Override public Optional<StorageLayout> getDBStrategy() {
public Optional<Compilation> getCompilation() { return Optional.ofNullable(storageLayout);
return Optional.ofNullable(compilation); }
}
@Override
@Override public Optional<Compilation> getCompilation() {
public Optional<Integer> getRank() { return Optional.ofNullable(compilation);
return Optional.ofNullable(this.rank); }
}
@Override
@Override public Optional<Integer> getRank() {
public Optional<Integer> getMax() { return Optional.ofNullable(this.rank);
return Optional.ofNullable(this.max); }
}
@Override
@Override public Optional<Integer> getMax() {
public Optional<Duration> getTimeout() { return Optional.ofNullable(this.max);
return Optional.ofNullable(this.timeout); }
}
@Override
@Override public Optional<Duration> getTimeout() {
public Answers getResultType() { return Optional.ofNullable(this.timeout);
return this.answers; }
}
@Override
@Override public Answers getResultType() {
public Images getImageType() { return this.answers;
return this.images; }
}
@Override
@Override public Images getImageType() {
public void setResultType(Answers type) { return this.images;
this.answers = type; }
}
@Override
@Override public void setResultType(Answers type) {
public void setImageType(Images type) { this.answers = type;
this.images = type; }
}
@Override
@Override public void setImageType(Images type) {
public boolean asksLists() { this.images = type;
return this.answers.equals(Answers.LIST); }
}
@Override
@Override public boolean asksLists() {
public boolean asksSet() { return this.answers.equals(Answers.LIST);
return this.answers.equals(Answers.SET); }
}
@Override
@Override public boolean asksSet() {
public boolean asksCountOnly() { return this.answers.equals(Answers.SET);
return this.answers.equals(Answers.COUNT_ONLY); }
}
@Override
@Override public boolean asksCountOnly() {
public ExternalAlgorithmHaltingConditions getExternalHaltingConditions() { return this.answers.equals(Answers.COUNT_ONLY);
if (this.externalHaltingConditions == null) { }
this.externalHaltingConditions = ExternalAlgorithmHaltingConditions.defaultConditions();
} @Override
return this.externalHaltingConditions; public ExternalAlgorithmHaltingConditions getExternalHaltingConditions() {
} if (this.externalHaltingConditions == null) {
this.externalHaltingConditions = ExternalAlgorithmHaltingConditions.defaultConditions();
@Override }
public Optional<Map<DBMSDriverParameters, String>> getDBMSDriverParameters() { return this.externalHaltingConditions;
Map<DBMSDriverParameters, String> result = new LinkedHashMap<>(); }
if (DBMSDriverParameters_URL != null) { @Override
result.put(DBMSDriverParameters.URL, DBMSDriverParameters_URL); public Optional<Map<DBMSDriverParameters, String>> getDBMSDriverParameters() {
} Map<DBMSDriverParameters, String> result = new LinkedHashMap<>();
if (DBMSDriverParameters_PORT != null) {
result.put(DBMSDriverParameters.PORT, DBMSDriverParameters_PORT); if (DBMSDriverParameters_URL != null) {
} result.put(DBMSDriverParameters.URL, DBMSDriverParameters_URL);
if (DBMSDriverParameters_DATABASE_NAME != null) { }
result.put(DBMSDriverParameters.DATABASE_NAME, DBMSDriverParameters_DATABASE_NAME); if (DBMSDriverParameters_PORT != null) {
} result.put(DBMSDriverParameters.PORT, DBMSDriverParameters_PORT);
if (DBMSDriverParameters_USER_NAME != null) { }
result.put(DBMSDriverParameters.USER_NAME, DBMSDriverParameters_USER_NAME); if (DBMSDriverParameters_DATABASE_NAME != null) {
} result.put(DBMSDriverParameters.DATABASE_NAME, DBMSDriverParameters_DATABASE_NAME);
if (DBMSDriverParameters_USER_PASSWORD != null) { }
result.put(DBMSDriverParameters.USER_PASSWORD, DBMSDriverParameters_USER_PASSWORD); if (DBMSDriverParameters_USER_NAME != null) {
} result.put(DBMSDriverParameters.USER_NAME, DBMSDriverParameters_USER_NAME);
if (DBMSDriverParameters_CLEAR_DB != null) { }
result.put(DBMSDriverParameters.CLEAR_DB, DBMSDriverParameters_CLEAR_DB); if (DBMSDriverParameters_USER_PASSWORD != null) {
} result.put(DBMSDriverParameters.USER_PASSWORD, DBMSDriverParameters_USER_PASSWORD);
}
if (result.isEmpty()) { if (DBMSDriverParameters_CLEAR_DB != null) {
return Optional.empty(); result.put(DBMSDriverParameters.CLEAR_DB, DBMSDriverParameters_CLEAR_DB);
} else { }
return Optional.of(result);
} if (result.isEmpty()) {
} return Optional.empty();
} else {
public Optional<ExplainerVerbosity> getExplainerVerbosity() { return Optional.of(result);
return Optional.ofNullable(explainerVerbosity); }
} }
public Optional<ExplainerSolver> getExplainerSolver() {
return Optional.ofNullable(explainerSolver); /// //////////////////////////////////////
} /// / OVERRIDDEN / PUBLIC SETTER METHODS
/// //////////////////////////////////////
public Optional<ExplainerType> getExplainerType() {
return Optional.ofNullable(explainerType); @Override
} public IAlgorithmParameters setExternalHaltingConditions(ExternalAlgorithmHaltingConditions hc) {
if (parametereSetAtConstruction) {
public Optional<ExplanationType> getExplanationType() { LOG.error("parameters have been already set ; wrong usage of the method");
return Optional.ofNullable(explanationType); }
} this.externalHaltingConditions = hc;
this.rank = externalHaltingConditions.rank();
/// ////////////////////////////////////// this.timeout = externalHaltingConditions.timeout();
/// / OVERRIDDEN / PUBLIC SETTER METHODS return this;
/// ////////////////////////////////////// }
@Override @Override
public IAlgorithmParameters setExternalHaltingConditions(ExternalAlgorithmHaltingConditions hc) { public IAlgorithmParameters setMax(Integer max) {
if (parametereSetAtConstruction) { this.max = max;
LOG.error("parameters have been already set ; wrong usage of the method"); return this;
} }
this.externalHaltingConditions = hc;
this.rank = externalHaltingConditions.rank(); @Override
this.timeout = externalHaltingConditions.timeout(); public IAlgorithmParameters setRank(Integer rank) {
return this; this.rank = rank;
} return this;
}
@Override
public IAlgorithmParameters setMax(Integer max) { @Override
this.max = max; public IAlgorithmParameters setTimeout(Duration timeout) {
return this; this.timeout = timeout;
} return this;
}
@Override
public IAlgorithmParameters setRank(Integer rank) { /**
this.rank = rank; * Sets the DB storage type (e.g., PostgreSQL, H2) by matching the input string
return this; * to an enum constant and then calling {@link #setParameter(Enum)}.
} *
* @param storageDBTypeName the name of the storage type (e.g., "H2",
@Override * "POSTGRESQL")
public IAlgorithmParameters setTimeout(Duration timeout) { * @return this {@link IAlgorithmParameters} instance for method chaining
this.timeout = timeout; */
return this; public IAlgorithmParameters setStorageType(String storageDBTypeName) {
} return setParameter(EnumUtils.findEnumFromString(storageDBTypeName, InternalStorageConfiguration.DBType.class));
}
/**
* Sets the DB storage type (e.g., PostgreSQL, H2) by matching the input string @Override
* to an enum constant and then calling {@link #setParameter(Enum)}. public IAlgorithmParameters setStorageType(DBType storage) {
* return setParameter(storage);
* @param storageDBTypeName the name of the storage type (e.g., "H2", }
* "POSTGRESQL")
* @return this {@link IAlgorithmParameters} instance for method chaining /**
*/ * Sets the database driver type (e.g., "JDBC") by matching the input string to
public IAlgorithmParameters setStorageType(String storageDBTypeName) { * an enum constant and then calling {@link #setParameter(Enum)}.
return setParameter(EnumUtils.findEnumFromString(storageDBTypeName, InternalStorageConfiguration.DBType.class)); *
} * @param storageDriverName the name of the driver type
* @return this {@link IAlgorithmParameters} instance for method chaining
@Override */
public IAlgorithmParameters setStorageType(DBType storage) { public IAlgorithmParameters setDBDriver(String storageDriverName) {
return setParameter(storage); return setParameter(
} EnumUtils.findEnumFromString(storageDriverName, InternalStorageConfiguration.DriverType.class));
}
/**
* Sets the database driver type (e.g., "JDBC") by matching the input string to @Override
* an enum constant and then calling {@link #setParameter(Enum)}. public IAlgorithmParameters setDBDriver(DriverType storageDriver) {
* return setParameter(storageDriver);
* @param storageDriverName the name of the driver type }
* @return this {@link IAlgorithmParameters} instance for method chaining
*/ /**
public IAlgorithmParameters setDBDriver(String storageDriverName) { * Sets the storage layout strategy (e.g., "DEFAULT") by matching the input
return setParameter( * string to an enum constant and then calling {@link #setParameter(Enum)}.
EnumUtils.findEnumFromString(storageDriverName, InternalStorageConfiguration.DriverType.class)); *
} * @param storageStrategyName the name of the storage layout
* @return this {@link IAlgorithmParameters} instance for method chaining
@Override */
public IAlgorithmParameters setDBDriver(DriverType storageDriver) { public IAlgorithmParameters setDBStrategy(String storageStrategyName) {
return setParameter(storageDriver); return setParameter(
} EnumUtils.findEnumFromString(storageStrategyName, InternalStorageConfiguration.StorageLayout.class));
}
/**
* Sets the storage layout strategy (e.g., "DEFAULT") by matching the input @Override
* string to an enum constant and then calling {@link #setParameter(Enum)}. public IAlgorithmParameters setDBStrategy(StorageLayout storageStrategy) {
* return setParameter(storageStrategy);
* @param storageStrategyName the name of the storage layout }
* @return this {@link IAlgorithmParameters} instance for method chaining
*/
public IAlgorithmParameters setDBStrategy(String storageStrategyName) { /**
return setParameter( * Sets the chase rule applier by matching the input string to an enum constant
EnumUtils.findEnumFromString(storageStrategyName, InternalStorageConfiguration.StorageLayout.class)); * and then calling {@link #setParameter(Enum)}.
} *
* @param applierName the name of the rule applier
@Override * @return this {@link IAlgorithmParameters} instance for method chaining
public IAlgorithmParameters setDBStrategy(StorageLayout storageStrategy) { */
return setParameter(storageStrategy); public IAlgorithmParameters setRuleApplier(String applierName) {
} return setParameter(
EnumUtils.findEnumFromString(applierName, InteGraalKeywords.Algorithms.Parameters.Chase.Applier.class));
}
/**
* Sets the chase rule applier by matching the input string to an enum constant @Override
* and then calling {@link #setParameter(Enum)}. public IAlgorithmParameters setRuleApplier(Applier applier) {
* return setParameter(applier);
* @param applierName the name of the rule applier }
* @return this {@link IAlgorithmParameters} instance for method chaining
*/ /**
public IAlgorithmParameters setRuleApplier(String applierName) { * Sets the scheduler by matching the input string to an enum constant and then
return setParameter( * calling {@link #setParameter(Enum)}.
EnumUtils.findEnumFromString(applierName, InteGraalKeywords.Algorithms.Parameters.Chase.Applier.class)); *
} * @param scheduler the name of the scheduler
* @return this {@link IAlgorithmParameters} instance for method chaining
@Override */
public IAlgorithmParameters setRuleApplier(Applier applier) { public IAlgorithmParameters setScheduler(String scheduler) {
return setParameter(applier); return setParameter(
} EnumUtils.findEnumFromString(scheduler, InteGraalKeywords.Algorithms.Parameters.Chase.Scheduler.class));
}
/**
* Sets the scheduler by matching the input string to an enum constant and then @Override
* calling {@link #setParameter(Enum)}. public IAlgorithmParameters setScheduler(Scheduler scheduler) {
* return setParameter(scheduler);
* @param scheduler the name of the scheduler }
* @return this {@link IAlgorithmParameters} instance for method chaining
*/ /**
public IAlgorithmParameters setScheduler(String scheduler) { * Sets the chase criterion (checker) by matching the input string to an enum
return setParameter( * constant and then calling {@link #setParameter(Enum)}.
EnumUtils.findEnumFromString(scheduler, InteGraalKeywords.Algorithms.Parameters.Chase.Scheduler.class)); *
} * @param criterionName the name of the chase checker
* @return this {@link IAlgorithmParameters} instance for method chaining
@Override */
public IAlgorithmParameters setScheduler(Scheduler scheduler) { public IAlgorithmParameters setCriterion(String criterionName) {
return setParameter(scheduler); return setParameter(EnumUtils.findEnumFromString(criterionName,
} InteGraalKeywords.Algorithms.Parameters.Chase.Checker.class));
}
/**
* Sets the chase criterion (checker) by matching the input string to an enum @Override
* constant and then calling {@link #setParameter(Enum)}. public IAlgorithmParameters setCriterion(Checker criterion) {
* return setParameter(criterion);
* @param criterionName the name of the chase checker }
* @return this {@link IAlgorithmParameters} instance for method chaining
*/ /**
public IAlgorithmParameters setCriterion(String criterionName) { * Sets the chase computer by matching the input string to an enum constant and
return setParameter(EnumUtils.findEnumFromString(criterionName, * then calling {@link #setParameter(Enum)}.
InteGraalKeywords.Algorithms.Parameters.Chase.Checker.class)); *
} * @param computerName the name of the chase computer
* @return this {@link IAlgorithmParameters} instance for method chaining
@Override */
public IAlgorithmParameters setCriterion(Checker criterion) { public IAlgorithmParameters setComputer(String computerName) {
return setParameter(criterion); return setParameter(EnumUtils.findEnumFromString(computerName,
} InteGraalKeywords.Algorithms.Parameters.Chase.Computer.class));
}
/**
* Sets the chase computer by matching the input string to an enum constant and @Override
* then calling {@link #setParameter(Enum)}. public IAlgorithmParameters setComputer(Computer computer) {
* return setParameter(computer);
* @param computerName the name of the chase computer }
* @return this {@link IAlgorithmParameters} instance for method chaining
*/ /**
public IAlgorithmParameters setComputer(String computerName) { * Sets the chase Skolemization approach by matching the input string to an enum
return setParameter(EnumUtils.findEnumFromString(computerName, * constant and then calling {@link #setParameter(Enum)}.
InteGraalKeywords.Algorithms.Parameters.Chase.Computer.class)); *
} * @param skolemizationName the name of the Skolemization approach
* @return this {@link IAlgorithmParameters} instance for method chaining
@Override */
public IAlgorithmParameters setComputer(Computer computer) { public IAlgorithmParameters setSkolemization(String skolemizationName) {
return setParameter(computer); return setParameter(EnumUtils.findEnumFromString(skolemizationName,
} InteGraalKeywords.Algorithms.Parameters.Chase.Namer.class));
}
/**
* Sets the chase Skolemization approach by matching the input string to an enum @Override
* constant and then calling {@link #setParameter(Enum)}. public IAlgorithmParameters setSkolemization(Namer skolemization) {
* return setParameter(skolemization);
* @param skolemizationName the name of the Skolemization approach }
* @return this {@link IAlgorithmParameters} instance for method chaining
*/ /**
public IAlgorithmParameters setSkolemization(String skolemizationName) { * Sets the chase evaluator by matching the input string to an enum
return setParameter(EnumUtils.findEnumFromString(skolemizationName, * constant and then calling {@link #setParameter(Enum)}.
InteGraalKeywords.Algorithms.Parameters.Chase.Namer.class)); *
} * @param evaluatorName the name of the evaluator
* @return this {@link IAlgorithmParameters} instance for method chaining
@Override */
public IAlgorithmParameters setSkolemization(Namer skolemization) { public IAlgorithmParameters setEvaluator(String evaluatorName) {
return setParameter(skolemization); return setParameter(EnumUtils.findEnumFromString(evaluatorName,
} InteGraalKeywords.Algorithms.Parameters.Chase.Evaluator.class));
}
/**
* Sets the chase evaluator by matching the input string to an enum @Override
* constant and then calling {@link #setParameter(Enum)}. public IAlgorithmParameters setEvaluator(Evaluator evaluator) {
* return setParameter(evaluator);
* @param evaluatorName the name of the evaluator }
* @return this {@link IAlgorithmParameters} instance for method chaining
*/
public IAlgorithmParameters setEvaluator(String evaluatorName) { /**
return setParameter(EnumUtils.findEnumFromString(evaluatorName, * Sets the chase transformer by matching the input string to an enum
InteGraalKeywords.Algorithms.Parameters.Chase.Evaluator.class)); * constant and then calling {@link #setParameter(Enum)}.
} *
* @param transformerName the name of the transformer
@Override * @return this {@link IAlgorithmParameters} instance for method chaining
public IAlgorithmParameters setEvaluator(Evaluator evaluator) { */
return setParameter(evaluator); public IAlgorithmParameters setTransformer(String transformerName) {
} return setParameter(EnumUtils.findEnumFromString(transformerName,
InteGraalKeywords.Algorithms.Parameters.Chase.Transformer.class));
}
/**
* Sets the chase transformer by matching the input string to an enum @Override
* constant and then calling {@link #setParameter(Enum)}. public IAlgorithmParameters setTransformer(Transformer transformer) {
* return setParameter(transformer);
* @param transformerName the name of the transformer }
* @return this {@link IAlgorithmParameters} instance for method chaining
*/
public IAlgorithmParameters setTransformer(String transformerName) { /**
return setParameter(EnumUtils.findEnumFromString(transformerName, * Sets the compilation approach (e.g., "DEFAULT") by matching the input string
InteGraalKeywords.Algorithms.Parameters.Chase.Transformer.class)); * to an enum constant and then calling {@link #setParameter(Enum)}.
} *
* @param compilationName the name of the compilation type
@Override * @return this {@link IAlgorithmParameters} instance for method chaining
public IAlgorithmParameters setTransformer(Transformer transformer) { */
return setParameter(transformer); public IAlgorithmParameters setCompilation(String compilationName) {
} return setParameter(EnumUtils.findEnumFromString(compilationName,
InteGraalKeywords.Algorithms.Parameters.Compilation.class));
}
/**
* Sets the compilation approach (e.g., "DEFAULT") by matching the input string @Override
* to an enum constant and then calling {@link #setParameter(Enum)}. public IAlgorithmParameters setCompilation(Compilation compilation) {
* return setParameter(compilation);
* @param compilationName the name of the compilation type }
* @return this {@link IAlgorithmParameters} instance for method chaining
*/ /**
public IAlgorithmParameters setCompilation(String compilationName) { * Sets a DBMS driver parameter based on the provided parameter name and value.
return setParameter(EnumUtils.findEnumFromString(compilationName, * The parameter name is mapped to an enum instance of
InteGraalKeywords.Algorithms.Parameters.Compilation.class)); * {@link DBMSDriverParameters}, and then the appropriate field in this class is
} * updated.
*
@Override * @param paramName the name of the DBMS driver parameter, e.g., "URL" or
public IAlgorithmParameters setCompilation(Compilation compilation) { * "PORT"
return setParameter(compilation); * @param paramValue the value to set for the specified parameter
} * @throws IllegalArgumentException if {@code paramName} does not match any
* known {@link DBMSDriverParameters} value
/** * @see #setDBMSDriverParameters(DBMSDriverParameters, String)
* Sets a DBMS driver parameter based on the provided parameter name and value. */
* The parameter name is mapped to an enum instance of public void setDBMSDriverParameters(String paramName, String paramValue) {
* {@link DBMSDriverParameters}, and then the appropriate field in this class is setDBMSDriverParameters(EnumUtils.findEnumFromString(paramName, DBMSDriverParameters.class), paramValue);
* updated. }
*
* @param paramName the name of the DBMS driver parameter, e.g., "URL" or public void setGSATSolverParameters(String paramName, String paramValue) {
* "PORT" setGSATSolverParameters(EnumUtils.findEnumFromString(paramName, GSATSolverParameters.class), paramValue);
* @param paramValue the value to set for the specified parameter }
* @throws IllegalArgumentException if {@code paramName} does not match any
* known {@link DBMSDriverParameters} value
* @see #setDBMSDriverParameters(DBMSDriverParameters, String) @Override
*/ public IAlgorithmParameters setDBMSDriverParameters(DBMSDriverParameters paramName, String value) {
public void setDBMSDriverParameters(String paramName, String paramValue) { switch (paramName) {
setDBMSDriverParameters(EnumUtils.findEnumFromString(paramName, DBMSDriverParameters.class), paramValue); case DATABASE_NAME -> this.DBMSDriverParameters_DATABASE_NAME = value;
} case PORT -> this.DBMSDriverParameters_PORT = value;
case URL -> this.DBMSDriverParameters_URL = value;
@Override case USER_NAME -> this.DBMSDriverParameters_USER_NAME = value;
public IAlgorithmParameters setDBMSDriverParameters(DBMSDriverParameters paramName, String value) { case USER_PASSWORD -> this.DBMSDriverParameters_USER_PASSWORD = value;
switch (paramName) { case CLEAR_DB -> this.DBMSDriverParameters_CLEAR_DB = value;
case DATABASE_NAME -> this.DBMSDriverParameters_DATABASE_NAME = value; default -> throw new IllegalArgumentException("Unexpected parameter: " + paramName);
case PORT -> this.DBMSDriverParameters_PORT = value; }
case URL -> this.DBMSDriverParameters_URL = value; return this;
case USER_NAME -> this.DBMSDriverParameters_USER_NAME = value; }
case USER_PASSWORD -> this.DBMSDriverParameters_USER_PASSWORD = value;
case CLEAR_DB -> this.DBMSDriverParameters_CLEAR_DB = value;
default -> throw new IllegalArgumentException("Unexpected parameter: " + paramName); @Override
} public IAlgorithmParameters setGSATSolverParameters(GSATSolverParameters paramName, String value) {
return this; switch (paramName) {
} case SMART_SOLVER_TRESHOLD -> this.GSATSolverParameters_SMART_SOLVER_TRESHOLD = Integer.parseInt(value);
case MARCO_PATH_TO_EXECUTABLE -> this.GSATSolverParameters_MARCO_PATH_TO_EXECUTABLE = value;
///////////////////////////////////////// default -> throw new IllegalArgumentException("Unexpected parameter: " + paramName);
//// PRIVATE / HELPER METHODS }
///////////////////////////////////////// return this;
}
/**
* Iterates over the provided {@code params}, handling each based on its @Override
* category (enumeration, open parameter from an enumeration, or open public Optional<String> getMARCOPathToExecutable() {
* parameter). return Optional.ofNullable(this.GSATSolverParameters_MARCO_PATH_TO_EXECUTABLE);
* }
* @param params one or more {@link IGParameter} objects that define parameter
* names and values @Override
* @return {@code true} if all parameters were handled successfully; public IAlgorithmParameters setMARCOPathToExecutable(String pathtoExecutable) {
* {@code false} if an unrecognized parameter was encountered this.GSATSolverParameters_MARCO_PATH_TO_EXECUTABLE = pathtoExecutable;
*/ return this;
@SuppressWarnings("unchecked") }
private boolean setParams(IGParameter<InteGraalKeywords, ?>... params) {
for (var param : params) { /////////////////////////////////////////
switch (param.name()) { //// PRIVATE / HELPER METHODS
// enumeration with closed set of values /////////////////////////////////////////
case InteGraalKeywords k when k.isEnumeration() -> setParameter((Enum<?>) param.value());
/**
// open set of values, but defined within an enumeration (e.g., * Iterates over the provided {@code params}, handling each based on its
// DBConnectionParams) * category (enumeration, open parameter from an enumeration, or open
case InteGraalKeywords k when !k.isEnumeration() && k.getParentEnum().isPresent() -> * parameter).
setOpenParameterFromEnumeration(k.getParentEnum().get(), param.name().toString(), *
param.value().toString()); * @param params one or more {@link IGParameter} objects that define parameter
* names and values
// open set of values (e.g., Rank, Timeout) * @return {@code true} if all parameters were handled successfully;
case InteGraalKeywords k when !k.isEnumeration() && !k.getParentEnum().isPresent() -> * {@code false} if an unrecognized parameter was encountered
setOpenParameter(k, param.value()); */
@SuppressWarnings("unchecked")
default -> { private boolean setParams(IGParameter<InteGraalKeywords, ?>... params) {
LOG.error("Cannot handle parameter " + param); for (var param : params) {
return false; switch (param.name()) {
} // enumeration with closed set of values
} case InteGraalKeywords k when k.isEnumeration() -> setParameter((Enum<?>) param.value());
}
return true; // open set of values, but defined within an enumeration (e.g.,
} // DBConnectionParams)
case InteGraalKeywords k when !k.isEnumeration() && k.getParentEnum().isPresent() ->
/** setOpenParameterFromEnumeration(k.getParentEnum().get(), param.name().toString(),
* Sets the value of a parameter based on the provided enum constant. This param.value().toString());
* method uses reflection to dynamically identify and set the field within this
* class that corresponds to the enum type of the given constant. The field name // open set of values (e.g., Rank, Timeout)
* is expected to match the simple name of the enum's class, with the first case InteGraalKeywords k when !k.isEnumeration() && !k.getParentEnum().isPresent() ->
* letter lowercased (following Java naming conventions) setOpenParameter(k, param.value());
*
* @param enumValue The enum constant to set as the value of the corresponding default -> {
* field. The enum's class simple name (lowercased) should LOG.error("Cannot handle parameter " + param);
* match the name of the field in this class. return false;
* @throws RuntimeException If no matching field is found for the enum type, or }
* if an error occurs while attempting to set the }
* field's value. This includes cases where the field }
* is not accessible or if the field name does not return true;
* match the expected naming convention. }
* @see Field#setAccessible(boolean)
*/ /**
public IAlgorithmParameters setParameter(Enum<?> enumValue) { * Sets the value of a parameter based on the provided enum constant. This
LOG.debug("Setting parameter {} for {}", enumValue, this.name); * method uses reflection to dynamically identify and set the field within this
validateParameter(enumValue); * class that corresponds to the enum type of the given constant. The field name
String fieldName = enumValue.getClass().getSimpleName(); * is expected to match the simple name of the enum's class, with the first
try { * letter lowercased (following Java naming conventions)
Field field = null; *
for (Field f : this.getClass().getDeclaredFields()) { * @param enumValue The enum constant to set as the value of the corresponding
if (fieldName.equalsIgnoreCase(f.getName())) { * field. The enum's class simple name (lowercased) should
field = f; * match the name of the field in this class.
break; * @throws RuntimeException If no matching field is found for the enum type, or
} * if an error occurs while attempting to set the
} * field's value. This includes cases where the field
if (field == null) { * is not accessible or if the field name does not
LOG.error("Cannot set parameter {}", enumValue); * match the expected naming convention.
throw new RuntimeException( * @see Field#setAccessible(boolean)
String.format("[%s::setParameter] Cannot set parameter: %s.", this.getClass(), enumValue)); */
} else { public IAlgorithmParameters setParameter(Enum<?> enumValue) {
field.setAccessible(true); LOG.debug("Setting parameter {} for {}", enumValue, this.name);
field.set(this, enumValue); validateParameter(enumValue);
} String fieldName = enumValue.getClass().getSimpleName();
} catch (IllegalAccessException e) { try {
LOG.error("Failed to set parameter: {}\n{}", fieldName, e.getMessage()); Field field = null;
throw new RuntimeException( for (Field f : this.getClass().getDeclaredFields()) {
String.format("[%s::setParameter] Failed to set parameter: %s.", this.getClass(), fieldName), e); if (fieldName.equalsIgnoreCase(f.getName())) {
} field = f;
return this; break;
} }
}
/** if (field == null) {
* Sets an open parameter (defined within a known enumeration) by mapping the LOG.error("Cannot set parameter {}", enumValue);
* given {@code propertyName} to the appropriate enum constant in throw new RuntimeException(
* {@code className}, and assigning the provided {@code value}. String.format("[%s::setParameter] Cannot set parameter: %s.", this.getClass(), enumValue));
* <p> } else {
* Currently, this is primarily used for {@code DBMSDriverParameters}. field.setAccessible(true);
* </p> field.set(this, enumValue);
* }
* @param className the enum's class, e.g., } catch (IllegalAccessException e) {
* {@code DBMSDriverParameters.class} LOG.error("Failed to set parameter: {}\n{}", fieldName, e.getMessage());
* @param propertyName the name of the enum constant, e.g., "URL" or "USER_NAME" throw new RuntimeException(
* @param value the string value to assign to this parameter String.format("[%s::setParameter] Failed to set parameter: %s.", this.getClass(), fieldName), e);
* @return this {@link IAlgorithmParameters} instance for method chaining }
* @throws IllegalArgumentException if {@code propertyName} does not match any return this;
* known constant in {@code className} }
*/
public IAlgorithmParameters setOpenParameterFromEnumeration(Class<? extends Enum<?>> className, String propertyName, /**
String value) { * Sets an open parameter (defined within a known enumeration) by mapping the
LOG.debug("Setting parameter {} for {} with value {} for {} ", propertyName, className.getSimpleName(), value, * given {@code propertyName} to the appropriate enum constant in
this.name); * {@code className}, and assigning the provided {@code value}.
* <p>
switch (className.getSimpleName().toUpperCase()) { * Currently, this is primarily used for {@code DBMSDriverParameters}.
case "DBMSDRIVERPARAMETERS" -> setDBMSDriverParameters(propertyName, value); * </p>
default -> throw new IllegalArgumentException("Unexpected value: " + className); *
} * @param className the enum's class, e.g.,
return this; * {@code DBMSDriverParameters.class}
} * @param propertyName the name of the enum constant, e.g., "URL" or "USER_NAME"
* @param value the string value to assign to this parameter
/** * @return this {@link IAlgorithmParameters} instance for method chaining
* Similar to {@link #setOpenParameterFromEnumeration(Class, String, String)}, * @throws IllegalArgumentException if {@code propertyName} does not match any
* but takes an {@code enumName} instead of the enum {@code className}. This * known constant in {@code className}
* method is used to handle open parameters where the parent enumeration is */
* already determined. public IAlgorithmParameters setOpenParameterFromEnumeration(Class<? extends Enum<?>> className, String propertyName,
* String value) {
* @param enumName the enumeration constant representing the parameter LOG.debug("Setting parameter {} for {} with value {} for {} ", propertyName, className.getSimpleName(), value,
* category this.name);
* @param propertyName the name of the specific parameter within that category
* @param value the string value to assign to the parameter switch (className.getSimpleName().toUpperCase()) {
* @return this {@link IAlgorithmParameters} instance for method chaining case "DBMSDRIVERPARAMETERS" -> setDBMSDriverParameters(propertyName, value);
* @throws IllegalArgumentException if {@code propertyName} does not match any case "GSATSOLVERPARAMETERS" -> setGSATSolverParameters(propertyName, value);
* recognized constant for the given default -> throw new IllegalArgumentException("Unexpected value: " + className);
* {@code enumName} }
*/ return this;
public IAlgorithmParameters setOpenParameterFromEnumeration(Enum<?> enumName, String propertyName, String value) { }
LOG.debug("Setting parameter {} for {} with value {} for {} ", propertyName, enumName.name(), value, this.name);
/**
switch (enumName.name().toUpperCase()) { * Similar to {@link #setOpenParameterFromEnumeration(Class, String, String)},
case "DBMSDRIVERPARAMETERS" -> setDBMSDriverParameters(propertyName, value); * but takes an {@code enumName} instead of the enum {@code className}. This
default -> throw new IllegalArgumentException("Unexpected value: " + enumName); * method is used to handle open parameters where the parent enumeration is
} * already determined.
return this; *
} * @param enumName the enumeration constant representing the parameter
* category
/** * @param propertyName the name of the specific parameter within that category
* Sets an open parameter (one that is not tied to a closed enumeration of * @param value the string value to assign to the parameter
* values) by matching its name to one of the fields declared in this class. If * @return this {@link IAlgorithmParameters} instance for method chaining
* found, the field is updated with the provided {@code value}. * @throws IllegalArgumentException if {@code propertyName} does not match any
* * recognized constant for the given
* @param k the keyword representing the parameter name * {@code enumName}
* @param value the value to set (type {@code Object} because parameters can */
* vary) public IAlgorithmParameters setOpenParameterFromEnumeration(Enum<?> enumName, String propertyName, String value) {
* @return this {@link IAlgorithmParameters} instance for method chaining LOG.debug("Setting parameter {} for {} with value {} for {} ", propertyName, enumName.name(), value, this.name);
* @throws RuntimeException if the parameter field cannot be found or set
* @see Field#setAccessible(boolean) switch (enumName.name().toUpperCase()) {
*/ case "DBMSDRIVERPARAMETERS" -> setDBMSDriverParameters(propertyName, value);
public IAlgorithmParameters setOpenParameter(InteGraalKeywords k, Object value) { default -> throw new IllegalArgumentException("Unexpected value: " + enumName);
LOG.debug("Setting parameter {} with value {} for {}", k, value, this.name); }
String fieldName = k.name(); return this;
try { }
Field field = null;
for (Field f : this.getClass().getDeclaredFields()) { /**
if (fieldName.equalsIgnoreCase(f.getName())) { * Sets an open parameter (one that is not tied to a closed enumeration of
field = f; * values) by matching its name to one of the fields declared in this class. If
break; * found, the field is updated with the provided {@code value}.
} *
} * @param k the keyword representing the parameter name
if (field == null) { * @param value the value to set (type {@code Object} because parameters can
LOG.error("Cannot set parameter {}", k); * vary)
throw new RuntimeException( * @return this {@link IAlgorithmParameters} instance for method chaining
String.format("[%s::setParameter] Cannot set parameter: %s.", this.getClass(), value)); * @throws RuntimeException if the parameter field cannot be found or set
} else { * @see Field#setAccessible(boolean)
field.setAccessible(true); */
field.set(this, value); public IAlgorithmParameters setOpenParameter(InteGraalKeywords k, Object value) {
} LOG.debug("Setting parameter {} with value {} for {}", k, value, this.name);
} catch (IllegalAccessException e) { String fieldName = k.name();
LOG.error("Failed to set parameter: {}\n{}", k, e.getMessage()); try {
throw new RuntimeException( Field field = null;
String.format("[%s::setParameter] Failed to set parameter: %s.", this.getClass(), k), e); for (Field f : this.getClass().getDeclaredFields()) {
} if (fieldName.equalsIgnoreCase(f.getName())) {
return this; field = f;
} break;
}
/** }
* Validates whether the specified enum value is allowable based on the current if (field == null) {
* algorithm's capabilities. For example, chase parameters cannot be used with LOG.error("Cannot set parameter {}", k);
* an algorithm that does not support chase. throw new RuntimeException(
* String.format("[%s::setParameter] Cannot set parameter: %s.", this.getClass(), value));
* @param enumValue the enum constant to validate } else {
* @throws IllegalArgumentException if the enum value is incompatible with the field.setAccessible(true);
* current algorithm field.set(this, value);
*/ }
private void validateParameter(Enum<?> enumValue) { } catch (IllegalAccessException e) {
if (enumValue.getClass().getEnclosingClass() == InteGraalKeywords.Algorithms.Parameters.Chase.class LOG.error("Failed to set parameter: {}\n{}", k, e.getMessage());
&& !usesSaturationAlgorithm()) { throw new RuntimeException(
throw new IllegalArgumentException( String.format("[%s::setParameter] Failed to set parameter: %s.", this.getClass(), k), e);
"Chase parameter " + enumValue + " cannot be set for " + getAlgorithm() + " algorithms."); }
} return this;
}
if (enumValue.getClass().getEnclosingClass() == InteGraalKeywords.Algorithms.Parameters.Compilation.class
&& !usesRuleCompilationAlgorithm()) { /**
throw new IllegalArgumentException( * Validates whether the specified enum value is allowable based on the current
"Compilation parameter " + enumValue + " cannot be set for " + getAlgorithm() + " algorithms."); * algorithm's capabilities. For example, chase parameters cannot be used with
} * an algorithm that does not support chase.
*
if (enumValue.getClass().getEnclosingClass() == InteGraalKeywords.InternalStorageConfiguration.class * @param enumValue the enum constant to validate
&& !usesStorage()) { * @throws IllegalArgumentException if the enum value is incompatible with the
throw new IllegalArgumentException( * current algorithm
"Storage parameter " + enumValue + " cannot be set for " + getAlgorithm() + " algorithms."); */
} private void validateParameter(Enum<?> enumValue) {
} if (enumValue.getClass().getEnclosingClass() == InteGraalKeywords.Algorithms.Parameters.Chase.class
&& !usesSaturationAlgorithm()) {
private void initDefaultValues() { throw new IllegalArgumentException(
"Chase parameter " + enumValue + " cannot be set for " + getAlgorithm() + " algorithms.");
this.answers = Answers.SET; }
this.max = 1_000_000; if (enumValue.getClass().getEnclosingClass() == InteGraalKeywords.Algorithms.Parameters.Compilation.class
this.rank = 1_00_00; && !usesRuleCompilationAlgorithm()) {
this.timeout = Duration.ofHours(1); throw new IllegalArgumentException(
} "Compilation parameter " + enumValue + " cannot be set for " + getAlgorithm() + " algorithms.");
}
/////////////////////////////////////////
//// toString() if (enumValue.getClass().getEnclosingClass() == InteGraalKeywords.InternalStorageConfiguration.class
///////////////////////////////////////// && !usesStorage()) {
throw new IllegalArgumentException(
/** "Storage parameter " + enumValue + " cannot be set for " + getAlgorithm() + " algorithms.");
* Returns a string representation of this {@code AlgorithmParameters} object, }
* which includes key fields and values. }
*
* @return a string describing the fields in this class private void initDefaultValues() {
*/
public String toString() { this.answers = Answers.SET;
return StringUtils.print(this);
} this.max = 1_000_000;
this.rank = 1_00_00;
this.timeout = Duration.ofHours(1);
}
/////////////////////////////////////////
//// toString()
/////////////////////////////////////////
/**
* Returns a string representation of this {@code AlgorithmParameters} object,
* which includes key fields and values.
*
* @return a string describing the fields in this class
*/
public String toString() {
return StringUtils.print(this);
}
@Override
public Optional<Algorithms.Parameters.Explanation> getExplanation() {
return Optional.ofNullable(explanation);
}
@Override
public IAlgorithmParameters setExplanationCategory(Algorithms.Parameters.Explanation explanationCategory) {
this.explanation = explanationCategory;
return this;
}
@Override
public Optional<ExplainerSolver> getExplainerSolver() {
return Optional.ofNullable(explainerSolver);
}
@Override
public IAlgorithmParameters setExplainerSolver(ExplainerSolver solver) {
this.explainerSolver = solver;
return this;
}
@Override
public Optional<ExplanationSupportType> getExplanationSupportType() {
return Optional.ofNullable(explanationSupportType);
}
@Override
public IAlgorithmParameters setExplanationSupportType(ExplanationSupportType explanationSupportType) {
this.explanationSupportType = explanationSupportType;
return this;
}
@Override
public Optional<ExplainerVerbosity> getExplainerVerbosity() {
return Optional.ofNullable(this.explainerVerbosity);
}
@Override
public IAlgorithmParameters setExplainerVerbosity(ExplainerVerbosity verbosity) {
this.explainerVerbosity = verbosity;
return this;
}
@Override
public Optional<GraphOfRuleInstancesType> getGraphOfRuleInstancesType() {
return Optional.ofNullable(this.graphOfRuleInstancesType);
}
@Override
public IAlgorithmParameters setGraphOfRuleInstancesType(GraphOfRuleInstancesType griType) {
this.graphOfRuleInstancesType = griType;
return this;
}
@Override
public Optional<GraphOfRuleInstancesComputation> getGraphOfRuleInstancesComputation() {
return Optional.ofNullable(this.graphOfRuleInstancesComputation);
}
@Override
public IAlgorithmParameters setGraphOfRuleInstancesType(GraphOfRuleInstancesComputation griComputation) {
this.graphOfRuleInstancesComputation = griComputation;
return this;
}
@Override
public Optional<Integer> getGMUSSolverTreshold() {
return Optional.ofNullable(GSATSolverParameters_SMART_SOLVER_TRESHOLD);
}
@Override
public IAlgorithmParameters setGMUSSolverTreshold(int treshold) {
this.GSATSolverParameters_SMART_SOLVER_TRESHOLD = treshold;
return this;
}
} }
...@@ -40,6 +40,9 @@ public class InputDataScenario implements IInputDataScenario { ...@@ -40,6 +40,9 @@ public class InputDataScenario implements IInputDataScenario {
private MW<RuleBase> rulebase = new MW<>(null, false, "Rulebase"); private MW<RuleBase> rulebase = new MW<>(null, false, "Rulebase");
private MW<Collection<Query>> querybase = new MW<>(null, false, "Querybase"); private MW<Collection<Query>> querybase = new MW<>(null, false, "Querybase");
// this sets the prefix of the input query base to consider
private Integer strikeLenght;
// Hybrid RuleBase // Hybrid RuleBase
private MW<HybridRuleBase> hybridRulebase = new MW<>(null, false, "Hybrid Rulebase"); private MW<HybridRuleBase> hybridRulebase = new MW<>(null, false, "Hybrid Rulebase");
private MW<HybridRuleBaseFilePath> hybridRulebaseFilePath = new MW<>(null, false, "Hybrid Rulebase"); private MW<HybridRuleBaseFilePath> hybridRulebaseFilePath = new MW<>(null, false, "Hybrid Rulebase");
...@@ -123,6 +126,16 @@ public class InputDataScenario implements IInputDataScenario { ...@@ -123,6 +126,16 @@ public class InputDataScenario implements IInputDataScenario {
setBase(querybase, qb); setBase(querybase, qb);
} }
@Override
public void setStrikeLength(int value) {
this.strikeLenght = value;
}
@Override
public Optional<Integer> getStrikeLength() {
return Optional.ofNullable(this.strikeLenght);
}
@Override @Override
public void setQuerybasePaths(String... paths) { public void setQuerybasePaths(String... paths) {
setBasePaths(querybasePaths, paths, InteGraalKeywords.SupportedFileExtensions.Querybase.class); setBasePaths(querybasePaths, paths, InteGraalKeywords.SupportedFileExtensions.Querybase.class);
......
...@@ -11,7 +11,7 @@ import fr.lirmm.boreal.util.enumerations.EnumUtils; ...@@ -11,7 +11,7 @@ import fr.lirmm.boreal.util.enumerations.EnumUtils;
* Contains parameters for an InteGraal algorithm or service. * Contains parameters for an InteGraal algorithm or service.
*/ */
public interface IAlgorithmParameters extends IStorageParameters, IAnswerType, IForwardChainingParameters, public interface IAlgorithmParameters extends IStorageParameters, IAnswerType, IForwardChainingParameters,
IBackwardChainingParameters, IHybridReasoningParameters, IEnvironmentExecutionParameters { IBackwardChainingParameters, IHybridReasoningParameters, IEnvironmentExecutionParameters, IExplanationParameters {
/** /**
* @return a description of the algorithm configuration. * @return a description of the algorithm configuration.
......
package fr.boreal.component_builder.api.algorithm;
import fr.boreal.configuration.keywords.InteGraalKeywords;
import java.util.Optional;
/**
* Interface for compilation parameters.
*/
interface IExplanationParameters {
/*
* GRI COMPUTATION
*/
Optional<InteGraalKeywords.Algorithms.Parameters.Explanation> getExplanation();
IAlgorithmParameters setExplanationCategory(InteGraalKeywords.Algorithms.Parameters.Explanation explanationCategory);
/*
* SOLVER
*/
Optional<InteGraalKeywords.Algorithms.Parameters.Explanation.ExplainerSolver> getExplainerSolver();
IAlgorithmParameters setExplainerSolver(InteGraalKeywords.Algorithms.Parameters.Explanation.ExplainerSolver solver);
/*
* EXPLANATION TYPE
*/
Optional<InteGraalKeywords.Algorithms.Parameters.Explanation.ExplanationSupportType> getExplanationSupportType();
IAlgorithmParameters setExplanationSupportType(InteGraalKeywords.Algorithms.Parameters.Explanation.ExplanationSupportType explanationSupportType);
/*
* VERBOSITY
*/
Optional<InteGraalKeywords.Algorithms.Parameters.Explanation.ExplainerVerbosity> getExplainerVerbosity();
IAlgorithmParameters setExplainerVerbosity(InteGraalKeywords.Algorithms.Parameters.Explanation.ExplainerVerbosity verbosity);
/*
* GRI TYPE
*/
Optional<InteGraalKeywords.Algorithms.Parameters.Explanation.GraphOfRuleInstancesType> getGraphOfRuleInstancesType();
IAlgorithmParameters setGraphOfRuleInstancesType(InteGraalKeywords.Algorithms.Parameters.Explanation.GraphOfRuleInstancesType griType);
/*
* GRI COMPUTATION
*/
Optional<InteGraalKeywords.Algorithms.Parameters.Explanation.GraphOfRuleInstancesComputation> getGraphOfRuleInstancesComputation();
IAlgorithmParameters setGraphOfRuleInstancesType(InteGraalKeywords.Algorithms.Parameters.Explanation.GraphOfRuleInstancesComputation griComputation);
/*
* GMUS Smart Solver Treshold
*/
Optional<Integer> getGMUSSolverTreshold();
IAlgorithmParameters setGMUSSolverTreshold(int treshold);
/*
* GMUS MARCO Path to Executable
*/
Optional<String> getMARCOPathToExecutable();
IAlgorithmParameters setMARCOPathToExecutable(String pathToExecutable);
public IAlgorithmParameters setGSATSolverParameters(InteGraalKeywords.Algorithms.Parameters.Explanation.GSATSolverParameters paramName, String value) ;
}
\ No newline at end of file
...@@ -50,4 +50,14 @@ interface IQueryBaseScenario { ...@@ -50,4 +50,14 @@ interface IQueryBaseScenario {
default void setQuerybase(Query query) { default void setQuerybase(Query query) {
setQuerybase(Set.of(query)); setQuerybase(Set.of(query));
} }
/**
* Sets the lenght of the prefix of the query sequence to consider
* @param value
*/
void setStrikeLength(int value);
Optional<Integer> getStrikeLength();
} }
...@@ -89,11 +89,14 @@ public enum InteGraalKeywords { ...@@ -89,11 +89,14 @@ public enum InteGraalKeywords {
USER_PASSWORD(String.class, DBMSDRIVERPARAMETERS), USER_PASSWORD(String.class, DBMSDRIVERPARAMETERS),
CLEAR_DB(String.class, DBMSDRIVERPARAMETERS), CLEAR_DB(String.class, DBMSDRIVERPARAMETERS),
EXPLANATION(Algorithms.Parameters.Explanation.class),
EXPLAINER_VERBOSITY(Algorithms.Parameters.Explanation.ExplainerVerbosity.class), EXPLAINER_VERBOSITY(Algorithms.Parameters.Explanation.ExplainerVerbosity.class),
EXPLAINER_SOLVER(Algorithms.Parameters.Explanation.ExplainerSolver.class), EXPLAINER_SOLVER(Algorithms.Parameters.Explanation.ExplainerSolver.class),
EXPLAINER_TYPE(Algorithms.Parameters.Explanation.ExplainerType.class), EXPLAINER_GRI_COMPUTATION(Algorithms.Parameters.Explanation.GraphOfRuleInstancesComputation.class),
EXPLANATION_TYPE(Algorithms.Parameters.Explanation.ExplanationType.class); EXPLAINER_GRI_TYPE(Algorithms.Parameters.Explanation.GraphOfRuleInstancesType.class),
EXPLANATION_SUPPORT_TYPE(Algorithms.Parameters.Explanation.ExplanationSupportType.class),
EXPLANATION_GMUS_SOLVER_TREHSOLD(Integer.class),
EXPLANATION_MARCO_PATH_EXECUTBLE(String.class);
// TODO Les paramètres peuvent-ils être partagés par les différents services ? // TODO Les paramètres peuvent-ils être partagés par les différents services ?
// Comment indiquer les valeurs autorisés d'un paramètre (cf. code ci-après) ? // Comment indiquer les valeurs autorisés d'un paramètre (cf. code ci-après) ?
...@@ -273,7 +276,12 @@ public enum InteGraalKeywords { ...@@ -273,7 +276,12 @@ public enum InteGraalKeywords {
/** /**
* CSV Rules Encoding * CSV Rules Encoding
*/ */
CSV_RLS_ENCODING; CSV_RLS_ENCODING,
/**
* Checks only that the inputs are valid
*/
CHECK_INPUTS_ONLY;
;
/** /**
* Specifies types of answers in InteGraal algorithms. * Specifies types of answers in InteGraal algorithms.
...@@ -566,7 +574,15 @@ public enum InteGraalKeywords { ...@@ -566,7 +574,15 @@ public enum InteGraalKeywords {
*/ */
public enum Explanation { public enum Explanation {
EXPLANATION; /**
* To compute minimal subsets of a KB
*/
MINIMAL_SUBSET_EXPLANATION,
/**
* To compute supports for proof trees
*/
PROVENANCE;
public enum ExplainerVerbosity { public enum ExplainerVerbosity {
/** /**
...@@ -576,7 +592,11 @@ public enum InteGraalKeywords { ...@@ -576,7 +592,11 @@ public enum InteGraalKeywords {
/** /**
* Runs the protocol and details inner steps within the static and dynamic steps * Runs the protocol and details inner steps within the static and dynamic steps
*/ */
DETAILED DETAILED,
/**
* Runs the protocol and gives the explanation time for the whole set of queries
*/
ALL_QUERY_WORKLOAD
} }
public enum ExplainerSolver { public enum ExplainerSolver {
...@@ -587,10 +607,27 @@ public enum InteGraalKeywords { ...@@ -587,10 +607,27 @@ public enum InteGraalKeywords {
/** /**
* Uses SAT4J as a GMUS solver for the explainer * Uses SAT4J as a GMUS solver for the explainer
*/ */
SAT4J SAT4J,
/**
* Uses SAT4J for small formulas and MARCO for larger formulas
*/
SMART_GSAT_SOLVER
} }
public enum ExplainerType { public enum GSATSolverParameters {
/**
* Threshold. Above use SAT4J. Below use MARCO
*/
SMART_SOLVER_TRESHOLD,
/**
* Path to marco.py in the sysmte
*/
MARCO_PATH_TO_EXECUTABLE
}
public enum GraphOfRuleInstancesComputation {
/** /**
* Uses an explainer that will compute the whole GRI first * Uses an explainer that will compute the whole GRI first
*/ */
...@@ -601,7 +638,7 @@ public enum InteGraalKeywords { ...@@ -601,7 +638,7 @@ public enum InteGraalKeywords {
INCREMENTAL_GRI INCREMENTAL_GRI
} }
public enum ExplanationType { public enum ExplanationSupportType {
/** /**
* The explainer will provide explanations that contain both facts and rules * The explainer will provide explanations that contain both facts and rules
*/ */
...@@ -615,6 +652,18 @@ public enum InteGraalKeywords { ...@@ -615,6 +652,18 @@ public enum InteGraalKeywords {
*/ */
RULE_SUPPORT RULE_SUPPORT
} }
public enum GraphOfRuleInstancesType {
/**
* Computes the GRI with rules and stores it into a KB
*/
KB_GRI,
/**
* Computes the GRI with an ad-hoc structure
*/
TRACKER
}
} }
} }
......
package fr.boreal.configuration.parameters; package fr.boreal.configuration.parameters;
import java.time.Duration;
import fr.boreal.configuration.keywords.InteGraalKeywords; import fr.boreal.configuration.keywords.InteGraalKeywords;
import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms; import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms;
import java.time.Duration;
public class IGParameterValueExtractor { public class IGParameterValueExtractor {
/** /**
* * @param params
* @param params * @return the first occurrence of a timeout in the params
* @return the first occurrence of a timeout in the params */
*/ public static Duration getTimeout(IGParameter<InteGraalKeywords, ?>... params) {
public static Duration getTimeout(IGParameter<InteGraalKeywords, ?>... params) {
return (Duration) search(params, InteGraalKeywords.TIMEOUT);
}
/**
* @param params
* @return the first occurrence of a rank in the params
*/
public static Integer getRank(IGParameter<InteGraalKeywords, ?>... params) {
return (Integer) search(params, InteGraalKeywords.RANK);
}
return (Duration) search(params, InteGraalKeywords.TIMEOUT); /**
* @param params
* @return the first occurrence of a max in the params
*/
public static Integer getMax(IGParameter<InteGraalKeywords, ?>... params) {
} return (Integer) search(params, InteGraalKeywords.MAX);
/** }
*
* @param params
* @return the first occurrence of a rank in the params
*/
public static Integer getRank(IGParameter<InteGraalKeywords, ?>... params) {
return (Integer) search(params, InteGraalKeywords.RANK); /**
* @param params
* @return the first occurrence of the type of query image in the params
*/
public static Algorithms.Images getImage(IGParameter<InteGraalKeywords, ?>... params) {
} return (Algorithms.Images) search(params, InteGraalKeywords.IMAGES);
/** }
*
* @param params
* @return the first occurrence of a max in the params
*/
public static Integer getMax(IGParameter<InteGraalKeywords, ?>... params) {
return (Integer) search(params, InteGraalKeywords.MAX); /**
* @param params
* @return returns true if the image type is not explicitly set as ALL
*/
public static boolean onlyConstants(IGParameter<InteGraalKeywords, ?>... params) {
} return !getImage(params).equals(InteGraalKeywords.Algorithms.Images.ALL);
/** }
*
* @param params
* @return the first occurrence of the type of query image in the params
*/
public static Algorithms.Images getImage(IGParameter<InteGraalKeywords, ?>... params) {
return (Algorithms.Images) search(params, InteGraalKeywords.IMAGES); private static Object search(IGParameter<InteGraalKeywords, ?>[] params, InteGraalKeywords name) {
for (var p : params) {
if (p.name().equals(name)) {
return p.value();
}
}
return null;
}
} public static InteGraalKeywords.Algorithms.Parameters.HybridTypes getHybridType(IGParameter<InteGraalKeywords, ?>[] params) {
return (InteGraalKeywords.Algorithms.Parameters.HybridTypes) search(params, InteGraalKeywords.HYBRIDTYPES);
}
/** public static Algorithms.Parameters.Explanation.ExplainerVerbosity explainerVerbosity(IGParameter<InteGraalKeywords, ?>[] params) {
* return (Algorithms.Parameters.Explanation.ExplainerVerbosity) search(params, InteGraalKeywords.EXPLAINER_VERBOSITY);
* @param params }
* @return returns true if the image type is not explicitly set as ALL
*/
public static boolean onlyConstants(IGParameter<InteGraalKeywords, ?>... params) {
return !getImage(params).equals(InteGraalKeywords.Algorithms.Images.ALL); public static Algorithms.Parameters.Explanation.ExplainerSolver getExplainerSolver(IGParameter<InteGraalKeywords, ?>... params) {
return (Algorithms.Parameters.Explanation.ExplainerSolver) search(params, InteGraalKeywords.EXPLAINER_SOLVER);
}
} public static Algorithms.Parameters.Explanation.GraphOfRuleInstancesComputation getGRIComputation(IGParameter<InteGraalKeywords, ?>... params) {
return (Algorithms.Parameters.Explanation.GraphOfRuleInstancesComputation) search(params, InteGraalKeywords.EXPLAINER_GRI_COMPUTATION);
}
private static Object search(IGParameter<InteGraalKeywords, ?>[] params, InteGraalKeywords name) { public static Algorithms.Parameters.Explanation.GraphOfRuleInstancesType getGRIType(IGParameter<InteGraalKeywords, ?>... params) {
for (var p : params) { return (Algorithms.Parameters.Explanation.GraphOfRuleInstancesType) search(params, InteGraalKeywords.EXPLAINER_GRI_TYPE);
if (p.name().equals(name)) { }
return p.value();
}
}
return null;
}
public static InteGraalKeywords.Algorithms.Parameters.HybridTypes getHybridType( public static Algorithms.Parameters.Explanation.ExplanationSupportType getExplanationSupportType(IGParameter<InteGraalKeywords, ?>... params) {
IGParameter<InteGraalKeywords, ?>[] params) { return (Algorithms.Parameters.Explanation.ExplanationSupportType) search(params, InteGraalKeywords.EXPLANATION_SUPPORT_TYPE);
}
return (InteGraalKeywords.Algorithms.Parameters.HybridTypes) search(params, InteGraalKeywords.HYBRIDTYPES);
public static Algorithms.Parameters.Explanation getExplanation(IGParameter<InteGraalKeywords, ?>... params) {
return (Algorithms.Parameters.Explanation) search(params, InteGraalKeywords.EXPLANATION);
}
} public static Algorithms.Parameters.Explanation getGMUSSolverTreshold(IGParameter<InteGraalKeywords, ?>... params) {
return (Algorithms.Parameters.Explanation) search(params, InteGraalKeywords.EXPLANATION_GMUS_SOLVER_TREHSOLD);
}
} }
package fr.boreal.explanation.api.builder;
import fr.boreal.configuration.keywords.InteGraalKeywords;
import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Explanation;
import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Explanation.ExplainerSolver;
import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Explanation.ExplanationSupportType;
import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Explanation.GraphOfRuleInstancesComputation;
import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Explanation.GraphOfRuleInstancesType;
import fr.boreal.configuration.parameters.IGParameter;
import fr.boreal.explanation.api.explainers.AtomicQueryExplainer;
import fr.boreal.explanation.api.solver.Solver;
import fr.boreal.explanation.kb_gri.explainers.incremental_gri.FactSupportExplainer_IncrementalKBGRI;
import fr.boreal.explanation.kb_gri.explainers.incremental_gri.KBSupportExplainer_IncrementalKBGRI;
import fr.boreal.explanation.kb_gri.explainers.incremental_gri.RuleSupportExplainer_IncrementalKBGRI;
import fr.boreal.explanation.kb_gri.explainers.static_gri.FactSupportExplainer_KBGRI;
import fr.boreal.explanation.kb_gri.explainers.static_gri.KBSupportExplainer_KBGRI;
import fr.boreal.explanation.kb_gri.explainers.static_gri.RuleSupportExplainer_KBGRI;
import fr.boreal.explanation.solving_enumerating.hybrid.HybridSAT4JMARCOSolver;
import fr.boreal.explanation.solving_enumerating.marco.MARCOGMUSSolver;
import fr.boreal.explanation.solving_enumerating.marco.MARCOParameters;
import fr.boreal.explanation.solving_enumerating.sat4j.Sat4JSolver;
import fr.boreal.explanation.tracker_gri.explainers.FactSupportExplainer_TrackerGRI;
import fr.boreal.explanation.tracker_gri.explainers.KBSupportExplainer_TrackerGRI;
import fr.boreal.explanation.tracker_gri.explainers.RuleSupportExplainer_TrackerGRI;
import fr.boreal.explanation.tracker_gri.explainers.UnambiguousProofTreeWhyProvenanceExplainer_TrackerGRI;
import fr.boreal.explanation.tracker_gri.explainers.incremental_tracker.FactSupportExplainer_IncrementalTrackerGRI;
import fr.boreal.explanation.tracker_gri.explainers.incremental_tracker.KBSupportExplainer_IncrementalTrackerGRI;
import fr.boreal.explanation.tracker_gri.explainers.incremental_tracker.RuleSupportExplainer_IncrementalTrackerGRI;
import fr.boreal.model.kb.api.FactBase;
import fr.boreal.model.kb.api.KnowledgeBase;
import fr.boreal.model.kb.api.RuleBase;
import java.util.Collection;
import java.util.Objects;
import static fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Explanation.ExplainerSolver.SAT4J;
import static fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Explanation.ExplanationSupportType.KB_SUPPORT;
import static fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Explanation.GraphOfRuleInstancesComputation.INCREMENTAL_GRI;
import static fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Explanation.GraphOfRuleInstancesType.KB_GRI;
import static fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Explanation.MINIMAL_SUBSET_EXPLANATION;
/**
* Builder/factory able to instantiate an {@link AtomicQueryExplainer} from the given list of parameters below
*/
public final class AtomicQueryExplainerBuilder {
/* params */
private Explanation explanation = MINIMAL_SUBSET_EXPLANATION;
private ExplainerSolver solverParam = SAT4J;
private GraphOfRuleInstancesComputation griComputationParam = INCREMENTAL_GRI;
private GraphOfRuleInstancesType griTypeParam = KB_GRI;
private ExplanationSupportType supportTypeParam = KB_SUPPORT;
private Integer solverTreshold;
private String pathToMARCOExecutable;
// instances
private Solver solverInstance;
private KnowledgeBase kbInstance;
private boolean externallySetSolver = false;
/* -------------------------------------------------------------------------------------- */
public AtomicQueryExplainerBuilder apply(KnowledgeBase kb, Collection<IGParameter<InteGraalKeywords, ?>> params) {
Objects.requireNonNull(kb, "kb is null, cannot build the explainer");
this.kbInstance = kb;
for (IGParameter<InteGraalKeywords, ?> p : params) {
switch (p.name()) {
case EXPLANATION -> this.explanation = (Explanation) p.value();
case EXPLAINER_SOLVER -> this.solverParam = (ExplainerSolver) p.value();
case EXPLAINER_GRI_COMPUTATION ->
this.griComputationParam = (GraphOfRuleInstancesComputation) p.value();
case EXPLAINER_GRI_TYPE -> this.griTypeParam = (GraphOfRuleInstancesType) p.value();
case EXPLANATION_SUPPORT_TYPE -> this.supportTypeParam = (ExplanationSupportType) p.value();
case EXPLANATION_GMUS_SOLVER_TREHSOLD -> this.solverTreshold = (Integer) p.value();
case EXPLANATION_MARCO_PATH_EXECUTBLE -> this.pathToMARCOExecutable = (String) p.value();
default -> { /* ignored – may belong to another component */}
}
}
return this;
}
public void withSolver(Solver solver) {
Objects.requireNonNull(solver, "cannot use this method with a null solver");
this.solverInstance = solver;
this.externallySetSolver = true;
}
/**
* Convenience one‑shot creation
*/
public static AtomicQueryExplainer<?> from(KnowledgeBase kb, Collection<IGParameter<InteGraalKeywords, ?>> params) {
return new AtomicQueryExplainerBuilder().apply(kb, params).build();
}
/**
* Builds an {@link AtomicQueryExplainer} implementation whose nature depends on the
* {@code EXPLANATION_SUPPORT_TYPE} parameter (defaults to {@code KB_SUPPORT}).
*/
public AtomicQueryExplainer<?> build() {
return switch (explanation) {
case MINIMAL_SUBSET_EXPLANATION -> buildMinimalSubsetExplainer();
case PROVENANCE -> buildProvenanceExplainer();
};
}
private AtomicQueryExplainer<?> buildProvenanceExplainer() {
return new UnambiguousProofTreeWhyProvenanceExplainer_TrackerGRI(kbInstance);
}
private AtomicQueryExplainer<?> buildMinimalSubsetExplainer() {
buildSolver();
return switch (supportTypeParam) {
case KB_SUPPORT -> buildKbSupportAtomicQueryExplainer();
case FACT_SUPPORT -> buildFactSupportAtomicQueryExplainer();
case RULE_SUPPORT -> buildRuleSupportAtomicQueryExplainer();
};
}
private void buildSolver() {
if (externallySetSolver) {
return;
}
this.solverInstance = switch (this.solverParam) {
case MARCO -> {
if (this.pathToMARCOExecutable != null) {
MARCOParameters.setPathToMarcoExecutable(this.pathToMARCOExecutable);
yield new MARCOGMUSSolver();
} else {
yield new MARCOGMUSSolver();
}
}
case SAT4J -> new Sat4JSolver();
case SMART_GSAT_SOLVER -> {
if (this.solverTreshold != null && this.solverTreshold > 0) {
if (this.pathToMARCOExecutable != null) {
yield new HybridSAT4JMARCOSolver(this.solverTreshold, this.pathToMARCOExecutable);
} else {
yield new HybridSAT4JMARCOSolver(this.solverTreshold);
}
} else {
yield new HybridSAT4JMARCOSolver();
}
}
};
}
private AtomicQueryExplainer<KnowledgeBase> buildKbSupportAtomicQueryExplainer() {
return
switch (this.griTypeParam) {
case KB_GRI -> createExplainerForKB_GRI();
case TRACKER -> createExplainerForKB_Tracker_GRI();
};
}
private AtomicQueryExplainer<FactBase> buildFactSupportAtomicQueryExplainer() {
return
switch (this.griTypeParam) {
case KB_GRI -> createExplainerForFB_GRI();
case TRACKER -> createExplainerForFB_Tracker_GRI();
};
}
private AtomicQueryExplainer<RuleBase> buildRuleSupportAtomicQueryExplainer() {
return
switch (this.griTypeParam) {
case KB_GRI -> createExplainerForRB_GRI();
case TRACKER -> createExplainerForRB_Tracker_GRI();
};
}
private AtomicQueryExplainer<KnowledgeBase> createExplainerForKB_GRI() {
return switch (this.griComputationParam) {
case STATIC_GRI -> new KBSupportExplainer_KBGRI(kbInstance, solverInstance);
case INCREMENTAL_GRI -> new KBSupportExplainer_IncrementalKBGRI(kbInstance, solverInstance);
};
}
private AtomicQueryExplainer<FactBase> createExplainerForFB_GRI() {
return switch (this.griComputationParam) {
case STATIC_GRI -> new FactSupportExplainer_KBGRI(kbInstance, solverInstance);
case INCREMENTAL_GRI -> new FactSupportExplainer_IncrementalKBGRI(kbInstance, solverInstance);
};
}
private AtomicQueryExplainer<RuleBase> createExplainerForRB_GRI() {
return switch (this.griComputationParam) {
case STATIC_GRI -> new RuleSupportExplainer_KBGRI(kbInstance, solverInstance);
case INCREMENTAL_GRI -> new RuleSupportExplainer_IncrementalKBGRI(kbInstance, solverInstance);
};
}
private AtomicQueryExplainer<KnowledgeBase> createExplainerForKB_Tracker_GRI() {
return switch (this.griComputationParam) {
case STATIC_GRI -> new KBSupportExplainer_TrackerGRI(kbInstance, solverInstance);
case INCREMENTAL_GRI -> new KBSupportExplainer_IncrementalTrackerGRI(kbInstance, solverInstance);
};
}
private AtomicQueryExplainer<FactBase> createExplainerForFB_Tracker_GRI() {
return switch (this.griComputationParam) {
case STATIC_GRI -> new FactSupportExplainer_TrackerGRI(kbInstance, solverInstance);
case INCREMENTAL_GRI -> new FactSupportExplainer_IncrementalTrackerGRI(kbInstance, solverInstance);
};
}
private AtomicQueryExplainer<RuleBase> createExplainerForRB_Tracker_GRI() {
return switch (this.griComputationParam) {
case STATIC_GRI -> new RuleSupportExplainer_TrackerGRI(kbInstance, solverInstance);
case INCREMENTAL_GRI -> new RuleSupportExplainer_IncrementalTrackerGRI(kbInstance, solverInstance);
};
}
}
package fr.boreal.explanation.api.explainers; package fr.boreal.explanation.api.explainers;
import fr.boreal.model.logicalElements.api.Atom;
import java.util.Iterator; import java.util.Iterator;
import java.util.Set; import java.util.Set;
/** /**
* Interface for an explainer * Interface for an explainer
* *
* @param <ExplanationType> the type of the (set of) explanations which is returned by the enumerator * @param <ExplanationType> the type of the (set of) explanations which is returned by the enumerator
* @param <QueryType> the type of the query * @param <QueryType> the type of the query
* @param <ExplanationContext> the context to use for finding explanations (eg. a knowledge base, a factbase, a rulebase) * @param <ExplanationContext> the context to use for finding explanations (eg. a knowledge base, a factbase, a rulebase)
*/ */
public interface QueryExplainer<ExplanationType, QueryType, ExplanationContext> { public interface QueryExplainer<ExplanationType, QueryType, ExplanationContext> {
...@@ -35,4 +37,15 @@ public interface QueryExplainer<ExplanationType, QueryType, ExplanationContext> ...@@ -35,4 +37,15 @@ public interface QueryExplainer<ExplanationType, QueryType, ExplanationContext>
*/ */
boolean canExplain(ExplanationContext context, QueryType query); boolean canExplain(ExplanationContext context, QueryType query);
/**
* @return true iff the query to explain is entailed by the KB
*/
boolean isQueryEntailed(Atom query);
;
/**
* @return true iff the query to explain is part of the input factbase
*/
boolean isQueryInInitialFB(Atom query) ;
} }
...@@ -4,11 +4,10 @@ import fr.boreal.forward_chaining.chase.Chase; ...@@ -4,11 +4,10 @@ import fr.boreal.forward_chaining.chase.Chase;
import fr.boreal.forward_chaining.chase.ChaseBuilder; import fr.boreal.forward_chaining.chase.ChaseBuilder;
import fr.boreal.forward_chaining.chase.lineage.LineageTracker; import fr.boreal.forward_chaining.chase.lineage.LineageTracker;
import fr.boreal.forward_chaining.chase.rule_applier.trigger_applier.facts_handler.DelegatedApplication; import fr.boreal.forward_chaining.chase.rule_applier.trigger_applier.facts_handler.DelegatedApplication;
import fr.boreal.forward_chaining.chase.rule_applier.trigger_applier.tracking.TriggerApplierWithTrackerImpl;
import fr.boreal.forward_chaining.chase.rule_applier.trigger_applier.facts_handler.DirectApplication;
import fr.boreal.forward_chaining.chase.rule_applier.trigger_applier.renamer.FreshRenamer; import fr.boreal.forward_chaining.chase.rule_applier.trigger_applier.renamer.FreshRenamer;
import fr.boreal.model.kb.api.KnowledgeBase; import fr.boreal.forward_chaining.chase.rule_applier.trigger_applier.tracking.TriggerApplierWithTrackerImpl;
import fr.boreal.model.kb.api.FactBase; import fr.boreal.model.kb.api.FactBase;
import fr.boreal.model.kb.api.KnowledgeBase;
import fr.boreal.model.kb.api.RuleBase; import fr.boreal.model.kb.api.RuleBase;
import fr.boreal.model.logicalElements.factory.impl.SameObjectTermFactory; import fr.boreal.model.logicalElements.factory.impl.SameObjectTermFactory;
...@@ -51,16 +50,31 @@ public class DefaultChaseForExplanations { ...@@ -51,16 +50,31 @@ public class DefaultChaseForExplanations {
.setTriggerApplier(triggerTracker) .setTriggerApplier(triggerTracker)
.useObliviousChecker() .useObliviousChecker()
.useNaiveComputer() .useNaiveComputer()
.useNaiveRuleScheduler() .useByPredicateRuleScheduler()
.useAllTransformer()
.build().get();
chase.execute();
return new TrackingChase(chase, triggerTracker.getTracker());
}
public static void incrementalChaseWithTracker(LineageTracker triggerTracker, FactBase fb, RuleBase rb) {
var applierWithFixedTracker = new TriggerApplierWithTrackerImpl(new FreshRenamer(SameObjectTermFactory.instance()), new DelegatedApplication(), triggerTracker);
Chase chase = ChaseBuilder.defaultBuilder(fb, rb)
.setTriggerApplier(applierWithFixedTracker)
.useObliviousChecker()
.useNaiveComputer()
.useByPredicateRuleScheduler()
.useAllTransformer() .useAllTransformer()
.build().get(); .build().get();
chase.execute(); chase.execute();
return new TrackingChase(chase,triggerTracker.getTracker());
} }
public static TrackingChase chaseForTracker(KnowledgeBase kb) { public static TrackingChase chaseForTracker(KnowledgeBase kb) {
return chaseForTracker(kb.getFactBase(), kb.getRuleBase()); return chaseForTracker(kb.getFactBase(), kb.getRuleBase());
} }
public record TrackingChase(Chase chase, LineageTracker tracker){} public record TrackingChase(Chase chase, LineageTracker tracker) {
}
} }
...@@ -15,4 +15,14 @@ public class PathFinder { ...@@ -15,4 +15,14 @@ public class PathFinder {
} }
} }
public static String ensureFilePath(String... paths) {
for (String p : paths) {
if (p != null && new File(p).exists()) {
return p;
}
}
throw new IllegalStateException(
"None of the provided paths exists: " + String.join(", ", paths));
}
} }
...@@ -3,10 +3,7 @@ package fr.boreal.explanation.configuration; ...@@ -3,10 +3,7 @@ package fr.boreal.explanation.configuration;
import com.opencsv.CSVWriter; import com.opencsv.CSVWriter;
import fr.boreal.model.kb.api.KnowledgeBase; import fr.boreal.model.kb.api.KnowledgeBase;
import java.io.ByteArrayOutputStream; import java.io.*;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.*; import java.util.*;
...@@ -312,6 +309,80 @@ public class StatsUtil { ...@@ -312,6 +309,80 @@ public class StatsUtil {
datasetOrder.add(datasetName); datasetOrder.add(datasetName);
} }
// public static void recordGCNFsize(
// File gcnffile,
// String queryNb,
// String explainerName,
// String operation,
// String datasetName
// ) {
// try (BufferedReader reader = new BufferedReader(new FileReader(file, StandardCharsets.UTF_8))) {
// String line;
// Pattern p = Pattern.compile("^p\\s+gcnf\\s+(\\d+)\\s+(\\d+)\\s+(\\d+).*$");
// while ((line = reader.readLine()) != null) {
// Matcher m = p.matcher(line.trim());
// if (m.matches()) {
// int vars = Integer.parseInt(m.group(1));
// int nb_clauses = Integer.parseInt(m.group(2));
// int clauses= Integer.parseInt(m.group(3));
// }
// }
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
// throw new IllegalArgumentException(
// "No valid 'p gcnf V G C' header found in " + file.getPath()
// );
// }
//
// // 2) Run the function (it prints its own stats to stdout)
// long startTime = System.currentTimeMillis();
// function.run();
// long elapsedTime = System.currentTimeMillis() - startTime;
//
// // 3) Restore stdout
// System.out.flush();
// System.setOut(oldOut);
//
// // 4) Extract the captured text
// String stdout = baos.toString(StandardCharsets.UTF_8);
//
// // 5) Parse the first “total : X.XXX” line
// double totalSeconds = parseTotalSeconds(stdout);
//
// // 6) Convert to milliseconds (long)
// long totalMs = Math.round(totalSeconds * 1000);
//
//
// System.out.printf("[Dataset=%s, %s] %s took %d ms (system call time %d ms) %n",
// datasetName, queryNb, operation, totalMs, elapsedTime);
//
// // comparator for the query order
// Comparator<String> comp = (s1, s2) -> {
// Pattern p = Pattern.compile("^Q(\\d+)(.*)$");
// Matcher m1 = p.matcher(s1), m2 = p.matcher(s2);
//
// if (m1.matches() && m2.matches()) {
// int n1 = Integer.parseInt(m1.group(1));
// int n2 = Integer.parseInt(m2.group(1));
// if (n1 != n2) return Integer.compare(n1, n2);
// return m1.group(2).compareTo(m2.group(2));
// }
// return s1.compareTo(s2);
// };
//
// timingRecordsByQuery.computeIfAbsent(datasetName, k -> new TreeMap<>(comp))
// .computeIfAbsent(queryNb, k -> new TreeMap<>())
// .computeIfAbsent(explainerName, k -> new TreeMap<>())
// .put(operation, totalMs);
//
// operationOrder
// .computeIfAbsent(explainerName, k -> new LinkedHashSet<>())
// .add(operation);
//
// datasetOrder.add(datasetName);
// }
public static void timerMarcoOrderedQueries( public static void timerMarcoOrderedQueries(
Runnable function, Runnable function,
String queryNb, String queryNb,
......
package fr.boreal.explanation.configuration.query_selection; package fr.boreal.explanation.configuration.query_selection;
import fr.boreal.explanation.util.InternalDLGPWriter;
import fr.boreal.forward_chaining.chase.Chase; import fr.boreal.forward_chaining.chase.Chase;
import fr.boreal.forward_chaining.chase.ChaseBuilder; import fr.boreal.forward_chaining.chase.ChaseBuilder;
import fr.boreal.model.kb.api.FactBase; import fr.boreal.model.kb.api.FactBase;
...@@ -7,14 +8,18 @@ import fr.boreal.model.kb.api.KnowledgeBase; ...@@ -7,14 +8,18 @@ import fr.boreal.model.kb.api.KnowledgeBase;
import fr.boreal.model.kb.api.RuleBase; import fr.boreal.model.kb.api.RuleBase;
import fr.boreal.model.kb.impl.RuleBaseImpl; import fr.boreal.model.kb.impl.RuleBaseImpl;
import fr.boreal.model.logicalElements.api.Atom; import fr.boreal.model.logicalElements.api.Atom;
import fr.boreal.model.logicalElements.api.Term;
import fr.boreal.model.rule.api.FORule; import fr.boreal.model.rule.api.FORule;
import fr.boreal.storage.natives.SimpleInMemoryGraphStore; import fr.boreal.storage.natives.SimpleInMemoryGraphStore;
import java.io.File;
import java.io.IOException;
import java.util.*; import java.util.*;
import java.util.Collections; import java.util.Collections;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class QuerySelector { public class QuerySelector {
static String benchPath = "integraal-explanation/src/test/resources/ruleml24/";
private static final Random RANDOM = new Random(); private static final Random RANDOM = new Random();
...@@ -44,6 +49,9 @@ public class QuerySelector { ...@@ -44,6 +49,9 @@ public class QuerySelector {
.getLastStepResults() .getLastStepResults()
.created_facts_as_factbase() .created_facts_as_factbase()
.getAtoms() .getAtoms()
.filter(a -> !a.getPredicate().label().startsWith("constant"))
.filter(a -> !a.getPredicate().label().startsWith("owl:Thing"))
.filter(a -> Arrays.stream(a.getTerms()).noneMatch(Term::isVariable))
.collect(Collectors.toList()); .collect(Collectors.toList());
if (!factsProduced.isEmpty()) { if (!factsProduced.isEmpty()) {
...@@ -62,7 +70,7 @@ public class QuerySelector { ...@@ -62,7 +70,7 @@ public class QuerySelector {
} }
public static List<Atom> selectQueriesFromQueryFile(KnowledgeBase kb, int nbQueries) { public static List<Atom> selectQueriesFromQueryFile(KnowledgeBase kb, int nbQueries) throws IOException {
Collection<FORule> rules = new ArrayList<FORule>(kb.getRuleBase().getRules()); Collection<FORule> rules = new ArrayList<FORule>(kb.getRuleBase().getRules());
RuleBase rb = new RuleBaseImpl(rules); RuleBase rb = new RuleBaseImpl(rules);
...@@ -88,6 +96,10 @@ public class QuerySelector { ...@@ -88,6 +96,10 @@ public class QuerySelector {
.getLastStepResults() .getLastStepResults()
.created_facts_as_factbase() .created_facts_as_factbase()
.getAtoms() .getAtoms()
.filter(a -> a.getPredicate().label().startsWith("query"))
.filter(a -> !a.getPredicate().label().startsWith("constant"))
.filter(a -> !a.getPredicate().label().startsWith("owl:Thing"))
.filter(a -> Arrays.stream(a.getTerms()).noneMatch(Term::isVariable))
.collect(Collectors.toList()); .collect(Collectors.toList());
if (!factsProduced.isEmpty()) { if (!factsProduced.isEmpty()) {
...@@ -95,25 +107,32 @@ public class QuerySelector { ...@@ -95,25 +107,32 @@ public class QuerySelector {
} }
} }
List<List<Atom>> allQueries = new ArrayList<>(); // List<List<Atom>> allQueries = new ArrayList<>();
for (int i = 0; i < foundAxiomEntailments.size(); i++) { // for (int i = 0; i < foundAxiomEntailments.size(); i++) {
List<Atom> l = new ArrayList<>(); // List<Atom> l = new ArrayList<>();
for (Atom a : foundAxiomEntailments.get(i)) { // for (Atom a : foundAxiomEntailments.get(i)) {
if (a.getPredicate().label().startsWith("query")) { // if (a.getPredicate().label().startsWith("query")) {
l.add(a); // l.add(a);
} // }
} // }
if (!l.isEmpty()) { // if (!l.isEmpty()) {
allQueries.add(l); // allQueries.add(l);
} // }
} // }
for (List<Atom> l : allQueries) { for (List<Atom> l : foundAxiomEntailments) {
System.out.println(l.size()); System.out.println(l.size());
} }
System.out.println(allQueries.size() + " levels"); System.out.println(foundAxiomEntailments.size() + " levels");
List<Atom> queries = sampleQueries(allQueries, nbQueries);
int i = 0;
for (List<Atom> l : foundAxiomEntailments) {
i++;
InternalDLGPWriter.writeAtomsToFile(l,
new File(benchPath + "lubm001/lubm001_all_queries_by_level_" + i + ".dlgp"));
}
List<Atom> queries = sampleQueries(foundAxiomEntailments, nbQueries);
Collections.shuffle(queries, RANDOM); Collections.shuffle(queries, RANDOM);
...@@ -122,7 +141,7 @@ public class QuerySelector { ...@@ -122,7 +141,7 @@ public class QuerySelector {
return queries; return queries;
} }
public static List<Atom> sampleQueries(List<List<Atom>> lists, int nbQueries) { public static List<Atom> sampleQueries(List<List<Atom>> lists, int nbQueries) {
if (lists == null || lists.isEmpty()) { if (lists == null || lists.isEmpty()) {
throw new IllegalArgumentException("The outer list must not be null or empty."); throw new IllegalArgumentException("The outer list must not be null or empty.");
} }
......
...@@ -5,13 +5,16 @@ import com.google.common.collect.HashBiMap; ...@@ -5,13 +5,16 @@ import com.google.common.collect.HashBiMap;
import fr.boreal.explanation.api.encoders.GSATEncoder_GRI; import fr.boreal.explanation.api.encoders.GSATEncoder_GRI;
import fr.boreal.explanation.api.encoders.GSATEncodingResult_GRI; import fr.boreal.explanation.api.encoders.GSATEncodingResult_GRI;
import fr.boreal.explanation.kb_gri.rule_transformation.GRIRuleTransformer; import fr.boreal.explanation.kb_gri.rule_transformation.GRIRuleTransformer;
import fr.boreal.explanation.util.HornClausePrinter;
import fr.boreal.model.kb.api.FactBase; import fr.boreal.model.kb.api.FactBase;
import fr.boreal.model.kb.api.KnowledgeBase; import fr.boreal.model.kb.api.KnowledgeBase;
import fr.boreal.model.logicalElements.api.*; import fr.boreal.model.logicalElements.api.Atom;
import fr.boreal.model.logicalElements.api.LogicalFunctionalTerm;
import fr.boreal.model.logicalElements.api.Predicate;
import fr.boreal.model.logicalElements.api.Term;
import fr.boreal.model.rule.api.FORule; import fr.boreal.model.rule.api.FORule;
import java.util.*; import java.util.ArrayList;
import java.util.List;
/** /**
* This abstract class contains the main algorithm for encoding factbase with 4 additional abstract methods * This abstract class contains the main algorithm for encoding factbase with 4 additional abstract methods
...@@ -45,6 +48,7 @@ public abstract class AbstractGSATEncoder_KBGRI implements GSATEncoder_GRI<Knowl ...@@ -45,6 +48,7 @@ public abstract class AbstractGSATEncoder_KBGRI implements GSATEncoder_GRI<Knowl
public BiMap<Integer, FORule> ruleIDMap = HashBiMap.create(); public BiMap<Integer, FORule> ruleIDMap = HashBiMap.create();
public List<List<Integer>> clauses = new ArrayList<>(); public List<List<Integer>> clauses = new ArrayList<>();
protected int nbGroup; protected int nbGroup;
private boolean debug = false;
public AbstractGSATEncoder_KBGRI() { public AbstractGSATEncoder_KBGRI() {
this.nbGroup = getStartingGroupNumber(); this.nbGroup = getStartingGroupNumber();
...@@ -109,105 +113,111 @@ public abstract class AbstractGSATEncoder_KBGRI implements GSATEncoder_GRI<Knowl ...@@ -109,105 +113,111 @@ public abstract class AbstractGSATEncoder_KBGRI implements GSATEncoder_GRI<Knowl
*/ */
public void assignGroupNumbersAndComputeClausesForRELEdges(FactBase filteredGRI, Atom query, java.util.function.Predicate<Atom> belongsToInitialFactbase) { public void assignGroupNumbersAndComputeClausesForRELEdges(FactBase filteredGRI, Atom query, java.util.function.Predicate<Atom> belongsToInitialFactbase) {
BiMap<Predicate, FORule> relEdgePredicateToRule = griRuleTransformer.getRuleToRelEdgePredicateMap().inverse(); BiMap<Predicate, FORule> relEdgePredicateToRule = griRuleTransformer.getRuleToRelEdgePredicateMap().inverse();
// Looping over all relEdge_r predicates // Looping over all relEdge_r predicates
// We compute a SET of clauses. Each clause represents a grounding of the rule (i.e. a particular relEdge_r atom). // We compute a SET of clauses. Each clause represents a grounding of the rule (i.e. a particular relEdge_r atom).
var predIt = filteredGRI.getPredicates(); var predIt = filteredGRI.getPredicates();
while (predIt.hasNext()) { while (predIt.hasNext()) {
Predicate relEdgePred = predIt.next(); Predicate relEdgePred = predIt.next();
if (relEdgePred.label().startsWith(GRIRuleTransformer.REL_EDGE_prefix)) { if (relEdgePred.label().startsWith(GRIRuleTransformer.REL_EDGE_prefix)) {
// All clauses/groundings of the same rule will be in the same group // All clauses/groundings of the same rule will be in the same group
var currentRule = relEdgePredicateToRule.get(relEdgePred); var currentRule = relEdgePredicateToRule.get(relEdgePred);
// We assign a new group to the currentRule // We assign a new group to the currentRule
int currentRuleID = computeRuleID(); int currentRuleID = computeRuleID();
if (needRule()) { if (needRule()) {
ruleIDMap.put(currentRuleID, currentRule); ruleIDMap.put(currentRuleID, currentRule);
} }
List<Atom> seenRelEgdeAtoms = new ArrayList<Atom>(); List<Atom> seenRelEgdeAtoms = new ArrayList<Atom>();
// We produce a clause for every REL_EDGE_currentRule atom (each represents a grounding of currentRule) // We produce a clause for every REL_EDGE_currentRule atom (each represents a grounding of currentRule)
var it = filteredGRI.getAtomsByPredicate(relEdgePred); var it = filteredGRI.getAtomsByPredicate(relEdgePred);
while (it.hasNext()) { while (it.hasNext()) {
// First, we check the relEdge atom has not been seen to avoid trigger-clause redundancy // First, we check the relEdge atom has not been seen to avoid trigger-clause redundancy
Atom relEdgeAtom = it.next(); Atom relEdgeAtom = it.next();
if (!seenRelEgdeAtoms.contains(relEdgeAtom)) { if (!seenRelEgdeAtoms.contains(relEdgeAtom)) {
// Now it has been seen! // Now it has been seen!
seenRelEgdeAtoms.add(relEdgeAtom); seenRelEgdeAtoms.add(relEdgeAtom);
// Prepare the resulting clause with its associated group number // Prepare the resulting clause with its associated group number
// We use the currentRuleID as the group number // We use the currentRuleID as the group number
List<Integer> relEdgeAtomClause = new ArrayList<>(); List<Integer> relEdgeAtomClause = new ArrayList<>();
relEdgeAtomClause.addFirst(currentRuleID); relEdgeAtomClause.addFirst(currentRuleID);
// We collect all identifiers of relevant bodyAtoms // We collect all identifiers of relevant bodyAtoms
Term[] relevantAtomIdentifierList = relEdgeAtom.getTerms(); Term[] relevantAtomIdentifierList = relEdgeAtom.getTerms();
// Checking (circular) redundancy: p ^ q -> q (e.g.) is not helpful so we skip it
// Checking (circular) redundancy: p ^ q -> q (e.g.) is not helpful so we skip it boolean redundant = false;
boolean redundant = false; for (int i = 0; i < relevantAtomIdentifierList.length - 1; i++) {
for (int i = 0; i < relevantAtomIdentifierList.length - 1; i++) { if (relevantAtomIdentifierList[i].equals(relevantAtomIdentifierList[relevantAtomIdentifierList.length - 1])) {
if (relevantAtomIdentifierList[i].equals(relevantAtomIdentifierList[relevantAtomIdentifierList.length-1])) { redundant = true;
redundant = true; break;
break; }
} }
} if (redundant) {
if (redundant) { continue;
continue; }
}
// Process the atom
// Process the atom for (int i = 0; i < relevantAtomIdentifierList.length; i++) {
for (int i = 0; i < relevantAtomIdentifierList.length; i++) { var relevantAtomIdentifier = (LogicalFunctionalTerm) relevantAtomIdentifierList[i];
var relevantAtomIdentifier = (LogicalFunctionalTerm) relevantAtomIdentifierList[i]; Atom relevantAtom = griRuleTransformer.getAtomFromFnTerm(relevantAtomIdentifier);
Atom relevantAtom = griRuleTransformer.getAtomFromFnTerm(relevantAtomIdentifier);
// Check that
// Check that // (1) the relevant atom has not already been encoded (it's sufficient to check that it's not in propVarIDMap)
// (1) the relevant atom has not already been encoded (it's sufficient to check that it's not in propVarIDMap) // (2) the relevant atom belongs to the original factbase
// (2) the relevant atom belongs to the original factbase if (!propVarIDMap.containsKey(relevantAtom)) {
if (!propVarIDMap.containsKey(relevantAtom)) { // Assign an integer to the relevant atom if unseen
// Assign an integer to the relevant atom if unseen propVarIDMap.put(relevantAtom, propVarIDMap.size() + 1);
propVarIDMap.put(relevantAtom, propVarIDMap.size() + 1);
// Moreover, if the relevant atom is an initial fact, we create a clause for it
// Moreover, if the relevant atom is an initial fact, we create a clause for it if (belongsToInitialFactbase.test(relevantAtom)) {
if (belongsToInitialFactbase.test(relevantAtom)) {
// Assign a group to the atom
// Assign a group to the atom int relAtomGroupID = computeRelAtomGroupID();
int relAtomGroupID = computeRelAtomGroupID(); if (needFact()) {
if (needFact()) { factIDMap.put(relAtomGroupID, relevantAtom);
factIDMap.put(relAtomGroupID, relevantAtom); }
}
// Create a singleton group with the rel atom to the gcnf
// Create a singleton group with the rel atom to the gcnf var atomClause = List.of(relAtomGroupID, propVarIDMap.get(relevantAtom));
var atomClause = List.of(relAtomGroupID, propVarIDMap.get(relevantAtom)); if (debug) {
clauses.add(atomClause); System.out.println(relevantAtom);
} System.out.println(atomClause);
} }
// Add each relevant atom to the relEdgeAtom clause, negating if it is not the head clauses.add(atomClause);
}
relEdgeAtomClause.add(propVarIDMap.get(relevantAtom) * -1); }
} // Add each relevant atom to the relEdgeAtom clause, negating if it is not the head
relEdgeAtomClause.set(relEdgeAtomClause.size() - 1, relEdgeAtomClause.getLast() * -1);
relEdgeAtomClause.add(propVarIDMap.get(relevantAtom) * -1);
}
// The clause is ready relEdgeAtomClause.set(relEdgeAtomClause.size() - 1, relEdgeAtomClause.getLast() * -1);
if (needRule()) {
clauses.add(relEdgeAtomClause); if (debug) {
} else { System.out.println(relEdgeAtom);
if (!clauses.contains(relEdgeAtomClause)) { System.out.println(relEdgeAtomClause);
clauses.add(relEdgeAtomClause); }
} // The clause is ready
} if (needRule()) {
clauses.add(relEdgeAtomClause);
} } else {
} if (!clauses.contains(relEdgeAtomClause)) {
} clauses.add(relEdgeAtomClause);
}
}
}
}
}
} }
// Check that there is no redundancy // Check that there is no redundancy
if (clauses.size() > clauses.stream().distinct().count()) { if (clauses.size() > clauses.stream().distinct().count()) {
throw new IllegalStateException("There is a redundant clause."); throw new IllegalStateException("There is a redundant clause.");
} }
} }
public abstract int computeRuleID(); public abstract int computeRuleID();
......
...@@ -14,7 +14,9 @@ import fr.boreal.model.logicalElements.api.Atom; ...@@ -14,7 +14,9 @@ import fr.boreal.model.logicalElements.api.Atom;
import fr.boreal.model.logicalElements.impl.AtomImpl; import fr.boreal.model.logicalElements.impl.AtomImpl;
import org.apache.commons.lang3.NotImplementedException; import org.apache.commons.lang3.NotImplementedException;
import java.util.*; import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate; import java.util.function.Predicate;
public abstract class AbstractDynamicGRIBasedExplainer_KBGRI<ExplanationType> implements AtomicQueryExplainer<ExplanationType> { public abstract class AbstractDynamicGRIBasedExplainer_KBGRI<ExplanationType> implements AtomicQueryExplainer<ExplanationType> {
...@@ -74,10 +76,10 @@ public abstract class AbstractDynamicGRIBasedExplainer_KBGRI<ExplanationType> im ...@@ -74,10 +76,10 @@ public abstract class AbstractDynamicGRIBasedExplainer_KBGRI<ExplanationType> im
downwardClosure.getFactBase().add(RELquery); downwardClosure.getFactBase().add(RELquery);
// chase only with the tracing rules // chase only with the tracing rules
griKBChase = DefaultChaseForExplanations.chase(downwardClosure.getFactBase(),this.transformedRB); griKBChase = DefaultChaseForExplanations.chase(downwardClosure.getFactBase(), this.transformedRB);
griKBChase.execute(); griKBChase.execute();
Predicate<Atom> belongsToInitialFactbase = atom -> this.intialAtoms.contains(atom) ; Predicate<Atom> belongsToInitialFactbase = atom -> this.intialAtoms.contains(atom);
return getGMUSProcessor(new MARCOGMUSSolver()).computeAllExplanations(downwardClosure, query, belongsToInitialFactbase); return getGMUSProcessor(new MARCOGMUSSolver()).computeAllExplanations(downwardClosure, query, belongsToInitialFactbase);
} }
...@@ -88,6 +90,7 @@ public abstract class AbstractDynamicGRIBasedExplainer_KBGRI<ExplanationType> im ...@@ -88,6 +90,7 @@ public abstract class AbstractDynamicGRIBasedExplainer_KBGRI<ExplanationType> im
public void pipelineWithTimerDetailed(String datasetName, Collection<Atom> queries) { public void pipelineWithTimerDetailed(String datasetName, Collection<Atom> queries) {
throw new NotImplementedException(); throw new NotImplementedException();
} }
@Override @Override
public void pipelineIn2StepsWithTimer(String datasetName, Collection<Atom> queries) { public void pipelineIn2StepsWithTimer(String datasetName, Collection<Atom> queries) {
throw new NotImplementedException(); throw new NotImplementedException();
...@@ -98,4 +101,13 @@ public abstract class AbstractDynamicGRIBasedExplainer_KBGRI<ExplanationType> im ...@@ -98,4 +101,13 @@ public abstract class AbstractDynamicGRIBasedExplainer_KBGRI<ExplanationType> im
throw new NotImplementedException(); throw new NotImplementedException();
} }
// abstract RuleTransformer getRuleTransformer(); // abstract RuleTransformer getRuleTransformer();
public boolean isQueryEntailed(Atom query) {
throw new NotImplementedException();
}
public boolean isQueryInInitialFB(Atom query) {
throw new NotImplementedException();
}
} }
...@@ -9,6 +9,7 @@ import fr.boreal.explanation.configuration.DefaultChaseForExplanations; ...@@ -9,6 +9,7 @@ import fr.boreal.explanation.configuration.DefaultChaseForExplanations;
import fr.boreal.explanation.configuration.StatsUtil; import fr.boreal.explanation.configuration.StatsUtil;
import fr.boreal.explanation.kb_gri.rule_transformation.GRIRuleTransformer; import fr.boreal.explanation.kb_gri.rule_transformation.GRIRuleTransformer;
import fr.boreal.explanation.kb_gri.rule_transformation.static_gri.RulesetForStaticGRIBuildingAndTracing; import fr.boreal.explanation.kb_gri.rule_transformation.static_gri.RulesetForStaticGRIBuildingAndTracing;
import fr.boreal.explanation.solving_enumerating.hybrid.HybridSAT4JMARCOSolver;
import fr.boreal.explanation.solving_enumerating.marco.MARCOGMUSSolver; import fr.boreal.explanation.solving_enumerating.marco.MARCOGMUSSolver;
import fr.boreal.explanation.solving_enumerating.sat4j.Sat4JSolver; import fr.boreal.explanation.solving_enumerating.sat4j.Sat4JSolver;
import fr.boreal.grd.api.GraphOfFORuleDependencies; import fr.boreal.grd.api.GraphOfFORuleDependencies;
...@@ -29,6 +30,7 @@ import fr.boreal.unifier.QueryUnifierAlgorithm; ...@@ -29,6 +30,7 @@ import fr.boreal.unifier.QueryUnifierAlgorithm;
import fr.boreal.views.FederatedFactBase; import fr.boreal.views.FederatedFactBase;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.util.*; import java.util.*;
import static fr.boreal.explanation.configuration.PathFinder.ensureFilePath; import static fr.boreal.explanation.configuration.PathFinder.ensureFilePath;
...@@ -95,7 +97,6 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType ...@@ -95,7 +97,6 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType
// marco // marco
MARCOGMUSSolver marcoSolver = new MARCOGMUSSolver(); MARCOGMUSSolver marcoSolver = new MARCOGMUSSolver();
String tmpFileName = "gsat.gcnf"; String tmpFileName = "gsat.gcnf";
File gcnffile = new File(tmpFileName); File gcnffile = new File(tmpFileName);
...@@ -103,6 +104,8 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType ...@@ -103,6 +104,8 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType
protected Set explanations; protected Set explanations;
protected Set<String> gmuses; protected Set<String> gmuses;
// memory of entailed queries
Set<Atom> entailedQueryCache = new HashSet<>();
/** /**
* Sets the initial KB * Sets the initial KB
* *
...@@ -124,7 +127,19 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType ...@@ -124,7 +127,19 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType
public void dynamicStep(Atom query) { public void dynamicStep(Atom query) {
checkQueryInInitialFB(query);
tmpFileName = "gsat";
String suffix = ".gcnf";
gcnffile = null;
try {
gcnffile = File.createTempFile(tmpFileName, suffix);
} catch (IOException e) {
throw new RuntimeException(e);
}
gcnffile.deleteOnExit();
isQueryInInitialFB(query);
dynamicStepClear(); dynamicStepClear();
if (!queryInInitialFB) { if (!queryInInitialFB) {
...@@ -135,6 +150,11 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType ...@@ -135,6 +150,11 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType
// compute the ancestor rules of the query // compute the ancestor rules of the query
computeAncestorRules(query); computeAncestorRules(query);
if (queryAncestorRules.isEmpty()) {
explanations = new HashSet();
return;
}
handleDynamicRB(); handleDynamicRB();
// if the GRI is not complete // if the GRI is not complete
...@@ -153,6 +173,10 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType ...@@ -153,6 +173,10 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType
// REL tracing // REL tracing
prepareRelTracing(query); prepareRelTracing(query);
chaseForRELPropagation(); chaseForRELPropagation();
if (dynamicKB.getFactBase().size()==1) {
explanations = new HashSet();
return;
}
encodeClauses(query); encodeClauses(query);
if (solver instanceof MARCOGMUSSolver) { if (solver instanceof MARCOGMUSSolver) {
writeMarcoGCNF(); writeMarcoGCNF();
...@@ -161,6 +185,8 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType ...@@ -161,6 +185,8 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType
} else if (solver instanceof Sat4JSolver) { } else if (solver instanceof Sat4JSolver) {
solveGMUSviaSat4j(); solveGMUSviaSat4j();
decodeGMUSesFromSat4j(); decodeGMUSesFromSat4j();
} else if (solver instanceof HybridSAT4JMARCOSolver) {
solveViaHybridSolver();
} }
// System.out.println("Query: " + query); // System.out.println("Query: " + query);
// System.out.println("Explanation: " + explanations); // System.out.println("Explanation: " + explanations);
...@@ -180,7 +206,7 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType ...@@ -180,7 +206,7 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType
StatsUtil.timerSumAllQueries(this::recordInitialFactbase, explainerName, "recordInitialFactbase", datasetName); StatsUtil.timerSumAllQueries(this::recordInitialFactbase, explainerName, "recordInitialFactbase", datasetName);
for (Atom query : queries) { for (Atom query : queries) {
StatsUtil.timerSumAllQueries(() -> checkQueryInInitialFB(query), explainerName, StatsUtil.timerSumAllQueries(() -> isQueryInInitialFB(query), explainerName,
"checkQueryInInitialFB", datasetName); "checkQueryInInitialFB", datasetName);
if (!queryInInitialFB) { if (!queryInInitialFB) {
...@@ -198,6 +224,12 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType ...@@ -198,6 +224,12 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType
StatsUtil.timerPerEachQuery(() -> computeAncestorRules(query), explainerName, StatsUtil.timerPerEachQuery(() -> computeAncestorRules(query), explainerName,
"Computing Ancestor Rules", datasetName); "Computing Ancestor Rules", datasetName);
if (queryAncestorRules.isEmpty()) {
explanations = new HashSet();
return;
}
if (seenRules.isEmpty()) { if (seenRules.isEmpty()) {
StatsUtil.timerPerEachQuery(() -> handleDynamicRB(), explainerName, "Creating Node Building Rules", datasetName); StatsUtil.timerPerEachQuery(() -> handleDynamicRB(), explainerName, "Creating Node Building Rules", datasetName);
} }
...@@ -213,6 +245,12 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType ...@@ -213,6 +245,12 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType
"prepareRelTracing", datasetName); "prepareRelTracing", datasetName);
StatsUtil.timerChasePerEachQuery(this::chaseForRELPropagation, dynamicKB, explainerName, StatsUtil.timerChasePerEachQuery(this::chaseForRELPropagation, dynamicKB, explainerName,
"chaseForRELPropagation", datasetName); "chaseForRELPropagation", datasetName);
if (dynamicKB.getFactBase().size()==1) {
explanations = new HashSet();
return;
}
StatsUtil.timerSumAllQueries(() -> encodeClauses(query), explainerName, StatsUtil.timerSumAllQueries(() -> encodeClauses(query), explainerName,
"encodeClauses", datasetName); "encodeClauses", datasetName);
...@@ -259,7 +297,24 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType ...@@ -259,7 +297,24 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType
for (Atom query : queries) { for (Atom query : queries) {
queryIndex++; queryIndex++;
StatsUtil.timerWithOrderedQuery(() -> checkQueryInInitialFB(query), "Q"+queryIndex, explainerName, String queryNumber = "Q"+queryIndex;
// String queryNumber = query.toString();
System.out.println("query: " + query);
tmpFileName = datasetName + queryIndex +"_static_gsat.gcnf";
String prefix = datasetName + queryIndex + "_static_gsat_";
String suffix = ".gcnf";
// gcnffile = new File(tmpFileName);
File gcnffile = null;
try {
gcnffile = File.createTempFile(prefix, suffix);
} catch (IOException e) {
throw new RuntimeException(e);
}
gcnffile.deleteOnExit();
StatsUtil.timerWithOrderedQuery(() -> isQueryInInitialFB(query), queryNumber, explainerName,
"Checking if query is already in input FB", datasetName); "Checking if query is already in input FB", datasetName);
if (!queryInInitialFB) { if (!queryInInitialFB) {
...@@ -268,35 +323,42 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType ...@@ -268,35 +323,42 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType
if (queryAncestorRules != null) { if (queryAncestorRules != null) {
// Where this is not the first query // Where this is not the first query
StatsUtil.timerWithOrderedQuery(this::clearAncestorRules, "Q"+queryIndex, explainerName, StatsUtil.timerWithOrderedQuery(this::clearAncestorRules, queryNumber, explainerName,
"Clearing Ancestor Rules", datasetName); "Clearing Ancestor Rules", datasetName);
} }
// compute the ancestor rules of the query // compute the ancestor rules of the query
StatsUtil.timerWithOrderedQuery(() -> computeAncestorRules(query), "Q"+queryIndex, explainerName, StatsUtil.timerWithOrderedQuery(() -> computeAncestorRules(query), queryNumber, explainerName,
"Computing Ancestor Rules", datasetName); "Computing Ancestor Rules", datasetName);
StatsUtil.timerWithOrderedQuery(this::handleDynamicRB, "Q"+queryIndex, explainerName, "Handle dynamic RB", datasetName);
if (queryAncestorRules.isEmpty()) {
explanations = new HashSet();
return;
}
StatsUtil.timerWithOrderedQuery(this::handleDynamicRB, queryNumber, explainerName, "Handle dynamic RB", datasetName);
// if the GRI is not complete // if the GRI is not complete
if (seenRules.size() < inputKB.getRuleBase().getRules().size()) { if (seenRules.size() < inputKB.getRuleBase().getRules().size()) {
if (!seenRules.containsAll(queryAncestorRules)) { if (!seenRules.containsAll(queryAncestorRules)) {
StatsUtil.timerWithOrderedQuery(this::handleStaticRB, "Q"+queryIndex, explainerName, "Handle static RB", datasetName); StatsUtil.timerWithOrderedQuery(this::handleStaticRB, queryNumber, explainerName, "Handle static RB", datasetName);
StatsUtil.timerWithOrderedQuery(this::chaseKBforGRI,"Q"+queryIndex, explainerName, "Chase for building partial GRI", datasetName); StatsUtil.timerWithOrderedQuery(this::chaseKBforGRI,queryNumber, explainerName, "Chase for building partial GRI", datasetName);
StatsUtil.recordSize((long) staticRB.getRules().size(), "Q"+queryIndex, explainerName, "GRI-building Rules", datasetName); StatsUtil.recordSize((long) staticRB.getRules().size(), queryNumber, explainerName, "GRI-building Rules", datasetName);
// System.out.println(staticRB.getRules());
} else { } else {
StatsUtil.recordSize(0L, "Q"+queryIndex, explainerName, "GRI-building Rules", datasetName); StatsUtil.recordSize(0L, queryNumber, explainerName, "GRI-building Rules", datasetName);
} }
} }
StatsUtil.recordSize((long) queryAncestorRules.size(), "Q"+queryIndex, explainerName, "Ancestor Rules", datasetName); StatsUtil.recordSize((long) queryAncestorRules.size(), queryNumber, explainerName, "Ancestor Rules", datasetName);
StatsUtil.recordSize((long) seenRules.size(), "Q"+queryIndex, explainerName, "Seen Rules", datasetName); StatsUtil.recordSize((long) seenRules.size(), queryNumber, explainerName, "Seen Rules", datasetName);
StatsUtil.recordSize((long) seenPredicates.size(), "Q"+queryIndex, explainerName, "Predicates", datasetName); StatsUtil.recordSize((long) seenPredicates.size(), queryNumber, explainerName, "Predicates", datasetName);
StatsUtil.recordSize((long) staticKB.getFactBase().size(), "Q"+queryIndex, explainerName, "GRI size", datasetName); StatsUtil.recordSize((long) staticKB.getFactBase().size(), queryNumber, explainerName, "GRI size", datasetName);
staticRuleHistory.add(staticRB); staticRuleHistory.add(staticRB);
dynamicRuleHistory.add(dynamicRB); dynamicRuleHistory.add(dynamicRB);
...@@ -306,44 +368,49 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType ...@@ -306,44 +368,49 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType
// filtering // filtering
StatsUtil.timerWithOrderedQuery(() -> prepareRelTracing(query), "Q"+queryIndex, explainerName, StatsUtil.timerWithOrderedQuery(() -> prepareRelTracing(query), queryNumber, explainerName,
"Preparing Rel Tracing", datasetName); "Preparing Rel Tracing", datasetName);
StatsUtil.timerWithOrderedQuery(this::chaseForRELPropagation, "Q"+queryIndex, explainerName, StatsUtil.timerWithOrderedQuery(this::chaseForRELPropagation, queryNumber, explainerName,
"Chase For Rel Tracing", datasetName); "Chase For Rel Tracing", datasetName);
StatsUtil.recordSize((long) dynamicKB.getRuleBase().getRules().size(), "Q"+queryIndex, explainerName, "Dynamic RB size", datasetName); if (dynamicKB.getFactBase().size()==1) {
StatsUtil.recordSize(dynamicKB.getFactBase().size(), "Q"+queryIndex, explainerName, "Dynamic FB size", datasetName); explanations = new HashSet();
return;
}
StatsUtil.timerWithOrderedQuery(() -> encodeClauses(query), "Q"+queryIndex, explainerName, StatsUtil.recordSize((long) dynamicKB.getRuleBase().getRules().size(), queryNumber, explainerName, "Dynamic RB size", datasetName);
StatsUtil.recordSize(dynamicKB.getFactBase().size(), queryNumber, explainerName, "Dynamic FB size", datasetName);
StatsUtil.timerWithOrderedQuery(() -> encodeClauses(query), queryNumber, explainerName,
"Encoding clauses", datasetName); "Encoding clauses", datasetName);
if (solver instanceof MARCOGMUSSolver) { if (solver instanceof MARCOGMUSSolver) {
StatsUtil.timerWithOrderedQuery(this::writeMarcoGCNF, "Q"+queryIndex, explainerName, StatsUtil.timerWithOrderedQuery(this::writeMarcoGCNF, queryNumber, explainerName,
"Writing GCNF", datasetName); "Writing GCNF", datasetName);
StatsUtil.timerMarcoOrderedQueries(this::solveGMUSviaMarco, "Q"+queryIndex, explainerName, StatsUtil.timerMarcoOrderedQueries(this::solveGMUSviaMarco, queryNumber, explainerName,
"Computing GMUSes via Marco", datasetName); "Computing GMUSes via Marco", datasetName);
StatsUtil.timerWithOrderedQuery(this::decodeGMUSesFromMarco, "Q"+queryIndex, explainerName, StatsUtil.timerWithOrderedQuery(this::decodeGMUSesFromMarco, queryNumber, explainerName,
"Decoding GMUSes from Marco", datasetName); "Decoding GMUSes from Marco", datasetName);
} else if (solver instanceof Sat4JSolver) { } else if (solver instanceof Sat4JSolver) {
StatsUtil.timerWithOrderedQuery(this::solveGMUSviaSat4j, "Q"+queryIndex, explainerName, StatsUtil.timerWithOrderedQuery(this::solveGMUSviaSat4j, queryNumber, explainerName,
"Computing GMUSes with sat4j", datasetName); "Computing GMUSes with sat4j", datasetName);
StatsUtil.timerWithOrderedQuery(this::decodeGMUSesFromSat4j, "Q"+queryIndex, explainerName, StatsUtil.timerWithOrderedQuery(this::decodeGMUSesFromSat4j, queryNumber, explainerName,
"Decoding GMUSes from sat4j", datasetName "Decoding GMUSes from sat4j", datasetName
); );
} }
// System.out.println("Explanation size = " + explanations); // System.out.println("Explanation size = " + explanations);
StatsUtil.recordSize((long) explanations.size(), "Q"+queryIndex, explainerName, "Explanations", datasetName); StatsUtil.recordSize((long) explanations.size(), queryNumber, explainerName, "Explanations", datasetName);
} else { } else {
StatsUtil.timerWithOrderedQuery(() -> returnExplanationForQueryInFB(query), "Q"+queryIndex, explainerName, StatsUtil.timerWithOrderedQuery(() -> returnExplanationForQueryInFB(query), queryNumber, explainerName,
"Returning the explanation for query already in FB", datasetName); "Returning the explanation for query already in FB", datasetName);
} }
// System.out.println("Inc GRI Query Ancestor Rules: " + queryAncestorRules); // System.out.println("Inc GRI Query Ancestor Rules: " + queryAncestorRules);
// System.out.println("query: " + query); // System.out.println("explanations: " + explanations);
} }
// System.out.println("Inc GRI REL-tracing RB: " + dynamicRuleHistory); // System.out.println("Inc GRI REL-tracing RB: " + dynamicRuleHistory);
...@@ -392,7 +459,7 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType ...@@ -392,7 +459,7 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType
); );
if (!unifiers.isEmpty()) { if (!unifiers.isEmpty()) {
ancestorRules.addAll(grd.getAncestorRules(rule)); ancestorRules.addAll(grd.getAncestorRules(rule,ancestorRules));
} }
} }
...@@ -400,19 +467,17 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType ...@@ -400,19 +467,17 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType
} }
public void buildingGRD() { public void buildingGRD() {
grd = new GRDImpl(inputKB.getRuleBase()); grd = new GRDImpl(inputKB.getRuleBase(), List.of());
} }
public void checkQueryInInitialFB(Atom query) {
if (belongsToInitialFactbase.test(query)) {
queryInInitialFB = true;
}
}
public void returnExplanationForQueryInFB(Atom query) { public void returnExplanationForQueryInFB(Atom query) {
explanations = getGMUSProcessor(solver).getQueryIsInTheIntitialFactbaseExplanation(query); explanations = getGMUSProcessor(solver).getQueryIsInTheIntitialFactbaseExplanation(query);
} }
public void returnEmptySetForExplanation() {
explanations = new HashSet();
}
public void clearAncestorRules() { public void clearAncestorRules() {
queryAncestorRules.clear(); queryAncestorRules.clear();
...@@ -422,7 +487,7 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType ...@@ -422,7 +487,7 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType
} }
private void dynamicStepClear() { public void dynamicStepClear() {
if (explanations != null) { if (explanations != null) {
explanations.clear(); explanations.clear();
} }
...@@ -497,6 +562,25 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType ...@@ -497,6 +562,25 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType
belongsToInitialFactbase = atom -> inputKB.getFactBase().contains(atom); belongsToInitialFactbase = atom -> inputKB.getFactBase().contains(atom);
} }
public boolean isQueryEntailed(Atom query) {
if (this.entailedQueryCache.contains(query)) {
return true;
}
Atom queryWithFuncId = GRIRuleTransformer.instance().createAtomWithStoredFnTermIdentifier(query);
if (staticKB.getFactBase().contains(queryWithFuncId)) {
entailedQueryCache.add(query);
return true;
}
return false;
}
public boolean isQueryInInitialFB(Atom query) {
if (belongsToInitialFactbase.test(query)) {
queryInInitialFB = true;
}
return queryInInitialFB;
}
public void chaseKBforGRI() { public void chaseKBforGRI() {
DefaultChaseForExplanations.chase(this.staticKB); DefaultChaseForExplanations.chase(this.staticKB);
} }
...@@ -530,13 +614,12 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType ...@@ -530,13 +614,12 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType
DefaultChaseForExplanations.chase(dynamicKB); DefaultChaseForExplanations.chase(dynamicKB);
} }
public void encodeClauses(Atom query) { public void encodeClauses(Atom query) {
encodingResult = getGMUSProcessor(solver).getEncoder().encode(dynamicKB, query, belongsToInitialFactbase); encodingResult = getGMUSProcessor(solver).getEncoder().encode(dynamicKB, query, belongsToInitialFactbase);
} }
public void writeMarcoGCNF() { public void writeMarcoGCNF() {
marcoSolver.writeGCNF(encodingResult.propVarIDMap(), encodingResult.clauses(), encodingResult.nbGroup()); marcoSolver.writeGCNF(encodingResult.propVarIDMap(), encodingResult.clauses(), encodingResult.nbGroup(),gcnffile);
} }
public void solveGMUSviaMarco() { public void solveGMUSviaMarco() {
...@@ -556,8 +639,58 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType ...@@ -556,8 +639,58 @@ public abstract class AbstractIncrementalGRIBasedExplainer_KBGRI<ExplanationType
explanations = getGMUSProcessor(solver).translateSAT4JGMUS(sat4jGmuses, encodingResult.factIDMap(), encodingResult.ruleIDMap()); explanations = getGMUSProcessor(solver).translateSAT4JGMUS(sat4jGmuses, encodingResult.factIDMap(), encodingResult.ruleIDMap());
} }
public void solveViaHybridSolver() {
var result = ((HybridSAT4JMARCOSolver) solver).solve(encodingResult);
switch (result.solver()) {
case MARCOGMUSSolver ignored -> {
explanations = getGMUSProcessor(solver).translateMARCOGMUS((Set<String>) result.solverResult(), encodingResult.factIDMap(), encodingResult.ruleIDMap());
}
case Sat4JSolver ignored ->
explanations = getGMUSProcessor(solver).translateSAT4JGMUS((List<List<List<Integer>>>) result.solverResult(), encodingResult.factIDMap(), encodingResult.ruleIDMap());
default -> throw new IllegalStateException("Unsupported solver conversion");
}
}
public boolean isGRIComplete() {
return seenRules.size() == inputKB.getRuleBase().getRules().size();
}
public boolean areCurrentAncestorRulesKnown() {
return seenRules.containsAll(this.queryAncestorRules);
}
public Set<ExplanationType> getLastComputedExplanations() {
return explanations;
}
public void placeHolder() { public void placeHolder() {
} }
abstract ExplanationProcessor_GRI getGMUSProcessor(Solver solver); abstract ExplanationProcessor_GRI getGMUSProcessor(Solver solver);
public String getPrintableStatistics() {
StringBuilder result = new StringBuilder();
result.append("\n\nStatistics for : " +this.getClass().getSimpleName()+"\n");
result.append("GRInstances size "+ this.staticKB.getFactBase().size() + "\n");
result.append("number of clauses "+ this.encodingResult.clauses().size() + "\n");
result.append("number of explanations "+ this.explanations.size() + "\n");
result.append("\n");
return result.toString();
}
public String getPrintableStatisticsXML() {
StringBuilder result = new StringBuilder();
result.append("<statistics>\n");
result.append(" <component>").append(this.getClass().getSimpleName()).append("</component>\n");
result.append(" <grInstancesSize>").append(this.staticKB.getFactBase().size()).append("</grInstancesSize>\n");
result.append(" <numberOfClauses>").append(this.encodingResult.clauses().size()).append("</numberOfClauses>\n");
result.append(" <numberOfExplanations>").append(this.explanations.size()).append("</numberOfExplanations>\n");
result.append("</statistics>");
return result.toString();
}
} }
...@@ -4,12 +4,13 @@ import fr.boreal.explanation.api.processors.ExplanationProcessor_GRI; ...@@ -4,12 +4,13 @@ import fr.boreal.explanation.api.processors.ExplanationProcessor_GRI;
import fr.boreal.explanation.api.solver.Solver; import fr.boreal.explanation.api.solver.Solver;
import fr.boreal.explanation.kb_gri.processors.FactSupportGMUSProcessor_KBGRI; import fr.boreal.explanation.kb_gri.processors.FactSupportGMUSProcessor_KBGRI;
import fr.boreal.explanation.solving_enumerating.marco.MARCOGMUSSolver; import fr.boreal.explanation.solving_enumerating.marco.MARCOGMUSSolver;
import fr.boreal.model.kb.api.FactBase;
import fr.boreal.model.kb.api.KnowledgeBase; import fr.boreal.model.kb.api.KnowledgeBase;
/** /**
* Computes kb-support explanations for a knowledge base and a ground atomic query * Computes kb-support explanations for a knowledge base and a ground atomic query
*/ */
public class FactSupportExplainer_IncrementalKBGRI extends AbstractIncrementalGRIBasedExplainer_KBGRI<KnowledgeBase> { public class FactSupportExplainer_IncrementalKBGRI extends AbstractIncrementalGRIBasedExplainer_KBGRI<FactBase> {
public FactSupportExplainer_IncrementalKBGRI(KnowledgeBase kb) { public FactSupportExplainer_IncrementalKBGRI(KnowledgeBase kb) {
super(kb, new MARCOGMUSSolver()); super(kb, new MARCOGMUSSolver());
} }
......
...@@ -5,11 +5,12 @@ import fr.boreal.explanation.api.solver.Solver; ...@@ -5,11 +5,12 @@ import fr.boreal.explanation.api.solver.Solver;
import fr.boreal.explanation.kb_gri.processors.RuleSupportGMUSProcessor_KBGRI; import fr.boreal.explanation.kb_gri.processors.RuleSupportGMUSProcessor_KBGRI;
import fr.boreal.explanation.solving_enumerating.marco.MARCOGMUSSolver; import fr.boreal.explanation.solving_enumerating.marco.MARCOGMUSSolver;
import fr.boreal.model.kb.api.KnowledgeBase; import fr.boreal.model.kb.api.KnowledgeBase;
import fr.boreal.model.kb.api.RuleBase;
/** /**
* Computes kb-support explanations for a knowledge base and a ground atomic query * Computes kb-support explanations for a knowledge base and a ground atomic query
*/ */
public class RuleSupportExplainer_IncrementalKBGRI extends AbstractIncrementalGRIBasedExplainer_KBGRI<KnowledgeBase> { public class RuleSupportExplainer_IncrementalKBGRI extends AbstractIncrementalGRIBasedExplainer_KBGRI<RuleBase> {
public RuleSupportExplainer_IncrementalKBGRI(KnowledgeBase kb) { public RuleSupportExplainer_IncrementalKBGRI(KnowledgeBase kb) {
super(kb, new MARCOGMUSSolver()); super(kb, new MARCOGMUSSolver());
} }
......
...@@ -9,6 +9,7 @@ import fr.boreal.explanation.configuration.DefaultChaseForExplanations; ...@@ -9,6 +9,7 @@ import fr.boreal.explanation.configuration.DefaultChaseForExplanations;
import fr.boreal.explanation.configuration.StatsUtil; import fr.boreal.explanation.configuration.StatsUtil;
import fr.boreal.explanation.kb_gri.rule_transformation.GRIRuleTransformer; import fr.boreal.explanation.kb_gri.rule_transformation.GRIRuleTransformer;
import fr.boreal.explanation.kb_gri.rule_transformation.static_gri.RulesetForStaticGRIBuildingAndTracing; import fr.boreal.explanation.kb_gri.rule_transformation.static_gri.RulesetForStaticGRIBuildingAndTracing;
import fr.boreal.explanation.solving_enumerating.hybrid.HybridSAT4JMARCOSolver;
import fr.boreal.explanation.solving_enumerating.marco.MARCOGMUSSolver; import fr.boreal.explanation.solving_enumerating.marco.MARCOGMUSSolver;
import fr.boreal.explanation.solving_enumerating.sat4j.Sat4JSolver; import fr.boreal.explanation.solving_enumerating.sat4j.Sat4JSolver;
import fr.boreal.grd.api.GraphOfFORuleDependencies; import fr.boreal.grd.api.GraphOfFORuleDependencies;
...@@ -26,13 +27,11 @@ import fr.boreal.storage.natives.SimpleInMemoryGraphStore; ...@@ -26,13 +27,11 @@ import fr.boreal.storage.natives.SimpleInMemoryGraphStore;
import fr.boreal.unifier.QueryUnifier; import fr.boreal.unifier.QueryUnifier;
import fr.boreal.unifier.QueryUnifierAlgorithm; import fr.boreal.unifier.QueryUnifierAlgorithm;
import fr.boreal.views.FederatedFactBase; import fr.boreal.views.FederatedFactBase;
import org.apache.commons.lang3.NotImplementedException;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.util.*; import java.util.*;
import static fr.boreal.explanation.configuration.PathFinder.ensureFilePath;
public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> implements AtomicQueryExplainer<ExplanationType> { public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> implements AtomicQueryExplainer<ExplanationType> {
/** /**
...@@ -60,7 +59,6 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp ...@@ -60,7 +59,6 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp
/** /**
* Static and dynamic knowledge bases * Static and dynamic knowledge bases
*/ */
protected KnowledgeBase staticKB; protected KnowledgeBase staticKB;
protected KnowledgeBase dynamicKB; protected KnowledgeBase dynamicKB;
...@@ -82,6 +80,8 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp ...@@ -82,6 +80,8 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp
java.util.function.Predicate<Atom> belongsToInitialFactbase; java.util.function.Predicate<Atom> belongsToInitialFactbase;
protected boolean queryEntailed = false; protected boolean queryEntailed = false;
protected boolean queryInInitialFB = false; protected boolean queryInInitialFB = false;
// memory of entailed queries
Set<Atom> entailedQueryCache = new HashSet<>();
// encoding // encoding
GSATEncodingResult_GRI encodingResult; GSATEncodingResult_GRI encodingResult;
...@@ -99,7 +99,7 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp ...@@ -99,7 +99,7 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp
// decoding // decoding
protected Set<ExplanationType> explanations; protected Set<ExplanationType> explanations;
protected Set<String> gmuses; protected Set<String> gmuses;
/** /**
...@@ -129,14 +129,13 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp ...@@ -129,14 +129,13 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp
* Dynamic step * Dynamic step
* *
* @param query * @param query
*
*/ */
public void dynamicStep(Atom query) { public void dynamicStep(Atom query) {
if (this.explanations != null) { if (this.explanations != null) {
dynamicStepClear(); dynamicStepClear();
} }
checkQueryEntailment(query);
checkQueryInInitialFB(query); checkQueryInInitialFB(query);
checkQueryEntailment(query);
if (queryEntailed & !queryInInitialFB) { if (queryEntailed & !queryInInitialFB) {
clearAncestorRules(); clearAncestorRules();
computeAncestorRules(query); computeAncestorRules(query);
...@@ -150,6 +149,8 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp ...@@ -150,6 +149,8 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp
} else if (solver instanceof Sat4JSolver) { } else if (solver instanceof Sat4JSolver) {
solveGMUSviaSat4j(); solveGMUSviaSat4j();
decodeGMUSesFromSat4j(); decodeGMUSesFromSat4j();
} else if (solver instanceof HybridSAT4JMARCOSolver) {
solveViaHybridSolver();
} }
} else if (queryInInitialFB) { } else if (queryInInitialFB) {
returnExplanationForQueryInFB(query); returnExplanationForQueryInFB(query);
...@@ -159,15 +160,9 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp ...@@ -159,15 +160,9 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp
} }
public void dynamicStepClear() { public void dynamicStepClear() {
if (explanations != null) { explanations = new HashSet<>();
explanations.clear(); gmuses = new HashSet<>();
} sat4jGmuses = new ArrayList<>();
if (gmuses != null) {
gmuses.clear();
}
if (sat4jGmuses != null) {
sat4jGmuses.clear();
}
} }
/* /*
...@@ -213,7 +208,7 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp ...@@ -213,7 +208,7 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp
} }
public void pipelineIn2StepsWithTimer (String datasetName, Collection<Atom> queries) { public void pipelineIn2StepsWithTimer(String datasetName, Collection<Atom> queries) {
String explainerName = this.getClass().getSimpleName() + " + " + this.solver.getClass().getSimpleName(); String explainerName = this.getClass().getSimpleName() + " + " + this.solver.getClass().getSimpleName();
StatsUtil.timerPerEachQuery(this::staticStep, explainerName, "Static Step", datasetName); StatsUtil.timerPerEachQuery(this::staticStep, explainerName, "Static Step", datasetName);
...@@ -228,56 +223,70 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp ...@@ -228,56 +223,70 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp
public void pipelineWithOrderedQuery(String datasetName, Collection<Atom> queries) { public void pipelineWithOrderedQuery(String datasetName, Collection<Atom> queries) {
String explainerName = this.getClass().getSimpleName() + " + " + this.solver.getClass().getSimpleName(); String explainerName = this.getClass().getSimpleName() + " + " + this.solver.getClass().getSimpleName();
StatsUtil.timerWithOrderedQuery(this::transformRules,"Pre-first-query", explainerName, "Transforming rules", datasetName); StatsUtil.timerWithOrderedQuery(this::transformRules, "Pre-first-query", explainerName, "Transforming rules", datasetName);
StatsUtil.timerWithOrderedQuery(this::prepareKBforGRI,"Pre-first-query", explainerName, "Preparing KB for GRI", datasetName); StatsUtil.timerWithOrderedQuery(this::prepareKBforGRI, "Pre-first-query", explainerName, "Preparing KB for GRI", datasetName);
StatsUtil.timerWithOrderedQuery(this::chaseKBforGRI,"Pre-first-query", explainerName, "Chasing on staticKB for GRI", datasetName); StatsUtil.timerWithOrderedQuery(this::chaseKBforGRI, "Pre-first-query", explainerName, "Chasing on staticKB for GRI", datasetName);
StatsUtil.timerWithOrderedQuery(this::recordInitialFactbase,"Pre-first-query", explainerName, "Recording initial factbase", datasetName); StatsUtil.timerWithOrderedQuery(this::recordInitialFactbase, "Pre-first-query", explainerName, "Recording initial factbase", datasetName);
StatsUtil.timerWithOrderedQuery(this::buildingGRD,"Pre-first-query", explainerName, "Recording initial factbase", datasetName); StatsUtil.timerWithOrderedQuery(this::buildingGRD, "Pre-first-query", explainerName, "Recording initial factbase", datasetName);
int queryIndex = 0; int queryIndex = 0;
for (Atom query : queries) { for (Atom query : queries) {
queryIndex++; queryIndex++;
StatsUtil.recordSize((long) staticKB.getFactBase().size(), "Q"+queryIndex, explainerName, "GRI size", datasetName); String queryNumber = "Q" + queryIndex;
// String queryNumber = query.toString();
tmpFileName = datasetName + queryIndex + "_static_gsat.gcnf";
String prefix = datasetName + queryIndex + "_static_gsat_";
String suffix = ".gcnf";
// gcnffile = new File(tmpFileName);
File gcnffile = null;
try {
gcnffile = File.createTempFile(prefix, suffix);
} catch (IOException e) {
throw new RuntimeException(e);
}
gcnffile.deleteOnExit();
StatsUtil.recordSize((long) staticKB.getFactBase().size(), queryNumber, explainerName, "GRI size", datasetName);
if (this.explanations != null) { if (this.explanations != null) {
StatsUtil.timerWithOrderedQuery(this::dynamicStepClear,"Q"+queryIndex, explainerName, StatsUtil.timerWithOrderedQuery(this::dynamicStepClear, queryNumber, explainerName,
"Clearing gmuses and explanations for the previous query", "Clearing gmuses and explanations for the previous query",
datasetName); datasetName);
} }
StatsUtil.timerWithOrderedQuery(() -> checkQueryEntailment(query),"Q"+queryIndex, explainerName, "Checking if query is entailed", datasetName); StatsUtil.timerWithOrderedQuery(() -> checkQueryEntailment(query), queryNumber, explainerName, "Checking if query is entailed", datasetName);
StatsUtil.timerWithOrderedQuery(() -> checkQueryInInitialFB(query),"Q"+queryIndex, explainerName, "Checking if query is already in input FB", datasetName); StatsUtil.timerWithOrderedQuery(() -> checkQueryInInitialFB(query), queryNumber, explainerName, "Checking if query is already in input FB", datasetName);
if (queryEntailed && !queryInInitialFB) { if (queryEntailed && !queryInInitialFB) {
StatsUtil.timerWithOrderedQuery(this::clearAncestorRules,"Q"+queryIndex, explainerName, "Clearing Ancestor Rules", datasetName); StatsUtil.timerWithOrderedQuery(this::clearAncestorRules, queryNumber, explainerName, "Clearing Ancestor Rules", datasetName);
StatsUtil.timerWithOrderedQuery(() -> computeAncestorRules(query),"Q"+queryIndex, explainerName, "Computing Ancestor Rules for each query", datasetName); StatsUtil.timerWithOrderedQuery(() -> computeAncestorRules(query), queryNumber, explainerName, "Computing Ancestor Rules for each query", datasetName);
StatsUtil.timerWithOrderedQuery(() -> prepareRelTracing(query),"Q"+queryIndex, explainerName, "Preparing Rel Tracing", datasetName); StatsUtil.timerWithOrderedQuery(() -> prepareRelTracing(query), queryNumber, explainerName, "Preparing Rel Tracing", datasetName);
staticRuleHistory.add(staticKB.getRuleBase()); staticRuleHistory.add(staticKB.getRuleBase());
dynamicRuleHistory.add(dynamicKB.getRuleBase()); dynamicRuleHistory.add(dynamicKB.getRuleBase());
StatsUtil.timerWithOrderedQuery(this::chaseForRELPropagation,"Q"+queryIndex, explainerName, "Chase For Rel Tracing", datasetName); StatsUtil.timerWithOrderedQuery(this::chaseForRELPropagation, queryNumber, explainerName, "Chase For Rel Tracing", datasetName);
StatsUtil.recordSize((long) dynamicKB.getRuleBase().getRules().size(), "Q"+queryIndex, explainerName, "Dynamic RB size", datasetName); StatsUtil.recordSize((long) dynamicKB.getRuleBase().getRules().size(), queryNumber, explainerName, "Dynamic RB size", datasetName);
StatsUtil.recordSize((long) dynamicKB.getFactBase().size(), "Q"+queryIndex, explainerName, "Dynamic FB size", datasetName); StatsUtil.recordSize((long) dynamicKB.getFactBase().size(), queryNumber, explainerName, "Dynamic FB size", datasetName);
StatsUtil.timerWithOrderedQuery(() -> encodeClauses(query),"Q"+queryIndex, explainerName, "Encoding clauses", datasetName); StatsUtil.timerWithOrderedQuery(() -> encodeClauses(query), queryNumber, explainerName, "Encoding clauses", datasetName);
if (solver instanceof MARCOGMUSSolver) { if (solver instanceof MARCOGMUSSolver) {
StatsUtil.timerWithOrderedQuery(this::writeMarcoGCNF,"Q"+queryIndex, explainerName, "Writing GCNF", datasetName); StatsUtil.timerWithOrderedQuery(this::writeMarcoGCNF, queryNumber, explainerName, "Writing GCNF", datasetName);
StatsUtil.timerMarcoOrderedQueries(this::solveGMUSviaMarco,"Q"+queryIndex, explainerName, "Computing GMUSes via Marco", datasetName); StatsUtil.timerMarcoOrderedQueries(this::solveGMUSviaMarco, queryNumber, explainerName, "Computing GMUSes via Marco", datasetName);
StatsUtil.timerWithOrderedQuery(this::decodeGMUSesFromMarco,"Q"+queryIndex, explainerName, "Decoding GMUSes from Marco", datasetName); StatsUtil.timerWithOrderedQuery(this::decodeGMUSesFromMarco, queryNumber, explainerName, "Decoding GMUSes from Marco", datasetName);
} else if (solver instanceof Sat4JSolver) { } else if (solver instanceof Sat4JSolver) {
StatsUtil.timerWithOrderedQuery(this::solveGMUSviaSat4j,"Q"+queryIndex, explainerName, "Computing GMUSes with sat4j", datasetName); StatsUtil.timerWithOrderedQuery(this::solveGMUSviaSat4j, queryNumber, explainerName, "Computing GMUSes with sat4j", datasetName);
StatsUtil.timerWithOrderedQuery(this::decodeGMUSesFromSat4j,"Q"+queryIndex, explainerName, "Decoding GMUSes from sat4j", datasetName); StatsUtil.timerWithOrderedQuery(this::decodeGMUSesFromSat4j, queryNumber, explainerName, "Decoding GMUSes from sat4j", datasetName);
} }
StatsUtil.recordSize((long) explanations.size(), "Q"+queryIndex, explainerName, "Explanations", datasetName); StatsUtil.recordSize((long) explanations.size(), queryNumber, explainerName, "Explanations", datasetName);
} else if (queryInInitialFB) { } else if (queryInInitialFB) {
StatsUtil.timerWithOrderedQuery(() -> returnExplanationForQueryInFB(query),"Q"+queryIndex, explainerName, "Returning the explanation for query already in FB", datasetName); StatsUtil.timerWithOrderedQuery(() -> returnExplanationForQueryInFB(query), queryNumber, explainerName, "Returning the explanation for query already in FB", datasetName);
} else { } else {
returnEmptySetForExplanation(); returnEmptySetForExplanation();
} }
...@@ -311,11 +320,12 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp ...@@ -311,11 +320,12 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp
/** /**
* compute queryAncestorRules (a set of rules (nodes) on the subgraph of the Graph of Rule Dependency * compute queryAncestorRules (a set of rules (nodes) on the subgraph of the Graph of Rule Dependency
* that contain all ancestor rules of rules that produce the query) * that contain all ancestor rules of rules that produce the query)
*
* @param rb rulebase * @param rb rulebase
* @param a atom * @param a atom
* @return * @return
*/ */
static private Set<FORule> getAncestorRules (RuleBase rb, Atom a) { static private Set<FORule> getAncestorRules(RuleBase rb, Atom a) {
Set<FORule> ancestorRules = new LinkedHashSet<>(); Set<FORule> ancestorRules = new LinkedHashSet<>();
for (FORule rule : rb.getRulesByHeadPredicate(a.getPredicate())) { for (FORule rule : rb.getRulesByHeadPredicate(a.getPredicate())) {
...@@ -326,7 +336,7 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp ...@@ -326,7 +336,7 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp
); );
if (!unifiers.isEmpty()) { if (!unifiers.isEmpty()) {
ancestorRules.addAll(grd.getAncestorRules(rule)); ancestorRules.addAll(grd.getAncestorRules(rule,ancestorRules));
} }
} }
...@@ -335,7 +345,7 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp ...@@ -335,7 +345,7 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp
public void buildingGRD() { public void buildingGRD() {
grd = new GRDImpl(inputKB.getRuleBase()); grd = new GRDImpl(inputKB.getRuleBase(), List.of());
} }
public void transformRules() { public void transformRules() {
...@@ -358,6 +368,7 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp ...@@ -358,6 +368,7 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp
Atom queryWithFuncId = GRIRuleTransformer.instance().createAtomWithStoredFnTermIdentifier(query); Atom queryWithFuncId = GRIRuleTransformer.instance().createAtomWithStoredFnTermIdentifier(query);
if (staticKB.getFactBase().contains(queryWithFuncId)) { if (staticKB.getFactBase().contains(queryWithFuncId)) {
queryEntailed = true; queryEntailed = true;
this.entailedQueryCache.add(query);
} }
} }
...@@ -378,6 +389,7 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp ...@@ -378,6 +389,7 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp
public void clearAncestorRules() { public void clearAncestorRules() {
queryAncestorRules.clear(); queryAncestorRules.clear();
} }
public void computeAncestorRules(Atom query) { public void computeAncestorRules(Atom query) {
queryAncestorRules.addAll(getAncestorRules(inputKB.getRuleBase(), query)); queryAncestorRules.addAll(getAncestorRules(inputKB.getRuleBase(), query));
} }
...@@ -425,14 +437,13 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp ...@@ -425,14 +437,13 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp
} }
public void writeMarcoGCNF() { public void writeMarcoGCNF() {
marcoSolver.writeGCNF(encodingResult.propVarIDMap(), encodingResult.clauses(), encodingResult.nbGroup()); marcoSolver.writeGCNF(encodingResult.propVarIDMap(), encodingResult.clauses(), encodingResult.nbGroup(), gcnffile);
} }
public void solveGMUSviaMarco() { public void solveGMUSviaMarco() {
gmuses = marcoSolver.getGMUSes(gcnffile); gmuses = marcoSolver.getGMUSes(gcnffile);
} }
public void decodeGMUSesFromMarco() { public void decodeGMUSesFromMarco() {
explanations = getGMUSProcessor(solver).translateMARCOGMUS(gmuses, encodingResult.factIDMap(), encodingResult.ruleIDMap()); explanations = getGMUSProcessor(solver).translateMARCOGMUS(gmuses, encodingResult.factIDMap(), encodingResult.ruleIDMap());
} }
...@@ -445,17 +456,67 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp ...@@ -445,17 +456,67 @@ public abstract class AbstractStaticGRIBasedExplainer_KBGRI<ExplanationType> imp
explanations = getGMUSProcessor(solver).translateSAT4JGMUS(sat4jGmuses, encodingResult.factIDMap(), encodingResult.ruleIDMap()); explanations = getGMUSProcessor(solver).translateSAT4JGMUS(sat4jGmuses, encodingResult.factIDMap(), encodingResult.ruleIDMap());
} }
public void solveViaHybridSolver() {
var result = ((HybridSAT4JMARCOSolver) solver).solve(encodingResult);
switch (result.solver()) {
case MARCOGMUSSolver ignored -> {
explanations = getGMUSProcessor(solver).translateMARCOGMUS((Set<String>) result.solverResult(), encodingResult.factIDMap(), encodingResult.ruleIDMap());
}
case Sat4JSolver ignored ->
explanations = getGMUSProcessor(solver).translateSAT4JGMUS((List<List<List<Integer>>>) result.solverResult(), encodingResult.factIDMap(), encodingResult.ruleIDMap());
default -> throw new IllegalStateException("Unsupported solver");
}
}
abstract ExplanationProcessor_GRI getGMUSProcessor(Solver solver); abstract ExplanationProcessor_GRI getGMUSProcessor(Solver solver);
public boolean isQueryEntailed() {
return this.queryEntailed; public boolean isQueryEntailed(Atom query) {
if (this.entailedQueryCache.contains(query)) {
return true;
}
Atom queryWithFuncId = GRIRuleTransformer.instance().createAtomWithStoredFnTermIdentifier(query);
if (staticKB.getFactBase().contains(queryWithFuncId)) {
entailedQueryCache.add(query);
return true;
}
return false;
} }
public boolean isQueryInInitialFB() { public boolean isQueryInInitialFB(Atom query) {
return queryInInitialFB; return this.belongsToInitialFactbase.test(query);
} }
public Set<ExplanationType> getExplanations() { public Set<ExplanationType> getLastComputedExplanations() {
return explanations; return explanations;
} }
public GSATEncodingResult_GRI getEncoding() {
return encodingResult;
}
public String getPrintableStatistics() {
StringBuilder result = new StringBuilder();
result.append("\n\nStatistics for : " + this.getClass().getSimpleName() + "\n");
result.append("GRInstance size " + this.staticKB.getFactBase().size() + "\n");
result.append("number of clauses " + this.encodingResult.clauses().size() + "\n");
result.append("number of explanations " + this.explanations.size() + "\n");
result.append("\n");
return result.toString();
}
public String getPrintableStatisticsXML() {
StringBuilder result = new StringBuilder();
result.append("<statistics>\n");
result.append(" <component>").append(this.getClass().getSimpleName()).append("</component>\n");
result.append(" <grInstanceSize>").append(this.staticKB.getFactBase().size()).append("</grInstanceSize>\n");
result.append(" <numberOfClauses>").append(this.encodingResult.clauses().size()).append("</numberOfClauses>\n");
result.append(" <numberOfExplanations>").append(this.explanations.size()).append("</numberOfExplanations>\n");
result.append("</statistics>");
return result.toString();
}
} }
...@@ -312,4 +312,14 @@ public abstract class AbstractStaticGRIBasedExplainer_Baseline<ExplanationType> ...@@ -312,4 +312,14 @@ public abstract class AbstractStaticGRIBasedExplainer_Baseline<ExplanationType>
} }
abstract ExplanationProcessor_GRI getGMUSProcessor(Solver solver); abstract ExplanationProcessor_GRI getGMUSProcessor(Solver solver);
public boolean isQueryEntailed(Atom query){
throw new NotImplementedException();
}
public boolean isQueryInInitialFB(Atom query){
throw new NotImplementedException();
}
} }